#include <linux/if_ether.h>
 #include <linux/if_link.h>
+#include <net/devlink.h>
 #include <linux/mlx5/device.h>
 
 #define MLX5_MAX_UC_PER_VPORT(dev) \
 struct mlx5_flow_rule *
 mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn);
 
+int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode);
+int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode);
+
 #define MLX5_DEBUG_ESWITCH_MASK BIT(3)
 
 #define esw_info(dev, format, ...)                             \
 
 #ifdef CONFIG_RFS_ACCEL
 #include <linux/cpu_rmap.h>
 #endif
+#include <net/devlink.h>
 #include "mlx5_core.h"
 #include "fs_core.h"
 #ifdef CONFIG_MLX5_CORE_EN
                      void *data);
 };
 
+static const struct devlink_ops mlx5_devlink_ops = {
+#ifdef CONFIG_MLX5_CORE_EN
+       .eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
+       .eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
+#endif
+};
 
 static int init_one(struct pci_dev *pdev,
                    const struct pci_device_id *id)
 {
        struct mlx5_core_dev *dev;
+       struct devlink *devlink;
        struct mlx5_priv *priv;
        int err;
 
-       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-       if (!dev) {
+       devlink = devlink_alloc(&mlx5_devlink_ops, sizeof(*dev));
+       if (!devlink) {
                dev_err(&pdev->dev, "kzalloc failed\n");
                return -ENOMEM;
        }
+
+       dev = devlink_priv(devlink);
        priv = &dev->priv;
        priv->pci_dev_data = id->driver_data;
 
                goto clean_health;
        }
 
+       err = devlink_register(devlink, &pdev->dev);
+       if (err)
+               goto clean_load;
+
        return 0;
 
+clean_load:
+       mlx5_unload_one(dev, priv);
 clean_health:
        mlx5_health_cleanup(dev);
 close_pci:
        mlx5_pci_close(dev, priv);
 clean_dev:
        pci_set_drvdata(pdev, NULL);
-       kfree(dev);
+       devlink_free(devlink);
 
        return err;
 }
 static void remove_one(struct pci_dev *pdev)
 {
        struct mlx5_core_dev *dev  = pci_get_drvdata(pdev);
+       struct devlink *devlink = priv_to_devlink(dev);
        struct mlx5_priv *priv = &dev->priv;
 
+       devlink_unregister(devlink);
        if (mlx5_unload_one(dev, priv)) {
                dev_err(&dev->pdev->dev, "mlx5_unload_one failed\n");
                mlx5_health_cleanup(dev);
        mlx5_health_cleanup(dev);
        mlx5_pci_close(dev, priv);
        pci_set_drvdata(pdev, NULL);
-       kfree(dev);
+       devlink_free(devlink);
 }
 
 static pci_ers_result_t mlx5_pci_err_detected(struct pci_dev *pdev,