Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+15 −14
Original line number Diff line number Diff line
@@ -1086,7 +1086,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)

	rpriv->netdev = netdev;
	rpriv->rep = rep;
	rep->priv = rpriv;
	rep->rep_if[REP_ETH].priv = rpriv;
	INIT_LIST_HEAD(&rpriv->vport_sqs_list);

	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)
		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);
	err = tc_setup_cb_egdev_register(netdev, mlx5e_setup_tc_block_cb,
					 upriv);
@@ -1146,7 +1146,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
	struct mlx5e_priv *upriv;

	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);
	tc_setup_cb_egdev_unregister(netdev, mlx5e_setup_tc_block_cb,
				     upriv);
@@ -1164,11 +1165,11 @@ static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv)
	int 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.unload = mlx5e_vport_rep_unload;
		mlx5_eswitch_register_vport_rep(esw, vport, &rep);
		rep_if.load = mlx5e_vport_rep_load;
		rep_if.unload = mlx5e_vport_rep_unload;
		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)
	int 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)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5_eswitch *esw   = mdev->priv.eswitch;
	struct mlx5_eswitch_rep_if rep_if;
	struct mlx5e_rep_priv *rpriv;
	struct mlx5_eswitch_rep rep;

	rpriv = priv->ppriv;
	rpriv->netdev = priv->netdev;

	rep.load = mlx5e_nic_rep_load;
	rep.unload = mlx5e_nic_rep_unload;
	rep.priv = rpriv;
	rep_if.load = mlx5e_nic_rep_load;
	rep_if.unload = mlx5e_nic_rep_unload;
	rep_if.priv = rpriv;
	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 */
}
@@ -1208,7 +1209,7 @@ void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv)
	struct mlx5_eswitch *esw   = mdev->priv.eswitch;

	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)
+1 −1
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ struct mlx5e_rep_priv {
static inline
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 {
+5 −4
Original line number Diff line number Diff line
@@ -617,7 +617,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv,
						  FLOW_DISSECTOR_KEY_ENC_PORTS,
						  f->mask);
		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 mlx5e_priv *up_priv = netdev_priv(up_dev);

@@ -1522,7 +1522,7 @@ static int mlx5e_route_lookup_ipv4(struct mlx5e_priv *priv,
#else
	return -EOPNOTSUPP;
#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 (!switchdev_port_same_parent_id(priv->netdev, rt->dst.dev))
		*out_dev = uplink_rpriv->netdev;
@@ -1561,7 +1561,7 @@ static int mlx5e_route_lookup_ipv6(struct mlx5e_priv *priv,

	*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 (!switchdev_port_same_parent_id(priv->netdev, dst->dev))
		*out_dev = uplink_rpriv->netdev;
@@ -1864,7 +1864,8 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
			      struct mlx5e_tc_flow *flow)
{
	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;
	unsigned short family = ip_tunnel_info_af(tun_info);
	struct mlx5e_priv *up_priv = netdev_priv(up_dev);
+17 −5
Original line number Diff line number Diff line
@@ -45,6 +45,11 @@ enum {
	SRIOV_OFFLOADS
};

enum {
	REP_ETH,
	NUM_REP_TYPES,
};

#ifdef CONFIG_MLX5_ESWITCH

#define MLX5_MAX_UC_PER_VPORT(dev) \
@@ -138,16 +143,21 @@ struct mlx5_esw_sq {
	struct list_head	 list;
};

struct mlx5_eswitch_rep {
struct mlx5_eswitch_rep;
struct mlx5_eswitch_rep_if {
	int		       (*load)(struct mlx5_core_dev *dev,
				       struct mlx5_eswitch_rep *rep);
	void		       (*unload)(struct mlx5_eswitch_rep *rep);
	void			*priv;
	bool		       valid;
};

struct mlx5_eswitch_rep {
	struct mlx5_eswitch_rep_if rep_if[NUM_REP_TYPES];
	u16		       vport;
	u8		       hw_id[ETH_ALEN];
	u16		       vlan;
	u32		       vlan_refcount;
	bool		       valid;
};

struct mlx5_esw_offload {
@@ -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);
void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
				     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,
				       int vport_index);
void *mlx5_eswitch_get_uplink_priv(struct mlx5_eswitch *esw);
				       int vport_index,
				       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,
				 struct mlx5_esw_flow_attr *attr);
+50 −20
Original line number Diff line number Diff line
@@ -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");
	for (vf_vport = 1; vf_vport < esw->enabled_vports; vf_vport++) {
		rep = &esw->offloads.vport_reps[vf_vport];
		if (!rep->valid)
		if (!rep->rep_if[REP_ETH].valid)
			continue;

		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)
	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;
	int vport;

	for (vport = nvports - 1; vport >= 0; vport--) {
		rep = &esw->offloads.vport_reps[vport];
		if (!rep->valid)
		if (!rep->rep_if[rep_type].valid)
			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;
	int vport;
@@ -741,10 +751,10 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports)

	for (vport = 0; vport < nvports; vport++) {
		rep = &esw->offloads.vport_reps[vport];
		if (!rep->valid)
		if (!rep->rep_if[rep_type].valid)
			continue;

		err = rep->load(esw->dev, rep);
		err = rep->rep_if[rep_type].load(esw->dev, rep);
		if (err)
			goto err_reps;
	}
@@ -752,7 +762,26 @@ static int esw_offloads_load_reps(struct mlx5_eswitch *esw, int nvports)
	return 0;

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;
}

@@ -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,
				     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_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->unload = __rep->unload;
	rep->priv = __rep->priv;
	rep_if->load   = __rep_if->load;
	rep_if->unload = __rep_if->unload;
	rep_if->priv = __rep_if->priv;

	rep->valid = true;
	rep_if->valid = true;
}

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_eswitch_rep *rep;
@@ -1144,17 +1174,17 @@ void mlx5_eswitch_unregister_vport_rep(struct mlx5_eswitch *esw,
	rep = &offloads->vport_reps[vport_index];

	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
	struct mlx5_esw_offload *offloads = &esw->offloads;
	struct mlx5_eswitch_rep *rep;

	rep = &offloads->vport_reps[UPLINK_REP_INDEX];
	return rep->priv;
	return rep->rep_if[rep_type].priv;
}