diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/steering')
9 files changed, 248 insertions, 232 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c index b74b7d0f6590..004c56c2fc0c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c @@ -1577,6 +1577,7 @@ int mlx5dr_action_destroy(struct mlx5dr_action *action) break; case DR_ACTION_TYP_MODIFY_HDR: mlx5dr_icm_free_chunk(action->rewrite.chunk); + kfree(action->rewrite.data); refcount_dec(&action->rewrite.dmn->refcount); break; default: diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_crc32.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_crc32.c deleted file mode 100644 index 9e2eccbb1eb8..000000000000 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_crc32.c +++ /dev/null @@ -1,98 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB -/* Copyright (c) 2019 Mellanox Technologies. */ - -/* Copyright (c) 2011-2015 Stephan Brumme. All rights reserved. - * Slicing-by-16 contributed by Bulat Ziganshin - * - * This software is provided 'as-is', without any express or implied warranty. - * In no event will the author be held liable for any damages arising from the - * of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. - * 2. If you use this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * 3. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * - * Taken from http://create.stephan-brumme.com/crc32/ and adapted. - */ - -#include "dr_types.h" - -#define DR_STE_CRC_POLY 0xEDB88320L - -static u32 dr_ste_crc_tab32[8][256]; - -static void dr_crc32_calc_lookup_entry(u32 (*tbl)[256], u8 i, u8 j) -{ - tbl[i][j] = (tbl[i - 1][j] >> 8) ^ tbl[0][tbl[i - 1][j] & 0xff]; -} - -void mlx5dr_crc32_init_table(void) -{ - u32 crc, i, j; - - for (i = 0; i < 256; i++) { - crc = i; - for (j = 0; j < 8; j++) { - if (crc & 0x00000001L) - crc = (crc >> 1) ^ DR_STE_CRC_POLY; - else - crc = crc >> 1; - } - dr_ste_crc_tab32[0][i] = crc; - } - - /* Init CRC lookup tables according to crc_slice_8 algorithm */ - for (i = 0; i < 256; i++) { - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 1, i); - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 2, i); - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 3, i); - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 4, i); - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 5, i); - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 6, i); - dr_crc32_calc_lookup_entry(dr_ste_crc_tab32, 7, i); - } -} - -/* Compute CRC32 (Slicing-by-8 algorithm) */ -u32 mlx5dr_crc32_slice8_calc(const void *input_data, size_t length) -{ - const u32 *curr = (const u32 *)input_data; - const u8 *curr_char; - u32 crc = 0, one, two; - - if (!input_data) - return 0; - - /* Process eight bytes at once (Slicing-by-8) */ - while (length >= 8) { - one = *curr++ ^ crc; - two = *curr++; - - crc = dr_ste_crc_tab32[0][(two >> 24) & 0xff] - ^ dr_ste_crc_tab32[1][(two >> 16) & 0xff] - ^ dr_ste_crc_tab32[2][(two >> 8) & 0xff] - ^ dr_ste_crc_tab32[3][two & 0xff] - ^ dr_ste_crc_tab32[4][(one >> 24) & 0xff] - ^ dr_ste_crc_tab32[5][(one >> 16) & 0xff] - ^ dr_ste_crc_tab32[6][(one >> 8) & 0xff] - ^ dr_ste_crc_tab32[7][one & 0xff]; - - length -= 8; - } - - curr_char = (const u8 *)curr; - /* Remaining 1 to 7 bytes (standard algorithm) */ - while (length-- != 0) - crc = (crc >> 8) ^ dr_ste_crc_tab32[0][(crc & 0xff) - ^ *curr_char++]; - - return ((crc >> 24) & 0xff) | ((crc << 8) & 0xff0000) | - ((crc >> 8) & 0xff00) | ((crc << 24) & 0xff000000); -} diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c index 5b24732b18c0..a9da961d4d2f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c @@ -326,9 +326,6 @@ mlx5dr_domain_create(struct mlx5_core_dev *mdev, enum mlx5dr_domain_type type) goto uninit_resourses; } - /* Init CRC table for htbl CRC calculation */ - mlx5dr_crc32_init_table(); - return dmn; uninit_resourses: diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c index 67dea7698fc9..c6dbd856df94 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c @@ -102,13 +102,52 @@ static bool dr_mask_is_gre_set(struct mlx5dr_match_misc *misc) DR_MASK_IS_OUTER_MPLS_OVER_GRE_UDP_SET((_misc2), gre) || \ DR_MASK_IS_OUTER_MPLS_OVER_GRE_UDP_SET((_misc2), udp)) -static bool dr_mask_is_flex_parser_tnl_set(struct mlx5dr_match_misc3 *misc3) +static bool +dr_mask_is_misc3_vxlan_gpe_set(struct mlx5dr_match_misc3 *misc3) { return (misc3->outer_vxlan_gpe_vni || misc3->outer_vxlan_gpe_next_protocol || misc3->outer_vxlan_gpe_flags); } +static bool +dr_matcher_supp_flex_parser_vxlan_gpe(struct mlx5dr_cmd_caps *caps) +{ + return caps->flex_protocols & + MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED; +} + +static bool +dr_mask_is_flex_parser_tnl_vxlan_gpe_set(struct mlx5dr_match_param *mask, + struct mlx5dr_domain *dmn) +{ + return dr_mask_is_misc3_vxlan_gpe_set(&mask->misc3) && + dr_matcher_supp_flex_parser_vxlan_gpe(&dmn->info.caps); +} + +static bool dr_mask_is_misc_geneve_set(struct mlx5dr_match_misc *misc) +{ + return misc->geneve_vni || + misc->geneve_oam || + misc->geneve_protocol_type || + misc->geneve_opt_len; +} + +static bool +dr_matcher_supp_flex_parser_geneve(struct mlx5dr_cmd_caps *caps) +{ + return caps->flex_protocols & + MLX5_FLEX_PARSER_GENEVE_ENABLED; +} + +static bool +dr_mask_is_flex_parser_tnl_geneve_set(struct mlx5dr_match_param *mask, + struct mlx5dr_domain *dmn) +{ + return dr_mask_is_misc_geneve_set(&mask->misc) && + dr_matcher_supp_flex_parser_geneve(&dmn->info.caps); +} + static bool dr_mask_is_flex_parser_icmpv6_set(struct mlx5dr_match_misc3 *misc3) { return (misc3->icmpv6_type || misc3->icmpv6_code || @@ -137,24 +176,15 @@ static bool dr_mask_is_gvmi_or_qpn_set(struct mlx5dr_match_misc *misc) return (misc->source_sqn || misc->source_port); } -static bool -dr_matcher_supp_flex_parser_vxlan_gpe(struct mlx5dr_domain *dmn) -{ - return dmn->info.caps.flex_protocols & - MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED; -} - int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher, struct mlx5dr_matcher_rx_tx *nic_matcher, - bool ipv6) + enum mlx5dr_ipv outer_ipv, + enum mlx5dr_ipv inner_ipv) { - if (ipv6) { - nic_matcher->ste_builder = nic_matcher->ste_builder6; - nic_matcher->num_of_builders = nic_matcher->num_of_builders6; - } else { - nic_matcher->ste_builder = nic_matcher->ste_builder4; - nic_matcher->num_of_builders = nic_matcher->num_of_builders4; - } + nic_matcher->ste_builder = + nic_matcher->ste_builder_arr[outer_ipv][inner_ipv]; + nic_matcher->num_of_builders = + nic_matcher->num_of_builders_arr[outer_ipv][inner_ipv]; if (!nic_matcher->num_of_builders) { mlx5dr_dbg(matcher->tbl->dmn, @@ -167,26 +197,19 @@ int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher, static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, struct mlx5dr_matcher_rx_tx *nic_matcher, - bool ipv6) + enum mlx5dr_ipv outer_ipv, + enum mlx5dr_ipv inner_ipv) { struct mlx5dr_domain_rx_tx *nic_dmn = nic_matcher->nic_tbl->nic_dmn; struct mlx5dr_domain *dmn = matcher->tbl->dmn; struct mlx5dr_match_param mask = {}; struct mlx5dr_match_misc3 *misc3; struct mlx5dr_ste_build *sb; - u8 *num_of_builders; bool inner, rx; int idx = 0; int ret, i; - if (ipv6) { - sb = nic_matcher->ste_builder6; - num_of_builders = &nic_matcher->num_of_builders6; - } else { - sb = nic_matcher->ste_builder4; - num_of_builders = &nic_matcher->num_of_builders4; - } - + sb = nic_matcher->ste_builder_arr[outer_ipv][inner_ipv]; rx = nic_dmn->ste_type == MLX5DR_STE_TYPE_RX; /* Create a temporary mask to track and clear used mask fields */ @@ -249,7 +272,7 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, if (DR_MASK_IS_L2_DST(mask.outer, mask.misc, outer)) mlx5dr_ste_build_eth_l2_dst(&sb[idx++], &mask, inner, rx); - if (ipv6) { + if (outer_ipv == DR_RULE_IPV6) { if (dr_mask_is_dst_addr_set(&mask.outer)) mlx5dr_ste_build_eth_l3_ipv6_dst(&sb[idx++], &mask, inner, rx); @@ -271,10 +294,14 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, inner, rx); } - if (dr_mask_is_flex_parser_tnl_set(&mask.misc3) && - dr_matcher_supp_flex_parser_vxlan_gpe(dmn)) - mlx5dr_ste_build_flex_parser_tnl(&sb[idx++], &mask, - inner, rx); + if (dr_mask_is_flex_parser_tnl_vxlan_gpe_set(&mask, dmn)) + mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(&sb[idx++], + &mask, + inner, rx); + else if (dr_mask_is_flex_parser_tnl_geneve_set(&mask, dmn)) + mlx5dr_ste_build_flex_parser_tnl_geneve(&sb[idx++], + &mask, + inner, rx); if (DR_MASK_IS_ETH_L4_MISC_SET(mask.misc3, outer)) mlx5dr_ste_build_eth_l4_misc(&sb[idx++], &mask, inner, rx); @@ -325,7 +352,7 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, if (DR_MASK_IS_L2_DST(mask.inner, mask.misc, inner)) mlx5dr_ste_build_eth_l2_dst(&sb[idx++], &mask, inner, rx); - if (ipv6) { + if (inner_ipv == DR_RULE_IPV6) { if (dr_mask_is_dst_addr_set(&mask.inner)) mlx5dr_ste_build_eth_l3_ipv6_dst(&sb[idx++], &mask, inner, rx); @@ -373,7 +400,8 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, } } - *num_of_builders = idx; + nic_matcher->ste_builder = sb; + nic_matcher->num_of_builders_arr[outer_ipv][inner_ipv] = idx; return 0; } @@ -524,24 +552,33 @@ static void dr_matcher_uninit(struct mlx5dr_matcher *matcher) } } -static int dr_matcher_init_nic(struct mlx5dr_matcher *matcher, - struct mlx5dr_matcher_rx_tx *nic_matcher) +static int dr_matcher_set_all_ste_builders(struct mlx5dr_matcher *matcher, + struct mlx5dr_matcher_rx_tx *nic_matcher) { struct mlx5dr_domain *dmn = matcher->tbl->dmn; - int ret, ret_v4, ret_v6; - ret_v4 = dr_matcher_set_ste_builders(matcher, nic_matcher, false); - ret_v6 = dr_matcher_set_ste_builders(matcher, nic_matcher, true); + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV4, DR_RULE_IPV4); + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV4, DR_RULE_IPV6); + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV6, DR_RULE_IPV4); + dr_matcher_set_ste_builders(matcher, nic_matcher, DR_RULE_IPV6, DR_RULE_IPV6); - if (ret_v4 && ret_v6) { + if (!nic_matcher->ste_builder) { mlx5dr_dbg(dmn, "Cannot generate IPv4 or IPv6 rules with given mask\n"); return -EINVAL; } - if (!ret_v4) - nic_matcher->ste_builder = nic_matcher->ste_builder4; - else - nic_matcher->ste_builder = nic_matcher->ste_builder6; + return 0; +} + +static int dr_matcher_init_nic(struct mlx5dr_matcher *matcher, + struct mlx5dr_matcher_rx_tx *nic_matcher) +{ + struct mlx5dr_domain *dmn = matcher->tbl->dmn; + int ret; + + ret = dr_matcher_set_all_ste_builders(matcher, nic_matcher); + if (ret) + return ret; nic_matcher->e_anchor = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool, DR_CHUNK_SIZE_1, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c index 4187f2b112b8..32e94d2ee5e4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c @@ -595,6 +595,18 @@ static void dr_rule_clean_rule_members(struct mlx5dr_rule *rule, } } +static u16 dr_get_bits_per_mask(u16 byte_mask) +{ + u16 bits = 0; + + while (byte_mask) { + byte_mask = byte_mask & (byte_mask - 1); + bits++; + } + + return bits; +} + static bool dr_rule_need_enlarge_hash(struct mlx5dr_ste_htbl *htbl, struct mlx5dr_domain *dmn, struct mlx5dr_domain_rx_tx *nic_dmn) @@ -607,6 +619,9 @@ static bool dr_rule_need_enlarge_hash(struct mlx5dr_ste_htbl *htbl, if (!ctrl->may_grow) return false; + if (dr_get_bits_per_mask(htbl->byte_mask) * BITS_PER_BYTE <= htbl->chunk_size) + return false; + if (ctrl->num_of_collisions >= ctrl->increase_threshold && (ctrl->num_of_valid_entries - ctrl->num_of_collisions) >= ctrl->increase_threshold) return true; @@ -788,12 +803,10 @@ again: * it means that all the previous stes are the same, * if so, this rule is duplicated. */ - if (mlx5dr_ste_is_last_in_rule(nic_matcher, - matched_ste->ste_chain_location)) { - mlx5dr_info(dmn, "Duplicate rule inserted, aborting!!\n"); - return NULL; - } - return matched_ste; + if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste_location)) + return matched_ste; + + mlx5dr_dbg(dmn, "Duplicate rule inserted\n"); } if (!skip_rehash && dr_rule_need_enlarge_hash(cur_htbl, dmn, nic_dmn)) { @@ -956,12 +969,12 @@ static int dr_rule_destroy_rule(struct mlx5dr_rule *rule) return 0; } -static bool dr_rule_is_ipv6(struct mlx5dr_match_param *param) +static enum mlx5dr_ipv dr_rule_get_ipv(struct mlx5dr_match_spec *spec) { - return (param->outer.ip_version == 6 || - param->inner.ip_version == 6 || - param->outer.ethertype == ETH_P_IPV6 || - param->inner.ethertype == ETH_P_IPV6); + if (spec->ip_version == 6 || spec->ethertype == ETH_P_IPV6) + return DR_RULE_IPV6; + + return DR_RULE_IPV4; } static bool dr_rule_skip(enum mlx5dr_domain_type domain, @@ -1025,7 +1038,8 @@ dr_rule_create_rule_nic(struct mlx5dr_rule *rule, ret = mlx5dr_matcher_select_builders(matcher, nic_matcher, - dr_rule_is_ipv6(param)); + dr_rule_get_ipv(¶m->outer), + dr_rule_get_ipv(¶m->inner)); if (ret) goto out_err; @@ -1098,6 +1112,8 @@ dr_rule_create_rule_nic(struct mlx5dr_rule *rule, if (htbl) mlx5dr_htbl_put(htbl); + kfree(hw_ste_arr); + return 0; free_ste: diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c index 5df8436b2ae3..51803eef13dd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c @@ -700,6 +700,7 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, unsigned int irqn; void *cqc, *in; __be64 *pas; + int vector; u32 i; cq = kzalloc(sizeof(*cq), GFP_KERNEL); @@ -728,7 +729,8 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, if (!in) goto err_cqwq; - err = mlx5_vector2eqn(mdev, smp_processor_id(), &eqn, &irqn); + vector = smp_processor_id() % mlx5_comp_vectors_count(mdev); + err = mlx5_vector2eqn(mdev, vector, &eqn, &irqn); if (err) { kvfree(in); goto err_cqwq; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c index 4efe1b0be4a8..a5a266983dd3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c @@ -2,6 +2,7 @@ /* Copyright (c) 2019 Mellanox Technologies. */ #include <linux/types.h> +#include <linux/crc32.h> #include "dr_types.h" #define DR_STE_CRC_POLY 0xEDB88320L @@ -107,6 +108,13 @@ struct dr_hw_ste_format { u8 mask[DR_STE_SIZE_MASK]; }; +static u32 dr_ste_crc32_calc(const void *input_data, size_t length) +{ + u32 crc = crc32(0, input_data, length); + + return htonl(crc); +} + u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl) { struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p; @@ -128,7 +136,7 @@ u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl) bit = bit >> 1; } - crc32 = mlx5dr_crc32_slice8_calc(masked, DR_STE_SIZE_TAG); + crc32 = dr_ste_crc32_calc(masked, DR_STE_SIZE_TAG); index = crc32 & (htbl->chunk->num_of_entries - 1); return index; @@ -560,18 +568,6 @@ bool mlx5dr_ste_not_used_ste(struct mlx5dr_ste *ste) return !refcount_read(&ste->refcount); } -static u16 get_bits_per_mask(u16 byte_mask) -{ - u16 bits = 0; - - while (byte_mask) { - byte_mask = byte_mask & (byte_mask - 1); - bits++; - } - - return bits; -} - /* Init one ste as a pattern for ste data array */ void mlx5dr_ste_set_formatted_ste(u16 gvmi, struct mlx5dr_domain_rx_tx *nic_dmn, @@ -620,20 +616,12 @@ int mlx5dr_ste_create_next_htbl(struct mlx5dr_matcher *matcher, struct mlx5dr_ste_htbl *next_htbl; if (!mlx5dr_ste_is_last_in_rule(nic_matcher, ste->ste_chain_location)) { - u32 bits_in_mask; u8 next_lu_type; u16 byte_mask; next_lu_type = MLX5_GET(ste_general, hw_ste, next_lu_type); byte_mask = MLX5_GET(ste_general, hw_ste, byte_mask); - /* Don't allocate table more than required, - * the size of the table defined via the byte_mask, so no need - * to allocate more than that. - */ - bits_in_mask = get_bits_per_mask(byte_mask) * BITS_PER_BYTE; - log_table_size = min(log_table_size, bits_in_mask); - next_htbl = mlx5dr_ste_htbl_alloc(dmn->ste_icm_pool, log_table_size, next_lu_type, @@ -671,7 +659,7 @@ static void dr_ste_set_ctrl(struct mlx5dr_ste_htbl *htbl) htbl->ctrl.may_grow = true; - if (htbl->chunk_size == DR_CHUNK_SIZE_MAX - 1) + if (htbl->chunk_size == DR_CHUNK_SIZE_MAX - 1 || !htbl->byte_mask) htbl->ctrl.may_grow = false; /* Threshold is 50%, one is added to table of size 1 */ @@ -2095,68 +2083,110 @@ void mlx5dr_ste_build_eth_l4_misc(struct mlx5dr_ste_build *sb, sb->ste_build_tag_func = &dr_ste_build_eth_l4_misc_tag; } -static void dr_ste_build_flex_parser_tnl_bit_mask(struct mlx5dr_match_param *value, - bool inner, u8 *bit_mask) +static void +dr_ste_build_flex_parser_tnl_vxlan_gpe_bit_mask(struct mlx5dr_match_param *value, + bool inner, u8 *bit_mask) { struct mlx5dr_match_misc3 *misc_3_mask = &value->misc3; - if (misc_3_mask->outer_vxlan_gpe_flags || - misc_3_mask->outer_vxlan_gpe_next_protocol) { - MLX5_SET(ste_flex_parser_tnl, bit_mask, - flex_parser_tunneling_header_63_32, - (misc_3_mask->outer_vxlan_gpe_flags << 24) | - (misc_3_mask->outer_vxlan_gpe_next_protocol)); - misc_3_mask->outer_vxlan_gpe_flags = 0; - misc_3_mask->outer_vxlan_gpe_next_protocol = 0; - } - - if (misc_3_mask->outer_vxlan_gpe_vni) { - MLX5_SET(ste_flex_parser_tnl, bit_mask, - flex_parser_tunneling_header_31_0, - misc_3_mask->outer_vxlan_gpe_vni << 8); - misc_3_mask->outer_vxlan_gpe_vni = 0; - } + DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask, + outer_vxlan_gpe_flags, + misc_3_mask, outer_vxlan_gpe_flags); + DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask, + outer_vxlan_gpe_next_protocol, + misc_3_mask, outer_vxlan_gpe_next_protocol); + DR_STE_SET_MASK_V(flex_parser_tnl_vxlan_gpe, bit_mask, + outer_vxlan_gpe_vni, + misc_3_mask, outer_vxlan_gpe_vni); } -static int dr_ste_build_flex_parser_tnl_tag(struct mlx5dr_match_param *value, - struct mlx5dr_ste_build *sb, - u8 *hw_ste_p) +static int +dr_ste_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, + struct mlx5dr_ste_build *sb, + u8 *hw_ste_p) { struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p; struct mlx5dr_match_misc3 *misc3 = &value->misc3; u8 *tag = hw_ste->tag; - if (misc3->outer_vxlan_gpe_flags || - misc3->outer_vxlan_gpe_next_protocol) { - MLX5_SET(ste_flex_parser_tnl, tag, - flex_parser_tunneling_header_63_32, - (misc3->outer_vxlan_gpe_flags << 24) | - (misc3->outer_vxlan_gpe_next_protocol)); - misc3->outer_vxlan_gpe_flags = 0; - misc3->outer_vxlan_gpe_next_protocol = 0; - } - - if (misc3->outer_vxlan_gpe_vni) { - MLX5_SET(ste_flex_parser_tnl, tag, - flex_parser_tunneling_header_31_0, - misc3->outer_vxlan_gpe_vni << 8); - misc3->outer_vxlan_gpe_vni = 0; - } + DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, + outer_vxlan_gpe_flags, misc3, + outer_vxlan_gpe_flags); + DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, + outer_vxlan_gpe_next_protocol, misc3, + outer_vxlan_gpe_next_protocol); + DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, + outer_vxlan_gpe_vni, misc3, + outer_vxlan_gpe_vni); return 0; } -void mlx5dr_ste_build_flex_parser_tnl(struct mlx5dr_ste_build *sb, - struct mlx5dr_match_param *mask, - bool inner, bool rx) +void mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(struct mlx5dr_ste_build *sb, + struct mlx5dr_match_param *mask, + bool inner, bool rx) +{ + dr_ste_build_flex_parser_tnl_vxlan_gpe_bit_mask(mask, inner, + sb->bit_mask); + + sb->rx = rx; + sb->inner = inner; + sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER; + sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask); + sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_vxlan_gpe_tag; +} + +static void +dr_ste_build_flex_parser_tnl_geneve_bit_mask(struct mlx5dr_match_param *value, + u8 *bit_mask) +{ + struct mlx5dr_match_misc *misc_mask = &value->misc; + + DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask, + geneve_protocol_type, + misc_mask, geneve_protocol_type); + DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask, + geneve_oam, + misc_mask, geneve_oam); + DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask, + geneve_opt_len, + misc_mask, geneve_opt_len); + DR_STE_SET_MASK_V(flex_parser_tnl_geneve, bit_mask, + geneve_vni, + misc_mask, geneve_vni); +} + +static int +dr_ste_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, + struct mlx5dr_ste_build *sb, + u8 *hw_ste_p) { - dr_ste_build_flex_parser_tnl_bit_mask(mask, inner, sb->bit_mask); + struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p; + struct mlx5dr_match_misc *misc = &value->misc; + u8 *tag = hw_ste->tag; + + DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, + geneve_protocol_type, misc, geneve_protocol_type); + DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, + geneve_oam, misc, geneve_oam); + DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, + geneve_opt_len, misc, geneve_opt_len); + DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, + geneve_vni, misc, geneve_vni); + + return 0; +} +void mlx5dr_ste_build_flex_parser_tnl_geneve(struct mlx5dr_ste_build *sb, + struct mlx5dr_match_param *mask, + bool inner, bool rx) +{ + dr_ste_build_flex_parser_tnl_geneve_bit_mask(mask, sb->bit_mask); sb->rx = rx; sb->inner = inner; sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER; sb->byte_mask = dr_ste_conv_bit_to_byte_mask(sb->bit_mask); - sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_tag; + sb->ste_build_tag_func = &dr_ste_build_flex_parser_tnl_geneve_tag; } static void dr_ste_build_register_0_bit_mask(struct mlx5dr_match_param *value, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h index 1cb3769d4e3c..290fe61c33d0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h @@ -106,6 +106,12 @@ enum mlx5dr_action_type { DR_ACTION_TYP_MAX, }; +enum mlx5dr_ipv { + DR_RULE_IPV4, + DR_RULE_IPV6, + DR_RULE_IPV_MAX, +}; + struct mlx5dr_icm_pool; struct mlx5dr_icm_chunk; struct mlx5dr_icm_bucket; @@ -319,9 +325,12 @@ int mlx5dr_ste_build_flex_parser_1(struct mlx5dr_ste_build *sb, struct mlx5dr_match_param *mask, struct mlx5dr_cmd_caps *caps, bool inner, bool rx); -void mlx5dr_ste_build_flex_parser_tnl(struct mlx5dr_ste_build *sb, - struct mlx5dr_match_param *mask, - bool inner, bool rx); +void mlx5dr_ste_build_flex_parser_tnl_vxlan_gpe(struct mlx5dr_ste_build *sb, + struct mlx5dr_match_param *mask, + bool inner, bool rx); +void mlx5dr_ste_build_flex_parser_tnl_geneve(struct mlx5dr_ste_build *sb, + struct mlx5dr_match_param *mask, + bool inner, bool rx); void mlx5dr_ste_build_general_purpose(struct mlx5dr_ste_build *sb, struct mlx5dr_match_param *mask, bool inner, bool rx); @@ -679,11 +688,11 @@ struct mlx5dr_matcher_rx_tx { struct mlx5dr_ste_htbl *s_htbl; struct mlx5dr_ste_htbl *e_anchor; struct mlx5dr_ste_build *ste_builder; - struct mlx5dr_ste_build ste_builder4[DR_RULE_MAX_STES]; - struct mlx5dr_ste_build ste_builder6[DR_RULE_MAX_STES]; + struct mlx5dr_ste_build ste_builder_arr[DR_RULE_IPV_MAX] + [DR_RULE_IPV_MAX] + [DR_RULE_MAX_STES]; u8 num_of_builders; - u8 num_of_builders4; - u8 num_of_builders6; + u8 num_of_builders_arr[DR_RULE_IPV_MAX][DR_RULE_IPV_MAX]; u64 default_icm_addr; struct mlx5dr_table_rx_tx *nic_tbl; }; @@ -812,7 +821,8 @@ mlx5dr_matcher_supp_flex_parser_icmp_v6(struct mlx5dr_cmd_caps *caps) int mlx5dr_matcher_select_builders(struct mlx5dr_matcher *matcher, struct mlx5dr_matcher_rx_tx *nic_matcher, - bool ipv6); + enum mlx5dr_ipv outer_ipv, + enum mlx5dr_ipv inner_ipv); static inline u32 mlx5dr_icm_pool_chunk_size_to_entries(enum mlx5dr_icm_chunk_size chunk_size) @@ -962,9 +972,6 @@ void mlx5dr_ste_copy_param(u8 match_criteria, struct mlx5dr_match_param *set_param, struct mlx5dr_match_parameters *mask); -void mlx5dr_crc32_init_table(void); -u32 mlx5dr_crc32_slice8_calc(const void *input_data, size_t length); - struct mlx5dr_qp { struct mlx5_core_dev *mdev; struct mlx5_wq_qp wq; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5_ifc_dr.h b/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5_ifc_dr.h index 596c927220d9..1722f4668269 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5_ifc_dr.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/mlx5_ifc_dr.h @@ -548,6 +548,30 @@ struct mlx5_ifc_ste_flex_parser_tnl_bits { u8 reserved_at_40[0x40]; }; +struct mlx5_ifc_ste_flex_parser_tnl_vxlan_gpe_bits { + u8 outer_vxlan_gpe_flags[0x8]; + u8 reserved_at_8[0x10]; + u8 outer_vxlan_gpe_next_protocol[0x8]; + + u8 outer_vxlan_gpe_vni[0x18]; + u8 reserved_at_38[0x8]; + + u8 reserved_at_40[0x40]; +}; + +struct mlx5_ifc_ste_flex_parser_tnl_geneve_bits { + u8 reserved_at_0[0x2]; + u8 geneve_opt_len[0x6]; + u8 geneve_oam[0x1]; + u8 reserved_at_9[0x7]; + u8 geneve_protocol_type[0x10]; + + u8 geneve_vni[0x18]; + u8 reserved_at_38[0x8]; + + u8 reserved_at_40[0x40]; +}; + struct mlx5_ifc_ste_general_purpose_bits { u8 general_purpose_lookup_field[0x20]; |