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