From: Erez Shitrit <ere...@nvidia.com> Actions are depended on the sub-domain that will be used. So handle the actions accordingly. >From now on we don't fix-up for actions that doesn't fit the right domain, we will let it be failed by the FW while creating the STC for it.
Signed-off-by: Erez Shitrit <ere...@nvidia.com> Signed-off-by: Hamdan Igbaria <hamd...@nvidia.com> Acked-by: Matan Azrad <ma...@nvidia.com> --- drivers/net/mlx5/hws/mlx5dr.h | 5 +- drivers/net/mlx5/hws/mlx5dr_action.c | 222 +++++++++++++++++++++++---- drivers/net/mlx5/hws/mlx5dr_action.h | 2 +- 3 files changed, 200 insertions(+), 29 deletions(-) diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h index e0e7f5c147..58526fc08e 100644 --- a/drivers/net/mlx5/hws/mlx5dr.h +++ b/drivers/net/mlx5/hws/mlx5dr.h @@ -66,10 +66,13 @@ enum mlx5dr_action_flags { MLX5DR_ACTION_FLAG_HWS_RX = 1 << 3, MLX5DR_ACTION_FLAG_HWS_TX = 1 << 4, MLX5DR_ACTION_FLAG_HWS_FDB = 1 << 5, + MLX5DR_ACTION_FLAG_HWS_FDB_RX = 1 << 6, + MLX5DR_ACTION_FLAG_HWS_FDB_TX = 1 << 7, + MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED = 1 << 8, /* Shared action can be used over a few threads, since data is written * only once at the creation of the action. */ - MLX5DR_ACTION_FLAG_SHARED = 1 << 6, + MLX5DR_ACTION_FLAG_SHARED = 1 << 9, }; enum mlx5dr_action_aso_meter_color { diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c b/drivers/net/mlx5/hws/mlx5dr_action.c index 8e95abf7da..b9452a3ebc 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.c +++ b/drivers/net/mlx5/hws/mlx5dr_action.c @@ -10,6 +10,12 @@ /* Header removal size limited to 128B (64 words) */ #define MLX5DR_ACTION_REMOVE_HEADER_MAX_SIZE 128 +static struct mlx5dr_devx_obj * +mlx5dr_action_get_stc_obj_by_tbl_type(enum mlx5dr_table_type table_type, + struct mlx5dr_pool *stc_pool, + struct mlx5dr_pool_chunk *stc, + bool is_mirror); + /* This is the maximum allowed action order for each table type: * TX: POP_VLAN, CTR, ASO_METER, AS_CT, PUSH_VLAN, MODIFY, ENCAP, Term * RX: TAG, DECAP, POP_VLAN, CTR, ASO_METER, ASO_CT, PUSH_VLAN, MODIFY, @@ -220,8 +226,47 @@ static int mlx5dr_action_get_shared_stc(struct mlx5dr_action *action, } } + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_RX) { + ret = mlx5dr_action_get_shared_stc_nic(ctx, stc_type, + MLX5DR_TABLE_TYPE_FDB_RX); + if (ret) { + DR_LOG(ERR, "Failed to allocate FDB_RX shared STCs (type: %d)", + stc_type); + goto clean_nic_fdb_stc; + } + } + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_TX) { + ret = mlx5dr_action_get_shared_stc_nic(ctx, stc_type, + MLX5DR_TABLE_TYPE_FDB_TX); + if (ret) { + DR_LOG(ERR, "Failed to allocate FDB_TX shared STCs (type: %d)", + stc_type); + goto clean_nic_fdb_rx_stc; + } + } + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED) { + ret = mlx5dr_action_get_shared_stc_nic(ctx, stc_type, + MLX5DR_TABLE_TYPE_FDB_UNIFIED); + if (ret) { + DR_LOG(ERR, "Failed to allocate FDB_UNIFIED shared STCs (type: %d)", + stc_type); + goto clean_nic_fdb_tx_stc; + } + } + return 0; +clean_nic_fdb_tx_stc: + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_TX) + mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB_TX); +clean_nic_fdb_rx_stc: + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_RX) + mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB_RX); +clean_nic_fdb_stc: + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB) + mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB); clean_nic_tx_stc: if (action->flags & MLX5DR_ACTION_FLAG_HWS_TX) mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_NIC_TX); @@ -250,6 +295,15 @@ static void mlx5dr_action_put_shared_stc(struct mlx5dr_action *action, if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB) mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB); + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_RX) + mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB_RX); + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_TX) + mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB_TX); + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED) + mlx5dr_action_put_shared_stc_nic(ctx, stc_type, MLX5DR_TABLE_TYPE_FDB_UNIFIED); } static void @@ -689,14 +743,37 @@ static void mlx5dr_action_print_combo(enum mlx5dr_action_type *user_actions) } } +static const uint32_t * +mlx5dr_action_get_order_entry(enum mlx5dr_table_type table_type) +{ + switch (table_type) { + case MLX5DR_TABLE_TYPE_NIC_RX: + return action_order_arr[MLX5DR_TABLE_TYPE_NIC_RX]; + case MLX5DR_TABLE_TYPE_NIC_TX: + return action_order_arr[MLX5DR_TABLE_TYPE_NIC_TX]; + case MLX5DR_TABLE_TYPE_FDB: + case MLX5DR_TABLE_TYPE_FDB_RX: + case MLX5DR_TABLE_TYPE_FDB_TX: + case MLX5DR_TABLE_TYPE_FDB_UNIFIED: + return action_order_arr[MLX5DR_TABLE_TYPE_FDB]; + default: + assert(0); + DR_LOG(ERR, "no such type: %d", table_type); + return NULL; + } +} + bool mlx5dr_action_check_combo(enum mlx5dr_action_type *user_actions, enum mlx5dr_table_type table_type) { - const uint32_t *order_arr = action_order_arr[table_type]; + const uint32_t *order_arr = mlx5dr_action_get_order_entry(table_type); uint8_t order_idx = 0; uint8_t user_idx = 0; bool valid_combo; + if (!order_arr) + return false; + while (order_arr[order_idx] != BIT(MLX5DR_ACTION_TYP_LAST)) { /* User action order validated move to next user action */ if (BIT(user_actions[user_idx]) & order_arr[order_idx]) @@ -787,13 +864,10 @@ mlx5dr_action_fixup_stc_attr(struct mlx5dr_context *ctx, switch (stc_attr->action_type) { case MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE: - if (!is_mirror) - devx_obj = mlx5dr_pool_chunk_get_base_devx_obj(stc_attr->ste_table.ste_pool, - &stc_attr->ste_table.ste); - else - devx_obj = - mlx5dr_pool_chunk_get_base_devx_obj_mirror(stc_attr->ste_table.ste_pool, - &stc_attr->ste_table.ste); + devx_obj = mlx5dr_action_get_stc_obj_by_tbl_type(table_type, + stc_attr->ste_table.ste_pool, + &stc_attr->ste_table.ste, + is_mirror); *fixup_stc_attr = *stc_attr; fixup_stc_attr->ste_table.ste_obj_id = devx_obj->id; @@ -845,6 +919,19 @@ mlx5dr_action_fixup_stc_attr(struct mlx5dr_context *ctx, return use_fixup; } +static struct mlx5dr_devx_obj * +mlx5dr_action_get_stc_obj_by_tbl_type(enum mlx5dr_table_type table_type, + struct mlx5dr_pool *stc_pool, + struct mlx5dr_pool_chunk *stc, + bool is_mirror) +{ + if (table_type == MLX5DR_TABLE_TYPE_FDB_TX || + (is_mirror && table_type == MLX5DR_TABLE_TYPE_FDB)) /* Optimized ORIG in FDB_TX */ + return mlx5dr_pool_chunk_get_base_devx_obj_mirror(stc_pool, stc); + else + return mlx5dr_pool_chunk_get_base_devx_obj(stc_pool, stc); +} + int mlx5dr_action_alloc_single_stc(struct mlx5dr_context *ctx, struct mlx5dr_cmd_stc_modify_attr *stc_attr, uint32_t table_type, @@ -854,6 +941,7 @@ int mlx5dr_action_alloc_single_stc(struct mlx5dr_context *ctx, struct mlx5dr_pool *stc_pool = ctx->stc_pool[table_type]; struct mlx5dr_cmd_stc_modify_attr fixup_stc_attr = {0}; struct mlx5dr_devx_obj *devx_obj_0; + enum mlx5dr_table_type type; bool use_fixup; int ret; @@ -869,10 +957,13 @@ int mlx5dr_action_alloc_single_stc(struct mlx5dr_context *ctx, if (!mlx5dr_context_cap_dynamic_reparse(ctx)) stc_attr->reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE; - devx_obj_0 = mlx5dr_pool_chunk_get_base_devx_obj(stc_pool, stc); + type = (enum mlx5dr_table_type)table_type; + devx_obj_0 = mlx5dr_action_get_stc_obj_by_tbl_type(type, stc_pool, stc, false); /* According to table/action limitation change the stc_attr */ - use_fixup = mlx5dr_action_fixup_stc_attr(ctx, stc_attr, &fixup_stc_attr, table_type, false); + use_fixup = mlx5dr_action_fixup_stc_attr(ctx, stc_attr, &fixup_stc_attr, + (enum mlx5dr_table_type)table_type, + (table_type == MLX5DR_TABLE_TYPE_FDB_TX)); ret = mlx5dr_cmd_stc_modify(devx_obj_0, use_fixup ? &fixup_stc_attr : stc_attr); if (ret) { DR_LOG(ERR, "Failed to modify STC action_type %d tbl_type %d", @@ -916,12 +1007,15 @@ void mlx5dr_action_free_single_stc(struct mlx5dr_context *ctx, struct mlx5dr_pool *stc_pool = ctx->stc_pool[table_type]; struct mlx5dr_cmd_stc_modify_attr stc_attr = {0}; struct mlx5dr_devx_obj *devx_obj; + enum mlx5dr_table_type type; /* Modify the STC not to point to an object */ stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_DROP; stc_attr.action_offset = MLX5DR_ACTION_OFFSET_HIT; stc_attr.stc_offset = stc->offset; - devx_obj = mlx5dr_pool_chunk_get_base_devx_obj(stc_pool, stc); + type = (enum mlx5dr_table_type)table_type; + devx_obj = mlx5dr_action_get_stc_obj_by_tbl_type(type, stc_pool, stc, false); + mlx5dr_cmd_stc_modify(devx_obj, &stc_attr); if (table_type == MLX5DR_TABLE_TYPE_FDB) { @@ -1131,7 +1225,7 @@ mlx5dr_action_create_stcs(struct mlx5dr_action *action, MLX5DR_TABLE_TYPE_NIC_TX, &action->stc[MLX5DR_TABLE_TYPE_NIC_TX]); if (ret) - goto free_nic_rx_stc; + goto free_stcs_rx; } /* Allocate STC for FDB */ @@ -1140,22 +1234,59 @@ mlx5dr_action_create_stcs(struct mlx5dr_action *action, MLX5DR_TABLE_TYPE_FDB, &action->stc[MLX5DR_TABLE_TYPE_FDB]); if (ret) - goto free_nic_tx_stc; + goto free_stcs_tx; + } + + /* Allocate STC for FDB-RX */ + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_RX) { + ret = mlx5dr_action_alloc_single_stc(ctx, &stc_attr, + MLX5DR_TABLE_TYPE_FDB_RX, + &action->stc[MLX5DR_TABLE_TYPE_FDB_RX]); + if (ret) + goto free_stcs_fdb; + } + + /* Allocate STC for FDB-TX */ + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_TX) { + ret = mlx5dr_action_alloc_single_stc(ctx, &stc_attr, + MLX5DR_TABLE_TYPE_FDB_TX, + &action->stc[MLX5DR_TABLE_TYPE_FDB_TX]); + if (ret) + goto free_stcs_fdb_rx; + } + + /* Allocate STC for FDB Unified */ + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED) { + ret = mlx5dr_action_alloc_single_stc(ctx, &stc_attr, + MLX5DR_TABLE_TYPE_FDB_UNIFIED, + &action->stc[MLX5DR_TABLE_TYPE_FDB_UNIFIED]); + if (ret) + goto free_stcs_fdb_tx; } pthread_spin_unlock(&ctx->ctrl_lock); return 0; -free_nic_tx_stc: +free_stcs_fdb_tx: + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_TX) + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB_TX, + &action->stc[MLX5DR_TABLE_TYPE_FDB_TX]); +free_stcs_fdb_rx: + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_RX) + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB_RX, + &action->stc[MLX5DR_TABLE_TYPE_FDB_RX]); +free_stcs_fdb: + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB) + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB, + &action->stc[MLX5DR_TABLE_TYPE_FDB]); +free_stcs_tx: if (action->flags & MLX5DR_ACTION_FLAG_HWS_TX) - mlx5dr_action_free_single_stc(ctx, - MLX5DR_TABLE_TYPE_NIC_TX, + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_NIC_TX, &action->stc[MLX5DR_TABLE_TYPE_NIC_TX]); -free_nic_rx_stc: +free_stcs_rx: if (action->flags & MLX5DR_ACTION_FLAG_HWS_RX) - mlx5dr_action_free_single_stc(ctx, - MLX5DR_TABLE_TYPE_NIC_RX, + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_NIC_RX, &action->stc[MLX5DR_TABLE_TYPE_NIC_RX]); out_err: pthread_spin_unlock(&ctx->ctrl_lock); @@ -1182,6 +1313,18 @@ mlx5dr_action_destroy_stcs(struct mlx5dr_action *action) mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB, &action->stc[MLX5DR_TABLE_TYPE_FDB]); + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_RX) + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB_RX, + &action->stc[MLX5DR_TABLE_TYPE_FDB_RX]); + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_TX) + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB_TX, + &action->stc[MLX5DR_TABLE_TYPE_FDB_TX]); + + if (action->flags & MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED) + mlx5dr_action_free_single_stc(ctx, MLX5DR_TABLE_TYPE_FDB_UNIFIED, + &action->stc[MLX5DR_TABLE_TYPE_FDB_UNIFIED]); + pthread_spin_unlock(&ctx->ctrl_lock); } @@ -1198,7 +1341,10 @@ mlx5dr_action_is_hws_flags(uint32_t flags) { return flags & (MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_HWS_TX | - MLX5DR_ACTION_FLAG_HWS_FDB); + MLX5DR_ACTION_FLAG_HWS_FDB | + MLX5DR_ACTION_FLAG_HWS_FDB_RX | + MLX5DR_ACTION_FLAG_HWS_FDB_TX | + MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED); } static struct mlx5dr_action * @@ -1336,9 +1482,13 @@ mlx5dr_action_create_dest_tir(struct mlx5dr_context *ctx, return NULL; } - if ((flags & MLX5DR_ACTION_FLAG_ROOT_FDB) || - (flags & MLX5DR_ACTION_FLAG_HWS_FDB && !ctx->caps->fdb_tir_stc)) { - DR_LOG(ERR, "TIR action not support on FDB"); + if ((flags & (MLX5DR_ACTION_FLAG_ROOT_FDB | + MLX5DR_ACTION_FLAG_HWS_FDB_TX | + MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED)) || + ((flags & (MLX5DR_ACTION_FLAG_HWS_FDB | + MLX5DR_ACTION_FLAG_HWS_FDB_RX)) && + !ctx->caps->fdb_tir_stc)) { + DR_LOG(ERR, "TIR action not support on FDB or FDB_TX or UNIFIED"); rte_errno = ENOTSUP; return NULL; } @@ -1436,6 +1586,12 @@ mlx5dr_action_create_tag(struct mlx5dr_context *ctx, struct mlx5dr_action *action; int ret; + if (flags & (MLX5DR_ACTION_FLAG_HWS_FDB_TX | MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED)) { + DR_LOG(ERR, "TAG action not supported for UNIFIED or FDB_TX"); + rte_errno = ENOTSUP; + return NULL; + } + action = mlx5dr_action_create_generic(ctx, flags, MLX5DR_ACTION_TYP_TAG); if (!action) return NULL; @@ -1588,7 +1744,9 @@ mlx5dr_action_create_dest_vport(struct mlx5dr_context *ctx, struct mlx5dr_action *action; int ret; - if (!(flags & MLX5DR_ACTION_FLAG_HWS_FDB)) { + if (!(flags & (MLX5DR_ACTION_FLAG_HWS_FDB | MLX5DR_ACTION_FLAG_HWS_FDB_RX | + MLX5DR_ACTION_FLAG_HWS_FDB_TX | + MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED))) { DR_LOG(ERR, "Vport action is supported for FDB only"); rte_errno = EINVAL; return NULL; @@ -2317,11 +2475,21 @@ mlx5dr_action_create_dest_array(struct mlx5dr_context *ctx, return NULL; } - if (flags == (MLX5DR_ACTION_FLAG_HWS_RX | MLX5DR_ACTION_FLAG_SHARED)) { + if (!(flags & MLX5DR_ACTION_FLAG_SHARED)) { + DR_LOG(ERR, "Action flags not supported, should include SHARED"); + rte_errno = ENOTSUP; + return NULL; + } + + flags = flags & ~MLX5DR_ACTION_FLAG_SHARED; + + if (flags == MLX5DR_ACTION_FLAG_HWS_RX) { ft_attr.type = FS_FT_NIC_RX; ft_attr.level = MLX5_IFC_MULTI_PATH_FT_MAX_LEVEL - 1; table_type = MLX5DR_TABLE_TYPE_NIC_RX; - } else if (flags == (MLX5DR_ACTION_FLAG_HWS_FDB | MLX5DR_ACTION_FLAG_SHARED)) { + } else if (flags & (MLX5DR_ACTION_FLAG_HWS_FDB | MLX5DR_ACTION_FLAG_HWS_FDB_RX | + MLX5DR_ACTION_FLAG_HWS_FDB_TX | + MLX5DR_ACTION_FLAG_HWS_FDB_UNIFIED)) { ft_attr.type = FS_FT_FDB; ft_attr.level = ctx->caps->fdb_ft.max_level - 1; table_type = MLX5DR_TABLE_TYPE_FDB; @@ -2363,7 +2531,7 @@ mlx5dr_action_create_dest_array(struct mlx5dr_context *ctx, fte_attr.ignore_flow_level = 1; break; case MLX5DR_ACTION_TYP_MISS: - if (table_type != MLX5DR_TABLE_TYPE_FDB) { + if (!mlx5dr_table_is_fdb_any(table_type)) { DR_LOG(ERR, "Miss action supported for FDB only"); rte_errno = ENOTSUP; goto free_dest_list; diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h b/drivers/net/mlx5/hws/mlx5dr_action.h index 8ce4ecd5ba..b779e578fd 100644 --- a/drivers/net/mlx5/hws/mlx5dr_action.h +++ b/drivers/net/mlx5/hws/mlx5dr_action.h @@ -160,7 +160,7 @@ struct mlx5dr_action_template { struct mlx5dr_action { uint8_t type; - uint8_t flags; + uint16_t flags; struct mlx5dr_context *ctx; union { struct { -- 2.21.0