net/mlx5: Introducing E-Switch and l2 table
[cascardo/linux.git] / drivers / net / ethernet / mellanox / mlx5 / core / main.c
index 4ac8d4c..c6de324 100644 (file)
@@ -49,6 +49,9 @@
 #include <linux/delay.h>
 #include <linux/mlx5/mlx5_ifc.h>
 #include "mlx5_core.h"
+#ifdef CONFIG_MLX5_CORE_EN
+#include "eswitch.h"
+#endif
 
 MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
 MODULE_DESCRIPTION("Mellanox Connect-IB, ConnectX-4 core driver");
@@ -454,6 +457,9 @@ static int set_hca_ctrl(struct mlx5_core_dev *dev)
        struct mlx5_reg_host_endianess he_out;
        int err;
 
+       if (!mlx5_core_is_pf(dev))
+               return 0;
+
        memset(&he_in, 0, sizeof(he_in));
        he_in.he = MLX5_SET_HOST_ENDIANNESS;
        err = mlx5_core_access_reg(dev, &he_in,  sizeof(he_in),
@@ -462,42 +468,39 @@ static int set_hca_ctrl(struct mlx5_core_dev *dev)
        return err;
 }
 
-static int mlx5_core_enable_hca(struct mlx5_core_dev *dev)
+int mlx5_core_enable_hca(struct mlx5_core_dev *dev, u16 func_id)
 {
+       u32 out[MLX5_ST_SZ_DW(enable_hca_out)];
+       u32 in[MLX5_ST_SZ_DW(enable_hca_in)];
        int err;
-       struct mlx5_enable_hca_mbox_in in;
-       struct mlx5_enable_hca_mbox_out out;
 
-       memset(&in, 0, sizeof(in));
-       memset(&out, 0, sizeof(out));
-       in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_ENABLE_HCA);
+       memset(in, 0, sizeof(in));
+       MLX5_SET(enable_hca_in, in, opcode, MLX5_CMD_OP_ENABLE_HCA);
+       MLX5_SET(enable_hca_in, in, function_id, func_id);
+       memset(out, 0, sizeof(out));
+
        err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
        if (err)
                return err;
 
-       if (out.hdr.status)
-               return mlx5_cmd_status_to_err(&out.hdr);
-
-       return 0;
+       return mlx5_cmd_status_to_err_v2(out);
 }
 
-static int mlx5_core_disable_hca(struct mlx5_core_dev *dev)
+int mlx5_core_disable_hca(struct mlx5_core_dev *dev, u16 func_id)
 {
+       u32 out[MLX5_ST_SZ_DW(disable_hca_out)];
+       u32 in[MLX5_ST_SZ_DW(disable_hca_in)];
        int err;
-       struct mlx5_disable_hca_mbox_in in;
-       struct mlx5_disable_hca_mbox_out out;
 
-       memset(&in, 0, sizeof(in));
-       memset(&out, 0, sizeof(out));
-       in.hdr.opcode = cpu_to_be16(MLX5_CMD_OP_DISABLE_HCA);
-       err = mlx5_cmd_exec(dev, &in, sizeof(in), &out, sizeof(out));
+       memset(in, 0, sizeof(in));
+       MLX5_SET(disable_hca_in, in, opcode, MLX5_CMD_OP_DISABLE_HCA);
+       MLX5_SET(disable_hca_in, in, function_id, func_id);
+       memset(out, 0, sizeof(out));
+       err = mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
        if (err)
                return err;
 
-       if (out.hdr.status)
-               return mlx5_cmd_status_to_err(&out.hdr);
-
-       return 0;
+       return mlx5_cmd_status_to_err_v2(out);
 }
 
 static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
@@ -942,7 +945,7 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
 
        mlx5_pagealloc_init(dev);
 
-       err = mlx5_core_enable_hca(dev);
+       err = mlx5_core_enable_hca(dev, 0);
        if (err) {
                dev_err(&pdev->dev, "enable hca failed\n");
                goto err_pagealloc_cleanup;
@@ -1052,6 +1055,20 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
        mlx5_init_srq_table(dev);
        mlx5_init_mr_table(dev);
 
+#ifdef CONFIG_MLX5_CORE_EN
+       err = mlx5_eswitch_init(dev);
+       if (err) {
+               dev_err(&pdev->dev, "eswitch init failed %d\n", err);
+               goto err_reg_dev;
+       }
+#endif
+
+       err = mlx5_sriov_init(dev);
+       if (err) {
+               dev_err(&pdev->dev, "sriov init failed %d\n", err);
+               goto err_sriov;
+       }
+
        err = mlx5_register_device(dev);
        if (err) {
                dev_err(&pdev->dev, "mlx5_register_device failed %d\n", err);
@@ -1068,6 +1085,13 @@ out:
 
        return 0;
 
+err_sriov:
+       if (mlx5_sriov_cleanup(dev))
+               dev_err(&dev->pdev->dev, "sriov cleanup failed\n");
+
+#ifdef CONFIG_MLX5_CORE_EN
+       mlx5_eswitch_cleanup(dev->priv.eswitch);
+#endif
 err_reg_dev:
        mlx5_cleanup_mr_table(dev);
        mlx5_cleanup_srq_table(dev);
@@ -1106,7 +1130,7 @@ reclaim_boot_pages:
        mlx5_reclaim_startup_pages(dev);
 
 err_disable_hca:
-       mlx5_core_disable_hca(dev);
+       mlx5_core_disable_hca(dev, 0);
 
 err_pagealloc_cleanup:
        mlx5_pagealloc_cleanup(dev);
@@ -1123,6 +1147,13 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
 {
        int err = 0;
 
+       err = mlx5_sriov_cleanup(dev);
+       if (err) {
+               dev_warn(&dev->pdev->dev, "%s: sriov cleanup failed - abort\n",
+                        __func__);
+               return err;
+       }
+
        mutex_lock(&dev->intf_state_mutex);
        if (dev->interface_state == MLX5_INTERFACE_STATE_DOWN) {
                dev_warn(&dev->pdev->dev, "%s: interface is down, NOP\n",
@@ -1130,6 +1161,10 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
                goto out;
        }
        mlx5_unregister_device(dev);
+#ifdef CONFIG_MLX5_CORE_EN
+       mlx5_eswitch_cleanup(dev->priv.eswitch);
+#endif
+
        mlx5_cleanup_mr_table(dev);
        mlx5_cleanup_srq_table(dev);
        mlx5_cleanup_qp_table(dev);
@@ -1149,7 +1184,7 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv)
        }
        mlx5_pagealloc_stop(dev);
        mlx5_reclaim_startup_pages(dev);
-       mlx5_core_disable_hca(dev);
+       mlx5_core_disable_hca(dev, 0);
        mlx5_pagealloc_cleanup(dev);
        mlx5_cmd_cleanup(dev);
 
@@ -1195,6 +1230,7 @@ static int init_one(struct pci_dev *pdev,
                return -ENOMEM;
        }
        priv = &dev->priv;
+       priv->pci_dev_data = id->driver_data;
 
        pci_set_drvdata(pdev, dev);
 
@@ -1365,12 +1401,12 @@ static const struct pci_error_handlers mlx5_err_handler = {
 };
 
 static const struct pci_device_id mlx5_core_pci_table[] = {
-       { PCI_VDEVICE(MELLANOX, 0x1011) }, /* Connect-IB */
-       { PCI_VDEVICE(MELLANOX, 0x1012) }, /* Connect-IB VF */
-       { PCI_VDEVICE(MELLANOX, 0x1013) }, /* ConnectX-4 */
-       { PCI_VDEVICE(MELLANOX, 0x1014) }, /* ConnectX-4 VF */
-       { PCI_VDEVICE(MELLANOX, 0x1015) }, /* ConnectX-4LX */
-       { PCI_VDEVICE(MELLANOX, 0x1016) }, /* ConnectX-4LX VF */
+       { PCI_VDEVICE(MELLANOX, 0x1011) },                      /* Connect-IB */
+       { PCI_VDEVICE(MELLANOX, 0x1012), MLX5_PCI_DEV_IS_VF},   /* Connect-IB VF */
+       { PCI_VDEVICE(MELLANOX, 0x1013) },                      /* ConnectX-4 */
+       { PCI_VDEVICE(MELLANOX, 0x1014), MLX5_PCI_DEV_IS_VF},   /* ConnectX-4 VF */
+       { PCI_VDEVICE(MELLANOX, 0x1015) },                      /* ConnectX-4LX */
+       { PCI_VDEVICE(MELLANOX, 0x1016), MLX5_PCI_DEV_IS_VF},   /* ConnectX-4LX VF */
        { 0, }
 };
 
@@ -1381,7 +1417,8 @@ static struct pci_driver mlx5_core_driver = {
        .id_table       = mlx5_core_pci_table,
        .probe          = init_one,
        .remove         = remove_one,
-       .err_handler    = &mlx5_err_handler
+       .err_handler    = &mlx5_err_handler,
+       .sriov_configure   = mlx5_core_sriov_configure,
 };
 
 static int __init init(void)