1d65e841dSYevgeny Kliteynik // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2d65e841dSYevgeny Kliteynik /* Copyright (c) 2020 NVIDIA CORPORATION. All rights reserved. */
3d65e841dSYevgeny Kliteynik 
4d65e841dSYevgeny Kliteynik #include <linux/types.h>
5d65e841dSYevgeny Kliteynik #include <linux/crc32.h>
6d65e841dSYevgeny Kliteynik #include "dr_ste.h"
7d65e841dSYevgeny Kliteynik 
8d65e841dSYevgeny Kliteynik #define DR_STE_CALC_LU_TYPE(lookup_type, rx, inner) \
9*dd2d3c8dSYevgeny Kliteynik 	((inner) ? DR_STE_V0_LU_TYPE_##lookup_type##_I : \
10*dd2d3c8dSYevgeny Kliteynik 		   (rx) ? DR_STE_V0_LU_TYPE_##lookup_type##_D : \
11*dd2d3c8dSYevgeny Kliteynik 			  DR_STE_V0_LU_TYPE_##lookup_type##_O)
12*dd2d3c8dSYevgeny Kliteynik 
13*dd2d3c8dSYevgeny Kliteynik enum {
14*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_NOP				= 0x00,
15*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP		= 0x05,
16*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I		= 0x0a,
17*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_DST_O			= 0x06,
18*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_DST_I			= 0x07,
19*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_DST_D			= 0x1b,
20*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_SRC_O			= 0x08,
21*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_SRC_I			= 0x09,
22*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_SRC_D			= 0x1c,
23*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_O		= 0x36,
24*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_I		= 0x37,
25*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL2_SRC_DST_D		= 0x38,
26*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_O		= 0x0d,
27*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_I		= 0x0e,
28*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV6_DST_D		= 0x1e,
29*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_O		= 0x0f,
30*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_I		= 0x10,
31*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV6_SRC_D		= 0x1f,
32*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_O		= 0x11,
33*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_I		= 0x12,
34*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV4_5_TUPLE_D		= 0x20,
35*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_O		= 0x29,
36*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_I		= 0x2a,
37*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL3_IPV4_MISC_D		= 0x2b,
38*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL4_O			= 0x13,
39*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL4_I			= 0x14,
40*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL4_D			= 0x21,
41*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL4_MISC_O			= 0x2c,
42*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL4_MISC_I			= 0x2d,
43*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_ETHL4_MISC_D			= 0x2e,
44*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_MPLS_FIRST_O			= 0x15,
45*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_MPLS_FIRST_I			= 0x24,
46*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_MPLS_FIRST_D			= 0x25,
47*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_GRE				= 0x16,
48*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_FLEX_PARSER_0			= 0x22,
49*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_FLEX_PARSER_1			= 0x23,
50*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER	= 0x19,
51*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_GENERAL_PURPOSE		= 0x18,
52*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0		= 0x2f,
53*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1		= 0x30,
54*dd2d3c8dSYevgeny Kliteynik 	DR_STE_V0_LU_TYPE_DONT_CARE			= MLX5DR_STE_LU_TYPE_DONT_CARE,
55*dd2d3c8dSYevgeny Kliteynik };
56d65e841dSYevgeny Kliteynik 
57d65e841dSYevgeny Kliteynik static void
58d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value,
59d65e841dSYevgeny Kliteynik 					bool inner, u8 *bit_mask)
60d65e841dSYevgeny Kliteynik {
61d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
62d65e841dSYevgeny Kliteynik 
6346779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
6446779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
65d65e841dSYevgeny Kliteynik 
66d65e841dSYevgeny Kliteynik 	if (mask->smac_47_16 || mask->smac_15_0) {
67d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32,
68d65e841dSYevgeny Kliteynik 			 mask->smac_47_16 >> 16);
69d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0,
70d65e841dSYevgeny Kliteynik 			 mask->smac_47_16 << 16 | mask->smac_15_0);
71d65e841dSYevgeny Kliteynik 		mask->smac_47_16 = 0;
72d65e841dSYevgeny Kliteynik 		mask->smac_15_0 = 0;
73d65e841dSYevgeny Kliteynik 	}
74d65e841dSYevgeny Kliteynik 
7546779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid);
7646779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi);
7746779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio);
7846779098SYevgeny Kliteynik 	DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version);
79d65e841dSYevgeny Kliteynik 
80d65e841dSYevgeny Kliteynik 	if (mask->cvlan_tag) {
81d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
82d65e841dSYevgeny Kliteynik 		mask->cvlan_tag = 0;
83d65e841dSYevgeny Kliteynik 	} else if (mask->svlan_tag) {
84d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
85d65e841dSYevgeny Kliteynik 		mask->svlan_tag = 0;
86d65e841dSYevgeny Kliteynik 	}
87d65e841dSYevgeny Kliteynik }
88d65e841dSYevgeny Kliteynik 
89d65e841dSYevgeny Kliteynik static int
90d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value,
91d65e841dSYevgeny Kliteynik 				   struct mlx5dr_ste_build *sb,
92d65e841dSYevgeny Kliteynik 				   u8 *tag)
93d65e841dSYevgeny Kliteynik {
94d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
95d65e841dSYevgeny Kliteynik 
96d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16);
97d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0);
98d65e841dSYevgeny Kliteynik 
99d65e841dSYevgeny Kliteynik 	if (spec->smac_47_16 || spec->smac_15_0) {
100d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32,
101d65e841dSYevgeny Kliteynik 			 spec->smac_47_16 >> 16);
102d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0,
103d65e841dSYevgeny Kliteynik 			 spec->smac_47_16 << 16 | spec->smac_15_0);
104d65e841dSYevgeny Kliteynik 		spec->smac_47_16 = 0;
105d65e841dSYevgeny Kliteynik 		spec->smac_15_0 = 0;
106d65e841dSYevgeny Kliteynik 	}
107d65e841dSYevgeny Kliteynik 
108d65e841dSYevgeny Kliteynik 	if (spec->ip_version) {
109d65e841dSYevgeny Kliteynik 		if (spec->ip_version == IP_VERSION_IPV4) {
110d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4);
111d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
112d65e841dSYevgeny Kliteynik 		} else if (spec->ip_version == IP_VERSION_IPV6) {
113d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6);
114d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
115d65e841dSYevgeny Kliteynik 		} else {
116d65e841dSYevgeny Kliteynik 			return -EINVAL;
117d65e841dSYevgeny Kliteynik 		}
118d65e841dSYevgeny Kliteynik 	}
119d65e841dSYevgeny Kliteynik 
120d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid);
121d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi);
122d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio);
123d65e841dSYevgeny Kliteynik 
124d65e841dSYevgeny Kliteynik 	if (spec->cvlan_tag) {
125d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN);
126d65e841dSYevgeny Kliteynik 		spec->cvlan_tag = 0;
127d65e841dSYevgeny Kliteynik 	} else if (spec->svlan_tag) {
128d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN);
129d65e841dSYevgeny Kliteynik 		spec->svlan_tag = 0;
130d65e841dSYevgeny Kliteynik 	}
131d65e841dSYevgeny Kliteynik 	return 0;
132d65e841dSYevgeny Kliteynik }
133d65e841dSYevgeny Kliteynik 
134d65e841dSYevgeny Kliteynik static void
135d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb,
136d65e841dSYevgeny Kliteynik 				    struct mlx5dr_match_param *mask)
137d65e841dSYevgeny Kliteynik {
138d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask);
139d65e841dSYevgeny Kliteynik 
140d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner);
141d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
142d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag;
143d65e841dSYevgeny Kliteynik }
144d65e841dSYevgeny Kliteynik 
145d65e841dSYevgeny Kliteynik static int
146d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value,
147d65e841dSYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
148d65e841dSYevgeny Kliteynik 				    u8 *tag)
149d65e841dSYevgeny Kliteynik {
150d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
151d65e841dSYevgeny Kliteynik 
152d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96);
153d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64);
154d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32);
155d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0);
156d65e841dSYevgeny Kliteynik 
157d65e841dSYevgeny Kliteynik 	return 0;
158d65e841dSYevgeny Kliteynik }
159d65e841dSYevgeny Kliteynik 
160d65e841dSYevgeny Kliteynik static void
161d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb,
162d65e841dSYevgeny Kliteynik 				     struct mlx5dr_match_param *mask)
163d65e841dSYevgeny Kliteynik {
16446779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask);
165d65e841dSYevgeny Kliteynik 
166d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, sb->rx, sb->inner);
167d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
168d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_dst_tag;
169d65e841dSYevgeny Kliteynik }
170d65e841dSYevgeny Kliteynik 
171d65e841dSYevgeny Kliteynik static int
172d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value,
173d65e841dSYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
174d65e841dSYevgeny Kliteynik 				    u8 *tag)
175d65e841dSYevgeny Kliteynik {
176d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
177d65e841dSYevgeny Kliteynik 
178d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96);
179d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64);
180d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32);
181d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0);
182d65e841dSYevgeny Kliteynik 
183d65e841dSYevgeny Kliteynik 	return 0;
184d65e841dSYevgeny Kliteynik }
185d65e841dSYevgeny Kliteynik 
186d65e841dSYevgeny Kliteynik static void
187d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb,
188d65e841dSYevgeny Kliteynik 				     struct mlx5dr_match_param *mask)
189d65e841dSYevgeny Kliteynik {
19046779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask);
191d65e841dSYevgeny Kliteynik 
192d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner);
193d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
194d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag;
195d65e841dSYevgeny Kliteynik }
196d65e841dSYevgeny Kliteynik 
197d65e841dSYevgeny Kliteynik static int
198d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value,
199d65e841dSYevgeny Kliteynik 					struct mlx5dr_ste_build *sb,
200d65e841dSYevgeny Kliteynik 					u8 *tag)
201d65e841dSYevgeny Kliteynik {
202d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
203d65e841dSYevgeny Kliteynik 
204d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0);
205d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0);
206d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport);
207d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport);
208d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport);
209d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport);
210d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol);
211d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag);
212d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp);
213d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn);
214d65e841dSYevgeny Kliteynik 
215d65e841dSYevgeny Kliteynik 	if (spec->tcp_flags) {
216d65e841dSYevgeny Kliteynik 		DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec);
217d65e841dSYevgeny Kliteynik 		spec->tcp_flags = 0;
218d65e841dSYevgeny Kliteynik 	}
219d65e841dSYevgeny Kliteynik 
220d65e841dSYevgeny Kliteynik 	return 0;
221d65e841dSYevgeny Kliteynik }
222d65e841dSYevgeny Kliteynik 
223d65e841dSYevgeny Kliteynik static void
224d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb,
225d65e841dSYevgeny Kliteynik 					 struct mlx5dr_match_param *mask)
226d65e841dSYevgeny Kliteynik {
22746779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask);
228d65e841dSYevgeny Kliteynik 
229d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner);
230d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
231d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag;
232d65e841dSYevgeny Kliteynik }
233d65e841dSYevgeny Kliteynik 
234d65e841dSYevgeny Kliteynik static void
235d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value,
236d65e841dSYevgeny Kliteynik 					   bool inner, u8 *bit_mask)
237d65e841dSYevgeny Kliteynik {
238d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
239d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc_mask = &value->misc;
240d65e841dSYevgeny Kliteynik 
24146779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid);
24246779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi);
24346779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio);
24446779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag);
24546779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype);
24646779098SYevgeny Kliteynik 	DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version);
247d65e841dSYevgeny Kliteynik 
248d65e841dSYevgeny Kliteynik 	if (mask->svlan_tag || mask->cvlan_tag) {
249d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1);
250d65e841dSYevgeny Kliteynik 		mask->cvlan_tag = 0;
251d65e841dSYevgeny Kliteynik 		mask->svlan_tag = 0;
252d65e841dSYevgeny Kliteynik 	}
253d65e841dSYevgeny Kliteynik 
254d65e841dSYevgeny Kliteynik 	if (inner) {
255d65e841dSYevgeny Kliteynik 		if (misc_mask->inner_second_cvlan_tag ||
256d65e841dSYevgeny Kliteynik 		    misc_mask->inner_second_svlan_tag) {
257d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
258d65e841dSYevgeny Kliteynik 			misc_mask->inner_second_cvlan_tag = 0;
259d65e841dSYevgeny Kliteynik 			misc_mask->inner_second_svlan_tag = 0;
260d65e841dSYevgeny Kliteynik 		}
261d65e841dSYevgeny Kliteynik 
26246779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
263d65e841dSYevgeny Kliteynik 			       second_vlan_id, misc_mask, inner_second_vid);
26446779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
265d65e841dSYevgeny Kliteynik 			       second_cfi, misc_mask, inner_second_cfi);
26646779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
267d65e841dSYevgeny Kliteynik 			       second_priority, misc_mask, inner_second_prio);
268d65e841dSYevgeny Kliteynik 	} else {
269d65e841dSYevgeny Kliteynik 		if (misc_mask->outer_second_cvlan_tag ||
270d65e841dSYevgeny Kliteynik 		    misc_mask->outer_second_svlan_tag) {
271d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
272d65e841dSYevgeny Kliteynik 			misc_mask->outer_second_cvlan_tag = 0;
273d65e841dSYevgeny Kliteynik 			misc_mask->outer_second_svlan_tag = 0;
274d65e841dSYevgeny Kliteynik 		}
275d65e841dSYevgeny Kliteynik 
27646779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
277d65e841dSYevgeny Kliteynik 			       second_vlan_id, misc_mask, outer_second_vid);
27846779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
279d65e841dSYevgeny Kliteynik 			       second_cfi, misc_mask, outer_second_cfi);
28046779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
281d65e841dSYevgeny Kliteynik 			       second_priority, misc_mask, outer_second_prio);
282d65e841dSYevgeny Kliteynik 	}
283d65e841dSYevgeny Kliteynik }
284d65e841dSYevgeny Kliteynik 
285d65e841dSYevgeny Kliteynik static int
286d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value,
287d65e841dSYevgeny Kliteynik 				      bool inner, u8 *tag)
288d65e841dSYevgeny Kliteynik {
289d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer;
290d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc_spec = &value->misc;
291d65e841dSYevgeny Kliteynik 
292d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid);
293d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi);
294d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio);
295d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag);
296d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype);
297d65e841dSYevgeny Kliteynik 
298d65e841dSYevgeny Kliteynik 	if (spec->ip_version) {
299d65e841dSYevgeny Kliteynik 		if (spec->ip_version == IP_VERSION_IPV4) {
300d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4);
301d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
302d65e841dSYevgeny Kliteynik 		} else if (spec->ip_version == IP_VERSION_IPV6) {
303d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6);
304d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
305d65e841dSYevgeny Kliteynik 		} else {
306d65e841dSYevgeny Kliteynik 			return -EINVAL;
307d65e841dSYevgeny Kliteynik 		}
308d65e841dSYevgeny Kliteynik 	}
309d65e841dSYevgeny Kliteynik 
310d65e841dSYevgeny Kliteynik 	if (spec->cvlan_tag) {
311d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN);
312d65e841dSYevgeny Kliteynik 		spec->cvlan_tag = 0;
313d65e841dSYevgeny Kliteynik 	} else if (spec->svlan_tag) {
314d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN);
315d65e841dSYevgeny Kliteynik 		spec->svlan_tag = 0;
316d65e841dSYevgeny Kliteynik 	}
317d65e841dSYevgeny Kliteynik 
318d65e841dSYevgeny Kliteynik 	if (inner) {
319d65e841dSYevgeny Kliteynik 		if (misc_spec->inner_second_cvlan_tag) {
320d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
321d65e841dSYevgeny Kliteynik 			misc_spec->inner_second_cvlan_tag = 0;
322d65e841dSYevgeny Kliteynik 		} else if (misc_spec->inner_second_svlan_tag) {
323d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
324d65e841dSYevgeny Kliteynik 			misc_spec->inner_second_svlan_tag = 0;
325d65e841dSYevgeny Kliteynik 		}
326d65e841dSYevgeny Kliteynik 
327d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid);
328d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi);
329d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio);
330d65e841dSYevgeny Kliteynik 	} else {
331d65e841dSYevgeny Kliteynik 		if (misc_spec->outer_second_cvlan_tag) {
332d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
333d65e841dSYevgeny Kliteynik 			misc_spec->outer_second_cvlan_tag = 0;
334d65e841dSYevgeny Kliteynik 		} else if (misc_spec->outer_second_svlan_tag) {
335d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
336d65e841dSYevgeny Kliteynik 			misc_spec->outer_second_svlan_tag = 0;
337d65e841dSYevgeny Kliteynik 		}
338d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid);
339d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi);
340d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio);
341d65e841dSYevgeny Kliteynik 	}
342d65e841dSYevgeny Kliteynik 
343d65e841dSYevgeny Kliteynik 	return 0;
344d65e841dSYevgeny Kliteynik }
345d65e841dSYevgeny Kliteynik 
346d65e841dSYevgeny Kliteynik static void
347d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value,
348d65e841dSYevgeny Kliteynik 				    bool inner, u8 *bit_mask)
349d65e841dSYevgeny Kliteynik {
350d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
351d65e841dSYevgeny Kliteynik 
35246779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16);
35346779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0);
354d65e841dSYevgeny Kliteynik 
355d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
356d65e841dSYevgeny Kliteynik }
357d65e841dSYevgeny Kliteynik 
358d65e841dSYevgeny Kliteynik static int
359d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value,
360d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
361d65e841dSYevgeny Kliteynik 			       u8 *tag)
362d65e841dSYevgeny Kliteynik {
363d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
364d65e841dSYevgeny Kliteynik 
365d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16);
366d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0);
367d65e841dSYevgeny Kliteynik 
368d65e841dSYevgeny Kliteynik 	return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
369d65e841dSYevgeny Kliteynik }
370d65e841dSYevgeny Kliteynik 
371d65e841dSYevgeny Kliteynik static void
372d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb,
373d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
374d65e841dSYevgeny Kliteynik {
375d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask);
376d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner);
377d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
378d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag;
379d65e841dSYevgeny Kliteynik }
380d65e841dSYevgeny Kliteynik 
381d65e841dSYevgeny Kliteynik static void
382d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value,
38346779098SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
38446779098SYevgeny Kliteynik 				    u8 *bit_mask)
385d65e841dSYevgeny Kliteynik {
38646779098SYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer;
387d65e841dSYevgeny Kliteynik 
38846779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
38946779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
390d65e841dSYevgeny Kliteynik 
39146779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask);
392d65e841dSYevgeny Kliteynik }
393d65e841dSYevgeny Kliteynik 
394d65e841dSYevgeny Kliteynik static int
395d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value,
396d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
397d65e841dSYevgeny Kliteynik 			       u8 *tag)
398d65e841dSYevgeny Kliteynik {
399d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
400d65e841dSYevgeny Kliteynik 
401d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16);
402d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0);
403d65e841dSYevgeny Kliteynik 
404d65e841dSYevgeny Kliteynik 	return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
405d65e841dSYevgeny Kliteynik }
406d65e841dSYevgeny Kliteynik 
407d65e841dSYevgeny Kliteynik static void
408d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb,
409d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
410d65e841dSYevgeny Kliteynik {
41146779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask);
412d65e841dSYevgeny Kliteynik 
413d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner);
414d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
415d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag;
416d65e841dSYevgeny Kliteynik }
417d65e841dSYevgeny Kliteynik 
418d65e841dSYevgeny Kliteynik static void
419d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value,
420d65e841dSYevgeny Kliteynik 				    bool inner, u8 *bit_mask)
421d65e841dSYevgeny Kliteynik {
422d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
423d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
424d65e841dSYevgeny Kliteynik 
42546779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16);
42646779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0);
42746779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid);
42846779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi);
42946779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio);
43046779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag);
43146779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype);
43246779098SYevgeny Kliteynik 	DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version);
433d65e841dSYevgeny Kliteynik 
434d65e841dSYevgeny Kliteynik 	if (misc->vxlan_vni) {
435d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, bit_mask,
436d65e841dSYevgeny Kliteynik 			 l2_tunneling_network_id, (misc->vxlan_vni << 8));
437d65e841dSYevgeny Kliteynik 		misc->vxlan_vni = 0;
438d65e841dSYevgeny Kliteynik 	}
439d65e841dSYevgeny Kliteynik 
440d65e841dSYevgeny Kliteynik 	if (mask->svlan_tag || mask->cvlan_tag) {
441d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1);
442d65e841dSYevgeny Kliteynik 		mask->cvlan_tag = 0;
443d65e841dSYevgeny Kliteynik 		mask->svlan_tag = 0;
444d65e841dSYevgeny Kliteynik 	}
445d65e841dSYevgeny Kliteynik }
446d65e841dSYevgeny Kliteynik 
447d65e841dSYevgeny Kliteynik static int
448d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value,
449d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
450d65e841dSYevgeny Kliteynik 			       u8 *tag)
451d65e841dSYevgeny Kliteynik {
452d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
453d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
454d65e841dSYevgeny Kliteynik 
455d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16);
456d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0);
457d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid);
458d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi);
459d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag);
460d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio);
461d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype);
462d65e841dSYevgeny Kliteynik 
463d65e841dSYevgeny Kliteynik 	if (misc->vxlan_vni) {
464d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id,
465d65e841dSYevgeny Kliteynik 			 (misc->vxlan_vni << 8));
466d65e841dSYevgeny Kliteynik 		misc->vxlan_vni = 0;
467d65e841dSYevgeny Kliteynik 	}
468d65e841dSYevgeny Kliteynik 
469d65e841dSYevgeny Kliteynik 	if (spec->cvlan_tag) {
470d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN);
471d65e841dSYevgeny Kliteynik 		spec->cvlan_tag = 0;
472d65e841dSYevgeny Kliteynik 	} else if (spec->svlan_tag) {
473d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN);
474d65e841dSYevgeny Kliteynik 		spec->svlan_tag = 0;
475d65e841dSYevgeny Kliteynik 	}
476d65e841dSYevgeny Kliteynik 
477d65e841dSYevgeny Kliteynik 	if (spec->ip_version) {
478d65e841dSYevgeny Kliteynik 		if (spec->ip_version == IP_VERSION_IPV4) {
479d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4);
480d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
481d65e841dSYevgeny Kliteynik 		} else if (spec->ip_version == IP_VERSION_IPV6) {
482d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6);
483d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
484d65e841dSYevgeny Kliteynik 		} else {
485d65e841dSYevgeny Kliteynik 			return -EINVAL;
486d65e841dSYevgeny Kliteynik 		}
487d65e841dSYevgeny Kliteynik 	}
488d65e841dSYevgeny Kliteynik 
489d65e841dSYevgeny Kliteynik 	return 0;
490d65e841dSYevgeny Kliteynik }
491d65e841dSYevgeny Kliteynik 
492d65e841dSYevgeny Kliteynik static void
493d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb,
494d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
495d65e841dSYevgeny Kliteynik {
496d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask);
497d65e841dSYevgeny Kliteynik 
498*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_ETHL2_TUNNELING_I;
499d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
500d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag;
501d65e841dSYevgeny Kliteynik }
502d65e841dSYevgeny Kliteynik 
503d65e841dSYevgeny Kliteynik static int
504d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value,
505d65e841dSYevgeny Kliteynik 				     struct mlx5dr_ste_build *sb,
506d65e841dSYevgeny Kliteynik 				     u8 *tag)
507d65e841dSYevgeny Kliteynik {
508d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
509d65e841dSYevgeny Kliteynik 
510d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit);
511d65e841dSYevgeny Kliteynik 
512d65e841dSYevgeny Kliteynik 	return 0;
513d65e841dSYevgeny Kliteynik }
514d65e841dSYevgeny Kliteynik 
515d65e841dSYevgeny Kliteynik static void
516d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb,
517d65e841dSYevgeny Kliteynik 				      struct mlx5dr_match_param *mask)
518d65e841dSYevgeny Kliteynik {
51946779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask);
520d65e841dSYevgeny Kliteynik 
521d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner);
522d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
523d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag;
524d65e841dSYevgeny Kliteynik }
525d65e841dSYevgeny Kliteynik 
526d65e841dSYevgeny Kliteynik static int
527d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value,
528d65e841dSYevgeny Kliteynik 				   struct mlx5dr_ste_build *sb,
529d65e841dSYevgeny Kliteynik 				   u8 *tag)
530d65e841dSYevgeny Kliteynik {
531d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
532d65e841dSYevgeny Kliteynik 
533d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport);
534d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport);
535d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport);
536d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport);
537d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol);
538d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag);
539d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp);
540d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn);
541d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit);
542d65e841dSYevgeny Kliteynik 
543d65e841dSYevgeny Kliteynik 	if (spec->tcp_flags) {
544d65e841dSYevgeny Kliteynik 		DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec);
545d65e841dSYevgeny Kliteynik 		spec->tcp_flags = 0;
546d65e841dSYevgeny Kliteynik 	}
547d65e841dSYevgeny Kliteynik 
548d65e841dSYevgeny Kliteynik 	return 0;
549d65e841dSYevgeny Kliteynik }
550d65e841dSYevgeny Kliteynik 
551d65e841dSYevgeny Kliteynik static void
552d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb,
553d65e841dSYevgeny Kliteynik 				    struct mlx5dr_match_param *mask)
554d65e841dSYevgeny Kliteynik {
55546779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask);
556d65e841dSYevgeny Kliteynik 
557d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner);
558d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
559d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag;
560d65e841dSYevgeny Kliteynik }
561d65e841dSYevgeny Kliteynik 
562d65e841dSYevgeny Kliteynik static int
563d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value,
564d65e841dSYevgeny Kliteynik 			 struct mlx5dr_ste_build *sb,
565d65e841dSYevgeny Kliteynik 			 u8 *tag)
566d65e841dSYevgeny Kliteynik {
56746779098SYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc2 = &value->misc2;
568d65e841dSYevgeny Kliteynik 
569d65e841dSYevgeny Kliteynik 	if (sb->inner)
57046779098SYevgeny Kliteynik 		DR_STE_SET_MPLS(mpls, misc2, inner, tag);
571d65e841dSYevgeny Kliteynik 	else
57246779098SYevgeny Kliteynik 		DR_STE_SET_MPLS(mpls, misc2, outer, tag);
573d65e841dSYevgeny Kliteynik 
574d65e841dSYevgeny Kliteynik 	return 0;
575d65e841dSYevgeny Kliteynik }
576d65e841dSYevgeny Kliteynik 
577d65e841dSYevgeny Kliteynik static void
578d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb,
579d65e841dSYevgeny Kliteynik 			  struct mlx5dr_match_param *mask)
580d65e841dSYevgeny Kliteynik {
58146779098SYevgeny Kliteynik 	dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask);
582d65e841dSYevgeny Kliteynik 
583d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner);
584d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
585d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag;
586d65e841dSYevgeny Kliteynik }
587d65e841dSYevgeny Kliteynik 
588d65e841dSYevgeny Kliteynik static int
589d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value,
590d65e841dSYevgeny Kliteynik 			    struct mlx5dr_ste_build *sb,
591d65e841dSYevgeny Kliteynik 			    u8 *tag)
592d65e841dSYevgeny Kliteynik {
593d65e841dSYevgeny Kliteynik 	struct  mlx5dr_match_misc *misc = &value->misc;
594d65e841dSYevgeny Kliteynik 
595d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol);
596d65e841dSYevgeny Kliteynik 
597d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present);
598d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h);
599d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l);
600d65e841dSYevgeny Kliteynik 
601d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present);
602d65e841dSYevgeny Kliteynik 
603d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present);
604d65e841dSYevgeny Kliteynik 
605d65e841dSYevgeny Kliteynik 	return 0;
606d65e841dSYevgeny Kliteynik }
607d65e841dSYevgeny Kliteynik 
608d65e841dSYevgeny Kliteynik static void
609d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb,
610d65e841dSYevgeny Kliteynik 			     struct mlx5dr_match_param *mask)
611d65e841dSYevgeny Kliteynik {
61246779098SYevgeny Kliteynik 	dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask);
613d65e841dSYevgeny Kliteynik 
614*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_GRE;
615d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
616d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag;
617d65e841dSYevgeny Kliteynik }
618d65e841dSYevgeny Kliteynik 
619d65e841dSYevgeny Kliteynik static int
620d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value,
621d65e841dSYevgeny Kliteynik 			     struct mlx5dr_ste_build *sb,
622d65e841dSYevgeny Kliteynik 			     u8 *tag)
623d65e841dSYevgeny Kliteynik {
62446779098SYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc_2 = &value->misc2;
625d65e841dSYevgeny Kliteynik 
62646779098SYevgeny Kliteynik 	if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) {
627d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label,
62846779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_label);
629d65e841dSYevgeny Kliteynik 
630d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp,
63146779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_exp);
632d65e841dSYevgeny Kliteynik 
633d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos,
63446779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_s_bos);
635d65e841dSYevgeny Kliteynik 
636d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl,
63746779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_ttl);
638d65e841dSYevgeny Kliteynik 	} else {
639d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label,
64046779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_label);
641d65e841dSYevgeny Kliteynik 
642d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp,
64346779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_exp);
644d65e841dSYevgeny Kliteynik 
645d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos,
64646779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_s_bos);
647d65e841dSYevgeny Kliteynik 
648d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl,
64946779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_ttl);
650d65e841dSYevgeny Kliteynik 	}
651d65e841dSYevgeny Kliteynik 	return 0;
652d65e841dSYevgeny Kliteynik }
653d65e841dSYevgeny Kliteynik 
654d65e841dSYevgeny Kliteynik static void
655d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb,
656d65e841dSYevgeny Kliteynik 			      struct mlx5dr_match_param *mask)
657d65e841dSYevgeny Kliteynik {
65846779098SYevgeny Kliteynik 	dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask);
659d65e841dSYevgeny Kliteynik 
660*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_0;
661d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
662d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag;
663d65e841dSYevgeny Kliteynik }
664d65e841dSYevgeny Kliteynik 
665d65e841dSYevgeny Kliteynik #define ICMP_TYPE_OFFSET_FIRST_DW		24
666d65e841dSYevgeny Kliteynik #define ICMP_CODE_OFFSET_FIRST_DW		16
667d65e841dSYevgeny Kliteynik #define ICMP_HEADER_DATA_OFFSET_SECOND_DW	0
668d65e841dSYevgeny Kliteynik 
669d65e841dSYevgeny Kliteynik static int
670d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value,
671d65e841dSYevgeny Kliteynik 			 struct mlx5dr_ste_build *sb,
672d65e841dSYevgeny Kliteynik 			 u8 *tag)
673d65e841dSYevgeny Kliteynik {
674d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc3 *misc_3 = &value->misc3;
675d65e841dSYevgeny Kliteynik 	u32 icmp_header_data;
676d65e841dSYevgeny Kliteynik 	int dw0_location;
677d65e841dSYevgeny Kliteynik 	int dw1_location;
678d65e841dSYevgeny Kliteynik 	u32 icmp_type;
679d65e841dSYevgeny Kliteynik 	u32 icmp_code;
680d65e841dSYevgeny Kliteynik 	bool is_ipv4;
681d65e841dSYevgeny Kliteynik 
682d65e841dSYevgeny Kliteynik 	is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3);
683d65e841dSYevgeny Kliteynik 	if (is_ipv4) {
684d65e841dSYevgeny Kliteynik 		icmp_header_data	= misc_3->icmpv4_header_data;
685d65e841dSYevgeny Kliteynik 		icmp_type		= misc_3->icmpv4_type;
686d65e841dSYevgeny Kliteynik 		icmp_code		= misc_3->icmpv4_code;
687d65e841dSYevgeny Kliteynik 		dw0_location		= sb->caps->flex_parser_id_icmp_dw0;
688d65e841dSYevgeny Kliteynik 		dw1_location		= sb->caps->flex_parser_id_icmp_dw1;
689d65e841dSYevgeny Kliteynik 	} else {
690d65e841dSYevgeny Kliteynik 		icmp_header_data	= misc_3->icmpv6_header_data;
691d65e841dSYevgeny Kliteynik 		icmp_type		= misc_3->icmpv6_type;
692d65e841dSYevgeny Kliteynik 		icmp_code		= misc_3->icmpv6_code;
693d65e841dSYevgeny Kliteynik 		dw0_location		= sb->caps->flex_parser_id_icmpv6_dw0;
694d65e841dSYevgeny Kliteynik 		dw1_location		= sb->caps->flex_parser_id_icmpv6_dw1;
695d65e841dSYevgeny Kliteynik 	}
696d65e841dSYevgeny Kliteynik 
697d65e841dSYevgeny Kliteynik 	switch (dw0_location) {
698d65e841dSYevgeny Kliteynik 	case 4:
699d65e841dSYevgeny Kliteynik 		if (icmp_type) {
700d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_flex_parser_1, tag, flex_parser_4,
701d65e841dSYevgeny Kliteynik 				 (icmp_type << ICMP_TYPE_OFFSET_FIRST_DW));
702d65e841dSYevgeny Kliteynik 			if (is_ipv4)
703d65e841dSYevgeny Kliteynik 				misc_3->icmpv4_type = 0;
704d65e841dSYevgeny Kliteynik 			else
705d65e841dSYevgeny Kliteynik 				misc_3->icmpv6_type = 0;
706d65e841dSYevgeny Kliteynik 		}
707d65e841dSYevgeny Kliteynik 
708d65e841dSYevgeny Kliteynik 		if (icmp_code) {
709d65e841dSYevgeny Kliteynik 			u32 cur_val = MLX5_GET(ste_flex_parser_1, tag,
710d65e841dSYevgeny Kliteynik 					       flex_parser_4);
711d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_flex_parser_1, tag, flex_parser_4,
712d65e841dSYevgeny Kliteynik 				 cur_val | (icmp_code << ICMP_CODE_OFFSET_FIRST_DW));
713d65e841dSYevgeny Kliteynik 			if (is_ipv4)
714d65e841dSYevgeny Kliteynik 				misc_3->icmpv4_code = 0;
715d65e841dSYevgeny Kliteynik 			else
716d65e841dSYevgeny Kliteynik 				misc_3->icmpv6_code = 0;
717d65e841dSYevgeny Kliteynik 		}
718d65e841dSYevgeny Kliteynik 		break;
719d65e841dSYevgeny Kliteynik 	default:
720d65e841dSYevgeny Kliteynik 		return -EINVAL;
721d65e841dSYevgeny Kliteynik 	}
722d65e841dSYevgeny Kliteynik 
723d65e841dSYevgeny Kliteynik 	switch (dw1_location) {
724d65e841dSYevgeny Kliteynik 	case 5:
725d65e841dSYevgeny Kliteynik 		if (icmp_header_data) {
726d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_flex_parser_1, tag, flex_parser_5,
727d65e841dSYevgeny Kliteynik 				 (icmp_header_data << ICMP_HEADER_DATA_OFFSET_SECOND_DW));
728d65e841dSYevgeny Kliteynik 			if (is_ipv4)
729d65e841dSYevgeny Kliteynik 				misc_3->icmpv4_header_data = 0;
730d65e841dSYevgeny Kliteynik 			else
731d65e841dSYevgeny Kliteynik 				misc_3->icmpv6_header_data = 0;
732d65e841dSYevgeny Kliteynik 		}
733d65e841dSYevgeny Kliteynik 		break;
734d65e841dSYevgeny Kliteynik 	default:
735d65e841dSYevgeny Kliteynik 		return -EINVAL;
736d65e841dSYevgeny Kliteynik 	}
737d65e841dSYevgeny Kliteynik 
738d65e841dSYevgeny Kliteynik 	return 0;
739d65e841dSYevgeny Kliteynik }
740d65e841dSYevgeny Kliteynik 
741d65e841dSYevgeny Kliteynik static int
742d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb,
743d65e841dSYevgeny Kliteynik 			  struct mlx5dr_match_param *mask)
744d65e841dSYevgeny Kliteynik {
745d65e841dSYevgeny Kliteynik 	int ret;
746d65e841dSYevgeny Kliteynik 
74746779098SYevgeny Kliteynik 	ret = dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask);
748d65e841dSYevgeny Kliteynik 	if (ret)
749d65e841dSYevgeny Kliteynik 		return ret;
750d65e841dSYevgeny Kliteynik 
751*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_1;
752d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
753d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag;
754d65e841dSYevgeny Kliteynik 
755d65e841dSYevgeny Kliteynik 	return 0;
756d65e841dSYevgeny Kliteynik }
757d65e841dSYevgeny Kliteynik 
758d65e841dSYevgeny Kliteynik static int
759d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value,
760d65e841dSYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
761d65e841dSYevgeny Kliteynik 				    u8 *tag)
762d65e841dSYevgeny Kliteynik {
76346779098SYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc_2 = &value->misc2;
764d65e841dSYevgeny Kliteynik 
765d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field,
76646779098SYevgeny Kliteynik 		       misc_2, metadata_reg_a);
767d65e841dSYevgeny Kliteynik 
768d65e841dSYevgeny Kliteynik 	return 0;
769d65e841dSYevgeny Kliteynik }
770d65e841dSYevgeny Kliteynik 
771d65e841dSYevgeny Kliteynik static void
772d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb,
773d65e841dSYevgeny Kliteynik 				     struct mlx5dr_match_param *mask)
774d65e841dSYevgeny Kliteynik {
77546779098SYevgeny Kliteynik 	dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask);
776d65e841dSYevgeny Kliteynik 
777*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_GENERAL_PURPOSE;
778d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
779d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag;
780d65e841dSYevgeny Kliteynik }
781d65e841dSYevgeny Kliteynik 
782d65e841dSYevgeny Kliteynik static int
783d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value,
784d65e841dSYevgeny Kliteynik 				struct mlx5dr_ste_build *sb,
785d65e841dSYevgeny Kliteynik 				u8 *tag)
786d65e841dSYevgeny Kliteynik {
787d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc3 *misc3 = &value->misc3;
788d65e841dSYevgeny Kliteynik 
789d65e841dSYevgeny Kliteynik 	if (sb->inner) {
790d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num);
791d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num);
792d65e841dSYevgeny Kliteynik 	} else {
793d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num);
794d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num);
795d65e841dSYevgeny Kliteynik 	}
796d65e841dSYevgeny Kliteynik 
797d65e841dSYevgeny Kliteynik 	return 0;
798d65e841dSYevgeny Kliteynik }
799d65e841dSYevgeny Kliteynik 
800d65e841dSYevgeny Kliteynik static void
801d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb,
802d65e841dSYevgeny Kliteynik 				 struct mlx5dr_match_param *mask)
803d65e841dSYevgeny Kliteynik {
80446779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask);
805d65e841dSYevgeny Kliteynik 
806d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner);
807d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
808d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag;
809d65e841dSYevgeny Kliteynik }
810d65e841dSYevgeny Kliteynik 
811d65e841dSYevgeny Kliteynik static int
812d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value,
813d65e841dSYevgeny Kliteynik 					      struct mlx5dr_ste_build *sb,
814d65e841dSYevgeny Kliteynik 					      u8 *tag)
815d65e841dSYevgeny Kliteynik {
816d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc3 *misc3 = &value->misc3;
817d65e841dSYevgeny Kliteynik 
818d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
819d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_flags, misc3,
820d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_flags);
821d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
822d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_next_protocol, misc3,
823d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_next_protocol);
824d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
825d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_vni, misc3,
826d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_vni);
827d65e841dSYevgeny Kliteynik 
828d65e841dSYevgeny Kliteynik 	return 0;
829d65e841dSYevgeny Kliteynik }
830d65e841dSYevgeny Kliteynik 
831d65e841dSYevgeny Kliteynik static void
832d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb,
833d65e841dSYevgeny Kliteynik 					       struct mlx5dr_match_param *mask)
834d65e841dSYevgeny Kliteynik {
83546779098SYevgeny Kliteynik 	dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask);
836*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER;
837d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
838d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag;
839d65e841dSYevgeny Kliteynik }
840d65e841dSYevgeny Kliteynik 
841d65e841dSYevgeny Kliteynik static int
842d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value,
843d65e841dSYevgeny Kliteynik 					   struct mlx5dr_ste_build *sb,
844d65e841dSYevgeny Kliteynik 					   u8 *tag)
845d65e841dSYevgeny Kliteynik {
846d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
847d65e841dSYevgeny Kliteynik 
848d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
849d65e841dSYevgeny Kliteynik 		       geneve_protocol_type, misc, geneve_protocol_type);
850d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
851d65e841dSYevgeny Kliteynik 		       geneve_oam, misc, geneve_oam);
852d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
853d65e841dSYevgeny Kliteynik 		       geneve_opt_len, misc, geneve_opt_len);
854d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
855d65e841dSYevgeny Kliteynik 		       geneve_vni, misc, geneve_vni);
856d65e841dSYevgeny Kliteynik 
857d65e841dSYevgeny Kliteynik 	return 0;
858d65e841dSYevgeny Kliteynik }
859d65e841dSYevgeny Kliteynik 
860d65e841dSYevgeny Kliteynik static void
861d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb,
862d65e841dSYevgeny Kliteynik 					    struct mlx5dr_match_param *mask)
863d65e841dSYevgeny Kliteynik {
86446779098SYevgeny Kliteynik 	dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask);
865*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_FLEX_PARSER_TNL_HEADER;
866d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
867d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag;
868d65e841dSYevgeny Kliteynik }
869d65e841dSYevgeny Kliteynik 
870d65e841dSYevgeny Kliteynik static int
871d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value,
872d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
873d65e841dSYevgeny Kliteynik 			       u8 *tag)
874d65e841dSYevgeny Kliteynik {
875d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc2 = &value->misc2;
876d65e841dSYevgeny Kliteynik 
877d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0);
878d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1);
879d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2);
880d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3);
881d65e841dSYevgeny Kliteynik 
882d65e841dSYevgeny Kliteynik 	return 0;
883d65e841dSYevgeny Kliteynik }
884d65e841dSYevgeny Kliteynik 
885d65e841dSYevgeny Kliteynik static void
886d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb,
887d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
888d65e841dSYevgeny Kliteynik {
88946779098SYevgeny Kliteynik 	dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask);
890d65e841dSYevgeny Kliteynik 
891*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_0;
892d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
893d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag;
894d65e841dSYevgeny Kliteynik }
895d65e841dSYevgeny Kliteynik 
896d65e841dSYevgeny Kliteynik static int
897d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value,
898d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
899d65e841dSYevgeny Kliteynik 			       u8 *tag)
900d65e841dSYevgeny Kliteynik {
901d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc2 = &value->misc2;
902d65e841dSYevgeny Kliteynik 
903d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4);
904d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5);
905d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6);
906d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7);
907d65e841dSYevgeny Kliteynik 
908d65e841dSYevgeny Kliteynik 	return 0;
909d65e841dSYevgeny Kliteynik }
910d65e841dSYevgeny Kliteynik 
911d65e841dSYevgeny Kliteynik static void
912d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb,
913d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
914d65e841dSYevgeny Kliteynik {
91546779098SYevgeny Kliteynik 	dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask);
916d65e841dSYevgeny Kliteynik 
917*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_STEERING_REGISTERS_1;
918d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
919d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag;
920d65e841dSYevgeny Kliteynik }
921d65e841dSYevgeny Kliteynik 
922d65e841dSYevgeny Kliteynik static void
923d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value,
924d65e841dSYevgeny Kliteynik 				      u8 *bit_mask)
925d65e841dSYevgeny Kliteynik {
926d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc_mask = &value->misc;
927d65e841dSYevgeny Kliteynik 
92846779098SYevgeny Kliteynik 	DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port);
92946779098SYevgeny Kliteynik 	DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn);
930d65e841dSYevgeny Kliteynik 	misc_mask->source_eswitch_owner_vhca_id = 0;
931d65e841dSYevgeny Kliteynik }
932d65e841dSYevgeny Kliteynik 
933d65e841dSYevgeny Kliteynik static int
934d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
935d65e841dSYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
936d65e841dSYevgeny Kliteynik 				 u8 *tag)
937d65e841dSYevgeny Kliteynik {
938d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
939d65e841dSYevgeny Kliteynik 	struct mlx5dr_cmd_vport_cap *vport_cap;
940d65e841dSYevgeny Kliteynik 	struct mlx5dr_domain *dmn = sb->dmn;
941d65e841dSYevgeny Kliteynik 	struct mlx5dr_cmd_caps *caps;
942d65e841dSYevgeny Kliteynik 	u8 *bit_mask = sb->bit_mask;
943d65e841dSYevgeny Kliteynik 	bool source_gvmi_set;
944d65e841dSYevgeny Kliteynik 
945d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn);
946d65e841dSYevgeny Kliteynik 
947d65e841dSYevgeny Kliteynik 	if (sb->vhca_id_valid) {
948d65e841dSYevgeny Kliteynik 		/* Find port GVMI based on the eswitch_owner_vhca_id */
949d65e841dSYevgeny Kliteynik 		if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
950d65e841dSYevgeny Kliteynik 			caps = &dmn->info.caps;
951d65e841dSYevgeny Kliteynik 		else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
952d65e841dSYevgeny Kliteynik 					   dmn->peer_dmn->info.caps.gvmi))
953d65e841dSYevgeny Kliteynik 			caps = &dmn->peer_dmn->info.caps;
954d65e841dSYevgeny Kliteynik 		else
955d65e841dSYevgeny Kliteynik 			return -EINVAL;
9567863c912SYevgeny Kliteynik 
9577863c912SYevgeny Kliteynik 		misc->source_eswitch_owner_vhca_id = 0;
958d65e841dSYevgeny Kliteynik 	} else {
959d65e841dSYevgeny Kliteynik 		caps = &dmn->info.caps;
960d65e841dSYevgeny Kliteynik 	}
961d65e841dSYevgeny Kliteynik 
9627863c912SYevgeny Kliteynik 	source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi);
9637863c912SYevgeny Kliteynik 	if (source_gvmi_set) {
964d65e841dSYevgeny Kliteynik 		vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port);
965d65e841dSYevgeny Kliteynik 		if (!vport_cap) {
966d65e841dSYevgeny Kliteynik 			mlx5dr_err(dmn, "Vport 0x%x is invalid\n",
967d65e841dSYevgeny Kliteynik 				   misc->source_port);
968d65e841dSYevgeny Kliteynik 			return -EINVAL;
969d65e841dSYevgeny Kliteynik 		}
970d65e841dSYevgeny Kliteynik 
9717863c912SYevgeny Kliteynik 		if (vport_cap->vport_gvmi)
972d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi);
973d65e841dSYevgeny Kliteynik 
974d65e841dSYevgeny Kliteynik 		misc->source_port = 0;
9757863c912SYevgeny Kliteynik 	}
976d65e841dSYevgeny Kliteynik 
977d65e841dSYevgeny Kliteynik 	return 0;
978d65e841dSYevgeny Kliteynik }
979d65e841dSYevgeny Kliteynik 
980d65e841dSYevgeny Kliteynik static void
981d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb,
982d65e841dSYevgeny Kliteynik 				  struct mlx5dr_match_param *mask)
983d65e841dSYevgeny Kliteynik {
984d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask);
985d65e841dSYevgeny Kliteynik 
986*dd2d3c8dSYevgeny Kliteynik 	sb->lu_type = DR_STE_V0_LU_TYPE_SRC_GVMI_AND_QP;
987d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
988d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag;
989d65e841dSYevgeny Kliteynik }
990d65e841dSYevgeny Kliteynik 
991d65e841dSYevgeny Kliteynik struct mlx5dr_ste_ctx ste_ctx_v0 = {
992d65e841dSYevgeny Kliteynik 	.build_eth_l2_src_dst_init	= &dr_ste_v0_build_eth_l2_src_dst_init,
993d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv6_src_init	= &dr_ste_v0_build_eth_l3_ipv6_src_init,
994d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv6_dst_init	= &dr_ste_v0_build_eth_l3_ipv6_dst_init,
995d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv4_5_tuple_init	= &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init,
996d65e841dSYevgeny Kliteynik 	.build_eth_l2_src_init		= &dr_ste_v0_build_eth_l2_src_init,
997d65e841dSYevgeny Kliteynik 	.build_eth_l2_dst_init		= &dr_ste_v0_build_eth_l2_dst_init,
998d65e841dSYevgeny Kliteynik 	.build_eth_l2_tnl_init		= &dr_ste_v0_build_eth_l2_tnl_init,
999d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv4_misc_init	= &dr_ste_v0_build_eth_l3_ipv4_misc_init,
1000d65e841dSYevgeny Kliteynik 	.build_eth_ipv6_l3_l4_init	= &dr_ste_v0_build_eth_ipv6_l3_l4_init,
1001d65e841dSYevgeny Kliteynik 	.build_mpls_init		= &dr_ste_v0_build_mpls_init,
1002d65e841dSYevgeny Kliteynik 	.build_tnl_gre_init		= &dr_ste_v0_build_tnl_gre_init,
1003d65e841dSYevgeny Kliteynik 	.build_tnl_mpls_init		= &dr_ste_v0_build_tnl_mpls_init,
1004d65e841dSYevgeny Kliteynik 	.build_icmp_init		= &dr_ste_v0_build_icmp_init,
1005d65e841dSYevgeny Kliteynik 	.build_general_purpose_init	= &dr_ste_v0_build_general_purpose_init,
1006d65e841dSYevgeny Kliteynik 	.build_eth_l4_misc_init		= &dr_ste_v0_build_eth_l4_misc_init,
1007d65e841dSYevgeny Kliteynik 	.build_tnl_vxlan_gpe_init	= &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init,
1008d65e841dSYevgeny Kliteynik 	.build_tnl_geneve_init		= &dr_ste_v0_build_flex_parser_tnl_geneve_init,
1009d65e841dSYevgeny Kliteynik 	.build_register_0_init		= &dr_ste_v0_build_register_0_init,
1010d65e841dSYevgeny Kliteynik 	.build_register_1_init		= &dr_ste_v0_build_register_1_init,
1011d65e841dSYevgeny Kliteynik 	.build_src_gvmi_qpn_init	= &dr_ste_v0_build_src_gvmi_qpn_init,
1012d65e841dSYevgeny Kliteynik };
1013