From: Alexander Kozyrev <akozy...@nvidia.com> Create firmware and software steering meter color support. Allow matching on a meter color in both root and non-root groups.
Signed-off-by: Alexander Kozyrev <akozy...@nvidia.com> --- drivers/net/mlx5/mlx5_flow.h | 3 + drivers/net/mlx5/mlx5_flow_dv.c | 113 ++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+) diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 2d1a9dba27..99d3c40f36 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -208,6 +208,9 @@ enum mlx5_feature_name { #define MLX5_FLOW_ITEM_PORT_REPRESENTOR (UINT64_C(1) << 41) #define MLX5_FLOW_ITEM_REPRESENTED_PORT (UINT64_C(1) << 42) +/* Meter color item */ +#define MLX5_FLOW_ITEM_METER_COLOR (UINT64_C(1) << 44) + /* Outer Masks. */ #define MLX5_FLOW_LAYER_OUTER_L3 \ (MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6) diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 36059beb71..e1db68b532 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -3676,6 +3676,69 @@ flow_dv_validate_action_aso_ct(struct rte_eth_dev *dev, return 0; } +/** + * Validate METER_COLOR item. + * + * @param[in] dev + * Pointer to the rte_eth_dev structure. + * @param[in] item + * Item specification. + * @param[in] attr + * Attributes of flow that includes this item. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +static int +flow_dv_validate_item_meter_color(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + const struct rte_flow_attr *attr __rte_unused, + struct rte_flow_error *error) +{ + struct mlx5_priv *priv = dev->data->dev_private; + const struct rte_flow_item_meter_color *spec = item->spec; + const struct rte_flow_item_meter_color *mask = item->mask; + struct rte_flow_item_meter_color nic_mask = { + .color = RTE_COLORS + }; + int ret; + + if (priv->mtr_color_reg == REG_NON) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "meter color register" + " isn't available"); + ret = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, error); + if (ret < 0) + return ret; + if (!spec) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, + item->spec, + "data cannot be empty"); + if (spec->color > RTE_COLORS) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_CONF, + &spec->color, + "meter color is invalid"); + if (!mask) + mask = &rte_flow_item_meter_color_mask; + if (!mask->color) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, NULL, + "mask cannot be zero"); + + ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, + (const uint8_t *)&nic_mask, + sizeof(struct rte_flow_item_meter_color), + MLX5_ITEM_RANGE_NOT_ACCEPTED, error); + if (ret < 0) + return ret; + return 0; +} + int flow_dv_encap_decap_match_cb(void *tool_ctx __rte_unused, struct mlx5_list_entry *entry, void *cb_ctx) @@ -7410,6 +7473,13 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, if (ret < 0) return ret; break; + case RTE_FLOW_ITEM_TYPE_METER_COLOR: + ret = flow_dv_validate_item_meter_color(dev, items, + attr, error); + if (ret < 0) + return ret; + last_item = MLX5_FLOW_ITEM_METER_COLOR; + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, @@ -10485,6 +10555,45 @@ flow_dv_translate_item_flex(struct rte_eth_dev *dev, void *matcher, void *key, mlx5_flex_flow_translate_item(dev, matcher, key, item, is_inner); } +/** + * Add METER_COLOR item to matcher + * + * @param[in] dev + * The device to configure through. + * @param[in, out] key + * Flow matcher value. + * @param[in] item + * Flow pattern to translate. + * @param[in] key_type + * Set flow matcher mask or value. + */ +static void +flow_dv_translate_item_meter_color(struct rte_eth_dev *dev, void *key, + const struct rte_flow_item *item, + uint32_t key_type) +{ + const struct rte_flow_item_meter_color *color_m = item->mask; + const struct rte_flow_item_meter_color *color_v = item->spec; + uint32_t value, mask; + int reg = REG_NON; + + MLX5_ASSERT(color_v); + if (MLX5_ITEM_VALID(item, key_type)) + return; + MLX5_ITEM_UPDATE(item, key_type, color_v, color_m, + &rte_flow_item_meter_color_mask); + value = rte_col_2_mlx5_col(color_v->color); + mask = color_m ? + color_m->color : (UINT32_C(1) << MLX5_MTR_COLOR_BITS) - 1; + if (!!(key_type & MLX5_SET_MATCHER_SW)) + reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, NULL); + else + reg = flow_hw_get_reg_id(RTE_FLOW_ITEM_TYPE_METER_COLOR, 0); + if (reg == REG_NON) + return; + flow_dv_match_meta_reg(key, (enum modify_reg)reg, value, mask); +} + static uint32_t matcher_zero[MLX5_ST_SZ_DW(fte_match_param)] = { 0 }; #define HEADER_IS_ZERO(match_criteria, headers) \ @@ -13234,6 +13343,10 @@ flow_dv_translate_items(struct rte_eth_dev *dev, /* No other protocol should follow eCPRI layer. */ last_item = MLX5_FLOW_LAYER_ECPRI; break; + case RTE_FLOW_ITEM_TYPE_METER_COLOR: + flow_dv_translate_item_meter_color(dev, key, items, key_type); + last_item = MLX5_FLOW_ITEM_METER_COLOR; + break; default: break; } -- 2.25.1