* [PATCH v1 0/2] net/mlx5: add random compare support @ 2023-12-25 10:45 Michael Baum 2023-12-25 10:45 ` [PATCH v1 1/2] net/mlx5/hws: add support for compare matcher Michael Baum ` (2 more replies) 0 siblings, 3 replies; 30+ messages in thread From: Michael Baum @ 2023-12-25 10:45 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_RANDOM". Depends-on: series-30553 ("ethdev: add random item support") Depends-on: series-30606 ("ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE") Depends-on: series-30665 ("net/mlx5: add random item support") Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (1): net/mlx5: add support to compare random value drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 220 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 ++++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 70 +++++--- 10 files changed, 387 insertions(+), 27 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v1 1/2] net/mlx5/hws: add support for compare matcher 2023-12-25 10:45 [PATCH v1 0/2] net/mlx5: add random compare support Michael Baum @ 2023-12-25 10:45 ` Michael Baum 2023-12-25 10:45 ` [PATCH v1 2/2] net/mlx5: add support to compare random value Michael Baum 2024-01-28 10:22 ` [PATCH v2 0/2] net/mlx5: add random compare support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2023-12-25 10:45 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 220 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 ++++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 335 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 9e22dce6da..3033b4d3cd 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3440,6 +3440,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3478,6 +3479,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 876a47147d..702d6fadac 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index 18c2b07fc8..073ffd9633 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 005733372a..e13d88a1c1 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -371,6 +371,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_tranlate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_tranlate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2414,10 +2494,101 @@ mlx5dr_definer_conv_item_ib_l4(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2437,6 +2608,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2570,10 +2746,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_random(&cd, items, i); item_flags |= MLX5_FLOW_ITEM_RANDOM; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2594,6 +2778,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -2981,6 +3169,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -2998,13 +3187,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3019,6 +3230,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index 18591ef853..939143168d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -163,6 +194,8 @@ enum mlx5dr_definer_type { struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 4ea161eae6..55e0d882f0 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1452,3 +1457,46 @@ int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt) simple_free(mt); return 0; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} \ No newline at end of file diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 363a61fd41..ca6c212536 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -26,6 +26,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_RANGE_DEFINER = 1 << 0, MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -89,12 +90,19 @@ mlx5dr_matcher_mt_is_range(struct mlx5dr_match_template *mt) return (!!mt->range_definer); } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -120,4 +128,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v1 2/2] net/mlx5: add support to compare random value 2023-12-25 10:45 [PATCH v1 0/2] net/mlx5: add random compare support Michael Baum 2023-12-25 10:45 ` [PATCH v1 1/2] net/mlx5/hws: add support for compare matcher Michael Baum @ 2023-12-25 10:45 ` Michael Baum 2024-01-28 10:22 ` [PATCH v2 0/2] net/mlx5: add random compare support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2023-12-25 10:45 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index a944a9b5b0..d472f83909 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6643,18 +6643,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6663,6 +6700,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6674,19 +6712,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6694,7 +6726,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v2 0/2] net/mlx5: add random compare support 2023-12-25 10:45 [PATCH v1 0/2] net/mlx5: add random compare support Michael Baum 2023-12-25 10:45 ` [PATCH v1 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2023-12-25 10:45 ` [PATCH v1 2/2] net/mlx5: add support to compare random value Michael Baum @ 2024-01-28 10:22 ` Michael Baum 2024-01-28 10:22 ` [PATCH v2 1/2] net/mlx5/hws: add support for compare matcher Michael Baum ` (2 more replies) 2 siblings, 3 replies; 30+ messages in thread From: Michael Baum @ 2024-01-28 10:22 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_RANDOM". Depends-on: series-30606 ("ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE") v2: - Rebase. - Add "RTE_FLOW_FIELD_RANDOM" compare support. - Reduce the "Depends-on" list. Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (1): net/mlx5: add support to compare random value drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++-- 10 files changed, 410 insertions(+), 27 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v2 1/2] net/mlx5/hws: add support for compare matcher 2024-01-28 10:22 ` [PATCH v2 0/2] net/mlx5: add random compare support Michael Baum @ 2024-01-28 10:22 ` Michael Baum 2024-01-28 10:22 ` [PATCH v2 2/2] net/mlx5: add support to compare random value Michael Baum 2024-01-29 13:44 ` [PATCH v3 0/2] net/mlx5: add random compare support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-01-28 10:22 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 358 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 69404b5ed8..f64944f042 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3448,6 +3448,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3486,6 +3487,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 876a47147d..702d6fadac 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index 18c2b07fc8..073ffd9633 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 750eb9c7c6..06a56be8c6 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -376,6 +376,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_tranlate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_tranlate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2522,10 +2602,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_META: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_META, -1); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare metadata field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare tag field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2545,6 +2739,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2682,10 +2881,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i); item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2706,6 +2913,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -3093,6 +3304,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -3110,13 +3322,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3131,6 +3365,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index 7b7463fc91..42426ff846 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -168,6 +199,8 @@ enum mlx5dr_definer_type { struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 4ea161eae6..55e0d882f0 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1452,3 +1457,46 @@ int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt) simple_free(mt); return 0; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} \ No newline at end of file diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 363a61fd41..ca6c212536 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -26,6 +26,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_RANGE_DEFINER = 1 << 0, MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -89,12 +90,19 @@ mlx5dr_matcher_mt_is_range(struct mlx5dr_match_template *mt) return (!!mt->range_definer); } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -120,4 +128,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v2 2/2] net/mlx5: add support to compare random value 2024-01-28 10:22 ` [PATCH v2 0/2] net/mlx5: add random compare support Michael Baum 2024-01-28 10:22 ` [PATCH v2 1/2] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-01-28 10:22 ` Michael Baum 2024-01-29 13:44 ` [PATCH v3 0/2] net/mlx5: add random compare support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-01-28 10:22 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 01fdcbfed9..be303ea3a8 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6686,18 +6686,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6706,6 +6743,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6717,19 +6755,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6737,7 +6769,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 0/2] net/mlx5: add random compare support 2024-01-28 10:22 ` [PATCH v2 0/2] net/mlx5: add random compare support Michael Baum 2024-01-28 10:22 ` [PATCH v2 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2024-01-28 10:22 ` [PATCH v2 2/2] net/mlx5: add support to compare random value Michael Baum @ 2024-01-29 13:44 ` Michael Baum 2024-01-29 13:44 ` [PATCH v3 1/2] net/mlx5/hws: add support for compare matcher Michael Baum ` (2 more replies) 2 siblings, 3 replies; 30+ messages in thread From: Michael Baum @ 2024-01-29 13:44 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_RANDOM". Depends-on: series-30606 ("ethdev: add RTE_FLOW_ITEM_TYPE_COMPARE") v2: - Rebase. - Add "RTE_FLOW_FIELD_META" compare support. - Reduce the "Depends-on" list. v3: - Rebase. - Fix typo in function name, r/tranlate/translate. - Fix adding a line without newline at end of file. Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (1): net/mlx5: add support to compare random value drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++-- 10 files changed, 410 insertions(+), 27 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 1/2] net/mlx5/hws: add support for compare matcher 2024-01-29 13:44 ` [PATCH v3 0/2] net/mlx5: add random compare support Michael Baum @ 2024-01-29 13:44 ` Michael Baum 2024-01-29 13:44 ` [PATCH v3 2/2] net/mlx5: add support to compare random value Michael Baum 2024-02-07 16:14 ` [PATCH v4 0/2] net/mlx5: add random compare support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-01-29 13:44 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 358 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index f64f25dbb7..c8477658d7 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3455,6 +3455,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3493,6 +3494,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 876a47147d..702d6fadac 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index 18c2b07fc8..073ffd9633 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 79d98bbf78..2d86175ca2 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -383,6 +383,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_translate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_translate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2739,10 +2819,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_META: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_META, -1); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare metadata field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare tag field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2762,6 +2956,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2907,10 +3106,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i); item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2931,6 +3138,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -3318,6 +3529,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -3335,13 +3547,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3356,6 +3590,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index ced9d9da13..9f2b5e7dc9 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -188,6 +219,8 @@ struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; uint16_t extra_data; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 4ea161eae6..cede24237f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1452,3 +1457,46 @@ int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt) simple_free(mt); return 0; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 363a61fd41..ca6c212536 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -26,6 +26,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_RANGE_DEFINER = 1 << 0, MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -89,12 +90,19 @@ mlx5dr_matcher_mt_is_range(struct mlx5dr_match_template *mt) return (!!mt->range_definer); } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -120,4 +128,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v3 2/2] net/mlx5: add support to compare random value 2024-01-29 13:44 ` [PATCH v3 0/2] net/mlx5: add random compare support Michael Baum 2024-01-29 13:44 ` [PATCH v3 1/2] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-01-29 13:44 ` Michael Baum 2024-02-07 16:14 ` [PATCH v4 0/2] net/mlx5: add random compare support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-01-29 13:44 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 08e211a5b8..63e76c86b1 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6717,18 +6717,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6737,6 +6774,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6748,19 +6786,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6768,7 +6800,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v4 0/2] net/mlx5: add random compare support 2024-01-29 13:44 ` [PATCH v3 0/2] net/mlx5: add random compare support Michael Baum 2024-01-29 13:44 ` [PATCH v3 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2024-01-29 13:44 ` [PATCH v3 2/2] net/mlx5: add support to compare random value Michael Baum @ 2024-02-07 16:14 ` Michael Baum 2024-02-07 16:14 ` [PATCH v4 1/2] net/mlx5/hws: add support for compare matcher Michael Baum ` (2 more replies) 2 siblings, 3 replies; 30+ messages in thread From: Michael Baum @ 2024-02-07 16:14 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_RANDOM". v2: - Rebase. - Add "RTE_FLOW_FIELD_META" compare support. - Reduce the "Depends-on" list. v3: - Rebase. - Fix typo in function name, r/tranlate/translate. - Fix adding a line without newline at end of file. v4: - Rebase. - Update documentation. - Remove the "Depends-on" label. Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (1): net/mlx5: add support to compare random value doc/guides/nics/mlx5.rst | 9 +- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++-- 11 files changed, 417 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v4 1/2] net/mlx5/hws: add support for compare matcher 2024-02-07 16:14 ` [PATCH v4 0/2] net/mlx5: add random compare support Michael Baum @ 2024-02-07 16:14 ` Michael Baum 2024-02-07 16:14 ` [PATCH v4 2/2] net/mlx5: add support to compare random value Michael Baum 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-07 16:14 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 358 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 0035a1e616..f8956c8a87 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3459,6 +3459,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3497,6 +3498,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 876a47147d..702d6fadac 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index 18c2b07fc8..073ffd9633 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 79d98bbf78..2d86175ca2 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -383,6 +383,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_translate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_translate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2739,10 +2819,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_META: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_META, -1); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare metadata field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare tag field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2762,6 +2956,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2907,10 +3106,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i); item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2931,6 +3138,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -3318,6 +3529,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -3335,13 +3547,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3356,6 +3590,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index ced9d9da13..9f2b5e7dc9 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -188,6 +219,8 @@ struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; uint16_t extra_data; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 4ea161eae6..cede24237f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1452,3 +1457,46 @@ int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt) simple_free(mt); return 0; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 363a61fd41..ca6c212536 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -26,6 +26,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_RANGE_DEFINER = 1 << 0, MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -89,12 +90,19 @@ mlx5dr_matcher_mt_is_range(struct mlx5dr_match_template *mt) return (!!mt->range_definer); } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -120,4 +128,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v4 2/2] net/mlx5: add support to compare random value 2024-02-07 16:14 ` [PATCH v4 0/2] net/mlx5: add random compare support Michael Baum 2024-02-07 16:14 ` [PATCH v4 1/2] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-02-07 16:14 ` Michael Baum 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum 2 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-07 16:14 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> --- doc/guides/nics/mlx5.rst | 9 ++++- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index fa013b03bb..43ef8a99dc 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -820,8 +820,13 @@ Limitations - Only supported in HW steering(``dv_flow_en`` = 2) mode. - Only single flow is supported to the flow table. - - Only 32-bit comparison is supported. - - Only match with compare result between packet fields is supported. + - Only single item is supported per pattern template. + - Only 32-bit comparison is supported or 16-bits for random field. + - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. + - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. + - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with + ``RTE_FLOW_FIELD_VALUE``. Statistics diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 3af5e1f160..b5741f0817 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6717,18 +6717,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6737,6 +6774,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6748,19 +6786,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6768,7 +6800,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v5 0/3] net/mlx5: add compare item support 2024-02-07 16:14 ` [PATCH v4 0/2] net/mlx5: add random compare support Michael Baum 2024-02-07 16:14 ` [PATCH v4 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-07 16:14 ` [PATCH v4 2/2] net/mlx5: add support to compare random value Michael Baum @ 2024-02-14 7:30 ` Michael Baum 2024-02-14 7:30 ` [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher Michael Baum ` (3 more replies) 2 siblings, 4 replies; 30+ messages in thread From: Michael Baum @ 2024-02-14 7:30 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add HWS support for compare item with: - "RTE_FLOW_FIELD_TAG". - "RTE_FLOW_FIELD_NETA". - "RTE_FLOW_FIELD_VALUE". Add HWS + PMD support for compare item with: - "RTE_FLOW_FIELD_RANDOM". - "RTE_FLOW_FIELD_ESP_SEQ_NUM". v2: - Rebase. - Add "RTE_FLOW_FIELD_META" compare support. - Reduce the "Depends-on" list. v3: - Rebase. - Fix typo in function name, r/tranlate/translate. - Fix adding a line without newline at end of file. v4: - Rebase. - Update documentation. - Remove the "Depends-on" label. v5: - Rebase. - Add ESP sequence number suppoert and rename the series accordingly. Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (2): net/mlx5: add support to compare random value net/mlx5/hws: add compare ESP sequence number support doc/guides/nics/mlx5.rst | 10 +- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 261 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 73 +++++-- 11 files changed, 439 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum @ 2024-02-14 7:30 ` Michael Baum 2024-02-19 3:00 ` Suanming Mou 2024-02-14 7:30 ` [PATCH v5 2/3] net/mlx5: add support to compare random value Michael Baum ` (2 subsequent siblings) 3 siblings, 1 reply; 30+ messages in thread From: Michael Baum @ 2024-02-14 7:30 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> Signed-off-by: Michael Baum <michaelba@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 358 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 0035a1e616..f8956c8a87 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3459,6 +3459,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3497,6 +3498,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index 876a47147d..702d6fadac 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index 18c2b07fc8..073ffd9633 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 79d98bbf78..2d86175ca2 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -383,6 +383,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_translate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_translate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2739,10 +2819,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_META: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_META, -1); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare metadata field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare tag field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2762,6 +2956,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2907,10 +3106,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i); item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2931,6 +3138,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -3318,6 +3529,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -3335,13 +3547,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3356,6 +3590,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index ced9d9da13..9f2b5e7dc9 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -188,6 +219,8 @@ struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; uint16_t extra_data; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 4ea161eae6..cede24237f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1452,3 +1457,46 @@ int mlx5dr_match_template_destroy(struct mlx5dr_match_template *mt) simple_free(mt); return 0; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 363a61fd41..ca6c212536 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -26,6 +26,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_RANGE_DEFINER = 1 << 0, MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -89,12 +90,19 @@ mlx5dr_matcher_mt_is_range(struct mlx5dr_match_template *mt) return (!!mt->range_definer); } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -120,4 +128,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher 2024-02-14 7:30 ` [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-02-19 3:00 ` Suanming Mou 0 siblings, 0 replies; 30+ messages in thread From: Suanming Mou @ 2024-02-19 3:00 UTC (permalink / raw) To: Michael Baum, dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Slava Ovsiienko, Ori Kam, Hamdan Agbariya > -----Original Message----- > From: Michael Baum <michaelba@nvidia.com> > Sent: Wednesday, February 14, 2024 3:30 PM > To: dev@dpdk.org > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; Suanming > Mou <suanmingm@nvidia.com>; Hamdan Igbaria <hamdani@nvidia.com> > Subject: [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher > > From: Hamdan Igbaria <hamdani@nvidia.com> > > Add support for compare matcher, this matcher will allow direct comparison > between two packet fields, or a packet field and a value, with fully masked DW. > For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule > STE. > > Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> > Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> > --- > drivers/common/mlx5/mlx5_prm.h | 16 ++ > drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- > drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + > drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- > drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + > drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- > drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ > drivers/net/mlx5/hws/mlx5dr_matcher.c | 48 +++++ > drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- > 9 files changed, 358 insertions(+), 9 deletions(-) > > diff --git a/drivers/common/mlx5/mlx5_prm.h > b/drivers/common/mlx5/mlx5_prm.h index 0035a1e616..f8956c8a87 100644 > --- a/drivers/common/mlx5/mlx5_prm.h > +++ b/drivers/common/mlx5/mlx5_prm.h > @@ -3459,6 +3459,7 @@ enum mlx5_ifc_rtc_ste_format { > MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, > MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, > MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, > + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, > }; > > enum mlx5_ifc_rtc_reparse_mode { > @@ -3497,6 +3498,21 @@ struct mlx5_ifc_rtc_bits { > u8 reserved_at_1a0[0x260]; > }; > > +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { > + u8 match[0x1]; > + u8 reserved_at_1[0x2]; > + u8 base1[0x1]; > + u8 inverse1[0x1]; > + u8 reserved_at_5[0x1]; > + u8 operator1[0x2]; > + u8 reserved_at_8[0x3]; > + u8 base0[0x1]; > + u8 inverse0[0x1]; > + u8 reserved_at_a[0x1]; > + u8 operator0[0x2]; > + u8 compare_delta[0x10]; > +}; > + > struct mlx5_ifc_alias_context_bits { > u8 vhca_id_to_be_accessed[0x10]; > u8 reserved_at_10[0xd]; > diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c > b/drivers/net/mlx5/hws/mlx5dr_cmd.c > index 876a47147d..702d6fadac 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c > +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c > @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, > attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); > > attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); > - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? > - MLX5_IFC_RTC_STE_FORMAT_11DW : > - MLX5_IFC_RTC_STE_FORMAT_8DW); > + if (rtc_attr->is_compare) { > + MLX5_SET(rtc, attr, ste_format_0, > MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); > + } else { > + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? > + MLX5_IFC_RTC_STE_FORMAT_11DW : > MLX5_IFC_RTC_STE_FORMAT_8DW); > + } > > if (rtc_attr->is_scnd_range) { > MLX5_SET(rtc, attr, ste_format_1, > MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git > a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h > index 18c2b07fc8..073ffd9633 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h > +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h > @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { > uint8_t reparse_mode; > bool is_frst_jumbo; > bool is_scnd_range; > + bool is_compare; > }; > > struct mlx5dr_cmd_alias_obj_create_attr { diff --git > a/drivers/net/mlx5/hws/mlx5dr_debug.c > b/drivers/net/mlx5/hws/mlx5dr_debug.c > index 11557bcab8..a9094cd35b 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_debug.c > +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c > @@ -99,6 +99,7 @@ static int > mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher > *matcher) { > bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; > + bool is_compare = mlx5dr_matcher_is_compare(matcher); > enum mlx5dr_debug_res_type type; > int i, ret; > > @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, > struct mlx5dr_matcher *matcher > return rte_errno; > } > > - type = > MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; > + type = is_compare ? > MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINE > R : > + > MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; > ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt- > >definer, type); > if (ret) > return ret; > diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h > b/drivers/net/mlx5/hws/mlx5dr_debug.h > index 5cffdb10b5..a89a6a0b1d 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_debug.h > +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h > @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { > MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, > MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = > 4205, > MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = > 4206, > + > MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_ > DEFINER = 4207, > }; > > static inline uint64_t > diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c > b/drivers/net/mlx5/hws/mlx5dr_definer.c > index 79d98bbf78..2d86175ca2 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_definer.c > +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c > @@ -383,6 +383,86 @@ mlx5dr_definer_ptype_frag_set(struct > mlx5dr_definer_fc *fc, > DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } > > +static void > +mlx5dr_definer_compare_base_value_set(const void *item_spec, > + uint8_t *tag) > +{ > + uint32_t *ctrl = &(((uint32_t > *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); > + uint32_t *base = &(((uint32_t > *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); > + const struct rte_flow_item_compare *v = item_spec; > + const struct rte_flow_field_data *a = &v->a; > + const struct rte_flow_field_data *b = &v->b; > + const uint32_t *value; > + > + value = (const uint32_t *)&b->value[0]; > + > + if (a->field == RTE_FLOW_FIELD_RANDOM) > + *base = htobe32(*value << 16); > + else > + *base = htobe32(*value); > + > + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } > + > +static void > +mlx5dr_definer_compare_op_translate(enum rte_flow_item_compare_op op, > + uint8_t *tag) > +{ > + uint32_t *ctrl = &(((uint32_t > *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); > + uint8_t operator = 0; > + uint8_t inverse = 0; > + > + switch (op) { > + case RTE_FLOW_ITEM_COMPARE_EQ: > + operator = 2; > + break; > + case RTE_FLOW_ITEM_COMPARE_NE: > + operator = 2; > + inverse = 1; > + break; > + case RTE_FLOW_ITEM_COMPARE_LT: > + inverse = 1; > + break; > + case RTE_FLOW_ITEM_COMPARE_LE: > + operator = 1; > + break; > + case RTE_FLOW_ITEM_COMPARE_GT: > + operator = 1; > + inverse = 1; > + break; > + case RTE_FLOW_ITEM_COMPARE_GE: > + break; > + default: > + DR_LOG(ERR, "Invalid operation type %d", op); > + assert(false); > + } > + > + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); > + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); } > + > +static void > +mlx5dr_definer_compare_arg_set(const void *item_spec, > + uint8_t *tag) > +{ > + const struct rte_flow_item_compare *v = item_spec; > + enum rte_flow_item_compare_op op = v->operation; > + > + mlx5dr_definer_compare_op_translate(op, tag); } > + > +static void > +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, > + const void *item_spec, > + uint8_t *tag) > +{ > + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { > + mlx5dr_definer_compare_arg_set(item_spec, tag); > + if (fc->compare_set_base) > + mlx5dr_definer_compare_base_value_set(item_spec, > tag); > + } > +} > + > static void > mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, > const void *item_spec, > @@ -2739,10 +2819,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct > mlx5dr_definer_conv_data *cd, > return 0; > } > > +static int > +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_definer_compare_dw_selectors dw_offset) { > + struct mlx5dr_definer_fc *fc = NULL; > + int reg; > + > + if (f->offset) { > + DR_LOG(ERR, "field offset %u is not supported, only offset zero > supported", > + f->offset); > + goto err_notsup; > + } > + > + switch (f->field) { > + case RTE_FLOW_FIELD_META: > + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, > + > RTE_FLOW_ITEM_TYPE_META, -1); > + if (reg <= 0) { > + DR_LOG(ERR, "Invalid register for compare metadata > field"); > + rte_errno = EINVAL; > + return rte_errno; > + } > + > + fc = mlx5dr_definer_get_register_fc(cd, reg); > + if (!fc) > + return rte_errno; > + > + fc->item_idx = item_idx; > + fc->tag_set = &mlx5dr_definer_compare_set; > + fc->tag_mask_set = &mlx5dr_definer_ones_set; > + fc->compare_idx = dw_offset; > + break; > + case RTE_FLOW_FIELD_TAG: > + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, > + RTE_FLOW_ITEM_TYPE_TAG, > + f->tag_index); > + if (reg <= 0) { > + DR_LOG(ERR, "Invalid register for compare tag field"); > + rte_errno = EINVAL; > + return rte_errno; > + } > + > + fc = mlx5dr_definer_get_register_fc(cd, reg); > + if (!fc) > + return rte_errno; > + > + fc->item_idx = item_idx; > + fc->tag_set = &mlx5dr_definer_compare_set; > + fc->tag_mask_set = &mlx5dr_definer_ones_set; > + fc->compare_idx = dw_offset; > + break; > + case RTE_FLOW_FIELD_VALUE: > + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { > + DR_LOG(ERR, "Argument field does not support > immediate value"); > + goto err_notsup; > + } > + break; > + case RTE_FLOW_FIELD_RANDOM: > + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; > + fc->item_idx = item_idx; > + fc->tag_set = &mlx5dr_definer_compare_set; > + fc->tag_mask_set = &mlx5dr_definer_ones_set; > + fc->compare_idx = dw_offset; > + DR_CALC_SET_HDR(fc, random_number, random_number); > + break; > + default: > + DR_LOG(ERR, "%u field is not supported", f->field); > + goto err_notsup; > + } > + > + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) > + fc->compare_set_base = true; > + > + return 0; > + > +err_notsup: > + rte_errno = ENOTSUP; > + return rte_errno; > +} > + > +static int > +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, > + struct rte_flow_item *item, > + int item_idx) > +{ > + const struct rte_flow_item_compare *m = item->mask; > + const struct rte_flow_field_data *a = &m->a; > + const struct rte_flow_field_data *b = &m->b; > + int ret; > + > + if (m->width != 0xffffffff) { > + DR_LOG(ERR, "compare item width of 0x%x is not supported, > only full DW supported", > + m->width); > + rte_errno = ENOTSUP; > + return rte_errno; > + } > + > + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, > + > MLX5DR_DEFINER_COMPARE_ARGUMENT_0); > + if (ret) > + return ret; > + > + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, > + > MLX5DR_DEFINER_COMPARE_BASE_0); > + if (ret) > + return ret; > + > + return 0; > +} > + > static int > mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, > struct mlx5dr_match_template *mt, > - uint8_t *hl) > + uint8_t *hl, > + struct mlx5dr_matcher *matcher) > { > struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; > struct mlx5dr_definer_conv_data cd = {0}; @@ -2762,6 +2956,11 @@ > mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, > if (ret) > return ret; > > + if (mlx5dr_matcher_is_compare(matcher)) { > + DR_LOG(ERR, "Compare matcher not supported for > more than one item"); > + goto not_supp; > + } > + > switch ((int)items->type) { > case RTE_FLOW_ITEM_TYPE_ETH: > ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ > -2907,10 +3106,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context > *ctx, > ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, > i); > item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; > break; > + case RTE_FLOW_ITEM_TYPE_COMPARE: > + if (i) { > + DR_LOG(ERR, "Compare matcher not supported > for more than one item"); > + goto not_supp; > + } > + ret = mlx5dr_definer_conv_item_compare(&cd, items, > i); > + item_flags |= MLX5_FLOW_ITEM_COMPARE; > + matcher->flags |= > MLX5DR_MATCHER_FLAGS_COMPARE; > + break; > default: > DR_LOG(ERR, "Unsupported item type %d", items- > >type); > - rte_errno = ENOTSUP; > - return rte_errno; > + goto not_supp; > } > > cd.last_item = items->type; > @@ -2931,6 +3138,10 @@ mlx5dr_definer_conv_items_to_hl(struct > mlx5dr_context *ctx, > } > > return 0; > + > +not_supp: > + rte_errno = ENOTSUP; > + return rte_errno; > } > > static int > @@ -3318,6 +3529,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher > *matcher, { > struct mlx5dr_context *ctx = matcher->tbl->ctx; > struct mlx5dr_match_template *mt = matcher->mt; > + struct mlx5dr_definer_fc *fc; > uint8_t *match_hl; > int i, ret; > > @@ -3335,13 +3547,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher > *matcher, > * and allocate the match and range field copy array (fc & fcr). > */ > for (i = 0; i < matcher->num_of_mt; i++) { > - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); > + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, > +matcher); > if (ret) { > DR_LOG(ERR, "Failed to convert items to header > layout"); > goto free_fc; > } > } > > + if (mlx5dr_matcher_is_compare(matcher)) { > + ret = mlx5dr_matcher_validate_compare_attr(matcher); > + if (ret) > + goto free_fc; > + > + /* Due some HW limitation need to fill unused > + * DW's 0-5 and byte selectors with 0xff. > + */ > + for (i = 0; i < DW_SELECTORS_MATCH; i++) > + match_definer->dw_selector[i] = 0xff; > + > + for (i = 0; i < BYTE_SELECTORS; i++) > + match_definer->byte_selector[i] = 0xff; > + > + for (i = 0; i < mt[0].fc_sz; i++) { > + fc = &mt[0].fc[i]; > + match_definer->dw_selector[fc->compare_idx] = fc- > >byte_off / DW_SIZE; > + } > + > + goto out; > + } > + > /* Find the match definer layout for header layout match union */ > ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, > match_hl); > if (ret) { > @@ -3356,6 +3590,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher > *matcher, > goto free_fc; > } > > +out: > simple_free(match_hl); > return 0; > > diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h > b/drivers/net/mlx5/hws/mlx5dr_definer.h > index ced9d9da13..9f2b5e7dc9 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_definer.h > +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h > @@ -17,6 +17,37 @@ > #define DW_SELECTORS_RANGE 2 > #define BYTE_SELECTORS_RANGE 8 > > +enum mlx5dr_definer_compare_ste_dw_offset { > + /* In compare STE the matching DW's starts after the 3 actions */ > + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, > + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, > + MLX5DR_DEFINER_COMPARE_STE_BASE_1, > + MLX5DR_DEFINER_COMPARE_STE_BASE_0, > + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, > + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, > + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, > + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, > +}; > + > +enum mlx5dr_definer_dw_selectors { > + MLX5DR_DEFINER_SELECTOR_DW0, > + MLX5DR_DEFINER_SELECTOR_DW1, > + MLX5DR_DEFINER_SELECTOR_DW2, > + MLX5DR_DEFINER_SELECTOR_DW3, > + MLX5DR_DEFINER_SELECTOR_DW4, > + MLX5DR_DEFINER_SELECTOR_DW5, > + MLX5DR_DEFINER_SELECTOR_DW6, > + MLX5DR_DEFINER_SELECTOR_DW7, > + MLX5DR_DEFINER_SELECTOR_DW8, > +}; > + > +enum mlx5dr_definer_compare_dw_selectors { > + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = > MLX5DR_DEFINER_SELECTOR_DW4, > + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = > MLX5DR_DEFINER_SELECTOR_DW5, > + MLX5DR_DEFINER_COMPARE_BASE_0 = > MLX5DR_DEFINER_SELECTOR_DW2, > + MLX5DR_DEFINER_COMPARE_BASE_1 = > MLX5DR_DEFINER_SELECTOR_DW3, }; > + > enum mlx5dr_definer_fname { > MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, > MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, > @@ -188,6 +219,8 @@ struct mlx5dr_definer_fc { > uint8_t item_idx; > uint8_t is_range; > uint16_t extra_data; > + uint8_t compare_idx; > + bool compare_set_base; > uint32_t byte_off; > int bit_off; > uint32_t bit_mask; > diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c > b/drivers/net/mlx5/hws/mlx5dr_matcher.c > index 4ea161eae6..cede24237f 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c > +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c > @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct > mlx5dr_matcher *matcher, > rtc_attr.log_depth = attr->table.sz_col_log; > rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); > rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); > + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); > rtc_attr.miss_ft_id = matcher->end_ft->id; > > if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) > { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct > mlx5dr_matcher *matcher, > rtc_attr.num_hash_definer = 1; > rtc_attr.match_definer_0 = > mlx5dr_definer_get_id(matcher- > >hash_definer); > + } else if (mlx5dr_matcher_is_compare(matcher)) { > + rtc_attr.match_definer_0 = ctx->caps- > >trivial_match_definer; > + rtc_attr.fw_gen_wqe = true; > + rtc_attr.num_hash_definer = 1; > } else { > /* The first mt is used since all share the same > definer */ > rtc_attr.match_definer_0 = > mlx5dr_definer_get_id(mt->definer); > @@ -1452,3 +1457,46 @@ int mlx5dr_match_template_destroy(struct > mlx5dr_match_template *mt) > simple_free(mt); > return 0; > } > + > +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher > +*matcher) { > + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; > + struct mlx5dr_matcher_attr *attr = &matcher->attr; > + > + if (mlx5dr_table_is_root(matcher->tbl)) { > + DR_LOG(ERR, "Compare matcher is not supported for root > tables"); > + goto err; > + } > + > + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { > + DR_LOG(ERR, "Compare matcher is only supported with pre- > defined table size"); > + goto err; > + } > + > + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || > + attr->distribute_mode != > MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { > + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted > and distribute by hash"); > + goto err; > + } > + > + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { > + DR_LOG(ERR, "Compare matcher match templates and action > templates must be 1 for each"); > + goto err; > + } > + > + if (attr->table.sz_col_log || attr->table.sz_row_log) { > + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); > + goto err; > + } > + > + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, > MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { > + DR_LOG(ERR, "Gen WQE Compare match format not > supported"); > + goto err; > + } > + > + return 0; > + > +err: > + rte_errno = ENOTSUP; > + return rte_errno; > +} > diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h > b/drivers/net/mlx5/hws/mlx5dr_matcher.h > index 363a61fd41..ca6c212536 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h > +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h > @@ -26,6 +26,7 @@ enum mlx5dr_matcher_flags { > MLX5DR_MATCHER_FLAGS_RANGE_DEFINER = 1 << 0, > MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, > MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, > + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, > }; > > struct mlx5dr_match_template { > @@ -89,12 +90,19 @@ mlx5dr_matcher_mt_is_range(struct > mlx5dr_match_template *mt) > return (!!mt->range_definer); > } > > +static inline bool > +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) { > + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); } > + > static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher > *matcher) { > /* Currently HWS doesn't support hash different from match or range */ > return unlikely(matcher->flags & > (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | > - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); > + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | > + MLX5DR_MATCHER_FLAGS_COMPARE)); > } > > int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -120,4 > +128,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, > enum mlx5dr_table_type type, > struct mlx5dr_devx_obj *devx_obj); > > +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher > +*matcher); > + > #endif /* MLX5DR_MATCHER_H_ */ > -- > 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v5 2/3] net/mlx5: add support to compare random value 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum 2024-02-14 7:30 ` [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-02-14 7:30 ` Michael Baum 2024-02-19 3:00 ` Suanming Mou 2024-02-14 7:30 ` [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum 3 siblings, 1 reply; 30+ messages in thread From: Michael Baum @ 2024-02-14 7:30 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> --- doc/guides/nics/mlx5.rst | 9 ++++- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index fa013b03bb..43ef8a99dc 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -820,8 +820,13 @@ Limitations - Only supported in HW steering(``dv_flow_en`` = 2) mode. - Only single flow is supported to the flow table. - - Only 32-bit comparison is supported. - - Only match with compare result between packet fields is supported. + - Only single item is supported per pattern template. + - Only 32-bit comparison is supported or 16-bits for random field. + - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. + - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. + - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with + ``RTE_FLOW_FIELD_VALUE``. Statistics diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 3af5e1f160..b5741f0817 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6717,18 +6717,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6737,6 +6774,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6748,19 +6786,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6768,7 +6800,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v5 2/3] net/mlx5: add support to compare random value 2024-02-14 7:30 ` [PATCH v5 2/3] net/mlx5: add support to compare random value Michael Baum @ 2024-02-19 3:00 ` Suanming Mou 0 siblings, 0 replies; 30+ messages in thread From: Suanming Mou @ 2024-02-19 3:00 UTC (permalink / raw) To: Michael Baum, dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Slava Ovsiienko, Ori Kam > -----Original Message----- > From: Michael Baum <michaelba@nvidia.com> > Sent: Wednesday, February 14, 2024 3:30 PM > To: dev@dpdk.org > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; Suanming > Mou <suanmingm@nvidia.com> > Subject: [PATCH v5 2/3] net/mlx5: add support to compare random value > > Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with > "RTE_FLOW_FIELD_RAMDOM" as an argument. > The random field is supported only when base is an immediate value, random > field cannot be compared with enother field. > > Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> > --- > doc/guides/nics/mlx5.rst | 9 ++++- > drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- > 2 files changed, 59 insertions(+), 20 deletions(-) > > diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index > fa013b03bb..43ef8a99dc 100644 > --- a/doc/guides/nics/mlx5.rst > +++ b/doc/guides/nics/mlx5.rst > @@ -820,8 +820,13 @@ Limitations > > - Only supported in HW steering(``dv_flow_en`` = 2) mode. > - Only single flow is supported to the flow table. > - - Only 32-bit comparison is supported. > - - Only match with compare result between packet fields is supported. > + - Only single item is supported per pattern template. > + - Only 32-bit comparison is supported or 16-bits for random field. > + - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, > + ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. > + - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. > + - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with > + ``RTE_FLOW_FIELD_VALUE``. > > > Statistics > diff --git a/drivers/net/mlx5/mlx5_flow_hw.c > b/drivers/net/mlx5/mlx5_flow_hw.c index 3af5e1f160..b5741f0817 100644 > --- a/drivers/net/mlx5/mlx5_flow_hw.c > +++ b/drivers/net/mlx5/mlx5_flow_hw.c > @@ -6717,18 +6717,55 @@ flow_hw_prepend_item(const struct rte_flow_item > *items, > return copied_items; > } > > -static inline bool > -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) > +static int > +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, > + enum rte_flow_field_id base_field, > + struct rte_flow_error *error) > { > - switch (field) { > + switch (arg_field) { > + case RTE_FLOW_FIELD_TAG: > + case RTE_FLOW_FIELD_META: > + break; > + case RTE_FLOW_FIELD_RANDOM: > + if (base_field == RTE_FLOW_FIELD_VALUE) > + return 0; > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > + NULL, > + "compare random is supported only > with immediate value"); > + default: > + return rte_flow_error_set(error, ENOTSUP, > + > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > + NULL, > + "compare item argument field is not > supported"); > + } > + switch (base_field) { > case RTE_FLOW_FIELD_TAG: > case RTE_FLOW_FIELD_META: > case RTE_FLOW_FIELD_VALUE: > - return true; > + break; > + default: > + return rte_flow_error_set(error, ENOTSUP, > + > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > + NULL, > + "compare item base field is not > supported"); > + } > + return 0; > +} > + > +static inline uint32_t > +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) { > + switch (field) { > + case RTE_FLOW_FIELD_TAG: > + case RTE_FLOW_FIELD_META: > + return 32; > + case RTE_FLOW_FIELD_RANDOM: > + return 16; > default: > break; > } > - return false; > + return 0; > } > > static int > @@ -6737,6 +6774,7 @@ flow_hw_validate_item_compare(const struct > rte_flow_item *item, { > const struct rte_flow_item_compare *comp_m = item->mask; > const struct rte_flow_item_compare *comp_v = item->spec; > + int ret; > > if (unlikely(!comp_m)) > return rte_flow_error_set(error, EINVAL, @@ -6748,19 +6786,13 > @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, > "compare item only support full mask"); > - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || > - !flow_hw_item_compare_field_supported(comp_m->b.field)) > - return rte_flow_error_set(error, ENOTSUP, > - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > - NULL, > - "compare item field not support"); > - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && > - comp_m->b.field == RTE_FLOW_FIELD_VALUE) > - return rte_flow_error_set(error, EINVAL, > - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > - NULL, > - "compare between value is not valid"); > + ret = flow_hw_item_compare_field_validate(comp_m->a.field, > + comp_m->b.field, error); > + if (ret < 0) > + return ret; > if (comp_v) { > + uint32_t width; > + > if (comp_v->operation != comp_m->operation || > comp_v->a.field != comp_m->a.field || > comp_v->b.field != comp_m->b.field) @@ -6768,7 +6800,9 > @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, > > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, > "compare item spec/mask not > matching"); > - if ((comp_v->width & comp_m->width) != 32) > + width = flow_hw_item_compare_width_supported(comp_v- > >a.field); > + MLX5_ASSERT(width > 0); > + if ((comp_v->width & comp_m->width) != width) > return rte_flow_error_set(error, EINVAL, > > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, > -- > 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum 2024-02-14 7:30 ` [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-14 7:30 ` [PATCH v5 2/3] net/mlx5: add support to compare random value Michael Baum @ 2024-02-14 7:30 ` Michael Baum 2024-02-19 2:59 ` Suanming Mou 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum 3 siblings, 1 reply; 30+ messages in thread From: Michael Baum @ 2024-02-14 7:30 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_ESP_SEQ_NUM" field. Signed-off-by: Michael Baum <michaelba@nvidia.com> --- doc/guides/nics/mlx5.rst | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 22 ++++++++++++++++++++-- drivers/net/mlx5/mlx5_flow_hw.c | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 43ef8a99dc..b793f1ef58 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -823,6 +823,7 @@ Limitations - Only single item is supported per pattern template. - Only 32-bit comparison is supported or 16-bits for random field. - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_ESP_SEQ_NUM``, ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 2d86175ca2..b29d7451e7 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -396,10 +396,20 @@ mlx5dr_definer_compare_base_value_set(const void *item_spec, value = (const uint32_t *)&b->value[0]; - if (a->field == RTE_FLOW_FIELD_RANDOM) + switch (a->field) { + case RTE_FLOW_FIELD_RANDOM: *base = htobe32(*value << 16); - else + break; + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: *base = htobe32(*value); + break; + case RTE_FLOW_FIELD_ESP_SEQ_NUM: + *base = *value; + break; + default: + break; + } MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } @@ -2887,6 +2897,14 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f, fc->compare_idx = dw_offset; DR_CALC_SET_HDR(fc, random_number, random_number); break; + case RTE_FLOW_FIELD_ESP_SEQ_NUM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, ipsec, sequence_number); + break; default: DR_LOG(ERR, "%u field is not supported", f->field); goto err_notsup; diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index b5741f0817..4d6fb489b2 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6725,6 +6725,7 @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, switch (arg_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: break; case RTE_FLOW_FIELD_RANDOM: if (base_field == RTE_FLOW_FIELD_VALUE) @@ -6743,6 +6744,7 @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: break; default: return rte_flow_error_set(error, ENOTSUP, @@ -6759,6 +6761,7 @@ flow_hw_item_compare_width_supported(enum rte_flow_field_id field) switch (field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: return 32; case RTE_FLOW_FIELD_RANDOM: return 16; -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support 2024-02-14 7:30 ` [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum @ 2024-02-19 2:59 ` Suanming Mou 2024-02-19 7:21 ` Michael Baum 0 siblings, 1 reply; 30+ messages in thread From: Suanming Mou @ 2024-02-19 2:59 UTC (permalink / raw) To: Michael Baum, dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Slava Ovsiienko, Ori Kam Hi, > -----Original Message----- > From: Michael Baum <michaelba@nvidia.com> > Sent: Wednesday, February 14, 2024 3:30 PM > To: dev@dpdk.org > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; Suanming > Mou <suanmingm@nvidia.com> > Subject: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number > support > > Add support for compare item with "RTE_FLOW_FIELD_ESP_SEQ_NUM" field. Small comment, please don't forget to add the new supported comparison field to rel_notes. > > Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> > --- > doc/guides/nics/mlx5.rst | 1 + > drivers/net/mlx5/hws/mlx5dr_definer.c | 22 ++++++++++++++++++++-- > drivers/net/mlx5/mlx5_flow_hw.c | 3 +++ > 3 files changed, 24 insertions(+), 2 deletions(-) > > diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index > 43ef8a99dc..b793f1ef58 100644 > --- a/doc/guides/nics/mlx5.rst > +++ b/doc/guides/nics/mlx5.rst > @@ -823,6 +823,7 @@ Limitations > - Only single item is supported per pattern template. > - Only 32-bit comparison is supported or 16-bits for random field. > - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, > + ``RTE_FLOW_FIELD_ESP_SEQ_NUM``, > ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. > - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. > - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with diff > --git a/drivers/net/mlx5/hws/mlx5dr_definer.c > b/drivers/net/mlx5/hws/mlx5dr_definer.c > index 2d86175ca2..b29d7451e7 100644 > --- a/drivers/net/mlx5/hws/mlx5dr_definer.c > +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c > @@ -396,10 +396,20 @@ mlx5dr_definer_compare_base_value_set(const void > *item_spec, > > value = (const uint32_t *)&b->value[0]; > > - if (a->field == RTE_FLOW_FIELD_RANDOM) > + switch (a->field) { > + case RTE_FLOW_FIELD_RANDOM: > *base = htobe32(*value << 16); > - else > + break; > + case RTE_FLOW_FIELD_TAG: > + case RTE_FLOW_FIELD_META: > *base = htobe32(*value); > + break; > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > + *base = *value; > + break; > + default: > + break; > + } > > MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } @@ -2887,6 > +2897,14 @@ mlx5dr_definer_conv_item_compare_field(const struct > rte_flow_field_data *f, > fc->compare_idx = dw_offset; > DR_CALC_SET_HDR(fc, random_number, random_number); > break; > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > + fc = &cd- > >fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER]; > + fc->item_idx = item_idx; > + fc->tag_set = &mlx5dr_definer_compare_set; > + fc->tag_mask_set = &mlx5dr_definer_ones_set; > + fc->compare_idx = dw_offset; > + DR_CALC_SET_HDR(fc, ipsec, sequence_number); > + break; > default: > DR_LOG(ERR, "%u field is not supported", f->field); > goto err_notsup; > diff --git a/drivers/net/mlx5/mlx5_flow_hw.c > b/drivers/net/mlx5/mlx5_flow_hw.c index b5741f0817..4d6fb489b2 100644 > --- a/drivers/net/mlx5/mlx5_flow_hw.c > +++ b/drivers/net/mlx5/mlx5_flow_hw.c > @@ -6725,6 +6725,7 @@ flow_hw_item_compare_field_validate(enum > rte_flow_field_id arg_field, > switch (arg_field) { > case RTE_FLOW_FIELD_TAG: > case RTE_FLOW_FIELD_META: > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > break; > case RTE_FLOW_FIELD_RANDOM: > if (base_field == RTE_FLOW_FIELD_VALUE) @@ -6743,6 +6744,7 > @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, > case RTE_FLOW_FIELD_TAG: > case RTE_FLOW_FIELD_META: > case RTE_FLOW_FIELD_VALUE: > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > break; > default: > return rte_flow_error_set(error, ENOTSUP, @@ -6759,6 +6761,7 > @@ flow_hw_item_compare_width_supported(enum rte_flow_field_id field) > switch (field) { > case RTE_FLOW_FIELD_TAG: > case RTE_FLOW_FIELD_META: > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > return 32; > case RTE_FLOW_FIELD_RANDOM: > return 16; > -- > 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support 2024-02-19 2:59 ` Suanming Mou @ 2024-02-19 7:21 ` Michael Baum 2024-02-19 7:37 ` Suanming Mou 0 siblings, 1 reply; 30+ messages in thread From: Michael Baum @ 2024-02-19 7:21 UTC (permalink / raw) To: Suanming Mou, dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Slava Ovsiienko, Ori Kam Hi, > -----Original Message----- > From: Suanming Mou <suanmingm@nvidia.com> > Sent: Monday, 19 February 2024 5:00 > To: Michael Baum <michaelba@nvidia.com>; dev@dpdk.org > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com> > Subject: RE: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence > number support > > Hi, > > > -----Original Message----- > > From: Michael Baum <michaelba@nvidia.com> > > Sent: Wednesday, February 14, 2024 3:30 PM > > To: dev@dpdk.org > > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; > > Suanming Mou <suanmingm@nvidia.com> > > Subject: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number > > support > > > > Add support for compare item with "RTE_FLOW_FIELD_ESP_SEQ_NUM" > field. The basic support of other fields is inserted in this release without specifying the supported fields. I kept the behavior with this field. > > Small comment, please don't forget to add the new supported comparison > field to rel_notes. > > > > > Signed-off-by: Michael Baum <michaelba@nvidia.com> > Acked-by: Suanming Mou <suanmingm@nvidia.com> > > > --- > > doc/guides/nics/mlx5.rst | 1 + > > drivers/net/mlx5/hws/mlx5dr_definer.c | 22 ++++++++++++++++++++-- > > drivers/net/mlx5/mlx5_flow_hw.c | 3 +++ > > 3 files changed, 24 insertions(+), 2 deletions(-) > > > > diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index > > 43ef8a99dc..b793f1ef58 100644 > > --- a/doc/guides/nics/mlx5.rst > > +++ b/doc/guides/nics/mlx5.rst > > @@ -823,6 +823,7 @@ Limitations > > - Only single item is supported per pattern template. > > - Only 32-bit comparison is supported or 16-bits for random field. > > - Only supported for ``RTE_FLOW_FIELD_META``, > > ``RTE_FLOW_FIELD_TAG``, > > + ``RTE_FLOW_FIELD_ESP_SEQ_NUM``, > > ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. > > - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. > > - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared > > with diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c > > b/drivers/net/mlx5/hws/mlx5dr_definer.c > > index 2d86175ca2..b29d7451e7 100644 > > --- a/drivers/net/mlx5/hws/mlx5dr_definer.c > > +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c > > @@ -396,10 +396,20 @@ mlx5dr_definer_compare_base_value_set(const > void > > *item_spec, > > > > value = (const uint32_t *)&b->value[0]; > > > > - if (a->field == RTE_FLOW_FIELD_RANDOM) > > + switch (a->field) { > > + case RTE_FLOW_FIELD_RANDOM: > > *base = htobe32(*value << 16); > > - else > > + break; > > + case RTE_FLOW_FIELD_TAG: > > + case RTE_FLOW_FIELD_META: > > *base = htobe32(*value); > > + break; > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > + *base = *value; > > + break; > > + default: > > + break; > > + } > > > > MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } @@ - > 2887,6 > > +2897,14 @@ mlx5dr_definer_conv_item_compare_field(const struct > > rte_flow_field_data *f, > > fc->compare_idx = dw_offset; > > DR_CALC_SET_HDR(fc, random_number, random_number); > > break; > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > + fc = &cd- > > >fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER]; > > + fc->item_idx = item_idx; > > + fc->tag_set = &mlx5dr_definer_compare_set; > > + fc->tag_mask_set = &mlx5dr_definer_ones_set; > > + fc->compare_idx = dw_offset; > > + DR_CALC_SET_HDR(fc, ipsec, sequence_number); > > + break; > > default: > > DR_LOG(ERR, "%u field is not supported", f->field); > > goto err_notsup; > > diff --git a/drivers/net/mlx5/mlx5_flow_hw.c > > b/drivers/net/mlx5/mlx5_flow_hw.c index b5741f0817..4d6fb489b2 > 100644 > > --- a/drivers/net/mlx5/mlx5_flow_hw.c > > +++ b/drivers/net/mlx5/mlx5_flow_hw.c > > @@ -6725,6 +6725,7 @@ flow_hw_item_compare_field_validate(enum > > rte_flow_field_id arg_field, > > switch (arg_field) { > > case RTE_FLOW_FIELD_TAG: > > case RTE_FLOW_FIELD_META: > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > break; > > case RTE_FLOW_FIELD_RANDOM: > > if (base_field == RTE_FLOW_FIELD_VALUE) @@ -6743,6 > +6744,7 @@ > > flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, > > case RTE_FLOW_FIELD_TAG: > > case RTE_FLOW_FIELD_META: > > case RTE_FLOW_FIELD_VALUE: > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > break; > > default: > > return rte_flow_error_set(error, ENOTSUP, @@ -6759,6 > +6761,7 @@ > > flow_hw_item_compare_width_supported(enum rte_flow_field_id field) > > switch (field) { > > case RTE_FLOW_FIELD_TAG: > > case RTE_FLOW_FIELD_META: > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > return 32; > > case RTE_FLOW_FIELD_RANDOM: > > return 16; > > -- > > 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support 2024-02-19 7:21 ` Michael Baum @ 2024-02-19 7:37 ` Suanming Mou 0 siblings, 0 replies; 30+ messages in thread From: Suanming Mou @ 2024-02-19 7:37 UTC (permalink / raw) To: Michael Baum, dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Slava Ovsiienko, Ori Kam > -----Original Message----- > From: Michael Baum <michaelba@nvidia.com> > Sent: Monday, February 19, 2024 3:22 PM > To: Suanming Mou <suanmingm@nvidia.com>; dev@dpdk.org > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com> > Subject: RE: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number > support > > Hi, > > > -----Original Message----- > > From: Suanming Mou <suanmingm@nvidia.com> > > Sent: Monday, 19 February 2024 5:00 > > To: Michael Baum <michaelba@nvidia.com>; dev@dpdk.org > > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com> > > Subject: RE: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence > > number support > > > > Hi, > > > > > -----Original Message----- > > > From: Michael Baum <michaelba@nvidia.com> > > > Sent: Wednesday, February 14, 2024 3:30 PM > > > To: dev@dpdk.org > > > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > > > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; > > > Slava Ovsiienko <viacheslavo@nvidia.com>; Ori Kam > > > <orika@nvidia.com>; Suanming Mou <suanmingm@nvidia.com> > > > Subject: [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence > > > number support > > > > > > Add support for compare item with "RTE_FLOW_FIELD_ESP_SEQ_NUM" > > field. > > The basic support of other fields is inserted in this release without specifying the > supported fields. > I kept the behavior with this field. OK, I see. Thanks. > > > > > Small comment, please don't forget to add the new supported comparison > > field to rel_notes. > > > > > > > > Signed-off-by: Michael Baum <michaelba@nvidia.com> > > Acked-by: Suanming Mou <suanmingm@nvidia.com> > > > > > --- > > > doc/guides/nics/mlx5.rst | 1 + > > > drivers/net/mlx5/hws/mlx5dr_definer.c | 22 ++++++++++++++++++++-- > > > drivers/net/mlx5/mlx5_flow_hw.c | 3 +++ > > > 3 files changed, 24 insertions(+), 2 deletions(-) > > > > > > diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst > > > index > > > 43ef8a99dc..b793f1ef58 100644 > > > --- a/doc/guides/nics/mlx5.rst > > > +++ b/doc/guides/nics/mlx5.rst > > > @@ -823,6 +823,7 @@ Limitations > > > - Only single item is supported per pattern template. > > > - Only 32-bit comparison is supported or 16-bits for random field. > > > - Only supported for ``RTE_FLOW_FIELD_META``, > > > ``RTE_FLOW_FIELD_TAG``, > > > + ``RTE_FLOW_FIELD_ESP_SEQ_NUM``, > > > ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. > > > - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. > > > - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared > > > with diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c > > > b/drivers/net/mlx5/hws/mlx5dr_definer.c > > > index 2d86175ca2..b29d7451e7 100644 > > > --- a/drivers/net/mlx5/hws/mlx5dr_definer.c > > > +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c > > > @@ -396,10 +396,20 @@ mlx5dr_definer_compare_base_value_set(const > > void > > > *item_spec, > > > > > > value = (const uint32_t *)&b->value[0]; > > > > > > - if (a->field == RTE_FLOW_FIELD_RANDOM) > > > + switch (a->field) { > > > + case RTE_FLOW_FIELD_RANDOM: > > > *base = htobe32(*value << 16); > > > - else > > > + break; > > > + case RTE_FLOW_FIELD_TAG: > > > + case RTE_FLOW_FIELD_META: > > > *base = htobe32(*value); > > > + break; > > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > > + *base = *value; > > > + break; > > > + default: > > > + break; > > > + } > > > > > > MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } @@ - > > 2887,6 > > > +2897,14 @@ mlx5dr_definer_conv_item_compare_field(const struct > > > rte_flow_field_data *f, > > > fc->compare_idx = dw_offset; > > > DR_CALC_SET_HDR(fc, random_number, random_number); > > > break; > > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > > + fc = &cd- > > > >fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER]; > > > + fc->item_idx = item_idx; > > > + fc->tag_set = &mlx5dr_definer_compare_set; > > > + fc->tag_mask_set = &mlx5dr_definer_ones_set; > > > + fc->compare_idx = dw_offset; > > > + DR_CALC_SET_HDR(fc, ipsec, sequence_number); > > > + break; > > > default: > > > DR_LOG(ERR, "%u field is not supported", f->field); > > > goto err_notsup; > > > diff --git a/drivers/net/mlx5/mlx5_flow_hw.c > > > b/drivers/net/mlx5/mlx5_flow_hw.c index b5741f0817..4d6fb489b2 > > 100644 > > > --- a/drivers/net/mlx5/mlx5_flow_hw.c > > > +++ b/drivers/net/mlx5/mlx5_flow_hw.c > > > @@ -6725,6 +6725,7 @@ flow_hw_item_compare_field_validate(enum > > > rte_flow_field_id arg_field, > > > switch (arg_field) { > > > case RTE_FLOW_FIELD_TAG: > > > case RTE_FLOW_FIELD_META: > > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > > break; > > > case RTE_FLOW_FIELD_RANDOM: > > > if (base_field == RTE_FLOW_FIELD_VALUE) @@ -6743,6 > > +6744,7 @@ > > > flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, > > > case RTE_FLOW_FIELD_TAG: > > > case RTE_FLOW_FIELD_META: > > > case RTE_FLOW_FIELD_VALUE: > > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > > break; > > > default: > > > return rte_flow_error_set(error, ENOTSUP, @@ -6759,6 > > +6761,7 @@ > > > flow_hw_item_compare_width_supported(enum rte_flow_field_id field) > > > switch (field) { > > > case RTE_FLOW_FIELD_TAG: > > > case RTE_FLOW_FIELD_META: > > > + case RTE_FLOW_FIELD_ESP_SEQ_NUM: > > > return 32; > > > case RTE_FLOW_FIELD_RANDOM: > > > return 16; > > > -- > > > 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6 0/3] net/mlx5: add compare item support 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum ` (2 preceding siblings ...) 2024-02-14 7:30 ` [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum @ 2024-02-26 13:03 ` Michael Baum 2024-02-26 13:03 ` [PATCH v6 1/3] net/mlx5/hws: add support for compare matcher Michael Baum ` (3 more replies) 3 siblings, 4 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:03 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add HWS support for compare item with: - "RTE_FLOW_FIELD_TAG". - "RTE_FLOW_FIELD_NETA". - "RTE_FLOW_FIELD_VALUE". Add HWS + PMD support for compare item with: - "RTE_FLOW_FIELD_RANDOM". - "RTE_FLOW_FIELD_ESP_SEQ_NUM". v2: - Rebase. - Add "RTE_FLOW_FIELD_META" compare support. - Reduce the "Depends-on" list. v3: - Rebase. - Fix typo in function name, r/tranlate/translate. - Fix adding a line without newline at end of file. v4: - Rebase. - Update documentation. - Remove the "Depends-on" label. v5: - Rebase. - Add ESP sequence number suppoert and rename the series accordingly. v6: - Rebase. - Add "Acked-by" from v5. Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (2): net/mlx5: add support to compare random value net/mlx5/hws: add compare ESP sequence number support doc/guides/nics/mlx5.rst | 10 +- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 261 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 53 ++++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 73 +++++-- 11 files changed, 444 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6 1/3] net/mlx5/hws: add support for compare matcher 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum @ 2024-02-26 13:03 ` Michael Baum 2024-02-26 13:03 ` [PATCH v6 2/3] net/mlx5: add support to compare random value Michael Baum ` (2 subsequent siblings) 3 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:03 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 53 ++++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 363 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 282e59e52c..aceacb04d0 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3463,6 +3463,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3501,6 +3502,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index fd07028e5f..0e0cc479a6 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index ee4a61b7eb..9d385fc57f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index b8a546989a..da50b64fb4 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -411,6 +411,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_translate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_translate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2782,10 +2862,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_META: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_META, -1); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare metadata field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare tag field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2805,6 +2999,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2950,10 +3149,18 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i); item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2974,6 +3181,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -3391,6 +3602,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -3408,13 +3620,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3435,6 +3669,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index 71cc0e94de..ca530ebf30 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -188,6 +219,8 @@ struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; uint16_t extra_data; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 402242308d..8a74a1ed7d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1635,3 +1640,51 @@ int mlx5dr_matcher_resize_rule_move(struct mlx5dr_matcher *src_matcher, rte_errno = EINVAL; return -rte_errno; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (attr->resizable) { + DR_LOG(ERR, "Compare matcher does not support resizeing"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 0f2bf96e8b..6dc3bf4d0d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -27,6 +27,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, MLX5DR_MATCHER_FLAGS_RESIZABLE = 1 << 3, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -110,12 +111,19 @@ static inline bool mlx5dr_matcher_is_in_resize(struct mlx5dr_matcher *matcher) return !!matcher->resize_dst; } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -141,4 +149,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6 2/3] net/mlx5: add support to compare random value 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum 2024-02-26 13:03 ` [PATCH v6 1/3] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-02-26 13:03 ` Michael Baum 2024-02-26 13:03 ` [PATCH v6 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum 3 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:03 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> --- doc/guides/nics/mlx5.rst | 9 ++++- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 0d2213497a..c0a5768117 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -431,8 +431,13 @@ Limitations - Only supported in HW steering(``dv_flow_en`` = 2) mode. - Only single flow is supported to the flow table. - - Only 32-bit comparison is supported. - - Only match with compare result between packet fields is supported. + - Only single item is supported per pattern template. + - Only 32-bit comparison is supported or 16-bits for random field. + - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. + - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. + - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with + ``RTE_FLOW_FIELD_VALUE``. - No Tx metadata go to the E-Switch steering domain for the Flow group 0. The flows within group 0 and set metadata action are rejected by hardware. diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 0d09c220df..b0e93baaf2 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6721,18 +6721,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6741,6 +6778,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6752,19 +6790,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6772,7 +6804,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v6 3/3] net/mlx5/hws: add compare ESP sequence number support 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum 2024-02-26 13:03 ` [PATCH v6 1/3] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-26 13:03 ` [PATCH v6 2/3] net/mlx5: add support to compare random value Michael Baum @ 2024-02-26 13:03 ` Michael Baum 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum 3 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:03 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_ESP_SEQ_NUM" field. Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> --- doc/guides/nics/mlx5.rst | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 22 ++++++++++++++++++++-- drivers/net/mlx5/mlx5_flow_hw.c | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index c0a5768117..d7bf81161e 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -434,6 +434,7 @@ Limitations - Only single item is supported per pattern template. - Only 32-bit comparison is supported or 16-bits for random field. - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_ESP_SEQ_NUM``, ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index da50b64fb4..39269b4ede 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -424,10 +424,20 @@ mlx5dr_definer_compare_base_value_set(const void *item_spec, value = (const uint32_t *)&b->value[0]; - if (a->field == RTE_FLOW_FIELD_RANDOM) + switch (a->field) { + case RTE_FLOW_FIELD_RANDOM: *base = htobe32(*value << 16); - else + break; + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: *base = htobe32(*value); + break; + case RTE_FLOW_FIELD_ESP_SEQ_NUM: + *base = *value; + break; + default: + break; + } MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } @@ -2930,6 +2940,14 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f, fc->compare_idx = dw_offset; DR_CALC_SET_HDR(fc, random_number, random_number); break; + case RTE_FLOW_FIELD_ESP_SEQ_NUM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, ipsec, sequence_number); + break; default: DR_LOG(ERR, "%u field is not supported", f->field); goto err_notsup; diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index b0e93baaf2..33922bddff 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6729,6 +6729,7 @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, switch (arg_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: break; case RTE_FLOW_FIELD_RANDOM: if (base_field == RTE_FLOW_FIELD_VALUE) @@ -6747,6 +6748,7 @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: break; default: return rte_flow_error_set(error, ENOTSUP, @@ -6763,6 +6765,7 @@ flow_hw_item_compare_width_supported(enum rte_flow_field_id field) switch (field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: return 32; case RTE_FLOW_FIELD_RANDOM: return 16; -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v7 0/3] net/mlx5: add compare item support 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum ` (2 preceding siblings ...) 2024-02-26 13:03 ` [PATCH v6 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum @ 2024-02-26 13:18 ` Michael Baum 2024-02-26 13:18 ` [PATCH v7 1/3] net/mlx5/hws: add support for compare matcher Michael Baum ` (3 more replies) 3 siblings, 4 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:18 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add HWS support for compare item with: - "RTE_FLOW_FIELD_TAG". - "RTE_FLOW_FIELD_NETA". - "RTE_FLOW_FIELD_VALUE". Add HWS + PMD support for compare item with: - "RTE_FLOW_FIELD_RANDOM". - "RTE_FLOW_FIELD_ESP_SEQ_NUM". v2: - Rebase. - Add "RTE_FLOW_FIELD_META" compare support. - Reduce the "Depends-on" list. v3: - Rebase. - Fix typo in function name, r/tranlate/translate. - Fix adding a line without newline at end of file. v4: - Rebase. - Update documentation. - Remove the "Depends-on" label. v5: - Rebase. - Add ESP sequence number suppoert and rename the series accordingly. v6: - Rebase. - Add "Acked-by" from v5. v7: - Rebase. Hamdan Igbaria (1): net/mlx5/hws: add support for compare matcher Michael Baum (2): net/mlx5: add support to compare random value net/mlx5/hws: add compare ESP sequence number support doc/guides/nics/mlx5.rst | 10 +- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 261 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 53 ++++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- drivers/net/mlx5/mlx5_flow_hw.c | 73 +++++-- 11 files changed, 444 insertions(+), 29 deletions(-) -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v7 1/3] net/mlx5/hws: add support for compare matcher 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum @ 2024-02-26 13:18 ` Michael Baum 2024-02-26 13:18 ` [PATCH v7 2/3] net/mlx5: add support to compare random value Michael Baum ` (2 subsequent siblings) 3 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:18 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou, Hamdan Igbaria From: Hamdan Igbaria <hamdani@nvidia.com> Add support for compare matcher, this matcher will allow direct comparison between two packet fields, or a packet field and a value, with fully masked DW. For now this matcher hash table is limited to size 1x1, thus it supports only 1 rule STE. Signed-off-by: Hamdan Igbaria <hamdani@nvidia.com> Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> --- drivers/common/mlx5/mlx5_prm.h | 16 ++ drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 243 +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 53 ++++++ drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- 9 files changed, 363 insertions(+), 9 deletions(-) diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h index 282e59e52c..aceacb04d0 100644 --- a/drivers/common/mlx5/mlx5_prm.h +++ b/drivers/common/mlx5/mlx5_prm.h @@ -3463,6 +3463,7 @@ enum mlx5_ifc_rtc_ste_format { MLX5_IFC_RTC_STE_FORMAT_8DW = 0x4, MLX5_IFC_RTC_STE_FORMAT_11DW = 0x5, MLX5_IFC_RTC_STE_FORMAT_RANGE = 0x7, + MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE = 0x8, }; enum mlx5_ifc_rtc_reparse_mode { @@ -3501,6 +3502,21 @@ struct mlx5_ifc_rtc_bits { u8 reserved_at_1a0[0x260]; }; +struct mlx5_ifc_ste_match_4dw_range_ctrl_dw_bits { + u8 match[0x1]; + u8 reserved_at_1[0x2]; + u8 base1[0x1]; + u8 inverse1[0x1]; + u8 reserved_at_5[0x1]; + u8 operator1[0x2]; + u8 reserved_at_8[0x3]; + u8 base0[0x1]; + u8 inverse0[0x1]; + u8 reserved_at_a[0x1]; + u8 operator0[0x2]; + u8 compare_delta[0x10]; +}; + struct mlx5_ifc_alias_context_bits { u8 vhca_id_to_be_accessed[0x10]; u8 reserved_at_10[0xd]; diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.c b/drivers/net/mlx5/hws/mlx5dr_cmd.c index fd07028e5f..0e0cc479a6 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.c +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.c @@ -370,9 +370,12 @@ mlx5dr_cmd_rtc_create(struct ibv_context *ctx, attr, obj_type, MLX5_GENERAL_OBJ_TYPE_RTC); attr = MLX5_ADDR_OF(create_rtc_in, in, rtc); - MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? - MLX5_IFC_RTC_STE_FORMAT_11DW : - MLX5_IFC_RTC_STE_FORMAT_8DW); + if (rtc_attr->is_compare) { + MLX5_SET(rtc, attr, ste_format_0, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE); + } else { + MLX5_SET(rtc, attr, ste_format_0, rtc_attr->is_frst_jumbo ? + MLX5_IFC_RTC_STE_FORMAT_11DW : MLX5_IFC_RTC_STE_FORMAT_8DW); + } if (rtc_attr->is_scnd_range) { MLX5_SET(rtc, attr, ste_format_1, MLX5_IFC_RTC_STE_FORMAT_RANGE); diff --git a/drivers/net/mlx5/hws/mlx5dr_cmd.h b/drivers/net/mlx5/hws/mlx5dr_cmd.h index ee4a61b7eb..9d385fc57f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_cmd.h +++ b/drivers/net/mlx5/hws/mlx5dr_cmd.h @@ -82,6 +82,7 @@ struct mlx5dr_cmd_rtc_create_attr { uint8_t reparse_mode; bool is_frst_jumbo; bool is_scnd_range; + bool is_compare; }; struct mlx5dr_cmd_alias_obj_create_attr { diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 11557bcab8..a9094cd35b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -99,6 +99,7 @@ static int mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher) { bool is_root = matcher->tbl->level == MLX5DR_ROOT_LEVEL; + bool is_compare = mlx5dr_matcher_is_compare(matcher); enum mlx5dr_debug_res_type type; int i, ret; @@ -117,7 +118,8 @@ mlx5dr_debug_dump_matcher_match_template(FILE *f, struct mlx5dr_matcher *matcher return rte_errno; } - type = MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; + type = is_compare ? MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER : + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_MATCH_DEFINER; ret = mlx5dr_debug_dump_matcher_template_definer(f, mt, mt->definer, type); if (ret) return ret; diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index 5cffdb10b5..a89a6a0b1d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -24,6 +24,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_MATCHER_ACTION_TEMPLATE = 4204, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_HASH_DEFINER = 4205, MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_RANGE_DEFINER = 4206, + MLX5DR_DEBUG_RES_TYPE_MATCHER_TEMPLATE_COMPARE_MATCH_DEFINER = 4207, }; static inline uint64_t diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index cde41f1617..45e5bc5a61 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -411,6 +411,86 @@ mlx5dr_definer_ptype_frag_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, !!packet_type, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_compare_base_value_set(const void *item_spec, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint32_t *base = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_BASE_0]); + const struct rte_flow_item_compare *v = item_spec; + const struct rte_flow_field_data *a = &v->a; + const struct rte_flow_field_data *b = &v->b; + const uint32_t *value; + + value = (const uint32_t *)&b->value[0]; + + if (a->field == RTE_FLOW_FIELD_RANDOM) + *base = htobe32(*value << 16); + else + *base = htobe32(*value); + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); +} + +static void +mlx5dr_definer_compare_op_translate(enum rte_flow_item_compare_op op, + uint8_t *tag) +{ + uint32_t *ctrl = &(((uint32_t *)tag)[MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1]); + uint8_t operator = 0; + uint8_t inverse = 0; + + switch (op) { + case RTE_FLOW_ITEM_COMPARE_EQ: + operator = 2; + break; + case RTE_FLOW_ITEM_COMPARE_NE: + operator = 2; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LT: + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_LE: + operator = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GT: + operator = 1; + inverse = 1; + break; + case RTE_FLOW_ITEM_COMPARE_GE: + break; + default: + DR_LOG(ERR, "Invalid operation type %d", op); + assert(false); + } + + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, inverse0, inverse); + MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, operator0, operator); +} + +static void +mlx5dr_definer_compare_arg_set(const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_compare *v = item_spec; + enum rte_flow_item_compare_op op = v->operation; + + mlx5dr_definer_compare_op_translate(op, tag); +} + +static void +mlx5dr_definer_compare_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + if (fc->compare_idx == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + mlx5dr_definer_compare_arg_set(item_spec, tag); + if (fc->compare_set_base) + mlx5dr_definer_compare_base_value_set(item_spec, tag); + } +} + static void mlx5dr_definer_integrity_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -2782,10 +2862,124 @@ mlx5dr_definer_conv_item_vxlan_gpe(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +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_definer_compare_dw_selectors dw_offset) +{ + struct mlx5dr_definer_fc *fc = NULL; + int reg; + + if (f->offset) { + DR_LOG(ERR, "field offset %u is not supported, only offset zero supported", + f->offset); + goto err_notsup; + } + + switch (f->field) { + case RTE_FLOW_FIELD_META: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_META, -1); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare metadata field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_TAG: + reg = flow_hw_get_reg_id_from_ctx(cd->ctx, + RTE_FLOW_ITEM_TYPE_TAG, + f->tag_index); + if (reg <= 0) { + DR_LOG(ERR, "Invalid register for compare tag field"); + rte_errno = EINVAL; + return rte_errno; + } + + fc = mlx5dr_definer_get_register_fc(cd, reg); + if (!fc) + return rte_errno; + + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + break; + case RTE_FLOW_FIELD_VALUE: + if (dw_offset == MLX5DR_DEFINER_COMPARE_ARGUMENT_0) { + DR_LOG(ERR, "Argument field does not support immediate value"); + goto err_notsup; + } + break; + case RTE_FLOW_FIELD_RANDOM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_RANDOM_NUM]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, random_number, random_number); + break; + default: + DR_LOG(ERR, "%u field is not supported", f->field); + goto err_notsup; + } + + if (fc && other_f && other_f->field == RTE_FLOW_FIELD_VALUE) + fc->compare_set_base = true; + + return 0; + +err_notsup: + rte_errno = ENOTSUP; + return rte_errno; +} + +static int +mlx5dr_definer_conv_item_compare(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_compare *m = item->mask; + const struct rte_flow_field_data *a = &m->a; + const struct rte_flow_field_data *b = &m->b; + int ret; + + if (m->width != 0xffffffff) { + DR_LOG(ERR, "compare item width of 0x%x is not supported, only full DW supported", + m->width); + rte_errno = ENOTSUP; + return rte_errno; + } + + ret = mlx5dr_definer_conv_item_compare_field(a, b, cd, item_idx, + MLX5DR_DEFINER_COMPARE_ARGUMENT_0); + if (ret) + return ret; + + ret = mlx5dr_definer_conv_item_compare_field(b, NULL, cd, item_idx, + MLX5DR_DEFINER_COMPARE_BASE_0); + if (ret) + return ret; + + return 0; +} + static int mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, struct mlx5dr_match_template *mt, - uint8_t *hl) + uint8_t *hl, + struct mlx5dr_matcher *matcher) { struct mlx5dr_definer_fc fc[MLX5DR_DEFINER_FNAME_MAX] = {{0}}; struct mlx5dr_definer_conv_data cd = {0}; @@ -2805,6 +2999,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, if (ret) return ret; + if (mlx5dr_matcher_is_compare(matcher)) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + switch ((int)items->type) { case RTE_FLOW_ITEM_TYPE_ETH: ret = mlx5dr_definer_conv_item_eth(&cd, items, i); @@ -2950,12 +3149,20 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_vxlan_gpe(&cd, items, i); item_flags |= MLX5_FLOW_LAYER_VXLAN_GPE; break; + case RTE_FLOW_ITEM_TYPE_COMPARE: + if (i) { + DR_LOG(ERR, "Compare matcher not supported for more than one item"); + goto not_supp; + } + ret = mlx5dr_definer_conv_item_compare(&cd, items, i); + item_flags |= MLX5_FLOW_ITEM_COMPARE; + matcher->flags |= MLX5DR_MATCHER_FLAGS_COMPARE; + break; case RTE_FLOW_ITEM_TYPE_VOID: break; default: DR_LOG(ERR, "Unsupported item type %d", items->type); - rte_errno = ENOTSUP; - return rte_errno; + goto not_supp; } cd.last_item = items->type; @@ -2976,6 +3183,10 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, } return 0; + +not_supp: + rte_errno = ENOTSUP; + return rte_errno; } static int @@ -3393,6 +3604,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, { struct mlx5dr_context *ctx = matcher->tbl->ctx; struct mlx5dr_match_template *mt = matcher->mt; + struct mlx5dr_definer_fc *fc; uint8_t *match_hl; int i, ret; @@ -3410,13 +3622,35 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, * and allocate the match and range field copy array (fc & fcr). */ for (i = 0; i < matcher->num_of_mt; i++) { - ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl); + ret = mlx5dr_definer_conv_items_to_hl(ctx, &mt[i], match_hl, matcher); if (ret) { DR_LOG(ERR, "Failed to convert items to header layout"); goto free_fc; } } + if (mlx5dr_matcher_is_compare(matcher)) { + ret = mlx5dr_matcher_validate_compare_attr(matcher); + if (ret) + goto free_fc; + + /* Due some HW limitation need to fill unused + * DW's 0-5 and byte selectors with 0xff. + */ + for (i = 0; i < DW_SELECTORS_MATCH; i++) + match_definer->dw_selector[i] = 0xff; + + for (i = 0; i < BYTE_SELECTORS; i++) + match_definer->byte_selector[i] = 0xff; + + for (i = 0; i < mt[0].fc_sz; i++) { + fc = &mt[0].fc[i]; + match_definer->dw_selector[fc->compare_idx] = fc->byte_off / DW_SIZE; + } + + goto out; + } + /* Find the match definer layout for header layout match union */ ret = mlx5dr_definer_find_best_match_fit(ctx, match_definer, match_hl); if (ret) { @@ -3437,6 +3671,7 @@ mlx5dr_definer_calc_layout(struct mlx5dr_matcher *matcher, goto free_fc; } +out: simple_free(match_hl); return 0; diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.h b/drivers/net/mlx5/hws/mlx5dr_definer.h index 71cc0e94de..ca530ebf30 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.h +++ b/drivers/net/mlx5/hws/mlx5dr_definer.h @@ -17,6 +17,37 @@ #define DW_SELECTORS_RANGE 2 #define BYTE_SELECTORS_RANGE 8 +enum mlx5dr_definer_compare_ste_dw_offset { + /* In compare STE the matching DW's starts after the 3 actions */ + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_1 = 3, + MLX5DR_DEFINER_COMPARE_STE_ARGUMENT_0, + MLX5DR_DEFINER_COMPARE_STE_BASE_1, + MLX5DR_DEFINER_COMPARE_STE_BASE_0, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_3, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_2, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_1, + MLX5DR_DEFINER_COMPARE_STE_TAG_DW_0, +}; + +enum mlx5dr_definer_dw_selectors { + MLX5DR_DEFINER_SELECTOR_DW0, + MLX5DR_DEFINER_SELECTOR_DW1, + MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_SELECTOR_DW3, + MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_SELECTOR_DW6, + MLX5DR_DEFINER_SELECTOR_DW7, + MLX5DR_DEFINER_SELECTOR_DW8, +}; + +enum mlx5dr_definer_compare_dw_selectors { + MLX5DR_DEFINER_COMPARE_ARGUMENT_0 = MLX5DR_DEFINER_SELECTOR_DW4, + MLX5DR_DEFINER_COMPARE_ARGUMENT_1 = MLX5DR_DEFINER_SELECTOR_DW5, + MLX5DR_DEFINER_COMPARE_BASE_0 = MLX5DR_DEFINER_SELECTOR_DW2, + MLX5DR_DEFINER_COMPARE_BASE_1 = MLX5DR_DEFINER_SELECTOR_DW3, +}; + enum mlx5dr_definer_fname { MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_O, MLX5DR_DEFINER_FNAME_ETH_SMAC_48_16_I, @@ -188,6 +219,8 @@ struct mlx5dr_definer_fc { uint8_t item_idx; uint8_t is_range; uint16_t extra_data; + uint8_t compare_idx; + bool compare_set_base; uint32_t byte_off; int bit_off; uint32_t bit_mask; diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.c b/drivers/net/mlx5/hws/mlx5dr_matcher.c index 402242308d..8a74a1ed7d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.c +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.c @@ -485,6 +485,7 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.log_depth = attr->table.sz_col_log; rtc_attr.is_frst_jumbo = mlx5dr_matcher_mt_is_jumbo(mt); rtc_attr.is_scnd_range = mlx5dr_matcher_mt_is_range(mt); + rtc_attr.is_compare = mlx5dr_matcher_is_compare(matcher); rtc_attr.miss_ft_id = matcher->end_ft->id; if (attr->insert_mode == MLX5DR_MATCHER_INSERT_BY_HASH) { @@ -497,6 +498,10 @@ static int mlx5dr_matcher_create_rtc(struct mlx5dr_matcher *matcher, rtc_attr.num_hash_definer = 1; rtc_attr.match_definer_0 = mlx5dr_definer_get_id(matcher->hash_definer); + } else if (mlx5dr_matcher_is_compare(matcher)) { + rtc_attr.match_definer_0 = ctx->caps->trivial_match_definer; + rtc_attr.fw_gen_wqe = true; + rtc_attr.num_hash_definer = 1; } else { /* The first mt is used since all share the same definer */ rtc_attr.match_definer_0 = mlx5dr_definer_get_id(mt->definer); @@ -1635,3 +1640,51 @@ int mlx5dr_matcher_resize_rule_move(struct mlx5dr_matcher *src_matcher, rte_errno = EINVAL; return -rte_errno; } + +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher) +{ + struct mlx5dr_cmd_query_caps *caps = matcher->tbl->ctx->caps; + struct mlx5dr_matcher_attr *attr = &matcher->attr; + + if (mlx5dr_table_is_root(matcher->tbl)) { + DR_LOG(ERR, "Compare matcher is not supported for root tables"); + goto err; + } + + if (attr->mode != MLX5DR_MATCHER_RESOURCE_MODE_HTABLE) { + DR_LOG(ERR, "Compare matcher is only supported with pre-defined table size"); + goto err; + } + + if (attr->insert_mode != MLX5DR_MATCHER_INSERT_BY_HASH || + attr->distribute_mode != MLX5DR_MATCHER_DISTRIBUTE_BY_HASH) { + DR_LOG(ERR, "Gen WQE for compare matcher must be inserted and distribute by hash"); + goto err; + } + + if (matcher->num_of_mt != 1 || matcher->num_of_at != 1) { + DR_LOG(ERR, "Compare matcher match templates and action templates must be 1 for each"); + goto err; + } + + if (attr->table.sz_col_log || attr->table.sz_row_log) { + DR_LOG(ERR, "Compare matcher supports only 1x1 table size"); + goto err; + } + + if (attr->resizable) { + DR_LOG(ERR, "Compare matcher does not support resizeing"); + goto err; + } + + if (!IS_BIT_SET(caps->supp_ste_format_gen_wqe, MLX5_IFC_RTC_STE_FORMAT_4DW_RANGE)) { + DR_LOG(ERR, "Gen WQE Compare match format not supported"); + goto err; + } + + return 0; + +err: + rte_errno = ENOTSUP; + return rte_errno; +} diff --git a/drivers/net/mlx5/hws/mlx5dr_matcher.h b/drivers/net/mlx5/hws/mlx5dr_matcher.h index 0f2bf96e8b..6dc3bf4d0d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_matcher.h +++ b/drivers/net/mlx5/hws/mlx5dr_matcher.h @@ -27,6 +27,7 @@ enum mlx5dr_matcher_flags { MLX5DR_MATCHER_FLAGS_HASH_DEFINER = 1 << 1, MLX5DR_MATCHER_FLAGS_COLLISION = 1 << 2, MLX5DR_MATCHER_FLAGS_RESIZABLE = 1 << 3, + MLX5DR_MATCHER_FLAGS_COMPARE = 1 << 4, }; struct mlx5dr_match_template { @@ -110,12 +111,19 @@ static inline bool mlx5dr_matcher_is_in_resize(struct mlx5dr_matcher *matcher) return !!matcher->resize_dst; } +static inline bool +mlx5dr_matcher_is_compare(struct mlx5dr_matcher *matcher) +{ + return !!(matcher->flags & MLX5DR_MATCHER_FLAGS_COMPARE); +} + static inline bool mlx5dr_matcher_req_fw_wqe(struct mlx5dr_matcher *matcher) { /* Currently HWS doesn't support hash different from match or range */ return unlikely(matcher->flags & (MLX5DR_MATCHER_FLAGS_HASH_DEFINER | - MLX5DR_MATCHER_FLAGS_RANGE_DEFINER)); + MLX5DR_MATCHER_FLAGS_RANGE_DEFINER | + MLX5DR_MATCHER_FLAGS_COMPARE)); } int mlx5dr_matcher_conv_items_to_prm(uint64_t *match_buf, @@ -141,4 +149,6 @@ int mlx5dr_matcher_free_rtc_pointing(struct mlx5dr_context *ctx, enum mlx5dr_table_type type, struct mlx5dr_devx_obj *devx_obj); +int mlx5dr_matcher_validate_compare_attr(struct mlx5dr_matcher *matcher); + #endif /* MLX5DR_MATCHER_H_ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v7 2/3] net/mlx5: add support to compare random value 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum 2024-02-26 13:18 ` [PATCH v7 1/3] net/mlx5/hws: add support for compare matcher Michael Baum @ 2024-02-26 13:18 ` Michael Baum 2024-02-26 13:18 ` [PATCH v7 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum 2024-02-27 9:08 ` [PATCH v7 0/3] net/mlx5: add compare item support Raslan Darawsheh 3 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:18 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support to use "RTE_FLOW_ITEM_TYPE_COMPARE" with "RTE_FLOW_FIELD_RAMDOM" as an argument. The random field is supported only when base is an immediate value, random field cannot be compared with enother field. Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> --- doc/guides/nics/mlx5.rst | 9 ++++- drivers/net/mlx5/mlx5_flow_hw.c | 70 ++++++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 0d2213497a..c0a5768117 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -431,8 +431,13 @@ Limitations - Only supported in HW steering(``dv_flow_en`` = 2) mode. - Only single flow is supported to the flow table. - - Only 32-bit comparison is supported. - - Only match with compare result between packet fields is supported. + - Only single item is supported per pattern template. + - Only 32-bit comparison is supported or 16-bits for random field. + - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. + - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. + - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with + ``RTE_FLOW_FIELD_VALUE``. - No Tx metadata go to the E-Switch steering domain for the Flow group 0. The flows within group 0 and set metadata action are rejected by hardware. diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index 3ae1220587..f31ba2df2b 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6721,18 +6721,55 @@ flow_hw_prepend_item(const struct rte_flow_item *items, return copied_items; } -static inline bool -flow_hw_item_compare_field_supported(enum rte_flow_field_id field) +static int +flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, + enum rte_flow_field_id base_field, + struct rte_flow_error *error) { - switch (field) { + switch (arg_field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + break; + case RTE_FLOW_FIELD_RANDOM: + if (base_field == RTE_FLOW_FIELD_VALUE) + return 0; + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare random is supported only with immediate value"); + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item argument field is not supported"); + } + switch (base_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: - return true; + break; + default: + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, + "compare item base field is not supported"); + } + return 0; +} + +static inline uint32_t +flow_hw_item_compare_width_supported(enum rte_flow_field_id field) +{ + switch (field) { + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: + return 32; + case RTE_FLOW_FIELD_RANDOM: + return 16; default: break; } - return false; + return 0; } static int @@ -6741,6 +6778,7 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, { const struct rte_flow_item_compare *comp_m = item->mask; const struct rte_flow_item_compare *comp_v = item->spec; + int ret; if (unlikely(!comp_m)) return rte_flow_error_set(error, EINVAL, @@ -6752,19 +6790,13 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item only support full mask"); - if (!flow_hw_item_compare_field_supported(comp_m->a.field) || - !flow_hw_item_compare_field_supported(comp_m->b.field)) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare item field not support"); - if (comp_m->a.field == RTE_FLOW_FIELD_VALUE && - comp_m->b.field == RTE_FLOW_FIELD_VALUE) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, - NULL, - "compare between value is not valid"); + ret = flow_hw_item_compare_field_validate(comp_m->a.field, + comp_m->b.field, error); + if (ret < 0) + return ret; if (comp_v) { + uint32_t width; + if (comp_v->operation != comp_m->operation || comp_v->a.field != comp_m->a.field || comp_v->b.field != comp_m->b.field) @@ -6772,7 +6804,9 @@ flow_hw_validate_item_compare(const struct rte_flow_item *item, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "compare item spec/mask not matching"); - if ((comp_v->width & comp_m->width) != 32) + width = flow_hw_item_compare_width_supported(comp_v->a.field); + MLX5_ASSERT(width > 0); + if ((comp_v->width & comp_m->width) != width) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH v7 3/3] net/mlx5/hws: add compare ESP sequence number support 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum 2024-02-26 13:18 ` [PATCH v7 1/3] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-26 13:18 ` [PATCH v7 2/3] net/mlx5: add support to compare random value Michael Baum @ 2024-02-26 13:18 ` Michael Baum 2024-02-27 9:08 ` [PATCH v7 0/3] net/mlx5: add compare item support Raslan Darawsheh 3 siblings, 0 replies; 30+ messages in thread From: Michael Baum @ 2024-02-26 13:18 UTC (permalink / raw) To: dev Cc: Matan Azrad, Dariusz Sosnowski, Raslan Darawsheh, Viacheslav Ovsiienko, Ori Kam, Suanming Mou Add support for compare item with "RTE_FLOW_FIELD_ESP_SEQ_NUM" field. Signed-off-by: Michael Baum <michaelba@nvidia.com> Acked-by: Suanming Mou <suanmingm@nvidia.com> --- doc/guides/nics/mlx5.rst | 1 + drivers/net/mlx5/hws/mlx5dr_definer.c | 22 ++++++++++++++++++++-- drivers/net/mlx5/mlx5_flow_hw.c | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index c0a5768117..d7bf81161e 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -434,6 +434,7 @@ Limitations - Only single item is supported per pattern template. - Only 32-bit comparison is supported or 16-bits for random field. - Only supported for ``RTE_FLOW_FIELD_META``, ``RTE_FLOW_FIELD_TAG``, + ``RTE_FLOW_FIELD_ESP_SEQ_NUM``, ``RTE_FLOW_FIELD_RANDOM`` and ``RTE_FLOW_FIELD_VALUE``. - The field type ``RTE_FLOW_FIELD_VALUE`` must be the base (``b``) field. - The field type ``RTE_FLOW_FIELD_RANDOM`` can only be compared with diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 45e5bc5a61..c1508e6b53 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -424,10 +424,20 @@ mlx5dr_definer_compare_base_value_set(const void *item_spec, value = (const uint32_t *)&b->value[0]; - if (a->field == RTE_FLOW_FIELD_RANDOM) + switch (a->field) { + case RTE_FLOW_FIELD_RANDOM: *base = htobe32(*value << 16); - else + break; + case RTE_FLOW_FIELD_TAG: + case RTE_FLOW_FIELD_META: *base = htobe32(*value); + break; + case RTE_FLOW_FIELD_ESP_SEQ_NUM: + *base = *value; + break; + default: + break; + } MLX5_SET(ste_match_4dw_range_ctrl_dw, ctrl, base0, 1); } @@ -2930,6 +2940,14 @@ mlx5dr_definer_conv_item_compare_field(const struct rte_flow_field_data *f, fc->compare_idx = dw_offset; DR_CALC_SET_HDR(fc, random_number, random_number); break; + case RTE_FLOW_FIELD_ESP_SEQ_NUM: + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ESP_SEQUENCE_NUMBER]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_compare_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + fc->compare_idx = dw_offset; + DR_CALC_SET_HDR(fc, ipsec, sequence_number); + break; default: DR_LOG(ERR, "%u field is not supported", f->field); goto err_notsup; diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c index f31ba2df2b..531c90e0ee 100644 --- a/drivers/net/mlx5/mlx5_flow_hw.c +++ b/drivers/net/mlx5/mlx5_flow_hw.c @@ -6729,6 +6729,7 @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, switch (arg_field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: break; case RTE_FLOW_FIELD_RANDOM: if (base_field == RTE_FLOW_FIELD_VALUE) @@ -6747,6 +6748,7 @@ flow_hw_item_compare_field_validate(enum rte_flow_field_id arg_field, case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: case RTE_FLOW_FIELD_VALUE: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: break; default: return rte_flow_error_set(error, ENOTSUP, @@ -6763,6 +6765,7 @@ flow_hw_item_compare_width_supported(enum rte_flow_field_id field) switch (field) { case RTE_FLOW_FIELD_TAG: case RTE_FLOW_FIELD_META: + case RTE_FLOW_FIELD_ESP_SEQ_NUM: return 32; case RTE_FLOW_FIELD_RANDOM: return 16; -- 2.25.1 ^ permalink raw reply [flat|nested] 30+ messages in thread
* RE: [PATCH v7 0/3] net/mlx5: add compare item support 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum ` (2 preceding siblings ...) 2024-02-26 13:18 ` [PATCH v7 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum @ 2024-02-27 9:08 ` Raslan Darawsheh 3 siblings, 0 replies; 30+ messages in thread From: Raslan Darawsheh @ 2024-02-27 9:08 UTC (permalink / raw) To: Michael Baum, dev Cc: Matan Azrad, Dariusz Sosnowski, Slava Ovsiienko, Ori Kam, Suanming Mou Hi, > -----Original Message----- > From: Michael Baum <michaelba@nvidia.com> > Sent: Monday, February 26, 2024 3:19 PM > To: dev@dpdk.org > Cc: Matan Azrad <matan@nvidia.com>; Dariusz Sosnowski > <dsosnowski@nvidia.com>; Raslan Darawsheh <rasland@nvidia.com>; Slava > Ovsiienko <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; > Suanming Mou <suanmingm@nvidia.com> > Subject: [PATCH v7 0/3] net/mlx5: add compare item support > > Add HWS support for compare item with: > - "RTE_FLOW_FIELD_TAG". > - "RTE_FLOW_FIELD_NETA". > - "RTE_FLOW_FIELD_VALUE". > > Add HWS + PMD support for compare item with: > - "RTE_FLOW_FIELD_RANDOM". > - "RTE_FLOW_FIELD_ESP_SEQ_NUM". > > v2: > - Rebase. > - Add "RTE_FLOW_FIELD_META" compare support. > - Reduce the "Depends-on" list. > > v3: > - Rebase. > - Fix typo in function name, r/tranlate/translate. > - Fix adding a line without newline at end of file. > > v4: > - Rebase. > - Update documentation. > - Remove the "Depends-on" label. > > v5: > - Rebase. > - Add ESP sequence number suppoert and rename the series accordingly. > > v6: > - Rebase. > - Add "Acked-by" from v5. > > v7: > - Rebase. > > Hamdan Igbaria (1): > net/mlx5/hws: add support for compare matcher > > Michael Baum (2): > net/mlx5: add support to compare random value > net/mlx5/hws: add compare ESP sequence number support > > doc/guides/nics/mlx5.rst | 10 +- > drivers/common/mlx5/mlx5_prm.h | 16 ++ > drivers/net/mlx5/hws/mlx5dr_cmd.c | 9 +- > drivers/net/mlx5/hws/mlx5dr_cmd.h | 1 + > drivers/net/mlx5/hws/mlx5dr_debug.c | 4 +- > drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + > drivers/net/mlx5/hws/mlx5dr_definer.c | 261 > +++++++++++++++++++++++++- drivers/net/mlx5/hws/mlx5dr_definer.h | > 33 ++++ drivers/net/mlx5/hws/mlx5dr_matcher.c | 53 ++++++ > drivers/net/mlx5/hws/mlx5dr_matcher.h | 12 +- > drivers/net/mlx5/mlx5_flow_hw.c | 73 +++++-- > 11 files changed, 444 insertions(+), 29 deletions(-) > > -- > 2.25.1 Series applied to next-net-mlx, Kindest regards Raslan Darawsheh ^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2024-02-27 9:08 UTC | newest] Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-12-25 10:45 [PATCH v1 0/2] net/mlx5: add random compare support Michael Baum 2023-12-25 10:45 ` [PATCH v1 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2023-12-25 10:45 ` [PATCH v1 2/2] net/mlx5: add support to compare random value Michael Baum 2024-01-28 10:22 ` [PATCH v2 0/2] net/mlx5: add random compare support Michael Baum 2024-01-28 10:22 ` [PATCH v2 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2024-01-28 10:22 ` [PATCH v2 2/2] net/mlx5: add support to compare random value Michael Baum 2024-01-29 13:44 ` [PATCH v3 0/2] net/mlx5: add random compare support Michael Baum 2024-01-29 13:44 ` [PATCH v3 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2024-01-29 13:44 ` [PATCH v3 2/2] net/mlx5: add support to compare random value Michael Baum 2024-02-07 16:14 ` [PATCH v4 0/2] net/mlx5: add random compare support Michael Baum 2024-02-07 16:14 ` [PATCH v4 1/2] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-07 16:14 ` [PATCH v4 2/2] net/mlx5: add support to compare random value Michael Baum 2024-02-14 7:30 ` [PATCH v5 0/3] net/mlx5: add compare item support Michael Baum 2024-02-14 7:30 ` [PATCH v5 1/3] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-19 3:00 ` Suanming Mou 2024-02-14 7:30 ` [PATCH v5 2/3] net/mlx5: add support to compare random value Michael Baum 2024-02-19 3:00 ` Suanming Mou 2024-02-14 7:30 ` [PATCH v5 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum 2024-02-19 2:59 ` Suanming Mou 2024-02-19 7:21 ` Michael Baum 2024-02-19 7:37 ` Suanming Mou 2024-02-26 13:03 ` [PATCH v6 0/3] net/mlx5: add compare item support Michael Baum 2024-02-26 13:03 ` [PATCH v6 1/3] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-26 13:03 ` [PATCH v6 2/3] net/mlx5: add support to compare random value Michael Baum 2024-02-26 13:03 ` [PATCH v6 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum 2024-02-26 13:18 ` [PATCH v7 0/3] net/mlx5: add compare item support Michael Baum 2024-02-26 13:18 ` [PATCH v7 1/3] net/mlx5/hws: add support for compare matcher Michael Baum 2024-02-26 13:18 ` [PATCH v7 2/3] net/mlx5: add support to compare random value Michael Baum 2024-02-26 13:18 ` [PATCH v7 3/3] net/mlx5/hws: add compare ESP sequence number support Michael Baum 2024-02-27 9:08 ` [PATCH v7 0/3] net/mlx5: add compare item support Raslan Darawsheh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).