]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
net/mlx5: E-Switch, Add control for encapsulation
authorRoi Dayan <roid@mellanox.com>
Sun, 25 Sep 2016 11:27:17 +0000 (14:27 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Sat, 22 Apr 2017 17:26:40 +0000 (20:26 +0300)
Implement the devlink e-switch encapsulation control set and get
callbacks. Apply the value set by the user on the switchdev offloads
mode when creating the fast FDB table where offloaded rules will be set.

Signed-off-by: Roi Dayan <roid@mellanox.com>
Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/main.c

index b3281d1118b370cc0ca9aafb23b7470663f98b0d..21bed3c3334d1a5a6c0224b11d564d35ccc51a11 100644 (file)
@@ -1806,6 +1806,11 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
        esw->enabled_vports = 0;
        esw->mode = SRIOV_NONE;
        esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE;
+       if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) &&
+           MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap))
+               esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
+       else
+               esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
 
        dev->priv.eswitch = esw;
        return 0;
index 1f56ed9f5a6f78e20e76d63d8cba9bef847518a1..1e7f21be12339d55e1369306ea5ee25c30f7a1e6 100644 (file)
@@ -210,6 +210,7 @@ struct mlx5_esw_offload {
        DECLARE_HASHTABLE(encap_tbl, 8);
        u8 inline_mode;
        u64 num_flows;
+       u8 encap;
 };
 
 struct mlx5_eswitch {
@@ -322,6 +323,8 @@ int mlx5_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode);
 int mlx5_devlink_eswitch_inline_mode_set(struct devlink *devlink, u8 mode);
 int mlx5_devlink_eswitch_inline_mode_get(struct devlink *devlink, u8 *mode);
 int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode);
+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);
index ce3a2c040706fe602f52694cd3eae396c585abbc..189d24dbd3e32f9cb5e13b989b9858e30b27593c 100644 (file)
@@ -450,8 +450,7 @@ static int esw_create_offloads_fast_fdb_table(struct mlx5_eswitch *esw)
        esw_size = min_t(int, MLX5_CAP_GEN(dev, max_flow_counter) * ESW_OFFLOADS_NUM_GROUPS,
                         1 << MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size));
 
-       if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) &&
-           MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap))
+       if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE)
                flags |= MLX5_FLOW_TABLE_TUNNEL_EN;
 
        fdb = mlx5_create_auto_grouped_flow_table(root_ns, FDB_FAST_PATH,
@@ -1045,6 +1044,66 @@ int mlx5_eswitch_inline_mode_get(struct mlx5_eswitch *esw, int nvfs, u8 *mode)
        return 0;
 }
 
+int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, u8 encap)
+{
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+       int err;
+
+       if (!MLX5_CAP_GEN(dev, vport_group_manager))
+               return -EOPNOTSUPP;
+
+       if (esw->mode == SRIOV_NONE)
+               return -EOPNOTSUPP;
+
+       if (encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE &&
+           (!MLX5_CAP_ESW_FLOWTABLE_FDB(dev, encap) ||
+            !MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap)))
+               return -EOPNOTSUPP;
+
+       if (encap && encap != DEVLINK_ESWITCH_ENCAP_MODE_BASIC)
+               return -EOPNOTSUPP;
+
+       if (esw->mode == SRIOV_LEGACY) {
+               esw->offloads.encap = encap;
+               return 0;
+       }
+
+       if (esw->offloads.encap == encap)
+               return 0;
+
+       if (esw->offloads.num_flows > 0) {
+               esw_warn(dev, "Can't set encapsulation when flows are configured\n");
+               return -EOPNOTSUPP;
+       }
+
+       esw_destroy_offloads_fast_fdb_table(esw);
+
+       esw->offloads.encap = encap;
+       err = esw_create_offloads_fast_fdb_table(esw);
+       if (err) {
+               esw_warn(esw->dev, "Failed re-creating fast FDB table, err %d\n", err);
+               esw->offloads.encap = !encap;
+               (void) esw_create_offloads_fast_fdb_table(esw);
+       }
+       return err;
+}
+
+int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, u8 *encap)
+{
+       struct mlx5_core_dev *dev = devlink_priv(devlink);
+       struct mlx5_eswitch *esw = dev->priv.eswitch;
+
+       if (!MLX5_CAP_GEN(dev, vport_group_manager))
+               return -EOPNOTSUPP;
+
+       if (esw->mode == SRIOV_NONE)
+               return -EOPNOTSUPP;
+
+       *encap = esw->offloads.encap;
+       return 0;
+}
+
 void mlx5_eswitch_register_vport_rep(struct mlx5_eswitch *esw,
                                     int vport_index,
                                     struct mlx5_eswitch_rep *__rep)
index 9c2bec732af989f0e0cb9a3104aa9f22b5c7b85b..bde91a8bec7313e6c94d8739f219c6fdc237ac3d 100644 (file)
@@ -1280,6 +1280,8 @@ static const struct devlink_ops mlx5_devlink_ops = {
        .eswitch_mode_get = mlx5_devlink_eswitch_mode_get,
        .eswitch_inline_mode_set = mlx5_devlink_eswitch_inline_mode_set,
        .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
+       .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
+       .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
 #endif
 };