Commit 6ab36e35 authored by Or Gerlitz's avatar Or Gerlitz Committed by David S. Miller

net/mlx5: E-Switch, Add operational mode to the SRIOV e-Switch

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: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3ea00443
...@@ -428,7 +428,7 @@ esw_fdb_set_vport_promisc_rule(struct mlx5_eswitch *esw, u32 vport) ...@@ -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); 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); int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
struct mlx5_core_dev *dev = esw->dev; struct mlx5_core_dev *dev = esw->dev;
...@@ -479,7 +479,7 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports) ...@@ -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); esw_warn(dev, "Failed to create flow group err(%d)\n", err);
goto out; goto out;
} }
esw->fdb_table.addr_grp = g; esw->fdb_table.legacy.addr_grp = g;
/* Allmulti group : One rule that forwards any mcast traffic */ /* Allmulti group : One rule that forwards any mcast traffic */
MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable, 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) ...@@ -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); esw_warn(dev, "Failed to create allmulti flow group err(%d)\n", err);
goto out; goto out;
} }
esw->fdb_table.allmulti_grp = g; esw->fdb_table.legacy.allmulti_grp = g;
/* Promiscuous group : /* Promiscuous group :
* One rule that forward all unmatched traffic from previous groups * 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) ...@@ -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); esw_warn(dev, "Failed to create promisc flow group err(%d)\n", err);
goto out; goto out;
} }
esw->fdb_table.promisc_grp = g; esw->fdb_table.legacy.promisc_grp = g;
out: out:
if (err) { if (err) {
if (!IS_ERR_OR_NULL(esw->fdb_table.allmulti_grp)) { if (!IS_ERR_OR_NULL(esw->fdb_table.legacy.allmulti_grp)) {
mlx5_destroy_flow_group(esw->fdb_table.allmulti_grp); mlx5_destroy_flow_group(esw->fdb_table.legacy.allmulti_grp);
esw->fdb_table.allmulti_grp = NULL; esw->fdb_table.legacy.allmulti_grp = NULL;
} }
if (!IS_ERR_OR_NULL(esw->fdb_table.addr_grp)) { if (!IS_ERR_OR_NULL(esw->fdb_table.legacy.addr_grp)) {
mlx5_destroy_flow_group(esw->fdb_table.addr_grp); mlx5_destroy_flow_group(esw->fdb_table.legacy.addr_grp);
esw->fdb_table.addr_grp = NULL; esw->fdb_table.legacy.addr_grp = NULL;
} }
if (!IS_ERR_OR_NULL(esw->fdb_table.fdb)) { if (!IS_ERR_OR_NULL(esw->fdb_table.fdb)) {
mlx5_destroy_flow_table(esw->fdb_table.fdb); mlx5_destroy_flow_table(esw->fdb_table.fdb);
...@@ -533,20 +533,20 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports) ...@@ -533,20 +533,20 @@ static int esw_create_fdb_table(struct mlx5_eswitch *esw, int nvports)
return err; 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) if (!esw->fdb_table.fdb)
return; return;
esw_debug(esw->dev, "Destroy FDB Table\n"); esw_debug(esw->dev, "Destroy FDB Table\n");
mlx5_destroy_flow_group(esw->fdb_table.promisc_grp); mlx5_destroy_flow_group(esw->fdb_table.legacy.promisc_grp);
mlx5_destroy_flow_group(esw->fdb_table.allmulti_grp); mlx5_destroy_flow_group(esw->fdb_table.legacy.allmulti_grp);
mlx5_destroy_flow_group(esw->fdb_table.addr_grp); mlx5_destroy_flow_group(esw->fdb_table.legacy.addr_grp);
mlx5_destroy_flow_table(esw->fdb_table.fdb); mlx5_destroy_flow_table(esw->fdb_table.fdb);
esw->fdb_table.fdb = NULL; esw->fdb_table.fdb = NULL;
esw->fdb_table.addr_grp = NULL; esw->fdb_table.legacy.addr_grp = NULL;
esw->fdb_table.allmulti_grp = NULL; esw->fdb_table.legacy.allmulti_grp = NULL;
esw->fdb_table.promisc_grp = NULL; esw->fdb_table.legacy.promisc_grp = NULL;
} }
/* E-Switch vport UC/MC lists management */ /* E-Switch vport UC/MC lists management */
...@@ -1540,7 +1540,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num) ...@@ -1540,7 +1540,7 @@ static void esw_disable_vport(struct mlx5_eswitch *esw, int vport_num)
} }
/* Public E-Switch API */ /* 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 err;
int i; int i;
...@@ -1561,11 +1561,14 @@ int mlx5_eswitch_enable_sriov(struct mlx5_eswitch *esw, int nvfs) ...@@ -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)) 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_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); esw_disable_vport(esw, 0);
err = esw_create_fdb_table(esw, nvfs + 1); err = esw_create_legacy_fdb_table(esw, nvfs + 1);
if (err) if (err)
goto abort; goto abort;
...@@ -1590,8 +1593,8 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) ...@@ -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) MLX5_CAP_GEN(esw->dev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
return; return;
esw_info(esw->dev, "disable SRIOV: active vports(%d)\n", esw_info(esw->dev, "disable SRIOV: active vports(%d) mode(%d)\n",
esw->enabled_vports); esw->enabled_vports, esw->mode);
mc_promisc = esw->mc_promisc; mc_promisc = esw->mc_promisc;
...@@ -1601,8 +1604,9 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw) ...@@ -1601,8 +1604,9 @@ void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw)
if (mc_promisc && mc_promisc->uplink_rule) if (mc_promisc && mc_promisc->uplink_rule)
mlx5_del_flow_rule(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 */ /* VPORT 0 (PF) must be enabled back with non-sriov configuration */
esw_enable_vport(esw, 0, UC_ADDR_CHANGE); esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
} }
...@@ -1673,6 +1677,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) ...@@ -1673,6 +1677,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
esw->total_vports = total_vports; esw->total_vports = total_vports;
esw->enabled_vports = 0; esw->enabled_vports = 0;
esw->mode = SRIOV_NONE;
dev->priv.eswitch = esw; dev->priv.eswitch = esw;
esw_enable_vport(esw, 0, UC_ADDR_CHANGE); esw_enable_vport(esw, 0, UC_ADDR_CHANGE);
......
...@@ -134,9 +134,19 @@ struct mlx5_l2_table { ...@@ -134,9 +134,19 @@ struct mlx5_l2_table {
struct mlx5_eswitch_fdb { struct mlx5_eswitch_fdb {
void *fdb; void *fdb;
union {
struct legacy_fdb {
struct mlx5_flow_group *addr_grp; struct mlx5_flow_group *addr_grp;
struct mlx5_flow_group *allmulti_grp; struct mlx5_flow_group *allmulti_grp;
struct mlx5_flow_group *promisc_grp; struct mlx5_flow_group *promisc_grp;
} legacy;
};
};
enum {
SRIOV_NONE,
SRIOV_LEGACY,
SRIOV_OFFLOADS
}; };
struct mlx5_eswitch { struct mlx5_eswitch {
...@@ -153,13 +163,14 @@ struct mlx5_eswitch { ...@@ -153,13 +163,14 @@ struct mlx5_eswitch {
*/ */
struct mutex state_lock; struct mutex state_lock;
struct esw_mc_addr *mc_promisc; struct esw_mc_addr *mc_promisc;
int mode;
}; };
/* E-Switch API */ /* E-Switch API */
int mlx5_eswitch_init(struct mlx5_core_dev *dev); int mlx5_eswitch_init(struct mlx5_core_dev *dev);
void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw); void mlx5_eswitch_cleanup(struct mlx5_eswitch *esw);
void mlx5_eswitch_vport_event(struct mlx5_eswitch *esw, struct mlx5_eqe *eqe); 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); void mlx5_eswitch_disable_sriov(struct mlx5_eswitch *esw);
int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw,
int vport, u8 mac[ETH_ALEN]); int vport, u8 mac[ETH_ALEN]);
......
...@@ -167,7 +167,7 @@ int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -167,7 +167,7 @@ int mlx5_core_sriov_configure(struct pci_dev *pdev, int num_vfs)
mlx5_core_init_vfs(dev, num_vfs); mlx5_core_init_vfs(dev, num_vfs);
#ifdef CONFIG_MLX5_CORE_EN #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 #endif
return num_vfs; return num_vfs;
...@@ -209,7 +209,8 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev) ...@@ -209,7 +209,8 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev)
mlx5_core_init_vfs(dev, cur_vfs); mlx5_core_init_vfs(dev, cur_vfs);
#ifdef CONFIG_MLX5_CORE_EN #ifdef CONFIG_MLX5_CORE_EN
if (cur_vfs) if (cur_vfs)
mlx5_eswitch_enable_sriov(dev->priv.eswitch, cur_vfs); mlx5_eswitch_enable_sriov(dev->priv.eswitch, cur_vfs,
SRIOV_LEGACY);
#endif #endif
enable_vfs(dev, cur_vfs); enable_vfs(dev, cur_vfs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment