Merge tag 'gcc-plugins-v5.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / vdpa / mlx5 / net / mlx5_vnet.c
index 74264e5..f1d5481 100644 (file)
@@ -1,18 +1,28 @@
 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
 /* Copyright (c) 2020 Mellanox Technologies Ltd. */
 
+#include <linux/module.h>
 #include <linux/vdpa.h>
+#include <linux/vringh.h>
+#include <uapi/linux/virtio_net.h>
 #include <uapi/linux/virtio_ids.h>
 #include <linux/virtio_config.h>
+#include <linux/auxiliary_bus.h>
+#include <linux/mlx5/cq.h>
 #include <linux/mlx5/qp.h>
 #include <linux/mlx5/device.h>
+#include <linux/mlx5/driver.h>
 #include <linux/mlx5/vport.h>
 #include <linux/mlx5/fs.h>
-#include <linux/mlx5/device.h>
-#include "mlx5_vnet.h"
-#include "mlx5_vdpa_ifc.h"
+#include <linux/mlx5/mlx5_ifc_vdpa.h>
 #include "mlx5_vdpa.h"
 
+MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox VDPA driver");
+MODULE_LICENSE("Dual BSD/GPL");
+
+#define to_mlx5_vdpa_ndev(__mvdev)                                             \
+       container_of(__mvdev, struct mlx5_vdpa_net, mvdev)
 #define to_mvdev(__vdev) container_of((__vdev), struct mlx5_vdpa_dev, vdev)
 
 #define VALID_FEATURES_MASK                                                                        \
@@ -159,6 +169,11 @@ static bool mlx5_vdpa_debug;
                        mlx5_vdpa_info(mvdev, "%s\n", #_status);                                   \
        } while (0)
 
+static inline u32 mlx5_vdpa_max_qps(int max_vqs)
+{
+       return max_vqs / 2;
+}
+
 static void print_status(struct mlx5_vdpa_dev *mvdev, u8 status, bool set)
 {
        if (status & ~VALID_STATUS_MASK)
@@ -1522,6 +1537,11 @@ static inline bool mlx5_vdpa_is_little_endian(struct mlx5_vdpa_dev *mvdev)
                (mvdev->actual_features & (1ULL << VIRTIO_F_VERSION_1));
 }
 
+static __virtio16 cpu_to_mlx5vdpa16(struct mlx5_vdpa_dev *mvdev, u16 val)
+{
+       return __cpu_to_virtio16(mlx5_vdpa_is_little_endian(mvdev), val);
+}
+
 static int mlx5_vdpa_set_features(struct vdpa_device *vdev, u64 features)
 {
        struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
@@ -1535,8 +1555,8 @@ static int mlx5_vdpa_set_features(struct vdpa_device *vdev, u64 features)
                return err;
 
        ndev->mvdev.actual_features = features & ndev->mvdev.mlx_features;
-       ndev->config.mtu = __cpu_to_virtio16(mlx5_vdpa_is_little_endian(mvdev),
-                                            ndev->mtu);
+       ndev->config.mtu = cpu_to_mlx5vdpa16(mvdev, ndev->mtu);
+       ndev->config.status |= cpu_to_mlx5vdpa16(mvdev, VIRTIO_NET_S_LINK_UP);
        return err;
 }
 
@@ -1653,6 +1673,9 @@ static int mlx5_vdpa_change_map(struct mlx5_vdpa_net *ndev, struct vhost_iotlb *
        if (err)
                goto err_mr;
 
+       if (!(ndev->mvdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
+               return 0;
+
        restore_channels_info(ndev);
        err = setup_driver(ndev);
        if (err)
@@ -1920,8 +1943,11 @@ static void init_mvqs(struct mlx5_vdpa_net *ndev)
        }
 }
 
-void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
+static int mlx5v_probe(struct auxiliary_device *adev,
+                      const struct auxiliary_device_id *id)
 {
+       struct mlx5_adev *madev = container_of(adev, struct mlx5_adev, adev);
+       struct mlx5_core_dev *mdev = madev->mdev;
        struct virtio_net_config *config;
        struct mlx5_vdpa_dev *mvdev;
        struct mlx5_vdpa_net *ndev;
@@ -1935,7 +1961,7 @@ void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
        ndev = vdpa_alloc_device(struct mlx5_vdpa_net, mvdev.vdev, mdev->device, &mlx5_vdpa_ops,
                                 2 * mlx5_vdpa_max_qps(max_vqs));
        if (IS_ERR(ndev))
-               return ndev;
+               return PTR_ERR(ndev);
 
        ndev->mvdev.max_vqs = max_vqs;
        mvdev = &ndev->mvdev;
@@ -1964,7 +1990,8 @@ void *mlx5_vdpa_add_dev(struct mlx5_core_dev *mdev)
        if (err)
                goto err_reg;
 
-       return ndev;
+       dev_set_drvdata(&adev->dev, ndev);
+       return 0;
 
 err_reg:
        free_resources(ndev);
@@ -1973,10 +2000,28 @@ err_res:
 err_mtu:
        mutex_destroy(&ndev->reslock);
        put_device(&mvdev->vdev.dev);
-       return ERR_PTR(err);
+       return err;
 }
 
-void mlx5_vdpa_remove_dev(struct mlx5_vdpa_dev *mvdev)
+static void mlx5v_remove(struct auxiliary_device *adev)
 {
+       struct mlx5_vdpa_dev *mvdev = dev_get_drvdata(&adev->dev);
+
        vdpa_unregister_device(&mvdev->vdev);
 }
+
+static const struct auxiliary_device_id mlx5v_id_table[] = {
+       { .name = MLX5_ADEV_NAME ".vnet", },
+       {},
+};
+
+MODULE_DEVICE_TABLE(auxiliary, mlx5v_id_table);
+
+static struct auxiliary_driver mlx5v_driver = {
+       .name = "vnet",
+       .probe = mlx5v_probe,
+       .remove = mlx5v_remove,
+       .id_table = mlx5v_id_table,
+};
+
+module_auxiliary_driver(mlx5v_driver);