net/mlx5: E-Switch, Add operational mode to the SRIOV e-Switch
authorOr Gerlitz <ogerlitz@mellanox.com>
Fri, 1 Jul 2016 11:50:54 +0000 (14:50 +0300)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Jul 2016 18:40:39 +0000 (14:40 -0400)
Define three modes for the SRIOV e-switch operation, none (SRIOV_NONE,
none of the VF vports are enabled), legacy (SRIOV_LEGACY, the current mode)
and sriov offloads (SRIOV_OFFLOADS). Currently, when in SRIOV, only the
legacy mode is supported, where steering rules are of the form:

        destination mac --> VF vport

This patch does not change any functionality.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/sriov.c

index aebbd6ccb9fe29fb90d46518f854252236d35934..8068dde172e7127b842b52a4feaaf80d8d91366d 100644 (file)
@@ -428,7 +428,7 @@ esw_fdb_set_vport_promisc_rule(struct mlx5_eswitch *esw, u32 vport)
        return __esw_fdb_set_vport_rule(esw, vport, true, mac_c, mac_v);
 }
 
-static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
+static int esw_create_legacy_fdb_table(struct mlx5_eswitch *esw, int nvports)
 {
        int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
        struct mlx5_core_dev *dev = esw->dev;
@@ -479,7 +479,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
                esw_warn(dev, "Failed to create flow group err(%d)\n", err);
                goto out;
        }
-       esw->fdb_table.addr_grp = g;
+       esw->fdb_table.legacy.addr_grp = g;
 
        /* Allmulti group : One rule that forwards any mcast traffic */
        MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
@@ -494,7 +494,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
                esw_warn(dev, "Failed to create allmulti flow group err(%d)\n", err);
                goto out;
        }
-       esw->fdb_table.allmulti_grp = g;
+       esw->fdb_table.legacy.allmulti_grp = g;
 
        /* Promiscuous group :
         * One rule that forward all unmatched traffic from previous groups
@@ -511,17 +511,17 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
                esw_warn(dev, "Failed to create promisc flow group err(%d)\n", err);
                goto out;
        }
-       esw->fdb_table.promisc_grp = g;
+       esw->fdb_table.legacy.promisc_grp = g;
 
 out:
        if (err) {
-               if (!IS_ERR_OR_NULL(esw->fdb_table.allmulti_grp)) {
-                       mlx5_destroy_flow_group(esw->fdb_table.allmulti_grp);
-                       esw->fdb_table.allmulti_grp = NULL;
+               if (!IS_ERR_OR_NULL(esw->fdb_table.legacy.allmulti_grp)) {
+                       mlx5_destroy_flow_group(esw->fdb_table.legacy.allmulti_grp);
+                       esw->fdb_table.legacy.allmulti_grp = NULL;
                }
-               if (!IS_ERR_OR_NULL(esw->fdb_table.addr_grp)) {
-                       mlx5_destroy_flow_group(esw->fdb_table.addr_grp);
-                       esw->fdb_table.addr_grp = NULL;
+               if (!IS_ERR_OR_NULL(esw->fdb_table.legacy.addr_grp)) {
+                       mlx5_destroy_flow_group(esw->fdb_table.legacy.addr_grp);
+                       esw->fdb_table.legacy.addr_grp = NULL;
                }
                if (!IS_ERR_OR_NULL(esw->fdb_table.fdb)) {
                        mlx5_destroy_flow_table(esw->fdb_table.fdb);
@@ -533,20 +533,20 @@ out:
        return err;
 }
 
-static void esw_destroy_fdb_table(struct mlx5_eswitch *esw)
+static void esw_destroy_legacy_fdb_table(struct mlx5_eswitch *esw)
 {
        if (!esw->fdb_table.fdb)
                return;
 
        esw_debug(esw->dev, "Destroy FDB Table\n");
-       mlx5_destroy_flow_group(esw->fdb_table.promisc_grp);
-       mlx5_destroy_flow_group(esw->fdb_table.allmulti_grp);
-       mlx5_destroy_flow_group(esw->fdb_table.addr_grp);
+       mlx5_destroy_flow_group(esw->fdb_table.legacy.promisc_grp);
+       mlx5_destroy_flow_group(esw->fdb_table.legacy.allmulti_grp);
+       mlx5_destroy_flow_group(esw->fdb_table.legacy.addr_grp);
        mlx5_destroy_flow_table(esw->fdb_table.fdb);
        esw->fdb_table.fdb = NULL;
-       esw->fdb_table.addr_grp = NULL;
-       esw->fdb_table.allmulti_grp = NULL;
-       esw->fdb_table.promisc_grp = NULL;
+       esw->fdb_table.legacy.addr_grp = NULL;
+       esw->fdb_table.legacy.allmulti_grp = NULL;
+       esw->fdb_table.legacy.promisc_grp = NULL;
 }
 
 /* E-Switch vport UC/MC lists management */
@@ -1540,7 +1540,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num)
 }
 
 /* Public E-Switch API */
-int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs)
+int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode)
 {
        int err;
        int i;
@@ -1561,11 +1561,14 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs)
        if (!MLX5_CAP_ESW_EGRESS_ACL(esw->dev, ft_support))
                esw_warn(esw->dev, "E-Switch engress ACL is not supported by FW\n");
 
-       esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d)\n", nvfs);
+       esw_info(esw->dev, "E-Switch enable SRIOV: nvfs(%d) mode (%d)\n", nvfs, mode);
+       if (mode != SRIOV_LEGACY)
+               return -EINVAL;
 
+       esw->mode = mode;
        esw_disable_vport(esw, 0);
 
-       err = esw_create_fdb_table(esw, nvfs + 1);
+       err = esw_create_legacy_fdb_table(esw, nvfs + 1);
        if (err)
                goto abort;
 
@@ -1590,8 +1593,8 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
            MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
                return;
 
-       esw_info(esw->dev, "disable SRIOV: active vports(%d)\n",
-                esw->enabled_vports);
+       esw_info(esw->dev, "disable SRIOV: active vports(%d) mode(%d)\n",
+                esw->enabled_vports, esw->mode);
 
        mc_promisc = esw->mc_promisc;
 
@@ -1601,8 +1604,9 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
        if (mc_promisc && mc_promisc->uplink_rule)
                mlx5_del_flow_rule(mc_promisc->uplink_rule);
 
-       esw_destroy_fdb_table(esw);
+       esw_destroy_legacy_fdb_table(esw);
 
+       esw->mode = SRIOV_NONE;
        /* VPORT 0 (PF) must be enabled back with non-sriov configuration */
        esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
 }
@@ -1673,6 +1677,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
 
        esw->total_vports = total_vports;
        esw->enabled_vports = 0;
+       esw->mode = SRIOV_NONE;
 
        dev->priv.eswitch = esw;
        esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
index fd6800256d4a316cfcb7d49c9f4529355e5d7b8e..544fbfe8bcbd97bdb0e13ec494e92911e3e8171f 100644 (file)
@@ -134,9 +134,19 @@ struct mlx5_l2_table {
 
 struct mlx5_eswitch_fdb {
        void *fdb;
-       struct mlx5_flow_group *addr_grp;
-       struct mlx5_flow_group *allmulti_grp;
-       struct mlx5_flow_group *promisc_grp;
+       union {
+               struct legacy_fdb {
+                       struct mlx5_flow_group *addr_grp;
+                       struct mlx5_flow_group *allmulti_grp;
+                       struct mlx5_flow_group *promisc_grp;
+               } legacy;
+       };
+};
+
+enum {
+       SRIOV_NONE,
+       SRIOV_LEGACY,
+       SRIOV_OFFLOADS
 };
 
 struct mlx5_eswitch {
@@ -153,13 +163,14 @@ struct mlx5_eswitch {
         */
        struct mutex            state_lock;
        struct esw_mc_addr      *mc_promisc;
+       int                     mode;
 };
 
 /* E-Switch API */
 int mlx5_eswitch_init(struct mlx5_core_dev *dev);
 void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
 void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe);
-int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs);
+int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs, int mode);
 void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
 int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
                               int vport, u8 mac[ETH_ALEN]);
index d6a3f412ba9f03cf1de7df333af00b6a46185508..b380a6bc1f855223c0af19d9db28adb9c8150876 100644 (file)
@@ -167,7 +167,7 @@ int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
 
        mlx5_core_init_vfs(dev, num_vfs);
 #ifdef CONFIG_MLX5_CORE_EN
-       mlx5_eswitch_enable_sriov(dev->priv.eswitch, num_vfs);
+       mlx5_eswitch_enable_sriov(dev->priv.eswitch, num_vfs, SRIOV_LEGACY);
 #endif
 
        return num_vfs;
@@ -209,7 +209,8 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
        mlx5_core_init_vfs(dev, cur_vfs);
 #ifdef CONFIG_MLX5_CORE_EN
        if (cur_vfs)
-               mlx5_eswitch_enable_sriov(dev->priv.eswitch, cur_vfs);
+               mlx5_eswitch_enable_sriov(dev->priv.eswitch, cur_vfs,
+                                         SRIOV_LEGACY);
 #endif
 
        enable_vfs(dev, cur_vfs);