net/mlx5: E-Switch, Add state to eswitch vport representors
authorBodong Wang <bodong@mellanox.com>
Wed, 30 Jan 2019 03:48:31 +0000 (21:48 -0600)
committerSaeed Mahameed <saeedm@mellanox.com>
Sat, 16 Feb 2019 01:25:57 +0000 (17:25 -0800)
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>
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
include/linux/mlx5/eswitch.h

index 4979c7ee0ad744ffd159a25ef97cf308ccd27dc3..c6c9dad69ba80e338b61a196ab9e966e0cfe262f 100644 (file)
@@ -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;
index fab5121ffb8f5de2b5f39b6a0a7e43cca4b047e0..e3dbc1bc091754504f5c7d8ffb50dc8290da3f84 100644 (file)
@@ -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 {