Add support for matching metadata in HWS ingress rules.
It using REG_B matching which is supported for each device supports HWS.

Signed-off-by: Michael Baum <michae...@nvidia.com>
Reviewed-by: Erez Shitrit <ere...@nvidia.com>
---
 drivers/net/mlx5/hws/mlx5dr.h         |  1 +
 drivers/net/mlx5/hws/mlx5dr_definer.c | 32 ++++++++++++++++++---------
 drivers/net/mlx5/mlx5_flow.h          | 16 ++++++++------
 drivers/net/mlx5/mlx5_flow_dv.c       | 19 ++++++++++------
 drivers/net/mlx5/mlx5_flow_hw.c       | 23 +++++++++----------
 5 files changed, 55 insertions(+), 36 deletions(-)

diff --git a/drivers/net/mlx5/hws/mlx5dr.h b/drivers/net/mlx5/hws/mlx5dr.h
index d612f300c6..a323b29cb4 100644
--- a/drivers/net/mlx5/hws/mlx5dr.h
+++ b/drivers/net/mlx5/hws/mlx5dr.h
@@ -18,6 +18,7 @@ enum mlx5dr_table_type {
        MLX5DR_TABLE_TYPE_NIC_TX,
        MLX5DR_TABLE_TYPE_FDB,
        MLX5DR_TABLE_TYPE_MAX,
+       MLX5DR_TABLE_TYPE_DONTCARE = MLX5DR_TABLE_TYPE_MAX,
 };
 
 enum mlx5dr_matcher_resource_mode {
diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c 
b/drivers/net/mlx5/hws/mlx5dr_definer.c
index e036aca781..9b3508471b 100644
--- a/drivers/net/mlx5/hws/mlx5dr_definer.c
+++ b/drivers/net/mlx5/hws/mlx5dr_definer.c
@@ -1741,6 +1741,7 @@ mlx5dr_definer_conv_item_tag(struct 
mlx5dr_definer_conv_data *cd,
        if (item->type == RTE_FLOW_ITEM_TYPE_TAG)
                reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
                                                  RTE_FLOW_ITEM_TYPE_TAG,
+                                                 MLX5DR_TABLE_TYPE_DONTCARE,
                                                  v->index);
        else
                reg = (int)v->index;
@@ -1801,9 +1802,10 @@ mlx5dr_definer_conv_item_quota(struct 
mlx5dr_definer_conv_data *cd,
                               __rte_unused struct rte_flow_item *item,
                               int item_idx)
 {
-       int mtr_reg =
-       flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_METER_COLOR,
-                                   0);
+       int mtr_reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
+                                                 
RTE_FLOW_ITEM_TYPE_METER_COLOR,
+                                                 MLX5DR_TABLE_TYPE_DONTCARE,
+                                                 0);
        struct mlx5dr_definer_fc *fc;
 
        if (mtr_reg < 0) {
@@ -1822,6 +1824,7 @@ mlx5dr_definer_conv_item_quota(struct 
mlx5dr_definer_conv_data *cd,
 
 static int
 mlx5dr_definer_conv_item_metadata(struct mlx5dr_definer_conv_data *cd,
+                                 enum mlx5dr_table_type table_domain_type,
                                  struct rte_flow_item *item,
                                  int item_idx)
 {
@@ -1833,7 +1836,8 @@ mlx5dr_definer_conv_item_metadata(struct 
mlx5dr_definer_conv_data *cd,
        if (!m)
                return 0;
 
-       reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_META, -1);
+       reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_META,
+                                         table_domain_type, -1);
        if (reg <= 0) {
                DR_LOG(ERR, "Invalid register for item metadata");
                rte_errno = EINVAL;
@@ -2140,8 +2144,9 @@ mlx5dr_definer_conv_item_conntrack(struct 
mlx5dr_definer_conv_data *cd,
        if (!m)
                return 0;
 
-       reg = flow_hw_get_reg_id_from_ctx(cd->ctx, RTE_FLOW_ITEM_TYPE_CONNTRACK,
-                                         -1);
+       reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
+                                         RTE_FLOW_ITEM_TYPE_CONNTRACK,
+                                         MLX5DR_TABLE_TYPE_DONTCARE, -1);
        if (reg <= 0) {
                DR_LOG(ERR, "Invalid register for item conntrack");
                rte_errno = EINVAL;
@@ -2283,7 +2288,8 @@ mlx5dr_definer_conv_item_meter_color(struct 
mlx5dr_definer_conv_data *cd,
                return 0;
 
        reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
-                                         RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+                                         RTE_FLOW_ITEM_TYPE_METER_COLOR,
+                                         MLX5DR_TABLE_TYPE_DONTCARE, 0);
        MLX5_ASSERT(reg > 0);
 
        fc = mlx5dr_definer_get_register_fc(cd, reg);
@@ -2878,6 +2884,7 @@ mlx5dr_definer_conv_item_compare_field(const struct 
rte_flow_field_data *f,
                                       const struct rte_flow_field_data 
*other_f,
                                       struct mlx5dr_definer_conv_data *cd,
                                       int item_idx,
+                                      enum mlx5dr_table_type table_domain_type,
                                       enum mlx5dr_definer_compare_dw_selectors 
dw_offset)
 {
        struct mlx5dr_definer_fc *fc = NULL;
@@ -2892,7 +2899,8 @@ mlx5dr_definer_conv_item_compare_field(const struct 
rte_flow_field_data *f,
        switch (f->field) {
        case RTE_FLOW_FIELD_META:
                reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
-                                                 RTE_FLOW_ITEM_TYPE_META, -1);
+                                                 RTE_FLOW_ITEM_TYPE_META,
+                                                 table_domain_type, -1);
                if (reg <= 0) {
                        DR_LOG(ERR, "Invalid register for compare metadata 
field");
                        rte_errno = EINVAL;
@@ -2911,6 +2919,7 @@ mlx5dr_definer_conv_item_compare_field(const struct 
rte_flow_field_data *f,
        case RTE_FLOW_FIELD_TAG:
                reg = flow_hw_get_reg_id_from_ctx(cd->ctx,
                                                  RTE_FLOW_ITEM_TYPE_TAG,
+                                                 MLX5DR_TABLE_TYPE_DONTCARE,
                                                  f->tag_index);
                if (reg <= 0) {
                        DR_LOG(ERR, "Invalid register for compare tag field");
@@ -2966,6 +2975,7 @@ mlx5dr_definer_conv_item_compare_field(const struct 
rte_flow_field_data *f,
 
 static int
 mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd,
+                                enum mlx5dr_table_type table_domain_type,
                                 struct rte_flow_item *item,
                                 int item_idx)
 {
@@ -2982,11 +2992,13 @@ mlx5dr_definer_conv_item_compare(struct 
mlx5dr_definer_conv_data *cd,
        }
 
        ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx,
+                                                    table_domain_type,
                                                     
MLX5DR_DEFINER_COMPARE_ARGUMENT_0);
        if (ret)
                return ret;
 
        ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx,
+                                                    table_domain_type,
                                                     
MLX5DR_DEFINER_COMPARE_BASE_0);
        if (ret)
                return ret;
@@ -3082,7 +3094,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context 
*ctx,
                        item_flags |= MLX5_FLOW_ITEM_TAG;
                        break;
                case RTE_FLOW_ITEM_TYPE_META:
-                       ret = mlx5dr_definer_conv_item_metadata(&cd, items, i);
+                       ret = mlx5dr_definer_conv_item_metadata(&cd, 
matcher->tbl->type, items, i);
                        item_flags |= MLX5_FLOW_ITEM_METADATA;
                        break;
                case RTE_FLOW_ITEM_TYPE_GRE:
@@ -3173,7 +3185,7 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context 
*ctx,
                                DR_LOG(ERR, "Compare matcher not supported for 
more than one item");
                                goto not_supp;
                        }
-                       ret = mlx5dr_definer_conv_item_compare(&cd, items, i);
+                       ret = mlx5dr_definer_conv_item_compare(&cd, 
matcher->tbl->type, items, i);
                        item_flags |= MLX5_FLOW_ITEM_COMPARE;
                        matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE;
                        break;
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index a4d0ff7b13..9ad23e6624 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1722,12 +1722,12 @@ flow_hw_get_wire_port(struct ibv_context *ibctx)
 
 /*
  * Convert metadata or tag to the actual register.
- * META: Can only be used to match in the FDB in this stage, fixed C_1.
+ * META: Fixed C_1 for FDB mode, REG_A for NIC TX and REG_B for NIC RX.
  * TAG: C_x expect meter color reg and the reserved ones.
  */
 static __rte_always_inline int
-flow_hw_get_reg_id(struct rte_eth_dev *dev,
-                  enum rte_flow_item_type type, uint32_t id)
+flow_hw_get_reg_id(struct rte_eth_dev *dev, enum rte_flow_item_type type,
+                  enum mlx5dr_table_type domain_type, uint32_t id)
 {
        struct mlx5_dev_ctx_shared *sh = MLX5_SH(dev);
        struct mlx5_dev_registers *reg = &sh->registers;
@@ -1747,8 +1747,10 @@ flow_hw_get_reg_id(struct rte_eth_dev *dev,
                 * On non-root tables - REG_A corresponds to 
general_purpose_lookup_field,
                 * which translates to REG_A in NIC TX and to REG_B in NIC RX.
                 * However, current FW does not implement REG_B case right now, 
so
-                * REG_B case should be rejected on pattern template validation.
+                * REG_B case is return explicitly by this function for NIC RX.
                 */
+               if (domain_type == MLX5DR_TABLE_TYPE_NIC_RX)
+                       return REG_B;
                return REG_A;
        case RTE_FLOW_ITEM_TYPE_CONNTRACK:
        case RTE_FLOW_ITEM_TYPE_METER_COLOR:
@@ -1764,8 +1766,8 @@ flow_hw_get_reg_id(struct rte_eth_dev *dev,
 }
 
 static __rte_always_inline int
-flow_hw_get_reg_id_from_ctx(void *dr_ctx,
-                           enum rte_flow_item_type type, uint32_t id)
+flow_hw_get_reg_id_from_ctx(void *dr_ctx, enum rte_flow_item_type type,
+                           enum mlx5dr_table_type domain_type, uint32_t id)
 {
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
        uint16_t port;
@@ -1776,7 +1778,7 @@ flow_hw_get_reg_id_from_ctx(void *dr_ctx,
                priv = rte_eth_devices[port].data->dev_private;
                if (priv->dr_ctx == dr_ctx)
                        return flow_hw_get_reg_id(&rte_eth_devices[port],
-                                                 type, id);
+                                                 type, domain_type, id);
        }
 #else
        RTE_SET_USED(dr_ctx);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 75a8a223ab..8f07a6f888 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2089,6 +2089,7 @@ mlx5_flow_field_id_to_modify_info
                        if (priv->sh->config.dv_flow_en == 2)
                                reg = flow_hw_get_reg_id(dev,
                                                         RTE_FLOW_ITEM_TYPE_TAG,
+                                                        
MLX5DR_TABLE_TYPE_DONTCARE,
                                                         tag_index);
                        else
                                reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG,
@@ -2206,12 +2207,13 @@ mlx5_flow_field_id_to_modify_info
                        int reg;
 
                        if (priv->sh->config.dv_flow_en == 2)
-                               reg = flow_hw_get_reg_id
-                                       (dev,
-                                        RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+                               reg = flow_hw_get_reg_id(dev,
+                                                        
RTE_FLOW_ITEM_TYPE_METER_COLOR,
+                                                        
MLX5DR_TABLE_TYPE_DONTCARE,
+                                                        0);
                        else
                                reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR,
-                                                      0, error);
+                                                          0, error);
                        if (reg < 0)
                                return;
                        MLX5_ASSERT(reg != REG_NON);
@@ -10548,7 +10550,8 @@ flow_dv_translate_item_meta(struct rte_eth_dev *dev,
        if (!!(key_type & MLX5_SET_MATCHER_SW))
                reg = flow_dv_get_metadata_reg(dev, attr, NULL);
        else
-               reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_META, 0);
+               reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_META,
+                                        MLX5DR_TABLE_TYPE_DONTCARE, 0);
        if (reg < 0)
                return;
        MLX5_ASSERT(reg != REG_NON);
@@ -10651,7 +10654,8 @@ flow_dv_translate_item_tag(struct rte_eth_dev *dev, 
void *key,
        if (!!(key_type & MLX5_SET_MATCHER_SW))
                reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, index, NULL);
        else
-               reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, index);
+               reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+                                        MLX5DR_TABLE_TYPE_DONTCARE, index);
        MLX5_ASSERT(reg > 0);
        flow_dv_match_meta_reg(key, (enum modify_reg)reg, tag_v->data, 
tag_m->data);
 }
@@ -11350,7 +11354,8 @@ flow_dv_translate_item_meter_color(struct rte_eth_dev 
*dev, void *key,
                reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, NULL);
        else
                reg = flow_hw_get_reg_id(dev,
-                                        RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+                                        RTE_FLOW_ITEM_TYPE_METER_COLOR,
+                                        MLX5DR_TABLE_TYPE_DONTCARE, 0);
        if (reg == REG_NON)
                return;
        flow_dv_match_meta_reg(key, (enum modify_reg)reg, value, mask);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 783ad9e72a..b8a57e2e83 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5221,9 +5221,13 @@ flow_hw_validate_action_modify_field(struct rte_eth_dev 
*dev,
                                          RTE_FLOW_ERROR_TYPE_ACTION, action,
                                 "tag index is out of range");
        if ((action_conf->dst.field == RTE_FLOW_FIELD_TAG &&
-            flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, 
action_conf->dst.tag_index) == REG_NON) ||
+            flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+                               MLX5DR_TABLE_TYPE_DONTCARE,
+                               action_conf->dst.tag_index) == REG_NON) ||
            (action_conf->src.field == RTE_FLOW_FIELD_TAG &&
-            flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG, 
action_conf->src.tag_index) == REG_NON))
+            flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+                               MLX5DR_TABLE_TYPE_DONTCARE,
+                               action_conf->src.tag_index) == REG_NON))
                return rte_flow_error_set(error, EINVAL,
                                          RTE_FLOW_ERROR_TYPE_ACTION, action,
                                          "tag index is out of range");
@@ -7012,7 +7016,9 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
                                                          
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
                                                          NULL,
                                                          "Invalid tag index");
-                       tag_idx = flow_hw_get_reg_id(dev, 
RTE_FLOW_ITEM_TYPE_TAG, tag->index);
+                       tag_idx = flow_hw_get_reg_id(dev, 
RTE_FLOW_ITEM_TYPE_TAG,
+                                                    MLX5DR_TABLE_TYPE_DONTCARE,
+                                                    tag->index);
                        if (tag_idx == REG_NON)
                                return rte_flow_error_set(error, EINVAL,
                                                          
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -7058,20 +7064,13 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
                                                  " when egress attribute is 
set");
                        break;
                case RTE_FLOW_ITEM_TYPE_META:
-                       if (!priv->sh->config.dv_esw_en ||
-                           priv->sh->config.dv_xmeta_en != 
MLX5_XMETA_MODE_META32_HWS) {
-                               if (attr->ingress)
-                                       return rte_flow_error_set(error, EINVAL,
-                                                                 
RTE_FLOW_ERROR_TYPE_ITEM, NULL,
-                                                                 "META item is 
not supported"
-                                                                 " on current 
FW with ingress"
-                                                                 " attribute");
-                       }
+                       /* ingress + group 0 is not supported */
                        break;
                case RTE_FLOW_ITEM_TYPE_METER_COLOR:
                {
                        int reg = flow_hw_get_reg_id(dev,
                                                     
RTE_FLOW_ITEM_TYPE_METER_COLOR,
+                                                    MLX5DR_TABLE_TYPE_DONTCARE,
                                                     0);
                        if (reg == REG_NON)
                                return rte_flow_error_set(error, EINVAL,
-- 
2.25.1

Reply via email to