From: Alexander Kozyrev <akozy...@nvidia.com>

Create hardware steering meter color support.
Allow matching on a meter color using hardware steering.

Signed-off-by: Alexander Kozyrev <akozy...@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow.h    |  1 +
 drivers/net/mlx5/mlx5_flow_dv.c | 32 ++++++++++++++++++++++++++++++--
 drivers/net/mlx5/mlx5_flow_hw.c | 12 ++++++++++++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 99d3c40f36..514903dbe1 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1526,6 +1526,7 @@ flow_hw_get_reg_id(enum rte_flow_item_type type, uint32_t 
id)
                 */
                return REG_A;
        case RTE_FLOW_ITEM_TYPE_CONNTRACK:
+       case RTE_FLOW_ITEM_TYPE_METER_COLOR:
                return mlx5_flow_hw_aso_tag;
        case RTE_FLOW_ITEM_TYPE_TAG:
                MLX5_ASSERT(id < MLX5_FLOW_HW_TAGS_MAX);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index e1db68b532..0785734217 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1387,6 +1387,7 @@ mlx5_flow_item_field_width(struct rte_eth_dev *dev,
                return inherit < 0 ? 0 : inherit;
        case RTE_FLOW_FIELD_IPV4_ECN:
        case RTE_FLOW_FIELD_IPV6_ECN:
+       case RTE_FLOW_FIELD_METER_COLOR
                return 2;
        default:
                MLX5_ASSERT(false);
@@ -1846,6 +1847,31 @@ mlx5_flow_field_id_to_modify_info
                                info[idx].offset = data->offset;
                }
                break;
+       case RTE_FLOW_FIELD_METER_COLOR:
+               {
+                       const uint32_t color_mask =
+                               (UINT32_C(1) << MLX5_MTR_COLOR_BITS) - 1;
+                       int reg;
+
+                       if (priv->sh->config.dv_flow_en == 2)
+                               reg = flow_hw_get_reg_id
+                                       (RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+                       else
+                               reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR,
+                                                      0, error);
+                       if (reg < 0)
+                               return;
+                       MLX5_ASSERT(reg != REG_NON);
+                       MLX5_ASSERT((unsigned int)reg < RTE_DIM(reg_to_field));
+                       info[idx] = (struct field_modify_info){4, 0,
+                                               reg_to_field[reg]};
+                       if (mask)
+                               mask[idx] = flow_modify_info_mask_32_masked
+                                       (width, data->offset, color_mask);
+                       else
+                               info[idx].offset = data->offset;
+               }
+               break;
        case RTE_FLOW_FIELD_POINTER:
        case RTE_FLOW_FIELD_VALUE:
        default:
@@ -1893,7 +1919,7 @@ flow_dv_convert_action_modify_field
        uint32_t type, meta = 0;
 
        if (conf->src.field == RTE_FLOW_FIELD_POINTER ||
-           conf->src.field == RTE_FLOW_FIELD_VALUE) {
+           conf->src.field == RTE_FLOW_FIELD_VALUE) {/
                type = MLX5_MODIFICATION_TYPE_SET;
                /** For SET fill the destination field (field) first. */
                mlx5_flow_field_id_to_modify_info(&conf->dst, field, mask,
@@ -1902,7 +1928,9 @@ flow_dv_convert_action_modify_field
                item.spec = conf->src.field == RTE_FLOW_FIELD_POINTER ?
                                        (void *)(uintptr_t)conf->src.pvalue :
                                        (void *)(uintptr_t)&conf->src.value;
-               if (conf->dst.field == RTE_FLOW_FIELD_META) {
+               if (conf->dst.field == RTE_FLOW_FIELD_META ||
+                   conf->dst.field == RTE_FLOW_FIELD_TAG ||
+                   conf->dst.field == RTE_FLOW_FIELD_METER_COLOR) {
                        meta = *(const unaligned_uint32_t *)item.spec;
                        meta = rte_cpu_to_be_32(meta);
                        item.spec = &meta;
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 7e7b48f884..87b3e34cb4 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -870,6 +870,7 @@ flow_hw_modify_field_compile(struct rte_eth_dev *dev,
                                (void *)(uintptr_t)&conf->src.value;
                if (conf->dst.field == RTE_FLOW_FIELD_META ||
                    conf->dst.field == RTE_FLOW_FIELD_TAG ||
+                   conf->dst.field == RTE_FLOW_FIELD_METER_COLOR ||
                    conf->dst.field == (enum 
rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG) {
                        value = *(const unaligned_uint32_t *)item.spec;
                        value = rte_cpu_to_be_32(value);
@@ -1702,6 +1703,7 @@ flow_hw_modify_field_construct(struct mlx5_hw_q_job *job,
                rte_memcpy(values, mhdr_action->src.pvalue, sizeof(values));
        if (mhdr_action->dst.field == RTE_FLOW_FIELD_META ||
            mhdr_action->dst.field == RTE_FLOW_FIELD_TAG ||
+           mhdr_action->dst.field == RTE_FLOW_FIELD_METER_COLOR ||
            mhdr_action->dst.field == (enum 
rte_flow_field_id)MLX5_RTE_FLOW_FIELD_META_REG) {
                value_p = (unaligned_uint32_t *)values;
                *value_p = rte_cpu_to_be_32(*value_p);
@@ -3704,6 +3706,16 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
                                                                  " attribute");
                        }
                        break;
+               case RTE_FLOW_ITEM_TYPE_METER_COLOR:
+               {
+                       int reg = 
flow_hw_get_reg_id(RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+                       if (reg == REG_NON)
+                               return rte_flow_error_set(error, EINVAL,
+                                                         
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                                         NULL,
+                                                         "Unsupported meter 
color register");
+                       break;
+               }
                case RTE_FLOW_ITEM_TYPE_VOID:
                case RTE_FLOW_ITEM_TYPE_ETH:
                case RTE_FLOW_ITEM_TYPE_VLAN:
-- 
2.25.1

Reply via email to