110b69418SYevgeny Kliteynik // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 210b69418SYevgeny Kliteynik /* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */ 310b69418SYevgeny Kliteynik 410b69418SYevgeny Kliteynik #include <linux/types.h> 510b69418SYevgeny Kliteynik #include "mlx5_ifc_dr_ste_v1.h" 610b69418SYevgeny Kliteynik #include "dr_ste.h" 710b69418SYevgeny Kliteynik 810b69418SYevgeny Kliteynik #define DR_STE_CALC_DFNR_TYPE(lookup_type, inner) \ 910b69418SYevgeny Kliteynik ((inner) ? DR_STE_V1_LU_TYPE_##lookup_type##_I : \ 1010b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_##lookup_type##_O) 1110b69418SYevgeny Kliteynik 1210b69418SYevgeny Kliteynik enum dr_ste_v1_entry_format { 1310b69418SYevgeny Kliteynik DR_STE_V1_TYPE_BWC_BYTE = 0x0, 1410b69418SYevgeny Kliteynik DR_STE_V1_TYPE_BWC_DW = 0x1, 1510b69418SYevgeny Kliteynik DR_STE_V1_TYPE_MATCH = 0x2, 1610b69418SYevgeny Kliteynik }; 1710b69418SYevgeny Kliteynik 1810b69418SYevgeny Kliteynik /* Lookup type is built from 2B: [ Definer mode 1B ][ Definer index 1B ] */ 1910b69418SYevgeny Kliteynik enum { 2010b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_NOP = 0x0000, 2110b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_TNL = 0x0002, 2210b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_IBL3_EXT = 0x0102, 2310b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_O = 0x0003, 2410b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_IBL4 = 0x0103, 2510b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_I = 0x0004, 2610b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_SRC_QP_GVMI = 0x0104, 2710b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_SRC_O = 0x0005, 2810b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_HEADERS_O = 0x0105, 2910b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_SRC_I = 0x0006, 3010b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_HEADERS_I = 0x0106, 3110b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL3_IPV4_5_TUPLE_O = 0x0007, 3210b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_IPV6_DES_O = 0x0107, 3310b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL3_IPV4_5_TUPLE_I = 0x0008, 3410b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_IPV6_DES_I = 0x0108, 3510b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL4_O = 0x0009, 3610b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_IPV6_SRC_O = 0x0109, 3710b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL4_I = 0x000a, 3810b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_IPV6_SRC_I = 0x010a, 3910b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_SRC_DST_O = 0x000b, 4010b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_MPLS_O = 0x010b, 4110b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL2_SRC_DST_I = 0x000c, 4210b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_MPLS_I = 0x010c, 4310b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL3_IPV4_MISC_O = 0x000d, 4410b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_GRE = 0x010d, 4510b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER = 0x000e, 4610b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_GENERAL_PURPOSE = 0x010e, 4710b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL3_IPV4_MISC_I = 0x000f, 4810b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_STEERING_REGISTERS_0 = 0x010f, 4910b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_STEERING_REGISTERS_1 = 0x0110, 5010b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_FLEX_PARSER_0 = 0x0111, 5110b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_FLEX_PARSER_1 = 0x0112, 5210b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL4_MISC_O = 0x0113, 5310b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_ETHL4_MISC_I = 0x0114, 5410b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_INVALID = 0x00ff, 5510b69418SYevgeny Kliteynik DR_STE_V1_LU_TYPE_DONT_CARE = MLX5DR_STE_LU_TYPE_DONT_CARE, 5610b69418SYevgeny Kliteynik }; 5710b69418SYevgeny Kliteynik 58*a6098129SYevgeny Kliteynik static void dr_ste_v1_set_miss_addr(u8 *hw_ste_p, u64 miss_addr) 59*a6098129SYevgeny Kliteynik { 60*a6098129SYevgeny Kliteynik u64 index = miss_addr >> 6; 61*a6098129SYevgeny Kliteynik 62*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32, index >> 26); 63*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6, index); 64*a6098129SYevgeny Kliteynik } 65*a6098129SYevgeny Kliteynik 66*a6098129SYevgeny Kliteynik static u64 dr_ste_v1_get_miss_addr(u8 *hw_ste_p) 67*a6098129SYevgeny Kliteynik { 68*a6098129SYevgeny Kliteynik u64 index = 69*a6098129SYevgeny Kliteynik (MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_31_6) | 70*a6098129SYevgeny Kliteynik MLX5_GET(ste_match_bwc_v1, hw_ste_p, miss_address_39_32) << 26); 71*a6098129SYevgeny Kliteynik 72*a6098129SYevgeny Kliteynik return index << 6; 73*a6098129SYevgeny Kliteynik } 74*a6098129SYevgeny Kliteynik 75*a6098129SYevgeny Kliteynik static void dr_ste_v1_set_byte_mask(u8 *hw_ste_p, u16 byte_mask) 76*a6098129SYevgeny Kliteynik { 77*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, byte_mask, byte_mask); 78*a6098129SYevgeny Kliteynik } 79*a6098129SYevgeny Kliteynik 80*a6098129SYevgeny Kliteynik static u16 dr_ste_v1_get_byte_mask(u8 *hw_ste_p) 81*a6098129SYevgeny Kliteynik { 82*a6098129SYevgeny Kliteynik return MLX5_GET(ste_match_bwc_v1, hw_ste_p, byte_mask); 83*a6098129SYevgeny Kliteynik } 84*a6098129SYevgeny Kliteynik 85*a6098129SYevgeny Kliteynik static void dr_ste_v1_set_lu_type(u8 *hw_ste_p, u16 lu_type) 86*a6098129SYevgeny Kliteynik { 87*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, entry_format, lu_type >> 8); 88*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, match_definer_ctx_idx, lu_type & 0xFF); 89*a6098129SYevgeny Kliteynik } 90*a6098129SYevgeny Kliteynik 91*a6098129SYevgeny Kliteynik static void dr_ste_v1_set_next_lu_type(u8 *hw_ste_p, u16 lu_type) 92*a6098129SYevgeny Kliteynik { 93*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_entry_format, lu_type >> 8); 94*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, hash_definer_ctx_idx, lu_type & 0xFF); 95*a6098129SYevgeny Kliteynik } 96*a6098129SYevgeny Kliteynik 97*a6098129SYevgeny Kliteynik static u16 dr_ste_v1_get_next_lu_type(u8 *hw_ste_p) 98*a6098129SYevgeny Kliteynik { 99*a6098129SYevgeny Kliteynik u8 mode = MLX5_GET(ste_match_bwc_v1, hw_ste_p, next_entry_format); 100*a6098129SYevgeny Kliteynik u8 index = MLX5_GET(ste_match_bwc_v1, hw_ste_p, hash_definer_ctx_idx); 101*a6098129SYevgeny Kliteynik 102*a6098129SYevgeny Kliteynik return (mode << 8 | index); 103*a6098129SYevgeny Kliteynik } 104*a6098129SYevgeny Kliteynik 105*a6098129SYevgeny Kliteynik static void dr_ste_v1_set_hit_addr(u8 *hw_ste_p, u64 icm_addr, u32 ht_size) 106*a6098129SYevgeny Kliteynik { 107*a6098129SYevgeny Kliteynik u64 index = (icm_addr >> 5) | ht_size; 108*a6098129SYevgeny Kliteynik 109*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_39_32_size, index >> 27); 110*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_31_5_size, index); 111*a6098129SYevgeny Kliteynik } 112*a6098129SYevgeny Kliteynik 113*a6098129SYevgeny Kliteynik static void dr_ste_v1_init(u8 *hw_ste_p, u16 lu_type, 114*a6098129SYevgeny Kliteynik u8 entry_type, u16 gvmi) 115*a6098129SYevgeny Kliteynik { 116*a6098129SYevgeny Kliteynik dr_ste_v1_set_lu_type(hw_ste_p, lu_type); 117*a6098129SYevgeny Kliteynik dr_ste_v1_set_next_lu_type(hw_ste_p, MLX5DR_STE_LU_TYPE_DONT_CARE); 118*a6098129SYevgeny Kliteynik 119*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, gvmi, gvmi); 120*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, next_table_base_63_48, gvmi); 121*a6098129SYevgeny Kliteynik MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_63_48, gvmi); 122*a6098129SYevgeny Kliteynik } 123*a6098129SYevgeny Kliteynik 12410b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value, 12510b69418SYevgeny Kliteynik bool inner, u8 *bit_mask) 12610b69418SYevgeny Kliteynik { 12710b69418SYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 12810b69418SYevgeny Kliteynik 12910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, dmac_47_16, mask, dmac_47_16); 13010b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, dmac_15_0, mask, dmac_15_0); 13110b69418SYevgeny Kliteynik 13210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, smac_47_16, mask, smac_47_16); 13310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, smac_15_0, mask, smac_15_0); 13410b69418SYevgeny Kliteynik 13510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_vlan_id, mask, first_vid); 13610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_cfi, mask, first_cfi); 13710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, bit_mask, first_priority, mask, first_prio); 13810b69418SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src_dst_v1, bit_mask, l3_type, mask, ip_version); 13910b69418SYevgeny Kliteynik 14010b69418SYevgeny Kliteynik if (mask->cvlan_tag) { 14110b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst_v1, bit_mask, first_vlan_qualifier, -1); 14210b69418SYevgeny Kliteynik mask->cvlan_tag = 0; 14310b69418SYevgeny Kliteynik } else if (mask->svlan_tag) { 14410b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst_v1, bit_mask, first_vlan_qualifier, -1); 14510b69418SYevgeny Kliteynik mask->svlan_tag = 0; 14610b69418SYevgeny Kliteynik } 14710b69418SYevgeny Kliteynik } 14810b69418SYevgeny Kliteynik 14910b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value, 15010b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 15110b69418SYevgeny Kliteynik u8 *tag) 15210b69418SYevgeny Kliteynik { 15310b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 15410b69418SYevgeny Kliteynik 15510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, dmac_47_16, spec, dmac_47_16); 15610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, dmac_15_0, spec, dmac_15_0); 15710b69418SYevgeny Kliteynik 15810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, smac_47_16, spec, smac_47_16); 15910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, smac_15_0, spec, smac_15_0); 16010b69418SYevgeny Kliteynik 16110b69418SYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 16210b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst_v1, tag, l3_type, STE_IPV4); 16310b69418SYevgeny Kliteynik spec->ip_version = 0; 16410b69418SYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 16510b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst_v1, tag, l3_type, STE_IPV6); 16610b69418SYevgeny Kliteynik spec->ip_version = 0; 16710b69418SYevgeny Kliteynik } else if (spec->ip_version) { 16810b69418SYevgeny Kliteynik return -EINVAL; 16910b69418SYevgeny Kliteynik } 17010b69418SYevgeny Kliteynik 17110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_vlan_id, spec, first_vid); 17210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_cfi, spec, first_cfi); 17310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_dst_v1, tag, first_priority, spec, first_prio); 17410b69418SYevgeny Kliteynik 17510b69418SYevgeny Kliteynik if (spec->cvlan_tag) { 17610b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst_v1, tag, first_vlan_qualifier, DR_STE_CVLAN); 17710b69418SYevgeny Kliteynik spec->cvlan_tag = 0; 17810b69418SYevgeny Kliteynik } else if (spec->svlan_tag) { 17910b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_dst_v1, tag, first_vlan_qualifier, DR_STE_SVLAN); 18010b69418SYevgeny Kliteynik spec->svlan_tag = 0; 18110b69418SYevgeny Kliteynik } 18210b69418SYevgeny Kliteynik return 0; 18310b69418SYevgeny Kliteynik } 18410b69418SYevgeny Kliteynik 18510b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb, 18610b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 18710b69418SYevgeny Kliteynik { 18810b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask); 18910b69418SYevgeny Kliteynik 19010b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2_SRC_DST, sb->inner); 19110b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 19210b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_src_dst_tag; 19310b69418SYevgeny Kliteynik } 19410b69418SYevgeny Kliteynik 19510b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value, 19610b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 19710b69418SYevgeny Kliteynik u8 *tag) 19810b69418SYevgeny Kliteynik { 19910b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 20010b69418SYevgeny Kliteynik 20110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96); 20210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64); 20310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32); 20410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0); 20510b69418SYevgeny Kliteynik 20610b69418SYevgeny Kliteynik return 0; 20710b69418SYevgeny Kliteynik } 20810b69418SYevgeny Kliteynik 20910b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb, 21010b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 21110b69418SYevgeny Kliteynik { 21210b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask); 21310b69418SYevgeny Kliteynik 21410b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(IPV6_DES, sb->inner); 21510b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 21610b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv6_dst_tag; 21710b69418SYevgeny Kliteynik } 21810b69418SYevgeny Kliteynik 21910b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value, 22010b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 22110b69418SYevgeny Kliteynik u8 *tag) 22210b69418SYevgeny Kliteynik { 22310b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 22410b69418SYevgeny Kliteynik 22510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96); 22610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64); 22710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32); 22810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0); 22910b69418SYevgeny Kliteynik 23010b69418SYevgeny Kliteynik return 0; 23110b69418SYevgeny Kliteynik } 23210b69418SYevgeny Kliteynik 23310b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb, 23410b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 23510b69418SYevgeny Kliteynik { 23610b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask); 23710b69418SYevgeny Kliteynik 23810b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(IPV6_SRC, sb->inner); 23910b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 24010b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv6_src_tag; 24110b69418SYevgeny Kliteynik } 24210b69418SYevgeny Kliteynik 24310b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value, 24410b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 24510b69418SYevgeny Kliteynik u8 *tag) 24610b69418SYevgeny Kliteynik { 24710b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 24810b69418SYevgeny Kliteynik 24910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_address, spec, dst_ip_31_0); 25010b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_address, spec, src_ip_31_0); 25110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_port, spec, tcp_dport); 25210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, destination_port, spec, udp_dport); 25310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_port, spec, tcp_sport); 25410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, source_port, spec, udp_sport); 25510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, protocol, spec, ip_protocol); 25610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, fragmented, spec, frag); 25710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, dscp, spec, ip_dscp); 25810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_5_tuple_v1, tag, ecn, spec, ip_ecn); 25910b69418SYevgeny Kliteynik 26010b69418SYevgeny Kliteynik if (spec->tcp_flags) { 26110b69418SYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple_v1, tag, spec); 26210b69418SYevgeny Kliteynik spec->tcp_flags = 0; 26310b69418SYevgeny Kliteynik } 26410b69418SYevgeny Kliteynik 26510b69418SYevgeny Kliteynik return 0; 26610b69418SYevgeny Kliteynik } 26710b69418SYevgeny Kliteynik 26810b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb, 26910b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 27010b69418SYevgeny Kliteynik { 27110b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask); 27210b69418SYevgeny Kliteynik 27310b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL3_IPV4_5_TUPLE, sb->inner); 27410b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 27510b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv4_5_tuple_tag; 27610b69418SYevgeny Kliteynik } 27710b69418SYevgeny Kliteynik 27810b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value, 27910b69418SYevgeny Kliteynik bool inner, u8 *bit_mask) 28010b69418SYevgeny Kliteynik { 28110b69418SYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 28210b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 28310b69418SYevgeny Kliteynik 28410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_vlan_id, mask, first_vid); 28510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_cfi, mask, first_cfi); 28610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, first_priority, mask, first_prio); 28710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, ip_fragmented, mask, frag); // ? 28810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, l3_ethertype, mask, ethertype); // ? 28910b69418SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_src_v1, bit_mask, l3_type, mask, ip_version); 29010b69418SYevgeny Kliteynik 29110b69418SYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 29210b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, bit_mask, first_vlan_qualifier, -1); 29310b69418SYevgeny Kliteynik mask->cvlan_tag = 0; 29410b69418SYevgeny Kliteynik mask->svlan_tag = 0; 29510b69418SYevgeny Kliteynik } 29610b69418SYevgeny Kliteynik 29710b69418SYevgeny Kliteynik if (inner) { 29810b69418SYevgeny Kliteynik if (misc_mask->inner_second_cvlan_tag || 29910b69418SYevgeny Kliteynik misc_mask->inner_second_svlan_tag) { 30010b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, bit_mask, second_vlan_qualifier, -1); 30110b69418SYevgeny Kliteynik misc_mask->inner_second_cvlan_tag = 0; 30210b69418SYevgeny Kliteynik misc_mask->inner_second_svlan_tag = 0; 30310b69418SYevgeny Kliteynik } 30410b69418SYevgeny Kliteynik 30510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 30610b69418SYevgeny Kliteynik second_vlan_id, misc_mask, inner_second_vid); 30710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 30810b69418SYevgeny Kliteynik second_cfi, misc_mask, inner_second_cfi); 30910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 31010b69418SYevgeny Kliteynik second_priority, misc_mask, inner_second_prio); 31110b69418SYevgeny Kliteynik } else { 31210b69418SYevgeny Kliteynik if (misc_mask->outer_second_cvlan_tag || 31310b69418SYevgeny Kliteynik misc_mask->outer_second_svlan_tag) { 31410b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, bit_mask, second_vlan_qualifier, -1); 31510b69418SYevgeny Kliteynik misc_mask->outer_second_cvlan_tag = 0; 31610b69418SYevgeny Kliteynik misc_mask->outer_second_svlan_tag = 0; 31710b69418SYevgeny Kliteynik } 31810b69418SYevgeny Kliteynik 31910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 32010b69418SYevgeny Kliteynik second_vlan_id, misc_mask, outer_second_vid); 32110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 32210b69418SYevgeny Kliteynik second_cfi, misc_mask, outer_second_cfi); 32310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, 32410b69418SYevgeny Kliteynik second_priority, misc_mask, outer_second_prio); 32510b69418SYevgeny Kliteynik } 32610b69418SYevgeny Kliteynik } 32710b69418SYevgeny Kliteynik 32810b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value, 32910b69418SYevgeny Kliteynik bool inner, u8 *tag) 33010b69418SYevgeny Kliteynik { 33110b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer; 33210b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc_spec = &value->misc; 33310b69418SYevgeny Kliteynik 33410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, first_vlan_id, spec, first_vid); 33510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, first_cfi, spec, first_cfi); 33610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, first_priority, spec, first_prio); 33710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, ip_fragmented, spec, frag); 33810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, l3_ethertype, spec, ethertype); 33910b69418SYevgeny Kliteynik 34010b69418SYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 34110b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, l3_type, STE_IPV4); 34210b69418SYevgeny Kliteynik spec->ip_version = 0; 34310b69418SYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 34410b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, l3_type, STE_IPV6); 34510b69418SYevgeny Kliteynik spec->ip_version = 0; 34610b69418SYevgeny Kliteynik } else if (spec->ip_version) { 34710b69418SYevgeny Kliteynik return -EINVAL; 34810b69418SYevgeny Kliteynik } 34910b69418SYevgeny Kliteynik 35010b69418SYevgeny Kliteynik if (spec->cvlan_tag) { 35110b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, first_vlan_qualifier, DR_STE_CVLAN); 35210b69418SYevgeny Kliteynik spec->cvlan_tag = 0; 35310b69418SYevgeny Kliteynik } else if (spec->svlan_tag) { 35410b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, first_vlan_qualifier, DR_STE_SVLAN); 35510b69418SYevgeny Kliteynik spec->svlan_tag = 0; 35610b69418SYevgeny Kliteynik } 35710b69418SYevgeny Kliteynik 35810b69418SYevgeny Kliteynik if (inner) { 35910b69418SYevgeny Kliteynik if (misc_spec->inner_second_cvlan_tag) { 36010b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_CVLAN); 36110b69418SYevgeny Kliteynik misc_spec->inner_second_cvlan_tag = 0; 36210b69418SYevgeny Kliteynik } else if (misc_spec->inner_second_svlan_tag) { 36310b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_SVLAN); 36410b69418SYevgeny Kliteynik misc_spec->inner_second_svlan_tag = 0; 36510b69418SYevgeny Kliteynik } 36610b69418SYevgeny Kliteynik 36710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, second_vlan_id, misc_spec, inner_second_vid); 36810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, second_cfi, misc_spec, inner_second_cfi); 36910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, second_priority, misc_spec, inner_second_prio); 37010b69418SYevgeny Kliteynik } else { 37110b69418SYevgeny Kliteynik if (misc_spec->outer_second_cvlan_tag) { 37210b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_CVLAN); 37310b69418SYevgeny Kliteynik misc_spec->outer_second_cvlan_tag = 0; 37410b69418SYevgeny Kliteynik } else if (misc_spec->outer_second_svlan_tag) { 37510b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_src_v1, tag, second_vlan_qualifier, DR_STE_SVLAN); 37610b69418SYevgeny Kliteynik misc_spec->outer_second_svlan_tag = 0; 37710b69418SYevgeny Kliteynik } 37810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, second_vlan_id, misc_spec, outer_second_vid); 37910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, second_cfi, misc_spec, outer_second_cfi); 38010b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, second_priority, misc_spec, outer_second_prio); 38110b69418SYevgeny Kliteynik } 38210b69418SYevgeny Kliteynik 38310b69418SYevgeny Kliteynik return 0; 38410b69418SYevgeny Kliteynik } 38510b69418SYevgeny Kliteynik 38610b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value, 38710b69418SYevgeny Kliteynik bool inner, u8 *bit_mask) 38810b69418SYevgeny Kliteynik { 38910b69418SYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 39010b69418SYevgeny Kliteynik 39110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, smac_47_16, mask, smac_47_16); 39210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, bit_mask, smac_15_0, mask, smac_15_0); 39310b69418SYevgeny Kliteynik 39410b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 39510b69418SYevgeny Kliteynik } 39610b69418SYevgeny Kliteynik 39710b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l2_src_tag(struct mlx5dr_match_param *value, 39810b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 39910b69418SYevgeny Kliteynik u8 *tag) 40010b69418SYevgeny Kliteynik { 40110b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 40210b69418SYevgeny Kliteynik 40310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, smac_47_16, spec, smac_47_16); 40410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_src_v1, tag, smac_15_0, spec, smac_15_0); 40510b69418SYevgeny Kliteynik 40610b69418SYevgeny Kliteynik return dr_ste_v1_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 40710b69418SYevgeny Kliteynik } 40810b69418SYevgeny Kliteynik 40910b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_src_init(struct mlx5dr_ste_build *sb, 41010b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 41110b69418SYevgeny Kliteynik { 41210b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask); 41310b69418SYevgeny Kliteynik 41410b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2_SRC, sb->inner); 41510b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 41610b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_src_tag; 41710b69418SYevgeny Kliteynik } 41810b69418SYevgeny Kliteynik 41910b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value, 42010b69418SYevgeny Kliteynik bool inner, u8 *bit_mask) 42110b69418SYevgeny Kliteynik { 42210b69418SYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 42310b69418SYevgeny Kliteynik 42410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst_v1, bit_mask, dmac_47_16, mask, dmac_47_16); 42510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst_v1, bit_mask, dmac_15_0, mask, dmac_15_0); 42610b69418SYevgeny Kliteynik 42710b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask); 42810b69418SYevgeny Kliteynik } 42910b69418SYevgeny Kliteynik 43010b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l2_dst_tag(struct mlx5dr_match_param *value, 43110b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 43210b69418SYevgeny Kliteynik u8 *tag) 43310b69418SYevgeny Kliteynik { 43410b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 43510b69418SYevgeny Kliteynik 43610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst_v1, tag, dmac_47_16, spec, dmac_47_16); 43710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_dst_v1, tag, dmac_15_0, spec, dmac_15_0); 43810b69418SYevgeny Kliteynik 43910b69418SYevgeny Kliteynik return dr_ste_v1_build_eth_l2_src_or_dst_tag(value, sb->inner, tag); 44010b69418SYevgeny Kliteynik } 44110b69418SYevgeny Kliteynik 44210b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb, 44310b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 44410b69418SYevgeny Kliteynik { 44510b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l2_dst_bit_mask(mask, sb->inner, sb->bit_mask); 44610b69418SYevgeny Kliteynik 44710b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL2, sb->inner); 44810b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 44910b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_dst_tag; 45010b69418SYevgeny Kliteynik } 45110b69418SYevgeny Kliteynik 45210b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value, 45310b69418SYevgeny Kliteynik bool inner, u8 *bit_mask) 45410b69418SYevgeny Kliteynik { 45510b69418SYevgeny Kliteynik struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer; 45610b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 45710b69418SYevgeny Kliteynik 45810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, dmac_47_16, mask, dmac_47_16); 45910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, dmac_15_0, mask, dmac_15_0); 46010b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_vlan_id, mask, first_vid); 46110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_cfi, mask, first_cfi); 46210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, first_priority, mask, first_prio); 46310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, ip_fragmented, mask, frag); 46410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, bit_mask, l3_ethertype, mask, ethertype); 46510b69418SYevgeny Kliteynik DR_STE_SET_ONES(eth_l2_tnl_v1, bit_mask, l3_type, mask, ip_version); 46610b69418SYevgeny Kliteynik 46710b69418SYevgeny Kliteynik if (misc->vxlan_vni) { 46810b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, bit_mask, 46910b69418SYevgeny Kliteynik l2_tunneling_network_id, (misc->vxlan_vni << 8)); 47010b69418SYevgeny Kliteynik misc->vxlan_vni = 0; 47110b69418SYevgeny Kliteynik } 47210b69418SYevgeny Kliteynik 47310b69418SYevgeny Kliteynik if (mask->svlan_tag || mask->cvlan_tag) { 47410b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, bit_mask, first_vlan_qualifier, -1); 47510b69418SYevgeny Kliteynik mask->cvlan_tag = 0; 47610b69418SYevgeny Kliteynik mask->svlan_tag = 0; 47710b69418SYevgeny Kliteynik } 47810b69418SYevgeny Kliteynik } 47910b69418SYevgeny Kliteynik 48010b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value, 48110b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 48210b69418SYevgeny Kliteynik u8 *tag) 48310b69418SYevgeny Kliteynik { 48410b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 48510b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 48610b69418SYevgeny Kliteynik 48710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, dmac_47_16, spec, dmac_47_16); 48810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, dmac_15_0, spec, dmac_15_0); 48910b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_vlan_id, spec, first_vid); 49010b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_cfi, spec, first_cfi); 49110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, ip_fragmented, spec, frag); 49210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, first_priority, spec, first_prio); 49310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l2_tnl_v1, tag, l3_ethertype, spec, ethertype); 49410b69418SYevgeny Kliteynik 49510b69418SYevgeny Kliteynik if (misc->vxlan_vni) { 49610b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, tag, l2_tunneling_network_id, 49710b69418SYevgeny Kliteynik (misc->vxlan_vni << 8)); 49810b69418SYevgeny Kliteynik misc->vxlan_vni = 0; 49910b69418SYevgeny Kliteynik } 50010b69418SYevgeny Kliteynik 50110b69418SYevgeny Kliteynik if (spec->cvlan_tag) { 50210b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, tag, first_vlan_qualifier, DR_STE_CVLAN); 50310b69418SYevgeny Kliteynik spec->cvlan_tag = 0; 50410b69418SYevgeny Kliteynik } else if (spec->svlan_tag) { 50510b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, tag, first_vlan_qualifier, DR_STE_SVLAN); 50610b69418SYevgeny Kliteynik spec->svlan_tag = 0; 50710b69418SYevgeny Kliteynik } 50810b69418SYevgeny Kliteynik 50910b69418SYevgeny Kliteynik if (spec->ip_version == IP_VERSION_IPV4) { 51010b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, tag, l3_type, STE_IPV4); 51110b69418SYevgeny Kliteynik spec->ip_version = 0; 51210b69418SYevgeny Kliteynik } else if (spec->ip_version == IP_VERSION_IPV6) { 51310b69418SYevgeny Kliteynik MLX5_SET(ste_eth_l2_tnl_v1, tag, l3_type, STE_IPV6); 51410b69418SYevgeny Kliteynik spec->ip_version = 0; 51510b69418SYevgeny Kliteynik } else if (spec->ip_version) { 51610b69418SYevgeny Kliteynik return -EINVAL; 51710b69418SYevgeny Kliteynik } 51810b69418SYevgeny Kliteynik 51910b69418SYevgeny Kliteynik return 0; 52010b69418SYevgeny Kliteynik } 52110b69418SYevgeny Kliteynik 52210b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb, 52310b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 52410b69418SYevgeny Kliteynik { 52510b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask); 52610b69418SYevgeny Kliteynik 52710b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_ETHL2_TNL; 52810b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 52910b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l2_tnl_tag; 53010b69418SYevgeny Kliteynik } 53110b69418SYevgeny Kliteynik 53210b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value, 53310b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 53410b69418SYevgeny Kliteynik u8 *tag) 53510b69418SYevgeny Kliteynik { 53610b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 53710b69418SYevgeny Kliteynik 53810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l3_ipv4_misc_v1, tag, time_to_live, spec, ttl_hoplimit); 53910b69418SYevgeny Kliteynik 54010b69418SYevgeny Kliteynik return 0; 54110b69418SYevgeny Kliteynik } 54210b69418SYevgeny Kliteynik 54310b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb, 54410b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 54510b69418SYevgeny Kliteynik { 54610b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask); 54710b69418SYevgeny Kliteynik 54810b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL3_IPV4_MISC, sb->inner); 54910b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 55010b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l3_ipv4_misc_tag; 55110b69418SYevgeny Kliteynik } 55210b69418SYevgeny Kliteynik 55310b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value, 55410b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 55510b69418SYevgeny Kliteynik u8 *tag) 55610b69418SYevgeny Kliteynik { 55710b69418SYevgeny Kliteynik struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer; 55810b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 55910b69418SYevgeny Kliteynik 56010b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, dst_port, spec, tcp_dport); 56110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, src_port, spec, tcp_sport); 56210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, dst_port, spec, udp_dport); 56310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, src_port, spec, udp_sport); 56410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, protocol, spec, ip_protocol); 56510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, fragmented, spec, frag); 56610b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, dscp, spec, ip_dscp); 56710b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, ecn, spec, ip_ecn); 56810b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, ipv6_hop_limit, spec, ttl_hoplimit); 56910b69418SYevgeny Kliteynik 57010b69418SYevgeny Kliteynik if (sb->inner) 57110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, flow_label, misc, inner_ipv6_flow_label); 57210b69418SYevgeny Kliteynik else 57310b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_v1, tag, flow_label, misc, outer_ipv6_flow_label); 57410b69418SYevgeny Kliteynik 57510b69418SYevgeny Kliteynik if (spec->tcp_flags) { 57610b69418SYevgeny Kliteynik DR_STE_SET_TCP_FLAGS(eth_l4_v1, tag, spec); 57710b69418SYevgeny Kliteynik spec->tcp_flags = 0; 57810b69418SYevgeny Kliteynik } 57910b69418SYevgeny Kliteynik 58010b69418SYevgeny Kliteynik return 0; 58110b69418SYevgeny Kliteynik } 58210b69418SYevgeny Kliteynik 58310b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb, 58410b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 58510b69418SYevgeny Kliteynik { 58610b69418SYevgeny Kliteynik dr_ste_v1_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask); 58710b69418SYevgeny Kliteynik 58810b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(ETHL4, sb->inner); 58910b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 59010b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_ipv6_l3_l4_tag; 59110b69418SYevgeny Kliteynik } 59210b69418SYevgeny Kliteynik 59310b69418SYevgeny Kliteynik static int dr_ste_v1_build_mpls_tag(struct mlx5dr_match_param *value, 59410b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 59510b69418SYevgeny Kliteynik u8 *tag) 59610b69418SYevgeny Kliteynik { 59710b69418SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 59810b69418SYevgeny Kliteynik 59910b69418SYevgeny Kliteynik if (sb->inner) 60010b69418SYevgeny Kliteynik DR_STE_SET_MPLS(mpls_v1, misc2, inner, tag); 60110b69418SYevgeny Kliteynik else 60210b69418SYevgeny Kliteynik DR_STE_SET_MPLS(mpls_v1, misc2, outer, tag); 60310b69418SYevgeny Kliteynik 60410b69418SYevgeny Kliteynik return 0; 60510b69418SYevgeny Kliteynik } 60610b69418SYevgeny Kliteynik 60710b69418SYevgeny Kliteynik static void dr_ste_v1_build_mpls_init(struct mlx5dr_ste_build *sb, 60810b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 60910b69418SYevgeny Kliteynik { 61010b69418SYevgeny Kliteynik dr_ste_v1_build_mpls_tag(mask, sb, sb->bit_mask); 61110b69418SYevgeny Kliteynik 61210b69418SYevgeny Kliteynik sb->lu_type = DR_STE_CALC_DFNR_TYPE(MPLS, sb->inner); 61310b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 61410b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_mpls_tag; 61510b69418SYevgeny Kliteynik } 61610b69418SYevgeny Kliteynik 61710b69418SYevgeny Kliteynik static int dr_ste_v1_build_tnl_gre_tag(struct mlx5dr_match_param *value, 61810b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 61910b69418SYevgeny Kliteynik u8 *tag) 62010b69418SYevgeny Kliteynik { 62110b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 62210b69418SYevgeny Kliteynik 62310b69418SYevgeny Kliteynik DR_STE_SET_TAG(gre_v1, tag, gre_protocol, misc, gre_protocol); 62410b69418SYevgeny Kliteynik DR_STE_SET_TAG(gre_v1, tag, gre_k_present, misc, gre_k_present); 62510b69418SYevgeny Kliteynik DR_STE_SET_TAG(gre_v1, tag, gre_key_h, misc, gre_key_h); 62610b69418SYevgeny Kliteynik DR_STE_SET_TAG(gre_v1, tag, gre_key_l, misc, gre_key_l); 62710b69418SYevgeny Kliteynik 62810b69418SYevgeny Kliteynik DR_STE_SET_TAG(gre_v1, tag, gre_c_present, misc, gre_c_present); 62910b69418SYevgeny Kliteynik DR_STE_SET_TAG(gre_v1, tag, gre_s_present, misc, gre_s_present); 63010b69418SYevgeny Kliteynik 63110b69418SYevgeny Kliteynik return 0; 63210b69418SYevgeny Kliteynik } 63310b69418SYevgeny Kliteynik 63410b69418SYevgeny Kliteynik static void dr_ste_v1_build_tnl_gre_init(struct mlx5dr_ste_build *sb, 63510b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 63610b69418SYevgeny Kliteynik { 63710b69418SYevgeny Kliteynik dr_ste_v1_build_tnl_gre_tag(mask, sb, sb->bit_mask); 63810b69418SYevgeny Kliteynik 63910b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_GRE; 64010b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 64110b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_tnl_gre_tag; 64210b69418SYevgeny Kliteynik } 64310b69418SYevgeny Kliteynik 64410b69418SYevgeny Kliteynik static int dr_ste_v1_build_tnl_mpls_tag(struct mlx5dr_match_param *value, 64510b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 64610b69418SYevgeny Kliteynik u8 *tag) 64710b69418SYevgeny Kliteynik { 64810b69418SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 64910b69418SYevgeny Kliteynik 65010b69418SYevgeny Kliteynik if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc2)) { 65110b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_label, 65210b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_gre_label); 65310b69418SYevgeny Kliteynik 65410b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_exp, 65510b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_gre_exp); 65610b69418SYevgeny Kliteynik 65710b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_s_bos, 65810b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_gre_s_bos); 65910b69418SYevgeny Kliteynik 66010b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_ttl, 66110b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_gre_ttl); 66210b69418SYevgeny Kliteynik } else { 66310b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_label, 66410b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_udp_label); 66510b69418SYevgeny Kliteynik 66610b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_exp, 66710b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_udp_exp); 66810b69418SYevgeny Kliteynik 66910b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_s_bos, 67010b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_udp_s_bos); 67110b69418SYevgeny Kliteynik 67210b69418SYevgeny Kliteynik DR_STE_SET_TAG(mpls_v1, tag, mpls0_ttl, 67310b69418SYevgeny Kliteynik misc2, outer_first_mpls_over_udp_ttl); 67410b69418SYevgeny Kliteynik } 67510b69418SYevgeny Kliteynik 67610b69418SYevgeny Kliteynik return 0; 67710b69418SYevgeny Kliteynik } 67810b69418SYevgeny Kliteynik 67910b69418SYevgeny Kliteynik static void dr_ste_v1_build_tnl_mpls_init(struct mlx5dr_ste_build *sb, 68010b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 68110b69418SYevgeny Kliteynik { 68210b69418SYevgeny Kliteynik dr_ste_v1_build_tnl_mpls_tag(mask, sb, sb->bit_mask); 68310b69418SYevgeny Kliteynik 68410b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_MPLS_I; 68510b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 68610b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_tnl_mpls_tag; 68710b69418SYevgeny Kliteynik } 68810b69418SYevgeny Kliteynik 68910b69418SYevgeny Kliteynik static int dr_ste_v1_build_icmp_tag(struct mlx5dr_match_param *value, 69010b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 69110b69418SYevgeny Kliteynik u8 *tag) 69210b69418SYevgeny Kliteynik { 69310b69418SYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 69410b69418SYevgeny Kliteynik bool is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc3); 69510b69418SYevgeny Kliteynik u32 *icmp_header_data; 69610b69418SYevgeny Kliteynik u8 *icmp_type; 69710b69418SYevgeny Kliteynik u8 *icmp_code; 69810b69418SYevgeny Kliteynik 69910b69418SYevgeny Kliteynik if (is_ipv4) { 70010b69418SYevgeny Kliteynik icmp_header_data = &misc3->icmpv4_header_data; 70110b69418SYevgeny Kliteynik icmp_type = &misc3->icmpv4_type; 70210b69418SYevgeny Kliteynik icmp_code = &misc3->icmpv4_code; 70310b69418SYevgeny Kliteynik } else { 70410b69418SYevgeny Kliteynik icmp_header_data = &misc3->icmpv6_header_data; 70510b69418SYevgeny Kliteynik icmp_type = &misc3->icmpv6_type; 70610b69418SYevgeny Kliteynik icmp_code = &misc3->icmpv6_code; 70710b69418SYevgeny Kliteynik } 70810b69418SYevgeny Kliteynik 70910b69418SYevgeny Kliteynik MLX5_SET(ste_icmp_v1, tag, icmp_header_data, *icmp_header_data); 71010b69418SYevgeny Kliteynik MLX5_SET(ste_icmp_v1, tag, icmp_type, *icmp_type); 71110b69418SYevgeny Kliteynik MLX5_SET(ste_icmp_v1, tag, icmp_code, *icmp_code); 71210b69418SYevgeny Kliteynik 71310b69418SYevgeny Kliteynik *icmp_header_data = 0; 71410b69418SYevgeny Kliteynik *icmp_type = 0; 71510b69418SYevgeny Kliteynik *icmp_code = 0; 71610b69418SYevgeny Kliteynik 71710b69418SYevgeny Kliteynik return 0; 71810b69418SYevgeny Kliteynik } 71910b69418SYevgeny Kliteynik 72010b69418SYevgeny Kliteynik static int dr_ste_v1_build_icmp_init(struct mlx5dr_ste_build *sb, 72110b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 72210b69418SYevgeny Kliteynik { 72310b69418SYevgeny Kliteynik dr_ste_v1_build_icmp_tag(mask, sb, sb->bit_mask); 72410b69418SYevgeny Kliteynik 72510b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_ETHL4_MISC_O; 72610b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 72710b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_icmp_tag; 72810b69418SYevgeny Kliteynik 72910b69418SYevgeny Kliteynik return 0; 73010b69418SYevgeny Kliteynik } 73110b69418SYevgeny Kliteynik 73210b69418SYevgeny Kliteynik static int dr_ste_v1_build_general_purpose_tag(struct mlx5dr_match_param *value, 73310b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 73410b69418SYevgeny Kliteynik u8 *tag) 73510b69418SYevgeny Kliteynik { 73610b69418SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 73710b69418SYevgeny Kliteynik 73810b69418SYevgeny Kliteynik DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field, 73910b69418SYevgeny Kliteynik misc2, metadata_reg_a); 74010b69418SYevgeny Kliteynik 74110b69418SYevgeny Kliteynik return 0; 74210b69418SYevgeny Kliteynik } 74310b69418SYevgeny Kliteynik 74410b69418SYevgeny Kliteynik static void dr_ste_v1_build_general_purpose_init(struct mlx5dr_ste_build *sb, 74510b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 74610b69418SYevgeny Kliteynik { 74710b69418SYevgeny Kliteynik dr_ste_v1_build_general_purpose_tag(mask, sb, sb->bit_mask); 74810b69418SYevgeny Kliteynik 74910b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_GENERAL_PURPOSE; 75010b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 75110b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_general_purpose_tag; 75210b69418SYevgeny Kliteynik } 75310b69418SYevgeny Kliteynik 75410b69418SYevgeny Kliteynik static int dr_ste_v1_build_eth_l4_misc_tag(struct mlx5dr_match_param *value, 75510b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 75610b69418SYevgeny Kliteynik u8 *tag) 75710b69418SYevgeny Kliteynik { 75810b69418SYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 75910b69418SYevgeny Kliteynik 76010b69418SYevgeny Kliteynik if (sb->inner) { 76110b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc_v1, tag, seq_num, misc3, inner_tcp_seq_num); 76210b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc_v1, tag, ack_num, misc3, inner_tcp_ack_num); 76310b69418SYevgeny Kliteynik } else { 76410b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc_v1, tag, seq_num, misc3, outer_tcp_seq_num); 76510b69418SYevgeny Kliteynik DR_STE_SET_TAG(eth_l4_misc_v1, tag, ack_num, misc3, outer_tcp_ack_num); 76610b69418SYevgeny Kliteynik } 76710b69418SYevgeny Kliteynik 76810b69418SYevgeny Kliteynik return 0; 76910b69418SYevgeny Kliteynik } 77010b69418SYevgeny Kliteynik 77110b69418SYevgeny Kliteynik static void dr_ste_v1_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb, 77210b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 77310b69418SYevgeny Kliteynik { 77410b69418SYevgeny Kliteynik dr_ste_v1_build_eth_l4_misc_tag(mask, sb, sb->bit_mask); 77510b69418SYevgeny Kliteynik 77610b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_ETHL4_MISC_O; 77710b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 77810b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_eth_l4_misc_tag; 77910b69418SYevgeny Kliteynik } 78010b69418SYevgeny Kliteynik 78110b69418SYevgeny Kliteynik static int 78210b69418SYevgeny Kliteynik dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value, 78310b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 78410b69418SYevgeny Kliteynik u8 *tag) 78510b69418SYevgeny Kliteynik { 78610b69418SYevgeny Kliteynik struct mlx5dr_match_misc3 *misc3 = &value->misc3; 78710b69418SYevgeny Kliteynik 78810b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 78910b69418SYevgeny Kliteynik outer_vxlan_gpe_flags, misc3, 79010b69418SYevgeny Kliteynik outer_vxlan_gpe_flags); 79110b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 79210b69418SYevgeny Kliteynik outer_vxlan_gpe_next_protocol, misc3, 79310b69418SYevgeny Kliteynik outer_vxlan_gpe_next_protocol); 79410b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag, 79510b69418SYevgeny Kliteynik outer_vxlan_gpe_vni, misc3, 79610b69418SYevgeny Kliteynik outer_vxlan_gpe_vni); 79710b69418SYevgeny Kliteynik 79810b69418SYevgeny Kliteynik return 0; 79910b69418SYevgeny Kliteynik } 80010b69418SYevgeny Kliteynik 80110b69418SYevgeny Kliteynik static void 80210b69418SYevgeny Kliteynik dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb, 80310b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 80410b69418SYevgeny Kliteynik { 80510b69418SYevgeny Kliteynik dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask); 80610b69418SYevgeny Kliteynik 80710b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER; 80810b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 80910b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_tag; 81010b69418SYevgeny Kliteynik } 81110b69418SYevgeny Kliteynik 81210b69418SYevgeny Kliteynik static int 81310b69418SYevgeny Kliteynik dr_ste_v1_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value, 81410b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 81510b69418SYevgeny Kliteynik u8 *tag) 81610b69418SYevgeny Kliteynik { 81710b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 81810b69418SYevgeny Kliteynik 81910b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 82010b69418SYevgeny Kliteynik geneve_protocol_type, misc, geneve_protocol_type); 82110b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 82210b69418SYevgeny Kliteynik geneve_oam, misc, geneve_oam); 82310b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 82410b69418SYevgeny Kliteynik geneve_opt_len, misc, geneve_opt_len); 82510b69418SYevgeny Kliteynik DR_STE_SET_TAG(flex_parser_tnl_geneve, tag, 82610b69418SYevgeny Kliteynik geneve_vni, misc, geneve_vni); 82710b69418SYevgeny Kliteynik 82810b69418SYevgeny Kliteynik return 0; 82910b69418SYevgeny Kliteynik } 83010b69418SYevgeny Kliteynik 83110b69418SYevgeny Kliteynik static void 83210b69418SYevgeny Kliteynik dr_ste_v1_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb, 83310b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 83410b69418SYevgeny Kliteynik { 83510b69418SYevgeny Kliteynik dr_ste_v1_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask); 83610b69418SYevgeny Kliteynik 83710b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_FLEX_PARSER_TNL_HEADER; 83810b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 83910b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_flex_parser_tnl_geneve_tag; 84010b69418SYevgeny Kliteynik } 84110b69418SYevgeny Kliteynik 84210b69418SYevgeny Kliteynik static int dr_ste_v1_build_register_0_tag(struct mlx5dr_match_param *value, 84310b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 84410b69418SYevgeny Kliteynik u8 *tag) 84510b69418SYevgeny Kliteynik { 84610b69418SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 84710b69418SYevgeny Kliteynik 84810b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0); 84910b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1); 85010b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2); 85110b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3); 85210b69418SYevgeny Kliteynik 85310b69418SYevgeny Kliteynik return 0; 85410b69418SYevgeny Kliteynik } 85510b69418SYevgeny Kliteynik 85610b69418SYevgeny Kliteynik static void dr_ste_v1_build_register_0_init(struct mlx5dr_ste_build *sb, 85710b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 85810b69418SYevgeny Kliteynik { 85910b69418SYevgeny Kliteynik dr_ste_v1_build_register_0_tag(mask, sb, sb->bit_mask); 86010b69418SYevgeny Kliteynik 86110b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_STEERING_REGISTERS_0; 86210b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 86310b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_register_0_tag; 86410b69418SYevgeny Kliteynik } 86510b69418SYevgeny Kliteynik 86610b69418SYevgeny Kliteynik static int dr_ste_v1_build_register_1_tag(struct mlx5dr_match_param *value, 86710b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 86810b69418SYevgeny Kliteynik u8 *tag) 86910b69418SYevgeny Kliteynik { 87010b69418SYevgeny Kliteynik struct mlx5dr_match_misc2 *misc2 = &value->misc2; 87110b69418SYevgeny Kliteynik 87210b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4); 87310b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5); 87410b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6); 87510b69418SYevgeny Kliteynik DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7); 87610b69418SYevgeny Kliteynik 87710b69418SYevgeny Kliteynik return 0; 87810b69418SYevgeny Kliteynik } 87910b69418SYevgeny Kliteynik 88010b69418SYevgeny Kliteynik static void dr_ste_v1_build_register_1_init(struct mlx5dr_ste_build *sb, 88110b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 88210b69418SYevgeny Kliteynik { 88310b69418SYevgeny Kliteynik dr_ste_v1_build_register_1_tag(mask, sb, sb->bit_mask); 88410b69418SYevgeny Kliteynik 88510b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_STEERING_REGISTERS_1; 88610b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 88710b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_register_1_tag; 88810b69418SYevgeny Kliteynik } 88910b69418SYevgeny Kliteynik 89010b69418SYevgeny Kliteynik static void dr_ste_v1_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value, 89110b69418SYevgeny Kliteynik u8 *bit_mask) 89210b69418SYevgeny Kliteynik { 89310b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc_mask = &value->misc; 89410b69418SYevgeny Kliteynik 89510b69418SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp_v1, bit_mask, source_gvmi, misc_mask, source_port); 89610b69418SYevgeny Kliteynik DR_STE_SET_ONES(src_gvmi_qp_v1, bit_mask, source_qp, misc_mask, source_sqn); 89710b69418SYevgeny Kliteynik } 89810b69418SYevgeny Kliteynik 89910b69418SYevgeny Kliteynik static int dr_ste_v1_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value, 90010b69418SYevgeny Kliteynik struct mlx5dr_ste_build *sb, 90110b69418SYevgeny Kliteynik u8 *tag) 90210b69418SYevgeny Kliteynik { 90310b69418SYevgeny Kliteynik struct mlx5dr_match_misc *misc = &value->misc; 90410b69418SYevgeny Kliteynik struct mlx5dr_cmd_vport_cap *vport_cap; 90510b69418SYevgeny Kliteynik struct mlx5dr_domain *dmn = sb->dmn; 90610b69418SYevgeny Kliteynik struct mlx5dr_cmd_caps *caps; 90710b69418SYevgeny Kliteynik u8 *bit_mask = sb->bit_mask; 90810b69418SYevgeny Kliteynik 90910b69418SYevgeny Kliteynik DR_STE_SET_TAG(src_gvmi_qp_v1, tag, source_qp, misc, source_sqn); 91010b69418SYevgeny Kliteynik 91110b69418SYevgeny Kliteynik if (sb->vhca_id_valid) { 91210b69418SYevgeny Kliteynik /* Find port GVMI based on the eswitch_owner_vhca_id */ 91310b69418SYevgeny Kliteynik if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi) 91410b69418SYevgeny Kliteynik caps = &dmn->info.caps; 91510b69418SYevgeny Kliteynik else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id == 91610b69418SYevgeny Kliteynik dmn->peer_dmn->info.caps.gvmi)) 91710b69418SYevgeny Kliteynik caps = &dmn->peer_dmn->info.caps; 91810b69418SYevgeny Kliteynik else 91910b69418SYevgeny Kliteynik return -EINVAL; 92010b69418SYevgeny Kliteynik 92110b69418SYevgeny Kliteynik misc->source_eswitch_owner_vhca_id = 0; 92210b69418SYevgeny Kliteynik } else { 92310b69418SYevgeny Kliteynik caps = &dmn->info.caps; 92410b69418SYevgeny Kliteynik } 92510b69418SYevgeny Kliteynik 92610b69418SYevgeny Kliteynik if (!MLX5_GET(ste_src_gvmi_qp_v1, bit_mask, source_gvmi)) 92710b69418SYevgeny Kliteynik return 0; 92810b69418SYevgeny Kliteynik 92910b69418SYevgeny Kliteynik vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port); 93010b69418SYevgeny Kliteynik if (!vport_cap) { 93110b69418SYevgeny Kliteynik mlx5dr_err(dmn, "Vport 0x%x is disabled or invalid\n", 93210b69418SYevgeny Kliteynik misc->source_port); 93310b69418SYevgeny Kliteynik return -EINVAL; 93410b69418SYevgeny Kliteynik } 93510b69418SYevgeny Kliteynik 93610b69418SYevgeny Kliteynik if (vport_cap->vport_gvmi) 93710b69418SYevgeny Kliteynik MLX5_SET(ste_src_gvmi_qp_v1, tag, source_gvmi, vport_cap->vport_gvmi); 93810b69418SYevgeny Kliteynik 93910b69418SYevgeny Kliteynik misc->source_port = 0; 94010b69418SYevgeny Kliteynik return 0; 94110b69418SYevgeny Kliteynik } 94210b69418SYevgeny Kliteynik 94310b69418SYevgeny Kliteynik static void dr_ste_v1_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb, 94410b69418SYevgeny Kliteynik struct mlx5dr_match_param *mask) 94510b69418SYevgeny Kliteynik { 94610b69418SYevgeny Kliteynik dr_ste_v1_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask); 94710b69418SYevgeny Kliteynik 94810b69418SYevgeny Kliteynik sb->lu_type = DR_STE_V1_LU_TYPE_SRC_QP_GVMI; 94910b69418SYevgeny Kliteynik sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask); 95010b69418SYevgeny Kliteynik sb->ste_build_tag_func = &dr_ste_v1_build_src_gvmi_qpn_tag; 95110b69418SYevgeny Kliteynik } 95210b69418SYevgeny Kliteynik 95310b69418SYevgeny Kliteynik struct mlx5dr_ste_ctx ste_ctx_v1 = { 954*a6098129SYevgeny Kliteynik /* Builders */ 95510b69418SYevgeny Kliteynik .build_eth_l2_src_dst_init = &dr_ste_v1_build_eth_l2_src_dst_init, 95610b69418SYevgeny Kliteynik .build_eth_l3_ipv6_src_init = &dr_ste_v1_build_eth_l3_ipv6_src_init, 95710b69418SYevgeny Kliteynik .build_eth_l3_ipv6_dst_init = &dr_ste_v1_build_eth_l3_ipv6_dst_init, 95810b69418SYevgeny Kliteynik .build_eth_l3_ipv4_5_tuple_init = &dr_ste_v1_build_eth_l3_ipv4_5_tuple_init, 95910b69418SYevgeny Kliteynik .build_eth_l2_src_init = &dr_ste_v1_build_eth_l2_src_init, 96010b69418SYevgeny Kliteynik .build_eth_l2_dst_init = &dr_ste_v1_build_eth_l2_dst_init, 96110b69418SYevgeny Kliteynik .build_eth_l2_tnl_init = &dr_ste_v1_build_eth_l2_tnl_init, 96210b69418SYevgeny Kliteynik .build_eth_l3_ipv4_misc_init = &dr_ste_v1_build_eth_l3_ipv4_misc_init, 96310b69418SYevgeny Kliteynik .build_eth_ipv6_l3_l4_init = &dr_ste_v1_build_eth_ipv6_l3_l4_init, 96410b69418SYevgeny Kliteynik .build_mpls_init = &dr_ste_v1_build_mpls_init, 96510b69418SYevgeny Kliteynik .build_tnl_gre_init = &dr_ste_v1_build_tnl_gre_init, 96610b69418SYevgeny Kliteynik .build_tnl_mpls_init = &dr_ste_v1_build_tnl_mpls_init, 96710b69418SYevgeny Kliteynik .build_icmp_init = &dr_ste_v1_build_icmp_init, 96810b69418SYevgeny Kliteynik .build_general_purpose_init = &dr_ste_v1_build_general_purpose_init, 96910b69418SYevgeny Kliteynik .build_eth_l4_misc_init = &dr_ste_v1_build_eth_l4_misc_init, 97010b69418SYevgeny Kliteynik .build_tnl_vxlan_gpe_init = &dr_ste_v1_build_flex_parser_tnl_vxlan_gpe_init, 97110b69418SYevgeny Kliteynik .build_tnl_geneve_init = &dr_ste_v1_build_flex_parser_tnl_geneve_init, 97210b69418SYevgeny Kliteynik .build_register_0_init = &dr_ste_v1_build_register_0_init, 97310b69418SYevgeny Kliteynik .build_register_1_init = &dr_ste_v1_build_register_1_init, 97410b69418SYevgeny Kliteynik .build_src_gvmi_qpn_init = &dr_ste_v1_build_src_gvmi_qpn_init, 975*a6098129SYevgeny Kliteynik /* Getters and Setters */ 976*a6098129SYevgeny Kliteynik .ste_init = &dr_ste_v1_init, 977*a6098129SYevgeny Kliteynik .set_next_lu_type = &dr_ste_v1_set_next_lu_type, 978*a6098129SYevgeny Kliteynik .get_next_lu_type = &dr_ste_v1_get_next_lu_type, 979*a6098129SYevgeny Kliteynik .set_miss_addr = &dr_ste_v1_set_miss_addr, 980*a6098129SYevgeny Kliteynik .get_miss_addr = &dr_ste_v1_get_miss_addr, 981*a6098129SYevgeny Kliteynik .set_hit_addr = &dr_ste_v1_set_hit_addr, 982*a6098129SYevgeny Kliteynik .set_byte_mask = &dr_ste_v1_set_byte_mask, 983*a6098129SYevgeny Kliteynik .get_byte_mask = &dr_ste_v1_get_byte_mask, 98410b69418SYevgeny Kliteynik }; 985