forked from Minki/linux
net/mlx5: E-Switch, Add state to eswitch vport representors
Currently the eswitch vport reps have a valid indicator, which is set on register and unset on unregister. However, a rep can be loaded or not loaded when doing unregister, current driver checks if the vport of that rep is enabled as a flag to imply the rep is loaded. However, for ECPF, this is not valid as the host PF will enable the vports for its VFs instead. Add three states: {unregistered, registered, loaded}, with the following state changes across different operations: create: (none) -> unregistered reg: unregistered -> registered load: registered -> loaded unload: loaded -> registered unreg: registered -> unregistered Note that the state shall only be updated inside eswitch driver rather than individual drivers such as ETH or IB. Signed-off-by: Bodong Wang <bodong@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Suggested-by: Mark Bloch <markb@mellanox.com> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
parent
879c8f84e3
commit
f121e0ea95
@ -364,7 +364,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->rep_if[REP_ETH].valid)
|
||||
if (rep->rep_if[REP_ETH].state != REP_LOADED)
|
||||
continue;
|
||||
|
||||
err = __mlx5_eswitch_set_vport_vlan(esw, rep->vport, 0, 0, val);
|
||||
@ -1256,7 +1256,7 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw)
|
||||
struct mlx5_core_dev *dev = esw->dev;
|
||||
struct mlx5_esw_offload *offloads;
|
||||
struct mlx5_eswitch_rep *rep;
|
||||
u8 hw_id[ETH_ALEN];
|
||||
u8 hw_id[ETH_ALEN], rep_type;
|
||||
int vport;
|
||||
|
||||
esw->offloads.vport_reps = kcalloc(total_vfs,
|
||||
@ -1271,6 +1271,9 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw)
|
||||
mlx5_esw_for_all_reps(esw, vport, rep) {
|
||||
rep->vport = vport;
|
||||
ether_addr_copy(rep->hw_id, hw_id);
|
||||
|
||||
for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++)
|
||||
rep->rep_if[rep_type].state = REP_UNREGISTERED;
|
||||
}
|
||||
|
||||
offloads->vport_reps[0].vport = MLX5_VPORT_UPLINK;
|
||||
@ -1281,10 +1284,11 @@ int esw_offloads_init_reps(struct mlx5_eswitch *esw)
|
||||
static void __esw_offloads_unload_rep(struct mlx5_eswitch *esw,
|
||||
struct mlx5_eswitch_rep *rep, u8 rep_type)
|
||||
{
|
||||
if (!rep->rep_if[rep_type].valid)
|
||||
if (rep->rep_if[rep_type].state != REP_LOADED)
|
||||
return;
|
||||
|
||||
rep->rep_if[rep_type].unload(rep);
|
||||
rep->rep_if[rep_type].state = REP_REGISTERED;
|
||||
}
|
||||
|
||||
static void esw_offloads_unload_reps_type(struct mlx5_eswitch *esw, int nvports,
|
||||
@ -1311,10 +1315,18 @@ static void esw_offloads_unload_reps(struct mlx5_eswitch *esw, int nvports)
|
||||
static int __esw_offloads_load_rep(struct mlx5_eswitch *esw,
|
||||
struct mlx5_eswitch_rep *rep, u8 rep_type)
|
||||
{
|
||||
if (!rep->rep_if[rep_type].valid)
|
||||
int err = 0;
|
||||
|
||||
if (rep->rep_if[rep_type].state != REP_REGISTERED)
|
||||
return 0;
|
||||
|
||||
return rep->rep_if[rep_type].load(esw->dev, rep);
|
||||
err = rep->rep_if[rep_type].load(esw->dev, rep);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
rep->rep_if[rep_type].state = REP_LOADED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int esw_offloads_load_reps_type(struct mlx5_eswitch *esw, int nvports,
|
||||
@ -1861,7 +1873,7 @@ void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
|
||||
rep_if->get_proto_dev = __rep_if->get_proto_dev;
|
||||
rep_if->priv = __rep_if->priv;
|
||||
|
||||
rep_if->valid = true;
|
||||
rep_if->state = REP_REGISTERED;
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_eswitch_register_vport_rep);
|
||||
|
||||
@ -1873,10 +1885,11 @@ 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)
|
||||
if (esw->mode == SRIOV_OFFLOADS &&
|
||||
rep->rep_if[rep_type].state == REP_LOADED)
|
||||
rep->rep_if[rep_type].unload(rep);
|
||||
|
||||
rep->rep_if[rep_type].valid = false;
|
||||
rep->rep_if[rep_type].state = REP_UNREGISTERED;
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_eswitch_unregister_vport_rep);
|
||||
|
||||
@ -1896,7 +1909,7 @@ void *mlx5_eswitch_get_proto_dev(struct mlx5_eswitch *esw,
|
||||
|
||||
rep = mlx5_eswitch_get_rep(esw, vport);
|
||||
|
||||
if (rep->rep_if[rep_type].valid &&
|
||||
if (rep->rep_if[rep_type].state == REP_LOADED &&
|
||||
rep->rep_if[rep_type].get_proto_dev)
|
||||
return rep->rep_if[rep_type].get_proto_dev(rep);
|
||||
return NULL;
|
||||
|
@ -22,6 +22,12 @@ enum {
|
||||
NUM_REP_TYPES,
|
||||
};
|
||||
|
||||
enum {
|
||||
REP_UNREGISTERED,
|
||||
REP_REGISTERED,
|
||||
REP_LOADED,
|
||||
};
|
||||
|
||||
struct mlx5_eswitch_rep;
|
||||
struct mlx5_eswitch_rep_if {
|
||||
int (*load)(struct mlx5_core_dev *dev,
|
||||
@ -29,7 +35,7 @@ struct mlx5_eswitch_rep_if {
|
||||
void (*unload)(struct mlx5_eswitch_rep *rep);
|
||||
void *(*get_proto_dev)(struct mlx5_eswitch_rep *rep);
|
||||
void *priv;
|
||||
bool valid;
|
||||
u8 state;
|
||||
};
|
||||
|
||||
struct mlx5_eswitch_rep {
|
||||
|
Loading…
Reference in New Issue
Block a user