Commit a4b97ab4 authored by Mark Bloch's avatar Mark Bloch Committed by Saeed Mahameed

net/mlx5: E-Switch, Create generic header struct to be used by representors

Now that we don't store type dependent data in struct mlx5_eswitch_rep
we can create a generic interface, and representor type.

struct mlx5_eswitch_rep will store an array of interfaces, each
interface is used by a different representor type.

Once we moved to a more generic interface, rdma driver representors can
be added and utilize the same mechanism as the Ethernet driver
representors use.
Signed-off-by: default avatarMark Bloch <markb@mellanox.com>
Reviewed-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 5ed99fb4
...@@ -1086,7 +1086,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1086,7 +1086,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
rpriv->netdev = netdev; rpriv->netdev = netdev;
rpriv->rep = rep; rpriv->rep = rep;
rep->priv = rpriv; rep->rep_if[REP_ETH].priv = rpriv;
INIT_LIST_HEAD(&rpriv->vport_sqs_list); INIT_LIST_HEAD(&rpriv->vport_sqs_list);
err = mlx5e_attach_netdev(netdev_priv(netdev)); err = mlx5e_attach_netdev(netdev_priv(netdev));
...@@ -1103,7 +1103,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1103,7 +1103,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
goto err_detach_netdev; goto err_detach_netdev;
} }
uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch); uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch, REP_ETH);
upriv = netdev_priv(uplink_rpriv->netdev); upriv = netdev_priv(uplink_rpriv->netdev);
err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb, err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb,
upriv); upriv);
...@@ -1146,7 +1146,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep) ...@@ -1146,7 +1146,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
struct mlx5e_priv *upriv; struct mlx5e_priv *upriv;
unregister_netdev(netdev); unregister_netdev(netdev);
uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch); uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch,
REP_ETH);
upriv = netdev_priv(uplink_rpriv->netdev); upriv = netdev_priv(uplink_rpriv->netdev);
tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb, tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb,
upriv); upriv);
...@@ -1164,11 +1165,11 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv) ...@@ -1164,11 +1165,11 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv)
int vport; int vport;
for (vport = 1; vport < total_vfs; vport++) { for (vport = 1; vport < total_vfs; vport++) {
struct mlx5_eswitch_rep rep = {}; struct mlx5_eswitch_rep_if rep_if = {};
rep.load = mlx5e_vport_rep_load; rep_if.load = mlx5e_vport_rep_load;
rep.unload = mlx5e_vport_rep_unload; rep_if.unload = mlx5e_vport_rep_unload;
mlx5_eswitch_register_vport_rep(esw, vport, &rep); mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH);
} }
} }
...@@ -1180,24 +1181,24 @@ static void mlx5e_rep_unregister_vf_vports(struct mlx5e_priv *priv) ...@@ -1180,24 +1181,24 @@ static void mlx5e_rep_unregister_vf_vports(struct mlx5e_priv *priv)
int vport; int vport;
for (vport = 1; vport < total_vfs; vport++) for (vport = 1; vport < total_vfs; vport++)
mlx5_eswitch_unregister_vport_rep(esw, vport); mlx5_eswitch_unregister_vport_rep(esw, vport, REP_ETH);
} }
void mlx5e_register_vport_reps(struct mlx5e_priv *priv) void mlx5e_register_vport_reps(struct mlx5e_priv *priv)
{ {
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_eswitch *esw = mdev->priv.eswitch; struct mlx5_eswitch *esw = mdev->priv.eswitch;
struct mlx5_eswitch_rep_if rep_if;
struct mlx5e_rep_priv *rpriv; struct mlx5e_rep_priv *rpriv;
struct mlx5_eswitch_rep rep;
rpriv = priv->ppriv; rpriv = priv->ppriv;
rpriv->netdev = priv->netdev; rpriv->netdev = priv->netdev;
rep.load = mlx5e_nic_rep_load; rep_if.load = mlx5e_nic_rep_load;
rep.unload = mlx5e_nic_rep_unload; rep_if.unload = mlx5e_nic_rep_unload;
rep.priv = rpriv; rep_if.priv = rpriv;
INIT_LIST_HEAD(&rpriv->vport_sqs_list); INIT_LIST_HEAD(&rpriv->vport_sqs_list);
mlx5_eswitch_register_vport_rep(esw, 0, &rep); /* UPLINK PF vport*/ mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_ETH); /* UPLINK PF vport*/
mlx5e_rep_register_vf_vports(priv); /* VFs vports */ mlx5e_rep_register_vf_vports(priv); /* VFs vports */
} }
...@@ -1208,7 +1209,7 @@ void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv) ...@@ -1208,7 +1209,7 @@ void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv)
struct mlx5_eswitch *esw = mdev->priv.eswitch; struct mlx5_eswitch *esw = mdev->priv.eswitch;
mlx5e_rep_unregister_vf_vports(priv); /* VFs vports */ mlx5e_rep_unregister_vf_vports(priv); /* VFs vports */
mlx5_eswitch_unregister_vport_rep(esw, 0); /* UPLINK PF*/ mlx5_eswitch_unregister_vport_rep(esw, 0, REP_ETH); /* UPLINK PF*/
} }
void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev) void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev)
......
...@@ -64,7 +64,7 @@ struct mlx5e_rep_priv { ...@@ -64,7 +64,7 @@ struct mlx5e_rep_priv {
static inline static inline
struct mlx5e_rep_priv *mlx5e_rep_to_rep_priv(struct mlx5_eswitch_rep *rep) struct mlx5e_rep_priv *mlx5e_rep_to_rep_priv(struct mlx5_eswitch_rep *rep)
{ {
return (struct mlx5e_rep_priv *)rep->priv; return (struct mlx5e_rep_priv *)rep->rep_if[REP_ETH].priv;
} }
struct mlx5e_neigh { struct mlx5e_neigh {
......
...@@ -617,7 +617,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, ...@@ -617,7 +617,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
FLOW_DISSECTOR_KEY_ENC_PORTS, FLOW_DISSECTOR_KEY_ENC_PORTS,
f->mask); f->mask);
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
struct net_device *up_dev = uplink_rpriv->netdev; struct net_device *up_dev = uplink_rpriv->netdev;
struct mlx5e_priv *up_priv = netdev_priv(up_dev); struct mlx5e_priv *up_priv = netdev_priv(up_dev);
...@@ -1522,7 +1522,7 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv, ...@@ -1522,7 +1522,7 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
#else #else
return -EOPNOTSUPP; return -EOPNOTSUPP;
#endif #endif
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
/* if the egress device isn't on the same HW e-switch, we use the uplink */ /* if the egress device isn't on the same HW e-switch, we use the uplink */
if (!switchdev_port_same_parent_id(priv->netdev, rt->dst.dev)) if (!switchdev_port_same_parent_id(priv->netdev, rt->dst.dev))
*out_dev = uplink_rpriv->netdev; *out_dev = uplink_rpriv->netdev;
...@@ -1561,7 +1561,7 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv, ...@@ -1561,7 +1561,7 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,
*out_ttl = ip6_dst_hoplimit(dst); *out_ttl = ip6_dst_hoplimit(dst);
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
/* if the egress device isn't on the same HW e-switch, we use the uplink */ /* if the egress device isn't on the same HW e-switch, we use the uplink */
if (!switchdev_port_same_parent_id(priv->netdev, dst->dev)) if (!switchdev_port_same_parent_id(priv->netdev, dst->dev))
*out_dev = uplink_rpriv->netdev; *out_dev = uplink_rpriv->netdev;
...@@ -1864,7 +1864,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -1864,7 +1864,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow) struct mlx5e_tc_flow *flow)
{ {
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw); struct mlx5e_rep_priv *uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw,
REP_ETH);
struct net_device *up_dev = uplink_rpriv->netdev; struct net_device *up_dev = uplink_rpriv->netdev;
unsigned short family = ip_tunnel_info_af(tun_info); unsigned short family = ip_tunnel_info_af(tun_info);
struct mlx5e_priv *up_priv = netdev_priv(up_dev); struct mlx5e_priv *up_priv = netdev_priv(up_dev);
......
...@@ -45,6 +45,11 @@ enum { ...@@ -45,6 +45,11 @@ enum {
SRIOV_OFFLOADS SRIOV_OFFLOADS
}; };
enum {
REP_ETH,
NUM_REP_TYPES,
};
#ifdef CONFIG_MLX5_ESWITCH #ifdef CONFIG_MLX5_ESWITCH
#define MLX5_MAX_UC_PER_VPORT(dev) \ #define MLX5_MAX_UC_PER_VPORT(dev) \
...@@ -138,16 +143,21 @@ struct mlx5_esw_sq { ...@@ -138,16 +143,21 @@ struct mlx5_esw_sq {
struct list_head list; struct list_head list;
}; };
struct mlx5_eswitch_rep { struct mlx5_eswitch_rep;
struct mlx5_eswitch_rep_if {
int (*load)(struct mlx5_core_dev *dev, int (*load)(struct mlx5_core_dev *dev,
struct mlx5_eswitch_rep *rep); struct mlx5_eswitch_rep *rep);
void (*unload)(struct mlx5_eswitch_rep *rep); void (*unload)(struct mlx5_eswitch_rep *rep);
void *priv; void *priv;
bool valid;
};
struct mlx5_eswitch_rep {
struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES];
u16 vport; u16 vport;
u8 hw_id[ETH_ALEN]; u8 hw_id[ETH_ALEN];
u16 vlan; u16 vlan;
u32 vlan_refcount; u32 vlan_refcount;
bool valid;
}; };
struct mlx5_esw_offload { struct mlx5_esw_offload {
...@@ -268,10 +278,12 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap); ...@@ -268,10 +278,12 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap);
int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap); int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap);
void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
int vport_index, int vport_index,
struct mlx5_eswitch_rep *rep); struct mlx5_eswitch_rep_if *rep_if,
u8 rep_type);
void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
int vport_index); int vport_index,
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw); u8 rep_type);
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type);
int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw, int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
struct mlx5_esw_flow_attr *attr); struct mlx5_esw_flow_attr *attr);
......
...@@ -130,7 +130,7 @@ static int esw_set_global_vlan_pop(struct mlx5_eswitch *esw, u8 val) ...@@ -130,7 +130,7 @@ static int esw_set_global_vlan_pop(struct mlx5_eswitch *esw, u8 val)
esw_debug(esw->dev, "%s applying global %s policy\n", __func__, val ? "pop" : "none"); esw_debug(esw->dev, "%s applying global %s policy\n", __func__, val ? "pop" : "none");
for (vf_vport = 1; vf_vport < esw->enabled_vports; vf_vport++) { for (vf_vport = 1; vf_vport < esw->enabled_vports; vf_vport++) {
rep = &esw->offloads.vport_reps[vf_vport]; rep = &esw->offloads.vport_reps[vf_vport];
if (!rep->valid) if (!rep->rep_if[REP_ETH].valid)
continue; continue;
err = __mlx5_eswitch_set_vport_vlan(esw, rep->vport, 0, 0, val); err = __mlx5_eswitch_set_vport_vlan(esw, rep->vport, 0, 0, val);
...@@ -719,21 +719,31 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw) ...@@ -719,21 +719,31 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw)
return 0; return 0;
} }
static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports) static void esw_offloads_unload_reps_type(struct mlx5_eswitch *esw, int nvports,
u8 rep_type)
{ {
struct mlx5_eswitch_rep *rep; struct mlx5_eswitch_rep *rep;
int vport; int vport;
for (vport = nvports - 1; vport >= 0; vport--) { for (vport = nvports - 1; vport >= 0; vport--) {
rep = &esw->offloads.vport_reps[vport]; rep = &esw->offloads.vport_reps[vport];
if (!rep->valid) if (!rep->rep_if[rep_type].valid)
continue; continue;
rep->unload(rep); rep->rep_if[rep_type].unload(rep);
} }
} }
static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports)
{
u8 rep_type = NUM_REP_TYPES;
while (rep_type-- > 0)
esw_offloads_unload_reps_type(esw, nvports, rep_type);
}
static int esw_offloads_load_reps_type(struct mlx5_eswitch *esw, int nvports,
u8 rep_type)
{ {
struct mlx5_eswitch_rep *rep; struct mlx5_eswitch_rep *rep;
int vport; int vport;
...@@ -741,10 +751,10 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) ...@@ -741,10 +751,10 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports)
for (vport = 0; vport < nvports; vport++) { for (vport = 0; vport < nvports; vport++) {
rep = &esw->offloads.vport_reps[vport]; rep = &esw->offloads.vport_reps[vport];
if (!rep->valid) if (!rep->rep_if[rep_type].valid)
continue; continue;
err = rep->load(esw->dev, rep); err = rep->rep_if[rep_type].load(esw->dev, rep);
if (err) if (err)
goto err_reps; goto err_reps;
} }
...@@ -752,7 +762,26 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports) ...@@ -752,7 +762,26 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports)
return 0; return 0;
err_reps: err_reps:
esw_offloads_unload_reps(esw, vport); esw_offloads_unload_reps_type(esw, vport, rep_type);
return err;
}
static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports)
{
u8 rep_type = 0;
int err;
for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
err = esw_offloads_load_reps_type(esw, nvports, rep_type);
if (err)
goto err_reps;
}
return err;
err_reps:
while (rep_type-- > 0)
esw_offloads_unload_reps_type(esw, nvports, rep_type);
return err; return err;
} }
...@@ -1121,22 +1150,23 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap) ...@@ -1121,22 +1150,23 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap)
void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw, void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
int vport_index, int vport_index,
struct mlx5_eswitch_rep *__rep) struct mlx5_eswitch_rep_if *__rep_if,
u8 rep_type)
{ {
struct mlx5_esw_offload *offloads = &esw->offloads; struct mlx5_esw_offload *offloads = &esw->offloads;
struct mlx5_eswitch_rep *rep; struct mlx5_eswitch_rep_if *rep_if;
rep = &offloads->vport_reps[vport_index]; rep_if = &offloads->vport_reps[vport_index].rep_if[rep_type];
rep->load = __rep->load; rep_if->load = __rep_if->load;
rep->unload = __rep->unload; rep_if->unload = __rep_if->unload;
rep->priv = __rep->priv; rep_if->priv = __rep_if->priv;
rep->valid = true; rep_if->valid = true;
} }
void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
int vport_index) int vport_index, u8 rep_type)
{ {
struct mlx5_esw_offload *offloads = &esw->offloads; struct mlx5_esw_offload *offloads = &esw->offloads;
struct mlx5_eswitch_rep *rep; struct mlx5_eswitch_rep *rep;
...@@ -1144,17 +1174,17 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw, ...@@ -1144,17 +1174,17 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
rep = &offloads->vport_reps[vport_index]; rep = &offloads->vport_reps[vport_index];
if (esw->mode == SRIOV_OFFLOADS && esw->vports[vport_index].enabled) if (esw->mode == SRIOV_OFFLOADS && esw->vports[vport_index].enabled)
rep->unload(rep); rep->rep_if[rep_type].unload(rep);
rep->valid = false; rep->rep_if[rep_type].valid = false;
} }
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw) void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw, u8 rep_type)
{ {
#define UPLINK_REP_INDEX 0 #define UPLINK_REP_INDEX 0
struct mlx5_esw_offload *offloads = &esw->offloads; struct mlx5_esw_offload *offloads = &esw->offloads;
struct mlx5_eswitch_rep *rep; struct mlx5_eswitch_rep *rep;
rep = &offloads->vport_reps[UPLINK_REP_INDEX]; rep = &offloads->vport_reps[UPLINK_REP_INDEX];
return rep->priv; return rep->rep_if[rep_type].priv;
} }
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