From: Alexander Kozyrev <akozyrev@nvidia.com>
Create hardware steering meter color support.
Allow matching on a meter color using hardware steering.
Signed-off-by: Alexander Kozyrev <akozyrev@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(-)
@@ -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);
@@ -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;
@@ -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: