From: Alex Vesker <va...@nvidia.com>

Each steering entry (STE) has a bit called re-parse used for
re-parsing the packet in HW, re-parsing is needed after
reformat (e.g. push/pop/encapsulate/...) or when modifying the
packet headers requiring structure change (e.g. TCP to UDP).
Until now we re-parsed the packet in each STE leading to
longer processing per packet. With supported devices we
can control re-parse bit to allow better performance.

Signed-off-by: Alex Vesker <va...@nvidia.com>
Reviewed-by: Erez Shitrit <ere...@nvidia.com>
Acked-by: Matan Azrad <ma...@nvidia.com>
---
 drivers/common/mlx5/mlx5_prm.h        | 10 ++++-
 drivers/net/mlx5/hws/mlx5dr_action.c  | 58 +++++++++++++++++----------
 drivers/net/mlx5/hws/mlx5dr_action.h  |  2 +-
 drivers/net/mlx5/hws/mlx5dr_cmd.c     |  3 +-
 drivers/net/mlx5/hws/mlx5dr_cmd.h     |  2 +
 drivers/net/mlx5/hws/mlx5dr_context.c | 15 +++++++
 drivers/net/mlx5/hws/mlx5dr_context.h |  9 ++++-
 drivers/net/mlx5/hws/mlx5dr_matcher.c |  2 +
 8 files changed, 75 insertions(+), 26 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index bb2b990d5b..a5ecce98e9 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -3445,6 +3445,7 @@ enum mlx5_ifc_rtc_ste_format {
 enum mlx5_ifc_rtc_reparse_mode {
        MLX5_IFC_RTC_REPARSE_NEVER = 0x0,
        MLX5_IFC_RTC_REPARSE_ALWAYS = 0x1,
+       MLX5_IFC_RTC_REPARSE_BY_STC = 0x2,
 };
 
 #define MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX 16
@@ -3515,6 +3516,12 @@ enum mlx5_ifc_stc_action_type {
        MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_UPLINK = 0x86,
 };
 
+enum mlx5_ifc_stc_reparse_mode {
+       MLX5_IFC_STC_REPARSE_IGNORE = 0x0,
+       MLX5_IFC_STC_REPARSE_NEVER = 0x1,
+       MLX5_IFC_STC_REPARSE_ALWAYS = 0x2,
+};
+
 struct mlx5_ifc_stc_ste_param_ste_table_bits {
        u8 ste_obj_id[0x20];
        u8 match_definer_id[0x20];
@@ -3648,7 +3655,8 @@ enum {
 
 struct mlx5_ifc_stc_bits {
        u8 modify_field_select[0x40];
-       u8 reserved_at_40[0x48];
+       u8 reserved_at_40[0x46];
+       u8 reparse_mode[0x2];
        u8 table_type[0x8];
        u8 ste_action_offset[0x8];
        u8 action_type[0x8];
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.c 
b/drivers/net/mlx5/hws/mlx5dr_action.c
index 05b6e97576..bdccfb9cf3 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.c
+++ b/drivers/net/mlx5/hws/mlx5dr_action.c
@@ -124,16 +124,18 @@ static int mlx5dr_action_get_shared_stc_nic(struct 
mlx5dr_context *ctx,
                goto unlock_and_out;
        }
        switch (stc_type) {
-       case MLX5DR_CONTEXT_SHARED_STC_DECAP:
+       case MLX5DR_CONTEXT_SHARED_STC_DECAP_L3:
                stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE;
                stc_attr.action_offset = MLX5DR_ACTION_OFFSET_DW5;
+               stc_attr.reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE;
                stc_attr.remove_header.decap = 0;
                stc_attr.remove_header.start_anchor = 
MLX5_HEADER_ANCHOR_PACKET_START;
                stc_attr.remove_header.end_anchor = 
MLX5_HEADER_ANCHOR_IPV6_IPV4;
                break;
-       case MLX5DR_CONTEXT_SHARED_STC_POP:
+       case MLX5DR_CONTEXT_SHARED_STC_DOUBLE_POP:
                stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS;
                stc_attr.action_offset = MLX5DR_ACTION_OFFSET_DW5;
+               stc_attr.reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                stc_attr.remove_words.start_anchor = 
MLX5_HEADER_ANCHOR_FIRST_VLAN_START;
                stc_attr.remove_words.num_of_words = 
MLX5DR_ACTION_HDR_LEN_L2_VLAN;
                break;
@@ -512,6 +514,11 @@ int mlx5dr_action_alloc_single_stc(struct mlx5dr_context 
*ctx,
        }
 
        stc_attr->stc_offset = stc->offset;
+
+       /* Dynamic reparse not supported, overwrite and use default */
+       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);
 
        /* According to table/action limitation change the stc_attr */
@@ -600,6 +607,8 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
                                        struct mlx5dr_devx_obj *obj,
                                        struct mlx5dr_cmd_stc_modify_attr *attr)
 {
+       attr->reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE;
+
        switch (action->type) {
        case MLX5DR_ACTION_TYP_TAG:
                attr->action_type = MLX5_IFC_STC_ACTION_TYPE_TAG;
@@ -626,6 +635,7 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
        case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2:
        case MLX5DR_ACTION_TYP_MODIFY_HDR:
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW6;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                if (action->modify_header.num_of_actions == 1) {
                        attr->modify_action.data = 
action->modify_header.single_action;
                        attr->action_type = 
mlx5dr_action_get_mh_stc_type(attr->modify_action.data);
@@ -653,6 +663,7 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
        case MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2:
                attr->action_type = MLX5_IFC_STC_ACTION_TYPE_HEADER_REMOVE;
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW5;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                attr->remove_header.decap = 1;
                attr->remove_header.start_anchor = 
MLX5_HEADER_ANCHOR_PACKET_START;
                attr->remove_header.end_anchor = MLX5_HEADER_ANCHOR_INNER_MAC;
@@ -662,6 +673,7 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
        case MLX5DR_ACTION_TYP_INSERT_HEADER:
                attr->action_type = MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT;
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW6;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                attr->insert_header.encap = action->reformat.encap;
                attr->insert_header.insert_anchor = action->reformat.anchor;
                attr->insert_header.arg_id = action->reformat.arg_obj->id;
@@ -705,12 +717,14 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
        case MLX5DR_ACTION_TYP_POP_VLAN:
                attr->action_type = MLX5_IFC_STC_ACTION_TYPE_REMOVE_WORDS;
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW5;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                attr->remove_words.start_anchor = 
MLX5_HEADER_ANCHOR_FIRST_VLAN_START;
                attr->remove_words.num_of_words = MLX5DR_ACTION_HDR_LEN_L2_VLAN 
/ 2;
                break;
        case MLX5DR_ACTION_TYP_PUSH_VLAN:
                attr->action_type = MLX5_IFC_STC_ACTION_TYPE_HEADER_INSERT;
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW6;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                attr->insert_header.encap = 0;
                attr->insert_header.is_inline = 1;
                attr->insert_header.insert_anchor = 
MLX5_HEADER_ANCHOR_PACKET_START;
@@ -730,6 +744,7 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
        case MLX5DR_ACTION_TYP_REFORMAT_TRAILER:
                attr->action_type = MLX5_IFC_STC_ACTION_TYPE_TRAILER;
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW5;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                attr->reformat_trailer.type = action->reformat_trailer.type;
                attr->reformat_trailer.op = action->reformat_trailer.op;
                attr->reformat_trailer.size = action->reformat_trailer.size;
@@ -746,6 +761,7 @@ static void mlx5dr_action_fill_stc_attr(struct 
mlx5dr_action *action,
                        attr->remove_words.num_of_words = 
action->remove_header.num_of_words;
                }
                attr->action_offset = MLX5DR_ACTION_OFFSET_DW5;
+               attr->reparse_mode = MLX5_IFC_STC_REPARSE_ALWAYS;
                break;
        default:
                DR_LOG(ERR, "Invalid action type %d", action->type);
@@ -1310,7 +1326,7 @@ mlx5dr_action_create_pop_vlan(struct mlx5dr_context *ctx, 
uint32_t flags)
        if (!action)
                return NULL;
 
-       ret = mlx5dr_action_get_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_POP);
+       ret = mlx5dr_action_get_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DOUBLE_POP);
        if (ret) {
                DR_LOG(ERR, "Failed to create remove stc for reformat");
                goto free_action;
@@ -1325,7 +1341,7 @@ mlx5dr_action_create_pop_vlan(struct mlx5dr_context *ctx, 
uint32_t flags)
        return action;
 
 free_shared:
-       mlx5dr_action_put_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_POP);
+       mlx5dr_action_put_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DOUBLE_POP);
 free_action:
        simple_free(action);
        return NULL;
@@ -1481,7 +1497,7 @@ mlx5dr_action_handle_l2_to_tunnel_l3(struct mlx5dr_action 
*action,
        int ret;
 
        /* The action is remove-l2-header + insert-l3-header */
-       ret = mlx5dr_action_get_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DECAP);
+       ret = mlx5dr_action_get_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DECAP_L3);
        if (ret) {
                DR_LOG(ERR, "Failed to create remove stc for reformat");
                return ret;
@@ -1498,7 +1514,7 @@ mlx5dr_action_handle_l2_to_tunnel_l3(struct mlx5dr_action 
*action,
        return 0;
 
 put_shared_stc:
-       mlx5dr_action_put_shared_stc(action, MLX5DR_CONTEXT_SHARED_STC_DECAP);
+       mlx5dr_action_put_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DECAP_L3);
        return ret;
 }
 
@@ -2393,7 +2409,7 @@ static void mlx5dr_action_destroy_hws(struct 
mlx5dr_action *action)
                break;
        case MLX5DR_ACTION_TYP_POP_VLAN:
                mlx5dr_action_destroy_stcs(action);
-               mlx5dr_action_put_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_POP);
+               mlx5dr_action_put_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DOUBLE_POP);
                break;
        case MLX5DR_ACTION_TYP_DEST_ARRAY:
                mlx5dr_action_destroy_stcs(action);
@@ -2421,7 +2437,7 @@ static void mlx5dr_action_destroy_hws(struct 
mlx5dr_action *action)
                        mlx5dr_cmd_destroy_obj(obj);
                break;
        case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3:
-               mlx5dr_action_put_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DECAP);
+               mlx5dr_action_put_shared_stc(action, 
MLX5DR_CONTEXT_SHARED_STC_DECAP_L3);
                for (i = 0; i < action->reformat.num_of_hdrs; i++)
                        mlx5dr_action_destroy_stcs(&action[i]);
                mlx5dr_cmd_destroy_obj(action->reformat.arg_obj);
@@ -2481,6 +2497,7 @@ int mlx5dr_action_get_default_stc(struct mlx5dr_context 
*ctx,
 
        stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_NOP;
        stc_attr.action_offset = MLX5DR_ACTION_OFFSET_DW0;
+       stc_attr.reparse_mode = MLX5_IFC_STC_REPARSE_IGNORE;
        ret = mlx5dr_action_alloc_single_stc(ctx, &stc_attr, tbl_type,
                                             &default_stc->nop_ctr);
        if (ret) {
@@ -2858,7 +2875,7 @@ mlx5dr_action_setter_single_double_pop(struct 
mlx5dr_actions_apply_data *apply,
        apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
        apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] =
                htobe32(mlx5dr_action_get_shared_stc_offset(apply->common_res,
-                                                   
MLX5DR_CONTEXT_SHARED_STC_POP));
+                                                           
MLX5DR_CONTEXT_SHARED_STC_DOUBLE_POP));
 }
 
 static void
@@ -2893,7 +2910,7 @@ mlx5dr_action_setter_common_decap(struct 
mlx5dr_actions_apply_data *apply,
        apply->wqe_data[MLX5DR_ACTION_OFFSET_DW5] = 0;
        apply->wqe_ctrl->stc_ix[MLX5DR_ACTION_STC_IDX_DW5] =
                htobe32(mlx5dr_action_get_shared_stc_offset(apply->common_res,
-                                                           
MLX5DR_CONTEXT_SHARED_STC_DECAP));
+                                                           
MLX5DR_CONTEXT_SHARED_STC_DECAP_L3));
 }
 
 static void
@@ -2983,8 +3000,8 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
                                pop_setter->set_single = 
&mlx5dr_action_setter_single_double_pop;
                                break;
                        }
-                       setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_SINGLE1 | ASF_MODIFY);
-                       setter->flags |= ASF_SINGLE1 | ASF_REPARSE | ASF_REMOVE;
+                       setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_SINGLE1 | ASF_MODIFY | ASF_INSERT);
+                       setter->flags |= ASF_SINGLE1 | ASF_REMOVE;
                        setter->set_single = &mlx5dr_action_setter_single;
                        setter->idx_single = i;
                        pop_setter = setter;
@@ -2993,7 +3010,7 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
                case MLX5DR_ACTION_TYP_PUSH_VLAN:
                        /* Double insert inline */
                        setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_DOUBLE | ASF_REMOVE);
-                       setter->flags |= ASF_DOUBLE | ASF_REPARSE | ASF_MODIFY;
+                       setter->flags |= ASF_DOUBLE | ASF_INSERT;
                        setter->set_double = &mlx5dr_action_setter_push_vlan;
                        setter->idx_double = i;
                        break;
@@ -3001,7 +3018,7 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
                case MLX5DR_ACTION_TYP_MODIFY_HDR:
                        /* Double modify header list */
                        setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_DOUBLE | ASF_REMOVE);
-                       setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE;
+                       setter->flags |= ASF_DOUBLE | ASF_MODIFY;
                        setter->set_double = 
&mlx5dr_action_setter_modify_header;
                        setter->idx_double = i;
                        break;
@@ -3021,7 +3038,7 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
                case MLX5DR_ACTION_TYP_REFORMAT_TNL_L2_TO_L2:
                        /* Single remove header to header */
                        setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_SINGLE1 | ASF_MODIFY);
-                       setter->flags |= ASF_SINGLE1 | ASF_REMOVE | ASF_REPARSE;
+                       setter->flags |= ASF_SINGLE1 | ASF_REMOVE;
                        setter->set_single = &mlx5dr_action_setter_single;
                        setter->idx_single = i;
                        break;
@@ -3029,8 +3046,8 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
                case MLX5DR_ACTION_TYP_INSERT_HEADER:
                case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L2:
                        /* Double insert header with pointer */
-                       setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_DOUBLE);
-                       setter->flags |= ASF_DOUBLE | ASF_REPARSE;
+                       setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_DOUBLE | ASF_REMOVE);
+                       setter->flags |= ASF_DOUBLE | ASF_INSERT;
                        setter->set_double = &mlx5dr_action_setter_insert_ptr;
                        setter->idx_double = i;
                        break;
@@ -3038,7 +3055,7 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
                case MLX5DR_ACTION_TYP_REFORMAT_L2_TO_TNL_L3:
                        /* Single remove + Double insert header with pointer */
                        setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_SINGLE1 | ASF_DOUBLE);
-                       setter->flags |= ASF_SINGLE1 | ASF_DOUBLE | ASF_REPARSE 
| ASF_REMOVE;
+                       setter->flags |= ASF_SINGLE1 | ASF_DOUBLE;
                        setter->set_double = &mlx5dr_action_setter_insert_ptr;
                        setter->idx_double = i;
                        setter->set_single = &mlx5dr_action_setter_common_decap;
@@ -3047,9 +3064,8 @@ int mlx5dr_action_template_process(struct 
mlx5dr_action_template *at)
 
                case MLX5DR_ACTION_TYP_REFORMAT_TNL_L3_TO_L2:
                        /* Double modify header list with remove and push 
inline */
-                       setter = mlx5dr_action_setter_find_first(last_setter,
-                                                                ASF_DOUBLE | 
ASF_REMOVE);
-                       setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_REPARSE;
+                       setter = mlx5dr_action_setter_find_first(last_setter, 
ASF_DOUBLE | ASF_REMOVE);
+                       setter->flags |= ASF_DOUBLE | ASF_MODIFY | ASF_INSERT;
                        setter->set_double = &mlx5dr_action_setter_tnl_l3_to_l2;
                        setter->idx_double = i;
                        break;
diff --git a/drivers/net/mlx5/hws/mlx5dr_action.h 
b/drivers/net/mlx5/hws/mlx5dr_action.h
index 4046f658e6..328de65a1e 100644
--- a/drivers/net/mlx5/hws/mlx5dr_action.h
+++ b/drivers/net/mlx5/hws/mlx5dr_action.h
@@ -55,7 +55,7 @@ enum mlx5dr_action_setter_flag {
        ASF_SINGLE3 = 1 << 2,
        ASF_DOUBLE = ASF_SINGLE2 | ASF_SINGLE3,
        ASF_TRIPLE = ASF_SINGLE1 | ASF_DOUBLE,
-       ASF_REPARSE = 1 << 3,
+       ASF_INSERT = 1 << 3,
        ASF_REMOVE = 1 << 4,
        ASF_MODIFY = 1 << 5,
        ASF_CTR = 1 << 6,
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c 
b/drivers/net/mlx5/hws/mlx5dr_cmd.c
index 135d31dca1..07c820afe5 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.c
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c
@@ -394,7 +394,7 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx,
        MLX5_SET(rtc, attr, ste_table_base_id, rtc_attr->ste_base);
        MLX5_SET(rtc, attr, ste_table_offset, rtc_attr->ste_offset);
        MLX5_SET(rtc, attr, miss_flow_table_id, rtc_attr->miss_ft_id);
-       MLX5_SET(rtc, attr, reparse_mode, MLX5_IFC_RTC_REPARSE_ALWAYS);
+       MLX5_SET(rtc, attr, reparse_mode, rtc_attr->reparse_mode);
 
        devx_obj->obj = mlx5_glue->devx_obj_create(ctx, in, sizeof(in), out, 
sizeof(out));
        if (!devx_obj->obj) {
@@ -586,6 +586,7 @@ mlx5dr_cmd_stc_modify(struct mlx5dr_devx_obj *devx_obj,
        attr = MLX5_ADDR_OF(create_stc_in, in, stc);
        MLX5_SET(stc, attr, ste_action_offset, stc_attr->action_offset);
        MLX5_SET(stc, attr, action_type, stc_attr->action_type);
+       MLX5_SET(stc, attr, reparse_mode, stc_attr->reparse_mode);
        MLX5_SET64(stc, attr, modify_field_select,
                   MLX5_IFC_MODIFY_STC_FIELD_SELECT_NEW_STC);
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h 
b/drivers/net/mlx5/hws/mlx5dr_cmd.h
index cb27212a5b..7792fc48aa 100644
--- a/drivers/net/mlx5/hws/mlx5dr_cmd.h
+++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h
@@ -79,6 +79,7 @@ struct mlx5dr_cmd_rtc_create_attr {
        uint8_t table_type;
        uint8_t match_definer_0;
        uint8_t match_definer_1;
+       uint8_t reparse_mode;
        bool is_frst_jumbo;
        bool is_scnd_range;
 };
@@ -98,6 +99,7 @@ struct mlx5dr_cmd_stc_create_attr {
 struct mlx5dr_cmd_stc_modify_attr {
        uint32_t stc_offset;
        uint8_t action_offset;
+       uint8_t reparse_mode;
        enum mlx5_ifc_stc_action_type action_type;
        union {
                uint32_t id; /* TIRN, TAG, FT ID, STE ID, CRYPTO */
diff --git a/drivers/net/mlx5/hws/mlx5dr_context.c 
b/drivers/net/mlx5/hws/mlx5dr_context.c
index 08a5ee92a5..15d53c578a 100644
--- a/drivers/net/mlx5/hws/mlx5dr_context.c
+++ b/drivers/net/mlx5/hws/mlx5dr_context.c
@@ -4,6 +4,21 @@
 
 #include "mlx5dr_internal.h"
 
+bool mlx5dr_context_cap_dynamic_reparse(struct mlx5dr_context *ctx)
+{
+       return IS_BIT_SET(ctx->caps->rtc_reparse_mode, 
MLX5_IFC_RTC_REPARSE_BY_STC);
+}
+
+uint8_t mlx5dr_context_get_reparse_mode(struct mlx5dr_context *ctx)
+{
+       /* Prefer to use dynamic reparse, reparse only specific actions */
+       if (mlx5dr_context_cap_dynamic_reparse(ctx))
+               return MLX5_IFC_RTC_REPARSE_NEVER;
+
+       /* Otherwise use less efficient static */
+       return MLX5_IFC_RTC_REPARSE_ALWAYS;
+}
+
 static int mlx5dr_context_pools_init(struct mlx5dr_context *ctx)
 {
        struct mlx5dr_pool_attr pool_attr = {0};
diff --git a/drivers/net/mlx5/hws/mlx5dr_context.h 
b/drivers/net/mlx5/hws/mlx5dr_context.h
index 0ba8d0c92e..f476c2308c 100644
--- a/drivers/net/mlx5/hws/mlx5dr_context.h
+++ b/drivers/net/mlx5/hws/mlx5dr_context.h
@@ -11,8 +11,8 @@ enum mlx5dr_context_flags {
 };
 
 enum mlx5dr_context_shared_stc_type {
-       MLX5DR_CONTEXT_SHARED_STC_DECAP = 0,
-       MLX5DR_CONTEXT_SHARED_STC_POP = 1,
+       MLX5DR_CONTEXT_SHARED_STC_DECAP_L3 = 0,
+       MLX5DR_CONTEXT_SHARED_STC_DOUBLE_POP = 1,
        MLX5DR_CONTEXT_SHARED_STC_MAX = 2,
 };
 
@@ -60,4 +60,9 @@ mlx5dr_context_get_local_ibv(struct mlx5dr_context *ctx)
 
        return ctx->ibv_ctx;
 }
+
+bool mlx5dr_context_cap_dynamic_reparse(struct mlx5dr_context *ctx);
+
+uint8_t mlx5dr_context_get_reparse_mode(struct mlx5dr_context *ctx);
+
 #endif /* MLX5DR_CONTEXT_H_ */
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c 
b/drivers/net/mlx5/hws/mlx5dr_matcher.c
index 6f74cf3677..cd6cbdeceb 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.c
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c
@@ -583,6 +583,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher 
*matcher,
        rtc_attr.pd = ctx->pd_num;
        rtc_attr.ste_base = devx_obj->id;
        rtc_attr.ste_offset = ste->offset;
+       rtc_attr.reparse_mode = mlx5dr_context_get_reparse_mode(ctx);
        rtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, false);
        mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, false);
 
@@ -790,6 +791,7 @@ static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher 
*matcher)
        /* Allocate STC for jumps to STE */
        stc_attr.action_offset = MLX5DR_ACTION_OFFSET_HIT;
        stc_attr.action_type = MLX5_IFC_STC_ACTION_TYPE_JUMP_TO_STE_TABLE;
+       stc_attr.reparse_mode = MLX5_IFC_STC_REPARSE_NEVER;
        stc_attr.ste_table.ste = matcher->action_ste.ste;
        stc_attr.ste_table.ste_pool = matcher->action_ste.pool;
        stc_attr.ste_table.match_definer_id = ctx->caps->trivial_match_definer;
-- 
2.39.2

Reply via email to