Added support for RTC with insertion by hash/index and distribution
by normal/linear hash.

Supported modes are:

- INSERT_BY_HASH + DISTRIBUTE_BY_HASH: what we had until now
- INSERT_BY_INDEX + DISTRIBUTE_BY_HASH: Hash Split table, can also
  be used to calculate hash, in which case the result can be read
  from the hash_result meta-field (MLX5_MODI_HASH_RESULT)
- INSERT_BY_INDEX + DISTRIBUTE_BY_LINEAR: Linear Lookup table,
  supported only for metadata_reg_c3[31:16] bits

When setting INSERT_BY_INDEX mode, you can still provide number of
rules both through 'rule' and 'table' fields of matcher attributes,
but if 'table' is used, then 'table.sz_col_log' has to be 0.

When providing rule with index, this index is used both in rule
creation and deletion.

Signed-off-by: Yevgeny Kliteynik <klit...@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr.h         |  17 ++-
 drivers/net/mlx5/hws/mlx5dr_debug.c   |   6 +-
 drivers/net/mlx5/hws/mlx5dr_matcher.c | 211 +++++++++++++++++++++-----
 drivers/net/mlx5/hws/mlx5dr_matcher.h |   6 +
 drivers/net/mlx5/hws/mlx5dr_rule.c    |  23 ++-
 drivers/net/mlx5/hws/mlx5dr_rule.h    |   2 +-
 6 files changed, 217 insertions(+), 48 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index c0f9a5e984..b3b2bf34f2 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -111,6 +111,16 @@ enum mlx5dr_matcher_flow_src {
        MLX5DR_MATCHER_FLOW_SRC_VPORT = 0x2,
 };
 
+enum mlx5dr_matcher_insert_mode {
+       MLX5DR_MATCHER_INSERT_BY_HASH = 0x0,
+       MLX5DR_MATCHER_INSERT_BY_INDEX = 0x1,
+};
+
+enum mlx5dr_matcher_distribute_mode {
+       MLX5DR_MATCHER_DISTRIBUTE_BY_HASH = 0x0,
+       MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR = 0x1,
+};
+
 struct mlx5dr_matcher_attr {
        /* Processing priority inside table */
        uint32_t priority;
@@ -120,6 +130,9 @@ struct mlx5dr_matcher_attr {
        enum mlx5dr_matcher_resource_mode mode;
        /* Optimize insertion in case packet origin is the same for all rules */
        enum mlx5dr_matcher_flow_src optimize_flow_src;
+       /* Define the insertion and distribution modes for this matcher */
+       enum mlx5dr_matcher_insert_mode insert_mode;
+       enum mlx5dr_matcher_distribute_mode distribute_mode;
        union {
                struct {
                        uint8_t sz_row_log;
@@ -135,7 +148,9 @@ struct mlx5dr_matcher_attr {
 struct mlx5dr_rule_attr {
        uint16_t queue_id;
        void *user_data;
-       /* Valid if matcher optimize_using_rule_idx is set */
+       /* Valid if matcher optimize_using_rule_idx is set or
+        * if matcher is configured to insert rules by index.
+        */
        uint32_t rule_idx;
        uint32_t burst:1;
 };
diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c 
b/drivers/net/mlx5/hws/mlx5dr_debug.c
index 239dfcae46..0815327b18 100644
--- a/drivers/net/mlx5/hws/mlx5dr_debug.c
+++ b/drivers/net/mlx5/hws/mlx5dr_debug.c
@@ -158,7 +158,7 @@ mlx5dr_debug_dump_matcher_attr(FILE *f, struct 
mlx5dr_matcher *matcher)
        struct mlx5dr_matcher_attr *attr = &matcher->attr;
        int ret;
 
-       ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d\n",
+       ret = fprintf(f, "%d,0x%" PRIx64 ",%d,%d,%d,%d,%d,%d,%d,%d\n",
                      MLX5DR_DEBUG_RES_TYPE_MATCHER_ATTR,
                      (uint64_t)(uintptr_t)matcher,
                      attr->priority,
@@ -166,7 +166,9 @@ mlx5dr_debug_dump_matcher_attr(FILE *f, struct 
mlx5dr_matcher *matcher)
                      attr->table.sz_row_log,
                      attr->table.sz_col_log,
                      attr->optimize_using_rule_idx,
-                     attr->optimize_flow_src);
+                     attr->optimize_flow_src,
+                     attr->insert_mode,
+                     attr->distribute_mode);
        if (ret < 0) {
                rte_errno = EINVAL;
                return rte_errno;
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c 
b/drivers/net/mlx5/hws/mlx5dr_matcher.c
index 46217b2ab3..60865bf562 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.c
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c
@@ -4,6 +4,25 @@
 
 #include "mlx5dr_internal.h"
 
+enum mlx5dr_matcher_rtc_type {
+       DR_MATCHER_RTC_TYPE_MATCH,
+       DR_MATCHER_RTC_TYPE_STE_ARRAY,
+       DR_MATCHER_RTC_TYPE_MAX,
+};
+
+static const char * const mlx5dr_matcher_rtc_type_str[] = {
+       [DR_MATCHER_RTC_TYPE_MATCH] = "MATCH",
+       [DR_MATCHER_RTC_TYPE_STE_ARRAY] = "STE_ARRAY",
+       [DR_MATCHER_RTC_TYPE_MAX] = "UNKNOWN",
+};
+
+static const char *mlx5dr_matcher_rtc_type_to_str(enum mlx5dr_matcher_rtc_type 
rtc_type)
+{
+       if (rtc_type > DR_MATCHER_RTC_TYPE_MAX)
+               rtc_type = DR_MATCHER_RTC_TYPE_MAX;
+       return mlx5dr_matcher_rtc_type_str[rtc_type];
+}
+
 static bool mlx5dr_matcher_requires_col_tbl(uint8_t log_num_of_rules)
 {
        /* Collision table concatenation is done only for large rule tables */
@@ -320,10 +339,11 @@ static int mlx5dr_matcher_disconnect(struct 
mlx5dr_matcher *matcher)
 
 static void mlx5dr_matcher_set_rtc_attr_sz(struct mlx5dr_matcher *matcher,
                                           struct mlx5dr_cmd_rtc_create_attr 
*rtc_attr,
-                                          bool is_match_rtc,
+                                          enum mlx5dr_matcher_rtc_type 
rtc_type,
                                           bool is_mirror)
 {
        enum mlx5dr_matcher_flow_src flow_src = matcher->attr.optimize_flow_src;
+       bool is_match_rtc = rtc_type == DR_MATCHER_RTC_TYPE_MATCH;
        struct mlx5dr_pool_chunk *ste = &matcher->action_ste.ste;
 
        if ((flow_src == MLX5DR_MATCHER_FLOW_SRC_VPORT && !is_mirror) ||
@@ -382,9 +402,9 @@ int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context 
*ctx,
 }
 
 static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher,
-                                    bool is_match_rtc)
+                                    enum mlx5dr_matcher_rtc_type rtc_type)
 {
-       const char *rtc_type_str = is_match_rtc ? "match" : "action";
+       struct mlx5dr_matcher_attr *attr = &matcher->attr;
        struct mlx5dr_cmd_rtc_create_attr rtc_attr = {0};
        struct mlx5dr_context *ctx = matcher->tbl->ctx;
        struct mlx5dr_action_default_stc *default_stc;
@@ -395,33 +415,57 @@ static int mlx5dr_matcher_create_rtc(struct 
mlx5dr_matcher *matcher,
        struct mlx5dr_pool_chunk *ste;
        int ret;
 
-       if (is_match_rtc) {
+       switch (rtc_type) {
+       case DR_MATCHER_RTC_TYPE_MATCH:
                rtc_0 = &matcher->match_ste.rtc_0;
                rtc_1 = &matcher->match_ste.rtc_1;
                ste_pool = matcher->match_ste.pool;
                ste = &matcher->match_ste.ste;
-               ste->order = matcher->attr.table.sz_col_log +
-                            matcher->attr.table.sz_row_log;
-               rtc_attr.log_size = matcher->attr.table.sz_row_log;
-               rtc_attr.log_depth = matcher->attr.table.sz_col_log;
-               rtc_attr.update_index_mode = 
MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH;
-               /* The first match template is used since all share the same 
definer */
-               rtc_attr.definer_id = 
mlx5dr_definer_get_id(matcher->mt[0]->definer);
-               rtc_attr.is_jumbo = 
mlx5dr_definer_is_jumbo(matcher->mt[0]->definer);
+               ste->order = attr->table.sz_col_log + attr->table.sz_row_log;
+               rtc_attr.log_size = attr->table.sz_row_log;
+               rtc_attr.log_depth = attr->table.sz_col_log;
                rtc_attr.miss_ft_id = matcher->end_ft->id;
+
+               if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) {
+                       /* The usual Hash Table */
+                       rtc_attr.update_index_mode = 
MLX5_IFC_RTC_STE_UPDATE_MODE_BY_HASH;
+                       /* The first match template is used since all share the 
same definer */
+                       rtc_attr.definer_id = 
mlx5dr_definer_get_id(matcher->mt[0]->definer);
+                       rtc_attr.is_jumbo = 
mlx5dr_definer_is_jumbo(matcher->mt[0]->definer);
+               } else if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX) 
{
+                       rtc_attr.update_index_mode = 
MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET;
+                       rtc_attr.num_hash_definer = 1;
+
+                       if (attr->distribute_mode == 
MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) {
+                               /* Hash Split Table */
+                               rtc_attr.access_index_mode = 
MLX5_IFC_RTC_STE_ACCESS_MODE_BY_HASH;
+                               rtc_attr.definer_id =
+                                       
mlx5dr_definer_get_id(matcher->mt[0]->definer);
+                               rtc_attr.is_jumbo =
+                                       
mlx5dr_definer_is_jumbo(matcher->mt[0]->definer);
+                       } else if (attr->distribute_mode == 
MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) {
+                               /* Linear Lookup Table */
+                               rtc_attr.access_index_mode = 
MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR;
+                               rtc_attr.definer_id = 
ctx->caps->linear_match_definer;
+                       }
+               }
+
                /* Match pool requires implicit allocation */
                ret = mlx5dr_pool_chunk_alloc(ste_pool, ste);
                if (ret) {
-                       DR_LOG(ERR, "Failed to allocate STE for %s RTC", 
rtc_type_str);
+                       DR_LOG(ERR, "Failed to allocate STE for %s RTC",
+                              mlx5dr_matcher_rtc_type_to_str(rtc_type));
                        return ret;
                }
-       } else {
+               break;
+
+       case DR_MATCHER_RTC_TYPE_STE_ARRAY:
                rtc_0 = &matcher->action_ste.rtc_0;
                rtc_1 = &matcher->action_ste.rtc_1;
                ste_pool = matcher->action_ste.pool;
                ste = &matcher->action_ste.ste;
                ste->order = rte_log2_u32(matcher->action_ste.max_stes) +
-                            matcher->attr.table.sz_row_log;
+                            attr->table.sz_row_log;
                rtc_attr.log_size = ste->order;
                rtc_attr.log_depth = 0;
                rtc_attr.update_index_mode = 
MLX5_IFC_RTC_STE_UPDATE_MODE_BY_OFFSET;
@@ -429,6 +473,12 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher 
*matcher,
                rtc_attr.definer_id = ctx->caps->trivial_match_definer;
                rtc_attr.is_jumbo = false;
                rtc_attr.miss_ft_id = 0;
+               break;
+
+       default:
+               DR_LOG(ERR, "HWS Invalid RTC type");
+               rte_errno = EINVAL;
+               return rte_errno;
        }
 
        devx_obj = mlx5dr_pool_chunk_get_base_devx_obj(ste_pool, ste);
@@ -437,7 +487,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher 
*matcher,
        rtc_attr.ste_base = devx_obj->id;
        rtc_attr.ste_offset = ste->offset;
        rtc_attr.table_type = mlx5dr_table_get_res_fw_ft_type(tbl->type, false);
-       mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, is_match_rtc, false);
+       mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, false);
 
        /* STC is a single resource (devx_obj), use any STC for the ID */
        stc_pool = ctx->stc_pool[tbl->type];
@@ -447,7 +497,8 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher 
*matcher,
 
        *rtc_0 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr);
        if (!*rtc_0) {
-               DR_LOG(ERR, "Failed to create matcher %s RTC", rtc_type_str);
+               DR_LOG(ERR, "Failed to create matcher RTC of type %s",
+                      mlx5dr_matcher_rtc_type_to_str(rtc_type));
                goto free_ste;
        }
 
@@ -458,11 +509,12 @@ static int mlx5dr_matcher_create_rtc(struct 
mlx5dr_matcher *matcher,
 
                devx_obj = mlx5dr_pool_chunk_get_base_devx_obj_mirror(stc_pool, 
&default_stc->default_hit);
                rtc_attr.stc_base = devx_obj->id;
-               mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, 
is_match_rtc, true);
+               mlx5dr_matcher_set_rtc_attr_sz(matcher, &rtc_attr, rtc_type, 
true);
 
                *rtc_1 = mlx5dr_cmd_rtc_create(ctx->ibv_ctx, &rtc_attr);
                if (!*rtc_1) {
-                       DR_LOG(ERR, "Failed to create peer matcher %s RTC0", 
rtc_type_str);
+                       DR_LOG(ERR, "Failed to create peer matcher RTC of type 
%s",
+                              mlx5dr_matcher_rtc_type_to_str(rtc_type));
                        goto destroy_rtc_0;
                }
        }
@@ -472,36 +524,41 @@ static int mlx5dr_matcher_create_rtc(struct 
mlx5dr_matcher *matcher,
 destroy_rtc_0:
        mlx5dr_cmd_destroy_obj(*rtc_0);
 free_ste:
-       if (is_match_rtc)
+       if (rtc_type == DR_MATCHER_RTC_TYPE_MATCH)
                mlx5dr_pool_chunk_free(ste_pool, ste);
        return rte_errno;
 }
 
 static void mlx5dr_matcher_destroy_rtc(struct mlx5dr_matcher *matcher,
-                                      bool is_match_rtc)
+                                      enum mlx5dr_matcher_rtc_type rtc_type)
 {
        struct mlx5dr_table *tbl = matcher->tbl;
        struct mlx5dr_devx_obj *rtc_0, *rtc_1;
        struct mlx5dr_pool_chunk *ste;
        struct mlx5dr_pool *ste_pool;
 
-       if (is_match_rtc) {
+       switch (rtc_type) {
+       case DR_MATCHER_RTC_TYPE_MATCH:
                rtc_0 = matcher->match_ste.rtc_0;
                rtc_1 = matcher->match_ste.rtc_1;
                ste_pool = matcher->match_ste.pool;
                ste = &matcher->match_ste.ste;
-       } else {
+               break;
+       case DR_MATCHER_RTC_TYPE_STE_ARRAY:
                rtc_0 = matcher->action_ste.rtc_0;
                rtc_1 = matcher->action_ste.rtc_1;
                ste_pool = matcher->action_ste.pool;
                ste = &matcher->action_ste.ste;
+               break;
+       default:
+               return;
        }
 
        if (tbl->type == MLX5DR_TABLE_TYPE_FDB)
                mlx5dr_cmd_destroy_obj(rtc_1);
 
        mlx5dr_cmd_destroy_obj(rtc_0);
-       if (is_match_rtc)
+       if (rtc_type == DR_MATCHER_RTC_TYPE_MATCH)
                mlx5dr_pool_chunk_free(ste_pool, ste);
 }
 
@@ -572,7 +629,7 @@ static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher 
*matcher)
        }
 
        /* Allocate action RTC */
-       ret = mlx5dr_matcher_create_rtc(matcher, false);
+       ret = mlx5dr_matcher_create_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY);
        if (ret) {
                DR_LOG(ERR, "Failed to create action RTC");
                goto free_ste_pool;
@@ -595,7 +652,7 @@ static int mlx5dr_matcher_bind_at(struct mlx5dr_matcher 
*matcher)
        return 0;
 
 free_rtc:
-       mlx5dr_matcher_destroy_rtc(matcher, false);
+       mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY);
 free_ste_pool:
        mlx5dr_pool_destroy(matcher->action_ste.pool);
        return rte_errno;
@@ -609,7 +666,7 @@ static void mlx5dr_matcher_unbind_at(struct mlx5dr_matcher 
*matcher)
                return;
 
        mlx5dr_action_free_single_stc(tbl->ctx, tbl->type, 
&matcher->action_ste.stc);
-       mlx5dr_matcher_destroy_rtc(matcher, false);
+       mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_STE_ARRAY);
        mlx5dr_pool_destroy(matcher->action_ste.pool);
 }
 
@@ -674,6 +731,84 @@ static void mlx5dr_matcher_unbind_mt(struct mlx5dr_matcher 
*matcher)
        mlx5dr_pool_destroy(matcher->match_ste.pool);
 }
 
+static int
+mlx5dr_matcher_validate_insert_mode(struct mlx5dr_cmd_query_caps *caps,
+                                   struct mlx5dr_matcher *matcher,
+                                   bool is_root)
+{
+       struct mlx5dr_matcher_attr *attr = &matcher->attr;
+
+       if (is_root) {
+               if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE) {
+                       DR_LOG(ERR, "Root matcher supports only rule resource 
mode");
+                       goto not_supported;
+               }
+               if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH) {
+                       DR_LOG(ERR, "Root matcher supports only insert by hash 
mode");
+                       goto not_supported;
+               }
+               if (attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) 
{
+                       DR_LOG(ERR, "Root matcher supports only distribute by 
hash mode");
+                       goto not_supported;
+               }
+               if (attr->optimize_flow_src) {
+                       DR_LOG(ERR, "Root matcher can't specify FDB direction");
+                       goto not_supported;
+               }
+       }
+
+       switch (attr->insert_mode) {
+       case MLX5DR_MATCHER_INSERT_BY_HASH:
+               if (matcher->attr.distribute_mode != 
MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) {
+                       DR_LOG(ERR, "Invalid matcher distribute mode");
+                       goto not_supported;
+               }
+               break;
+
+       case MLX5DR_MATCHER_INSERT_BY_INDEX:
+               if (attr->table.sz_col_log) {
+                       DR_LOG(ERR, "Matcher with INSERT_BY_INDEX supports only 
Nx1 table size");
+                       goto not_supported;
+               }
+
+               if (attr->distribute_mode == MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) 
{
+                       /* Hash Split Table */
+                       if (!caps->rtc_hash_split_table) {
+                               DR_LOG(ERR, "FW doesn't support insert by index 
and hash distribute");
+                               goto not_supported;
+                       }
+               } else if (attr->distribute_mode == 
MLX5DR_MATCHER_DISTRIBUTE_BY_LINEAR) {
+                       /* Linear Lookup Table */
+                       if (!caps->rtc_linear_lookup_table ||
+                           !IS_BIT_SET(caps->access_index_mode,
+                                       MLX5_IFC_RTC_STE_ACCESS_MODE_LINEAR)) {
+                               DR_LOG(ERR, "FW doesn't support insert by index 
and linear distribute");
+                               goto not_supported;
+                       }
+
+                       if (attr->table.sz_row_log > 
MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX) {
+                               DR_LOG(ERR, "Matcher with linear distribute: 
rows exceed limit %d",
+                                      MLX5_IFC_RTC_LINEAR_LOOKUP_TBL_LOG_MAX);
+                               goto not_supported;
+                       }
+               } else {
+                       DR_LOG(ERR, "Matcher has unsupported distribute mode");
+                       goto not_supported;
+               }
+               break;
+
+       default:
+               DR_LOG(ERR, "Matcher has unsupported insert mode");
+               goto not_supported;
+       }
+
+       return 0;
+
+not_supported:
+       rte_errno = EOPNOTSUPP;
+       return rte_errno;
+}
+
 static int
 mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps *caps,
                            struct mlx5dr_matcher *matcher,
@@ -681,16 +816,10 @@ mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps 
*caps,
 {
        struct mlx5dr_matcher_attr *attr = &matcher->attr;
 
-       if (matcher->tbl->type != MLX5DR_TABLE_TYPE_FDB  && 
attr->optimize_flow_src) {
-               DR_LOG(ERR, "NIC domain doesn't support flow_src");
+       if (mlx5dr_matcher_validate_insert_mode(caps, matcher, is_root))
                goto not_supported;
-       }
 
        if (is_root) {
-               if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_RULE) {
-                       DR_LOG(ERR, "Root matcher supports only rule resource 
mode");
-                       goto not_supported;
-               }
                if (attr->optimize_flow_src) {
                        DR_LOG(ERR, "Root matcher can't specify FDB direction");
                        goto not_supported;
@@ -698,8 +827,14 @@ mlx5dr_matcher_process_attr(struct mlx5dr_cmd_query_caps 
*caps,
                return 0;
        }
 
+       if (matcher->tbl->type != MLX5DR_TABLE_TYPE_FDB  && 
attr->optimize_flow_src) {
+               DR_LOG(ERR, "NIC domain doesn't support flow_src");
+               goto not_supported;
+       }
+
        /* Convert number of rules to the required depth */
-       if (attr->mode == MLX5DR_MATCHER_RESOURCE_MODE_RULE)
+       if (attr->mode == MLX5DR_MATCHER_RESOURCE_MODE_RULE &&
+           attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH)
                attr->table.sz_col_log = 
mlx5dr_matcher_rules_to_tbl_depth(attr->rule.num_log);
 
        if (attr->table.sz_col_log > caps->rtc_log_depth_max) {
@@ -744,7 +879,7 @@ static int mlx5dr_matcher_create_and_connect(struct 
mlx5dr_matcher *matcher)
                goto unbind_at;
 
        /* Allocate the RTC for the new matcher */
-       ret = mlx5dr_matcher_create_rtc(matcher, true);
+       ret = mlx5dr_matcher_create_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH);
        if (ret)
                goto destroy_end_ft;
 
@@ -763,7 +898,7 @@ static int mlx5dr_matcher_create_and_connect(struct 
mlx5dr_matcher *matcher)
 destroy_shared:
        mlx5dr_matcher_create_uninit_shared(matcher);
 destroy_rtc:
-       mlx5dr_matcher_destroy_rtc(matcher, true);
+       mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH);
 destroy_end_ft:
        mlx5dr_matcher_destroy_end_ft(matcher);
 unbind_at:
@@ -777,7 +912,7 @@ static void mlx5dr_matcher_destroy_and_disconnect(struct 
mlx5dr_matcher *matcher
 {
        mlx5dr_matcher_disconnect(matcher);
        mlx5dr_matcher_create_uninit_shared(matcher);
-       mlx5dr_matcher_destroy_rtc(matcher, true);
+       mlx5dr_matcher_destroy_rtc(matcher, DR_MATCHER_RTC_TYPE_MATCH);
        mlx5dr_matcher_destroy_end_ft(matcher);
        mlx5dr_matcher_unbind_at(matcher);
        mlx5dr_matcher_unbind_mt(matcher);
diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h 
b/drivers/net/mlx5/hws/mlx5dr_matcher.h
index 62004078cf..2bebc4bcce 100644
--- a/drivers/net/mlx5/hws/mlx5dr_matcher.h
+++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h
@@ -82,4 +82,10 @@ int mlx5dr_matcher_create_aliased_obj(struct mlx5dr_context 
*ctx,
                                      uint32_t aliased_object_id,
                                      uint16_t object_type,
                                      struct mlx5dr_devx_obj **obj);
+
+static inline bool mlx5dr_matcher_is_insert_by_idx(struct mlx5dr_matcher 
*matcher)
+{
+       return matcher->attr.insert_mode == MLX5DR_MATCHER_INSERT_BY_INDEX;
+}
+
 #endif /* MLX5DR_MATCHER_H_ */
diff --git a/drivers/net/mlx5/hws/mlx5dr_rule.c 
b/drivers/net/mlx5/hws/mlx5dr_rule.c
index b27318e6d4..60a82c022f 100644
--- a/drivers/net/mlx5/hws/mlx5dr_rule.c
+++ b/drivers/net/mlx5/hws/mlx5dr_rule.c
@@ -118,7 +118,8 @@ static int mlx5dr_rule_alloc_action_ste(struct mlx5dr_rule 
*rule,
        int ret;
 
        /* Use rule_idx for locking optimzation, otherwise allocate from pool */
-       if (matcher->attr.optimize_using_rule_idx) {
+       if (matcher->attr.optimize_using_rule_idx ||
+           mlx5dr_matcher_is_insert_by_idx(matcher)) {
                rule->action_ste_idx = attr->rule_idx * 
matcher->action_ste.max_stes;
        } else {
                struct mlx5dr_pool_chunk ste = {0};
@@ -138,7 +139,9 @@ void mlx5dr_rule_free_action_ste_idx(struct mlx5dr_rule 
*rule)
 {
        struct mlx5dr_matcher *matcher = rule->matcher;
 
-       if (rule->action_ste_idx > -1 && 
!matcher->attr.optimize_using_rule_idx) {
+       if (rule->action_ste_idx > -1 &&
+           !matcher->attr.optimize_using_rule_idx &&
+           !mlx5dr_matcher_is_insert_by_idx(matcher)) {
                struct mlx5dr_pool_chunk ste = {0};
 
                /* This release is safe only when the rule match part was 
deleted */
@@ -244,9 +247,14 @@ static int mlx5dr_rule_create_hws(struct mlx5dr_rule *rule,
                mlx5dr_action_apply_setter(&apply, setter--, !i && is_jumbo);
 
                if (i == 0) {
-                       /* Handle last match STE */
-                       mlx5dr_definer_create_tag(items, mt->fc, mt->fc_sz,
-                                                 (uint8_t 
*)dep_wqe->wqe_data.action);
+                       /* Handle last match STE.
+                        * For hash split / linear lookup RTCs, packets 
reaching any STE
+                        * will always match and perform the specified actions, 
which
+                        * makes the tag irrelevant.
+                        */
+                       if (likely(!mlx5dr_matcher_is_insert_by_idx(matcher)))
+                               mlx5dr_definer_create_tag(items, mt->fc, 
mt->fc_sz,
+                                                         (uint8_t 
*)dep_wqe->wqe_data.action);
 
                        /* Rule has dependent WQEs, match dep_wqe is queued */
                        if (action_stes || apply.require_dep)
@@ -258,13 +266,14 @@ static int mlx5dr_rule_create_hws(struct mlx5dr_rule 
*rule,
                        ste_attr.send_attr.notify_hw = !attr->burst;
                        ste_attr.send_attr.user_data = dep_wqe->user_data;
                        ste_attr.send_attr.rule = dep_wqe->rule;
-                       ste_attr.direct_index = 0;
                        ste_attr.rtc_0 = dep_wqe->rtc_0;
                        ste_attr.rtc_1 = dep_wqe->rtc_1;
                        ste_attr.used_id_rtc_0 = &rule->rtc_0;
                        ste_attr.used_id_rtc_1 = &rule->rtc_1;
                        ste_attr.retry_rtc_0 = dep_wqe->retry_rtc_0;
                        ste_attr.retry_rtc_1 = dep_wqe->retry_rtc_1;
+                       ste_attr.direct_index = 
mlx5dr_matcher_is_insert_by_idx(matcher) ?
+                                               attr->rule_idx : 0;
                } else {
                        apply.next_direct_idx = --ste_attr.direct_index;
                }
@@ -364,6 +373,8 @@ static int mlx5dr_rule_destroy_hws(struct mlx5dr_rule *rule,
        ste_attr.wqe_tag = &rule->tag;
        ste_attr.wqe_tag_is_jumbo = 
mlx5dr_definer_is_jumbo(matcher->mt[0]->definer);
        ste_attr.gta_opcode = MLX5DR_WQE_GTA_OP_DEACTIVATE;
+       if (unlikely(mlx5dr_matcher_is_insert_by_idx(matcher)))
+               ste_attr.direct_index = attr->rule_idx;
 
        mlx5dr_send_ste(queue, &ste_attr);
 
diff --git a/drivers/net/mlx5/hws/mlx5dr_rule.h 
b/drivers/net/mlx5/hws/mlx5dr_rule.h
index 96c85674f2..f2fe418159 100644
--- a/drivers/net/mlx5/hws/mlx5dr_rule.h
+++ b/drivers/net/mlx5/hws/mlx5dr_rule.h
@@ -40,7 +40,7 @@ struct mlx5dr_rule {
        };
        uint32_t rtc_0; /* The RTC into which the STE was inserted */
        uint32_t rtc_1; /* The RTC into which the STE was inserted */
-       int action_ste_idx; /* Action STE pool ID */
+       int action_ste_idx; /* STE array index */
        uint8_t status; /* enum mlx5dr_rule_status */
        uint8_t pending_wqes;
 };
-- 
2.27.0

Reply via email to