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