]> www.infradead.org Git - users/hch/misc.git/commitdiff
net/mlx5: fs, add HWS flow table API functions
authorMoshe Shemesh <moshe@nvidia.com>
Thu, 9 Jan 2025 16:05:33 +0000 (18:05 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 14 Jan 2025 03:21:07 +0000 (19:21 -0800)
Add API functions to create, modify and destroy HW Steering flow tables.
Modify table enables change, connect or disconnect default miss table.
Add update root flow table API function.

Signed-off-by: Moshe Shemesh <moshe@nvidia.com>
Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20250109160546.1733647-3-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlx5/core/fs_core.h
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.h

index d309906d1106c178ce8fa51a6ede7dcae53434e1..7fd480a2570dfc894b7689975cb7382a3d34bc23 100644 (file)
@@ -192,7 +192,10 @@ struct mlx5_flow_handle {
 /* Type of children is mlx5_flow_group */
 struct mlx5_flow_table {
        struct fs_node                  node;
-       struct mlx5_fs_dr_table         fs_dr_table;
+       union {
+               struct mlx5_fs_dr_table         fs_dr_table;
+               struct mlx5_fs_hws_table        fs_hws_table;
+       };
        u32                             id;
        u16                             vport;
        unsigned int                    max_fte;
index ac61f96af1c3d318854478f33ee4ab154e1038b1..57d88088e18b2edae3f0a10419bad4fafd2c7f0f 100644 (file)
@@ -44,7 +44,120 @@ static int mlx5_cmd_hws_set_peer(struct mlx5_flow_root_namespace *ns,
        return 0;
 }
 
+static int mlx5_fs_set_ft_default_miss(struct mlx5_flow_root_namespace *ns,
+                                      struct mlx5_flow_table *ft,
+                                      struct mlx5_flow_table *next_ft)
+{
+       struct mlx5hws_table *next_tbl;
+       int err;
+
+       if (!ns->fs_hws_context.hws_ctx)
+               return -EINVAL;
+
+       /* if no change required, return */
+       if (!next_ft && !ft->fs_hws_table.miss_ft_set)
+               return 0;
+
+       next_tbl = next_ft ? next_ft->fs_hws_table.hws_table : NULL;
+       err = mlx5hws_table_set_default_miss(ft->fs_hws_table.hws_table, next_tbl);
+       if (err) {
+               mlx5_core_err(ns->dev, "Failed setting FT default miss (%d)\n", err);
+               return err;
+       }
+       ft->fs_hws_table.miss_ft_set = !!next_tbl;
+       return 0;
+}
+
+static int mlx5_cmd_hws_create_flow_table(struct mlx5_flow_root_namespace *ns,
+                                         struct mlx5_flow_table *ft,
+                                         struct mlx5_flow_table_attr *ft_attr,
+                                         struct mlx5_flow_table *next_ft)
+{
+       struct mlx5hws_context *ctx = ns->fs_hws_context.hws_ctx;
+       struct mlx5hws_table_attr tbl_attr = {};
+       struct mlx5hws_table *tbl;
+       int err;
+
+       if (mlx5_fs_cmd_is_fw_term_table(ft))
+               return mlx5_fs_cmd_get_fw_cmds()->create_flow_table(ns, ft, ft_attr,
+                                                                   next_ft);
+
+       if (ns->table_type != FS_FT_FDB) {
+               mlx5_core_err(ns->dev, "Table type %d not supported for HWS\n",
+                             ns->table_type);
+               return -EOPNOTSUPP;
+       }
+
+       tbl_attr.type = MLX5HWS_TABLE_TYPE_FDB;
+       tbl_attr.level = ft_attr->level;
+       tbl = mlx5hws_table_create(ctx, &tbl_attr);
+       if (!tbl) {
+               mlx5_core_err(ns->dev, "Failed creating hws flow_table\n");
+               return -EINVAL;
+       }
+
+       ft->fs_hws_table.hws_table = tbl;
+       ft->id = mlx5hws_table_get_id(tbl);
+
+       if (next_ft) {
+               err = mlx5_fs_set_ft_default_miss(ns, ft, next_ft);
+               if (err)
+                       goto destroy_table;
+       }
+
+       ft->max_fte = INT_MAX;
+
+       return 0;
+
+destroy_table:
+       mlx5hws_table_destroy(tbl);
+       ft->fs_hws_table.hws_table = NULL;
+       return err;
+}
+
+static int mlx5_cmd_hws_destroy_flow_table(struct mlx5_flow_root_namespace *ns,
+                                          struct mlx5_flow_table *ft)
+{
+       int err;
+
+       if (mlx5_fs_cmd_is_fw_term_table(ft))
+               return mlx5_fs_cmd_get_fw_cmds()->destroy_flow_table(ns, ft);
+
+       err = mlx5_fs_set_ft_default_miss(ns, ft, NULL);
+       if (err)
+               mlx5_core_err(ns->dev, "Failed to disconnect next table (%d)\n", err);
+
+       err = mlx5hws_table_destroy(ft->fs_hws_table.hws_table);
+       if (err)
+               mlx5_core_err(ns->dev, "Failed to destroy flow_table (%d)\n", err);
+
+       return err;
+}
+
+static int mlx5_cmd_hws_modify_flow_table(struct mlx5_flow_root_namespace *ns,
+                                         struct mlx5_flow_table *ft,
+                                         struct mlx5_flow_table *next_ft)
+{
+       if (mlx5_fs_cmd_is_fw_term_table(ft))
+               return mlx5_fs_cmd_get_fw_cmds()->modify_flow_table(ns, ft, next_ft);
+
+       return mlx5_fs_set_ft_default_miss(ns, ft, next_ft);
+}
+
+static int mlx5_cmd_hws_update_root_ft(struct mlx5_flow_root_namespace *ns,
+                                      struct mlx5_flow_table *ft,
+                                      u32 underlay_qpn,
+                                      bool disconnect)
+{
+       return mlx5_fs_cmd_get_fw_cmds()->update_root_ft(ns, ft, underlay_qpn,
+                                                        disconnect);
+}
+
 static const struct mlx5_flow_cmds mlx5_flow_cmds_hws = {
+       .create_flow_table = mlx5_cmd_hws_create_flow_table,
+       .destroy_flow_table = mlx5_cmd_hws_destroy_flow_table,
+       .modify_flow_table = mlx5_cmd_hws_modify_flow_table,
+       .update_root_ft = mlx5_cmd_hws_update_root_ft,
        .create_ns = mlx5_cmd_hws_create_ns,
        .destroy_ns = mlx5_cmd_hws_destroy_ns,
        .set_peer = mlx5_cmd_hws_set_peer,
index 17ac0d15025362d440381f3e175950de5a8948d2..c4af8d617b4d4ccc800579affbad129b8dcb3790 100644 (file)
@@ -10,6 +10,11 @@ struct mlx5_fs_hws_context {
        struct mlx5hws_context  *hws_ctx;
 };
 
+struct mlx5_fs_hws_table {
+       struct mlx5hws_table *hws_table;
+       bool miss_ft_set;
+};
+
 #ifdef CONFIG_MLX5_HW_STEERING
 
 const struct mlx5_flow_cmds *mlx5_fs_cmd_get_hws_cmds(void);