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) \
9d65e841dSYevgeny Kliteynik 	((inner) ? MLX5DR_STE_LU_TYPE_##lookup_type##_I : \
10d65e841dSYevgeny Kliteynik 		   (rx) ? MLX5DR_STE_LU_TYPE_##lookup_type##_D : \
11d65e841dSYevgeny Kliteynik 			  MLX5DR_STE_LU_TYPE_##lookup_type##_O)
12d65e841dSYevgeny Kliteynik 
13d65e841dSYevgeny Kliteynik static void
14d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_bit_mask(struct mlx5dr_match_param *value,
15d65e841dSYevgeny Kliteynik 					bool inner, u8 *bit_mask)
16d65e841dSYevgeny Kliteynik {
17d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
18d65e841dSYevgeny Kliteynik 
19*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
20*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
21d65e841dSYevgeny Kliteynik 
22d65e841dSYevgeny Kliteynik 	if (mask->smac_47_16 || mask->smac_15_0) {
23d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_47_32,
24d65e841dSYevgeny Kliteynik 			 mask->smac_47_16 >> 16);
25d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, smac_31_0,
26d65e841dSYevgeny Kliteynik 			 mask->smac_47_16 << 16 | mask->smac_15_0);
27d65e841dSYevgeny Kliteynik 		mask->smac_47_16 = 0;
28d65e841dSYevgeny Kliteynik 		mask->smac_15_0 = 0;
29d65e841dSYevgeny Kliteynik 	}
30d65e841dSYevgeny Kliteynik 
31*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_vlan_id, mask, first_vid);
32*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_cfi, mask, first_cfi);
33*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, bit_mask, first_priority, mask, first_prio);
34*46779098SYevgeny Kliteynik 	DR_STE_SET_ONES(eth_l2_src_dst, bit_mask, l3_type, mask, ip_version);
35d65e841dSYevgeny Kliteynik 
36d65e841dSYevgeny Kliteynik 	if (mask->cvlan_tag) {
37d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
38d65e841dSYevgeny Kliteynik 		mask->cvlan_tag = 0;
39d65e841dSYevgeny Kliteynik 	} else if (mask->svlan_tag) {
40d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, bit_mask, first_vlan_qualifier, -1);
41d65e841dSYevgeny Kliteynik 		mask->svlan_tag = 0;
42d65e841dSYevgeny Kliteynik 	}
43d65e841dSYevgeny Kliteynik }
44d65e841dSYevgeny Kliteynik 
45d65e841dSYevgeny Kliteynik static int
46d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_tag(struct mlx5dr_match_param *value,
47d65e841dSYevgeny Kliteynik 				   struct mlx5dr_ste_build *sb,
48d65e841dSYevgeny Kliteynik 				   u8 *tag)
49d65e841dSYevgeny Kliteynik {
50d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
51d65e841dSYevgeny Kliteynik 
52d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_47_16, spec, dmac_47_16);
53d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, dmac_15_0, spec, dmac_15_0);
54d65e841dSYevgeny Kliteynik 
55d65e841dSYevgeny Kliteynik 	if (spec->smac_47_16 || spec->smac_15_0) {
56d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, smac_47_32,
57d65e841dSYevgeny Kliteynik 			 spec->smac_47_16 >> 16);
58d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, smac_31_0,
59d65e841dSYevgeny Kliteynik 			 spec->smac_47_16 << 16 | spec->smac_15_0);
60d65e841dSYevgeny Kliteynik 		spec->smac_47_16 = 0;
61d65e841dSYevgeny Kliteynik 		spec->smac_15_0 = 0;
62d65e841dSYevgeny Kliteynik 	}
63d65e841dSYevgeny Kliteynik 
64d65e841dSYevgeny Kliteynik 	if (spec->ip_version) {
65d65e841dSYevgeny Kliteynik 		if (spec->ip_version == IP_VERSION_IPV4) {
66d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV4);
67d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
68d65e841dSYevgeny Kliteynik 		} else if (spec->ip_version == IP_VERSION_IPV6) {
69d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src_dst, tag, l3_type, STE_IPV6);
70d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
71d65e841dSYevgeny Kliteynik 		} else {
72d65e841dSYevgeny Kliteynik 			return -EINVAL;
73d65e841dSYevgeny Kliteynik 		}
74d65e841dSYevgeny Kliteynik 	}
75d65e841dSYevgeny Kliteynik 
76d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, first_vlan_id, spec, first_vid);
77d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, first_cfi, spec, first_cfi);
78d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src_dst, tag, first_priority, spec, first_prio);
79d65e841dSYevgeny Kliteynik 
80d65e841dSYevgeny Kliteynik 	if (spec->cvlan_tag) {
81d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_CVLAN);
82d65e841dSYevgeny Kliteynik 		spec->cvlan_tag = 0;
83d65e841dSYevgeny Kliteynik 	} else if (spec->svlan_tag) {
84d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src_dst, tag, first_vlan_qualifier, DR_STE_SVLAN);
85d65e841dSYevgeny Kliteynik 		spec->svlan_tag = 0;
86d65e841dSYevgeny Kliteynik 	}
87d65e841dSYevgeny Kliteynik 	return 0;
88d65e841dSYevgeny Kliteynik }
89d65e841dSYevgeny Kliteynik 
90d65e841dSYevgeny Kliteynik static void
91d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_dst_init(struct mlx5dr_ste_build *sb,
92d65e841dSYevgeny Kliteynik 				    struct mlx5dr_match_param *mask)
93d65e841dSYevgeny Kliteynik {
94d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_dst_bit_mask(mask, sb->inner, sb->bit_mask);
95d65e841dSYevgeny Kliteynik 
96d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC_DST, sb->rx, sb->inner);
97d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
98d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_dst_tag;
99d65e841dSYevgeny Kliteynik }
100d65e841dSYevgeny Kliteynik 
101d65e841dSYevgeny Kliteynik static int
102d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_tag(struct mlx5dr_match_param *value,
103d65e841dSYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
104d65e841dSYevgeny Kliteynik 				    u8 *tag)
105d65e841dSYevgeny Kliteynik {
106d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
107d65e841dSYevgeny Kliteynik 
108d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_127_96, spec, dst_ip_127_96);
109d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_95_64, spec, dst_ip_95_64);
110d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_63_32, spec, dst_ip_63_32);
111d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_dst, tag, dst_ip_31_0, spec, dst_ip_31_0);
112d65e841dSYevgeny Kliteynik 
113d65e841dSYevgeny Kliteynik 	return 0;
114d65e841dSYevgeny Kliteynik }
115d65e841dSYevgeny Kliteynik 
116d65e841dSYevgeny Kliteynik static void
117d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_dst_init(struct mlx5dr_ste_build *sb,
118d65e841dSYevgeny Kliteynik 				     struct mlx5dr_match_param *mask)
119d65e841dSYevgeny Kliteynik {
120*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv6_dst_tag(mask, sb, sb->bit_mask);
121d65e841dSYevgeny Kliteynik 
122d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_DST, sb->rx, sb->inner);
123d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
124d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_dst_tag;
125d65e841dSYevgeny Kliteynik }
126d65e841dSYevgeny Kliteynik 
127d65e841dSYevgeny Kliteynik static int
128d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_tag(struct mlx5dr_match_param *value,
129d65e841dSYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
130d65e841dSYevgeny Kliteynik 				    u8 *tag)
131d65e841dSYevgeny Kliteynik {
132d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
133d65e841dSYevgeny Kliteynik 
134d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_127_96, spec, src_ip_127_96);
135d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_95_64, spec, src_ip_95_64);
136d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_63_32, spec, src_ip_63_32);
137d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv6_src, tag, src_ip_31_0, spec, src_ip_31_0);
138d65e841dSYevgeny Kliteynik 
139d65e841dSYevgeny Kliteynik 	return 0;
140d65e841dSYevgeny Kliteynik }
141d65e841dSYevgeny Kliteynik 
142d65e841dSYevgeny Kliteynik static void
143d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv6_src_init(struct mlx5dr_ste_build *sb,
144d65e841dSYevgeny Kliteynik 				     struct mlx5dr_match_param *mask)
145d65e841dSYevgeny Kliteynik {
146*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv6_src_tag(mask, sb, sb->bit_mask);
147d65e841dSYevgeny Kliteynik 
148d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV6_SRC, sb->rx, sb->inner);
149d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
150d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv6_src_tag;
151d65e841dSYevgeny Kliteynik }
152d65e841dSYevgeny Kliteynik 
153d65e841dSYevgeny Kliteynik static int
154d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(struct mlx5dr_match_param *value,
155d65e841dSYevgeny Kliteynik 					struct mlx5dr_ste_build *sb,
156d65e841dSYevgeny Kliteynik 					u8 *tag)
157d65e841dSYevgeny Kliteynik {
158d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
159d65e841dSYevgeny Kliteynik 
160d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_address, spec, dst_ip_31_0);
161d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_address, spec, src_ip_31_0);
162d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, tcp_dport);
163d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, destination_port, spec, udp_dport);
164d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, tcp_sport);
165d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, source_port, spec, udp_sport);
166d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, protocol, spec, ip_protocol);
167d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, fragmented, spec, frag);
168d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, dscp, spec, ip_dscp);
169d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_5_tuple, tag, ecn, spec, ip_ecn);
170d65e841dSYevgeny Kliteynik 
171d65e841dSYevgeny Kliteynik 	if (spec->tcp_flags) {
172d65e841dSYevgeny Kliteynik 		DR_STE_SET_TCP_FLAGS(eth_l3_ipv4_5_tuple, tag, spec);
173d65e841dSYevgeny Kliteynik 		spec->tcp_flags = 0;
174d65e841dSYevgeny Kliteynik 	}
175d65e841dSYevgeny Kliteynik 
176d65e841dSYevgeny Kliteynik 	return 0;
177d65e841dSYevgeny Kliteynik }
178d65e841dSYevgeny Kliteynik 
179d65e841dSYevgeny Kliteynik static void
180d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_5_tuple_init(struct mlx5dr_ste_build *sb,
181d65e841dSYevgeny Kliteynik 					 struct mlx5dr_match_param *mask)
182d65e841dSYevgeny Kliteynik {
183*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag(mask, sb, sb->bit_mask);
184d65e841dSYevgeny Kliteynik 
185d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_5_TUPLE, sb->rx, sb->inner);
186d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
187d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_5_tuple_tag;
188d65e841dSYevgeny Kliteynik }
189d65e841dSYevgeny Kliteynik 
190d65e841dSYevgeny Kliteynik static void
191d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(struct mlx5dr_match_param *value,
192d65e841dSYevgeny Kliteynik 					   bool inner, u8 *bit_mask)
193d65e841dSYevgeny Kliteynik {
194d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
195d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc_mask = &value->misc;
196d65e841dSYevgeny Kliteynik 
197*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, first_vlan_id, mask, first_vid);
198*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, first_cfi, mask, first_cfi);
199*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, first_priority, mask, first_prio);
200*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, ip_fragmented, mask, frag);
201*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, l3_ethertype, mask, ethertype);
202*46779098SYevgeny Kliteynik 	DR_STE_SET_ONES(eth_l2_src, bit_mask, l3_type, mask, ip_version);
203d65e841dSYevgeny Kliteynik 
204d65e841dSYevgeny Kliteynik 	if (mask->svlan_tag || mask->cvlan_tag) {
205d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src, bit_mask, first_vlan_qualifier, -1);
206d65e841dSYevgeny Kliteynik 		mask->cvlan_tag = 0;
207d65e841dSYevgeny Kliteynik 		mask->svlan_tag = 0;
208d65e841dSYevgeny Kliteynik 	}
209d65e841dSYevgeny Kliteynik 
210d65e841dSYevgeny Kliteynik 	if (inner) {
211d65e841dSYevgeny Kliteynik 		if (misc_mask->inner_second_cvlan_tag ||
212d65e841dSYevgeny Kliteynik 		    misc_mask->inner_second_svlan_tag) {
213d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
214d65e841dSYevgeny Kliteynik 			misc_mask->inner_second_cvlan_tag = 0;
215d65e841dSYevgeny Kliteynik 			misc_mask->inner_second_svlan_tag = 0;
216d65e841dSYevgeny Kliteynik 		}
217d65e841dSYevgeny Kliteynik 
218*46779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
219d65e841dSYevgeny Kliteynik 			       second_vlan_id, misc_mask, inner_second_vid);
220*46779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
221d65e841dSYevgeny Kliteynik 			       second_cfi, misc_mask, inner_second_cfi);
222*46779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
223d65e841dSYevgeny Kliteynik 			       second_priority, misc_mask, inner_second_prio);
224d65e841dSYevgeny Kliteynik 	} else {
225d65e841dSYevgeny Kliteynik 		if (misc_mask->outer_second_cvlan_tag ||
226d65e841dSYevgeny Kliteynik 		    misc_mask->outer_second_svlan_tag) {
227d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, bit_mask, second_vlan_qualifier, -1);
228d65e841dSYevgeny Kliteynik 			misc_mask->outer_second_cvlan_tag = 0;
229d65e841dSYevgeny Kliteynik 			misc_mask->outer_second_svlan_tag = 0;
230d65e841dSYevgeny Kliteynik 		}
231d65e841dSYevgeny Kliteynik 
232*46779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
233d65e841dSYevgeny Kliteynik 			       second_vlan_id, misc_mask, outer_second_vid);
234*46779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
235d65e841dSYevgeny Kliteynik 			       second_cfi, misc_mask, outer_second_cfi);
236*46779098SYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, bit_mask,
237d65e841dSYevgeny Kliteynik 			       second_priority, misc_mask, outer_second_prio);
238d65e841dSYevgeny Kliteynik 	}
239d65e841dSYevgeny Kliteynik }
240d65e841dSYevgeny Kliteynik 
241d65e841dSYevgeny Kliteynik static int
242d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_or_dst_tag(struct mlx5dr_match_param *value,
243d65e841dSYevgeny Kliteynik 				      bool inner, u8 *tag)
244d65e841dSYevgeny Kliteynik {
245d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = inner ? &value->inner : &value->outer;
246d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc_spec = &value->misc;
247d65e841dSYevgeny Kliteynik 
248d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, first_vlan_id, spec, first_vid);
249d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, first_cfi, spec, first_cfi);
250d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, first_priority, spec, first_prio);
251d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, ip_fragmented, spec, frag);
252d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, l3_ethertype, spec, ethertype);
253d65e841dSYevgeny Kliteynik 
254d65e841dSYevgeny Kliteynik 	if (spec->ip_version) {
255d65e841dSYevgeny Kliteynik 		if (spec->ip_version == IP_VERSION_IPV4) {
256d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV4);
257d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
258d65e841dSYevgeny Kliteynik 		} else if (spec->ip_version == IP_VERSION_IPV6) {
259d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, l3_type, STE_IPV6);
260d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
261d65e841dSYevgeny Kliteynik 		} else {
262d65e841dSYevgeny Kliteynik 			return -EINVAL;
263d65e841dSYevgeny Kliteynik 		}
264d65e841dSYevgeny Kliteynik 	}
265d65e841dSYevgeny Kliteynik 
266d65e841dSYevgeny Kliteynik 	if (spec->cvlan_tag) {
267d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_CVLAN);
268d65e841dSYevgeny Kliteynik 		spec->cvlan_tag = 0;
269d65e841dSYevgeny Kliteynik 	} else if (spec->svlan_tag) {
270d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_src, tag, first_vlan_qualifier, DR_STE_SVLAN);
271d65e841dSYevgeny Kliteynik 		spec->svlan_tag = 0;
272d65e841dSYevgeny Kliteynik 	}
273d65e841dSYevgeny Kliteynik 
274d65e841dSYevgeny Kliteynik 	if (inner) {
275d65e841dSYevgeny Kliteynik 		if (misc_spec->inner_second_cvlan_tag) {
276d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
277d65e841dSYevgeny Kliteynik 			misc_spec->inner_second_cvlan_tag = 0;
278d65e841dSYevgeny Kliteynik 		} else if (misc_spec->inner_second_svlan_tag) {
279d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
280d65e841dSYevgeny Kliteynik 			misc_spec->inner_second_svlan_tag = 0;
281d65e841dSYevgeny Kliteynik 		}
282d65e841dSYevgeny Kliteynik 
283d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, inner_second_vid);
284d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, inner_second_cfi);
285d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, inner_second_prio);
286d65e841dSYevgeny Kliteynik 	} else {
287d65e841dSYevgeny Kliteynik 		if (misc_spec->outer_second_cvlan_tag) {
288d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_CVLAN);
289d65e841dSYevgeny Kliteynik 			misc_spec->outer_second_cvlan_tag = 0;
290d65e841dSYevgeny Kliteynik 		} else if (misc_spec->outer_second_svlan_tag) {
291d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_src, tag, second_vlan_qualifier, DR_STE_SVLAN);
292d65e841dSYevgeny Kliteynik 			misc_spec->outer_second_svlan_tag = 0;
293d65e841dSYevgeny Kliteynik 		}
294d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_vlan_id, misc_spec, outer_second_vid);
295d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_cfi, misc_spec, outer_second_cfi);
296d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l2_src, tag, second_priority, misc_spec, outer_second_prio);
297d65e841dSYevgeny Kliteynik 	}
298d65e841dSYevgeny Kliteynik 
299d65e841dSYevgeny Kliteynik 	return 0;
300d65e841dSYevgeny Kliteynik }
301d65e841dSYevgeny Kliteynik 
302d65e841dSYevgeny Kliteynik static void
303d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_bit_mask(struct mlx5dr_match_param *value,
304d65e841dSYevgeny Kliteynik 				    bool inner, u8 *bit_mask)
305d65e841dSYevgeny Kliteynik {
306d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
307d65e841dSYevgeny Kliteynik 
308*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_47_16, mask, smac_47_16);
309*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, bit_mask, smac_15_0, mask, smac_15_0);
310d65e841dSYevgeny Kliteynik 
311d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, inner, bit_mask);
312d65e841dSYevgeny Kliteynik }
313d65e841dSYevgeny Kliteynik 
314d65e841dSYevgeny Kliteynik static int
315d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_tag(struct mlx5dr_match_param *value,
316d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
317d65e841dSYevgeny Kliteynik 			       u8 *tag)
318d65e841dSYevgeny Kliteynik {
319d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
320d65e841dSYevgeny Kliteynik 
321d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, smac_47_16, spec, smac_47_16);
322d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_src, tag, smac_15_0, spec, smac_15_0);
323d65e841dSYevgeny Kliteynik 
324d65e841dSYevgeny Kliteynik 	return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
325d65e841dSYevgeny Kliteynik }
326d65e841dSYevgeny Kliteynik 
327d65e841dSYevgeny Kliteynik static void
328d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_src_init(struct mlx5dr_ste_build *sb,
329d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
330d65e841dSYevgeny Kliteynik {
331d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_bit_mask(mask, sb->inner, sb->bit_mask);
332d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_SRC, sb->rx, sb->inner);
333d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
334d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_src_tag;
335d65e841dSYevgeny Kliteynik }
336d65e841dSYevgeny Kliteynik 
337d65e841dSYevgeny Kliteynik static void
338d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_bit_mask(struct mlx5dr_match_param *value,
339*46779098SYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
340*46779098SYevgeny Kliteynik 				    u8 *bit_mask)
341d65e841dSYevgeny Kliteynik {
342*46779098SYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = sb->inner ? &value->inner : &value->outer;
343d65e841dSYevgeny Kliteynik 
344*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_47_16, mask, dmac_47_16);
345*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, bit_mask, dmac_15_0, mask, dmac_15_0);
346d65e841dSYevgeny Kliteynik 
347*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_src_or_dst_bit_mask(value, sb->inner, bit_mask);
348d65e841dSYevgeny Kliteynik }
349d65e841dSYevgeny Kliteynik 
350d65e841dSYevgeny Kliteynik static int
351d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_tag(struct mlx5dr_match_param *value,
352d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
353d65e841dSYevgeny Kliteynik 			       u8 *tag)
354d65e841dSYevgeny Kliteynik {
355d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
356d65e841dSYevgeny Kliteynik 
357d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, tag, dmac_47_16, spec, dmac_47_16);
358d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_dst, tag, dmac_15_0, spec, dmac_15_0);
359d65e841dSYevgeny Kliteynik 
360d65e841dSYevgeny Kliteynik 	return dr_ste_v0_build_eth_l2_src_or_dst_tag(value, sb->inner, tag);
361d65e841dSYevgeny Kliteynik }
362d65e841dSYevgeny Kliteynik 
363d65e841dSYevgeny Kliteynik static void
364d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_dst_init(struct mlx5dr_ste_build *sb,
365d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
366d65e841dSYevgeny Kliteynik {
367*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_dst_bit_mask(mask, sb, sb->bit_mask);
368d65e841dSYevgeny Kliteynik 
369d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL2_DST, sb->rx, sb->inner);
370d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
371d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_dst_tag;
372d65e841dSYevgeny Kliteynik }
373d65e841dSYevgeny Kliteynik 
374d65e841dSYevgeny Kliteynik static void
375d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_bit_mask(struct mlx5dr_match_param *value,
376d65e841dSYevgeny Kliteynik 				    bool inner, u8 *bit_mask)
377d65e841dSYevgeny Kliteynik {
378d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *mask = inner ? &value->inner : &value->outer;
379d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
380d65e841dSYevgeny Kliteynik 
381*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_47_16, mask, dmac_47_16);
382*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, dmac_15_0, mask, dmac_15_0);
383*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_vlan_id, mask, first_vid);
384*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_cfi, mask, first_cfi);
385*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, first_priority, mask, first_prio);
386*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, ip_fragmented, mask, frag);
387*46779098SYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, bit_mask, l3_ethertype, mask, ethertype);
388*46779098SYevgeny Kliteynik 	DR_STE_SET_ONES(eth_l2_tnl, bit_mask, l3_type, mask, ip_version);
389d65e841dSYevgeny Kliteynik 
390d65e841dSYevgeny Kliteynik 	if (misc->vxlan_vni) {
391d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, bit_mask,
392d65e841dSYevgeny Kliteynik 			 l2_tunneling_network_id, (misc->vxlan_vni << 8));
393d65e841dSYevgeny Kliteynik 		misc->vxlan_vni = 0;
394d65e841dSYevgeny Kliteynik 	}
395d65e841dSYevgeny Kliteynik 
396d65e841dSYevgeny Kliteynik 	if (mask->svlan_tag || mask->cvlan_tag) {
397d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, bit_mask, first_vlan_qualifier, -1);
398d65e841dSYevgeny Kliteynik 		mask->cvlan_tag = 0;
399d65e841dSYevgeny Kliteynik 		mask->svlan_tag = 0;
400d65e841dSYevgeny Kliteynik 	}
401d65e841dSYevgeny Kliteynik }
402d65e841dSYevgeny Kliteynik 
403d65e841dSYevgeny Kliteynik static int
404d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_tag(struct mlx5dr_match_param *value,
405d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
406d65e841dSYevgeny Kliteynik 			       u8 *tag)
407d65e841dSYevgeny Kliteynik {
408d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
409d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
410d65e841dSYevgeny Kliteynik 
411d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_47_16, spec, dmac_47_16);
412d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, dmac_15_0, spec, dmac_15_0);
413d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, first_vlan_id, spec, first_vid);
414d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, first_cfi, spec, first_cfi);
415d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, ip_fragmented, spec, frag);
416d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, first_priority, spec, first_prio);
417d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l2_tnl, tag, l3_ethertype, spec, ethertype);
418d65e841dSYevgeny Kliteynik 
419d65e841dSYevgeny Kliteynik 	if (misc->vxlan_vni) {
420d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, tag, l2_tunneling_network_id,
421d65e841dSYevgeny Kliteynik 			 (misc->vxlan_vni << 8));
422d65e841dSYevgeny Kliteynik 		misc->vxlan_vni = 0;
423d65e841dSYevgeny Kliteynik 	}
424d65e841dSYevgeny Kliteynik 
425d65e841dSYevgeny Kliteynik 	if (spec->cvlan_tag) {
426d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_CVLAN);
427d65e841dSYevgeny Kliteynik 		spec->cvlan_tag = 0;
428d65e841dSYevgeny Kliteynik 	} else if (spec->svlan_tag) {
429d65e841dSYevgeny Kliteynik 		MLX5_SET(ste_eth_l2_tnl, tag, first_vlan_qualifier, DR_STE_SVLAN);
430d65e841dSYevgeny Kliteynik 		spec->svlan_tag = 0;
431d65e841dSYevgeny Kliteynik 	}
432d65e841dSYevgeny Kliteynik 
433d65e841dSYevgeny Kliteynik 	if (spec->ip_version) {
434d65e841dSYevgeny Kliteynik 		if (spec->ip_version == IP_VERSION_IPV4) {
435d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV4);
436d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
437d65e841dSYevgeny Kliteynik 		} else if (spec->ip_version == IP_VERSION_IPV6) {
438d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_eth_l2_tnl, tag, l3_type, STE_IPV6);
439d65e841dSYevgeny Kliteynik 			spec->ip_version = 0;
440d65e841dSYevgeny Kliteynik 		} else {
441d65e841dSYevgeny Kliteynik 			return -EINVAL;
442d65e841dSYevgeny Kliteynik 		}
443d65e841dSYevgeny Kliteynik 	}
444d65e841dSYevgeny Kliteynik 
445d65e841dSYevgeny Kliteynik 	return 0;
446d65e841dSYevgeny Kliteynik }
447d65e841dSYevgeny Kliteynik 
448d65e841dSYevgeny Kliteynik static void
449d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l2_tnl_init(struct mlx5dr_ste_build *sb,
450d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
451d65e841dSYevgeny Kliteynik {
452d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_eth_l2_tnl_bit_mask(mask, sb->inner, sb->bit_mask);
453d65e841dSYevgeny Kliteynik 
454d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_ETHL2_TUNNELING_I;
455d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
456d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l2_tnl_tag;
457d65e841dSYevgeny Kliteynik }
458d65e841dSYevgeny Kliteynik 
459d65e841dSYevgeny Kliteynik static int
460d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_tag(struct mlx5dr_match_param *value,
461d65e841dSYevgeny Kliteynik 				     struct mlx5dr_ste_build *sb,
462d65e841dSYevgeny Kliteynik 				     u8 *tag)
463d65e841dSYevgeny Kliteynik {
464d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
465d65e841dSYevgeny Kliteynik 
466d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l3_ipv4_misc, tag, time_to_live, spec, ttl_hoplimit);
467d65e841dSYevgeny Kliteynik 
468d65e841dSYevgeny Kliteynik 	return 0;
469d65e841dSYevgeny Kliteynik }
470d65e841dSYevgeny Kliteynik 
471d65e841dSYevgeny Kliteynik static void
472d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l3_ipv4_misc_init(struct mlx5dr_ste_build *sb,
473d65e841dSYevgeny Kliteynik 				      struct mlx5dr_match_param *mask)
474d65e841dSYevgeny Kliteynik {
475*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l3_ipv4_misc_tag(mask, sb, sb->bit_mask);
476d65e841dSYevgeny Kliteynik 
477d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL3_IPV4_MISC, sb->rx, sb->inner);
478d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
479d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l3_ipv4_misc_tag;
480d65e841dSYevgeny Kliteynik }
481d65e841dSYevgeny Kliteynik 
482d65e841dSYevgeny Kliteynik static int
483d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_tag(struct mlx5dr_match_param *value,
484d65e841dSYevgeny Kliteynik 				   struct mlx5dr_ste_build *sb,
485d65e841dSYevgeny Kliteynik 				   u8 *tag)
486d65e841dSYevgeny Kliteynik {
487d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_spec *spec = sb->inner ? &value->inner : &value->outer;
488d65e841dSYevgeny Kliteynik 
489d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, tcp_dport);
490d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, src_port, spec, tcp_sport);
491d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, dst_port, spec, udp_dport);
492d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, src_port, spec, udp_sport);
493d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, protocol, spec, ip_protocol);
494d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, fragmented, spec, frag);
495d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, dscp, spec, ip_dscp);
496d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, ecn, spec, ip_ecn);
497d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(eth_l4, tag, ipv6_hop_limit, spec, ttl_hoplimit);
498d65e841dSYevgeny Kliteynik 
499d65e841dSYevgeny Kliteynik 	if (spec->tcp_flags) {
500d65e841dSYevgeny Kliteynik 		DR_STE_SET_TCP_FLAGS(eth_l4, tag, spec);
501d65e841dSYevgeny Kliteynik 		spec->tcp_flags = 0;
502d65e841dSYevgeny Kliteynik 	}
503d65e841dSYevgeny Kliteynik 
504d65e841dSYevgeny Kliteynik 	return 0;
505d65e841dSYevgeny Kliteynik }
506d65e841dSYevgeny Kliteynik 
507d65e841dSYevgeny Kliteynik static void
508d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_ipv6_l3_l4_init(struct mlx5dr_ste_build *sb,
509d65e841dSYevgeny Kliteynik 				    struct mlx5dr_match_param *mask)
510d65e841dSYevgeny Kliteynik {
511*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_ipv6_l3_l4_tag(mask, sb, sb->bit_mask);
512d65e841dSYevgeny Kliteynik 
513d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4, sb->rx, sb->inner);
514d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
515d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_ipv6_l3_l4_tag;
516d65e841dSYevgeny Kliteynik }
517d65e841dSYevgeny Kliteynik 
518d65e841dSYevgeny Kliteynik static int
519d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_tag(struct mlx5dr_match_param *value,
520d65e841dSYevgeny Kliteynik 			 struct mlx5dr_ste_build *sb,
521d65e841dSYevgeny Kliteynik 			 u8 *tag)
522d65e841dSYevgeny Kliteynik {
523*46779098SYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc2 = &value->misc2;
524d65e841dSYevgeny Kliteynik 
525d65e841dSYevgeny Kliteynik 	if (sb->inner)
526*46779098SYevgeny Kliteynik 		DR_STE_SET_MPLS(mpls, misc2, inner, tag);
527d65e841dSYevgeny Kliteynik 	else
528*46779098SYevgeny Kliteynik 		DR_STE_SET_MPLS(mpls, misc2, outer, tag);
529d65e841dSYevgeny Kliteynik 
530d65e841dSYevgeny Kliteynik 	return 0;
531d65e841dSYevgeny Kliteynik }
532d65e841dSYevgeny Kliteynik 
533d65e841dSYevgeny Kliteynik static void
534d65e841dSYevgeny Kliteynik dr_ste_v0_build_mpls_init(struct mlx5dr_ste_build *sb,
535d65e841dSYevgeny Kliteynik 			  struct mlx5dr_match_param *mask)
536d65e841dSYevgeny Kliteynik {
537*46779098SYevgeny Kliteynik 	dr_ste_v0_build_mpls_tag(mask, sb, sb->bit_mask);
538d65e841dSYevgeny Kliteynik 
539d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(MPLS_FIRST, sb->rx, sb->inner);
540d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
541d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_mpls_tag;
542d65e841dSYevgeny Kliteynik }
543d65e841dSYevgeny Kliteynik 
544d65e841dSYevgeny Kliteynik static int
545d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_tag(struct mlx5dr_match_param *value,
546d65e841dSYevgeny Kliteynik 			    struct mlx5dr_ste_build *sb,
547d65e841dSYevgeny Kliteynik 			    u8 *tag)
548d65e841dSYevgeny Kliteynik {
549d65e841dSYevgeny Kliteynik 	struct  mlx5dr_match_misc *misc = &value->misc;
550d65e841dSYevgeny Kliteynik 
551d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_protocol, misc, gre_protocol);
552d65e841dSYevgeny Kliteynik 
553d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_k_present, misc, gre_k_present);
554d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_key_h, misc, gre_key_h);
555d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_key_l, misc, gre_key_l);
556d65e841dSYevgeny Kliteynik 
557d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_c_present, misc, gre_c_present);
558d65e841dSYevgeny Kliteynik 
559d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(gre, tag, gre_s_present, misc, gre_s_present);
560d65e841dSYevgeny Kliteynik 
561d65e841dSYevgeny Kliteynik 	return 0;
562d65e841dSYevgeny Kliteynik }
563d65e841dSYevgeny Kliteynik 
564d65e841dSYevgeny Kliteynik static void
565d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_gre_init(struct mlx5dr_ste_build *sb,
566d65e841dSYevgeny Kliteynik 			     struct mlx5dr_match_param *mask)
567d65e841dSYevgeny Kliteynik {
568*46779098SYevgeny Kliteynik 	dr_ste_v0_build_tnl_gre_tag(mask, sb, sb->bit_mask);
569d65e841dSYevgeny Kliteynik 
570d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_GRE;
571d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
572d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_tnl_gre_tag;
573d65e841dSYevgeny Kliteynik }
574d65e841dSYevgeny Kliteynik 
575d65e841dSYevgeny Kliteynik static int
576d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_tag(struct mlx5dr_match_param *value,
577d65e841dSYevgeny Kliteynik 			     struct mlx5dr_ste_build *sb,
578d65e841dSYevgeny Kliteynik 			     u8 *tag)
579d65e841dSYevgeny Kliteynik {
580*46779098SYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc_2 = &value->misc2;
581d65e841dSYevgeny Kliteynik 
582*46779098SYevgeny Kliteynik 	if (DR_STE_IS_OUTER_MPLS_OVER_GRE_SET(misc_2)) {
583d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label,
584*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_label);
585d65e841dSYevgeny Kliteynik 
586d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp,
587*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_exp);
588d65e841dSYevgeny Kliteynik 
589d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos,
590*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_s_bos);
591d65e841dSYevgeny Kliteynik 
592d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl,
593*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_gre_ttl);
594d65e841dSYevgeny Kliteynik 	} else {
595d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_label,
596*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_label);
597d65e841dSYevgeny Kliteynik 
598d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_exp,
599*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_exp);
600d65e841dSYevgeny Kliteynik 
601d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_s_bos,
602*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_s_bos);
603d65e841dSYevgeny Kliteynik 
604d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(flex_parser_0, tag, parser_3_ttl,
605*46779098SYevgeny Kliteynik 			       misc_2, outer_first_mpls_over_udp_ttl);
606d65e841dSYevgeny Kliteynik 	}
607d65e841dSYevgeny Kliteynik 	return 0;
608d65e841dSYevgeny Kliteynik }
609d65e841dSYevgeny Kliteynik 
610d65e841dSYevgeny Kliteynik static void
611d65e841dSYevgeny Kliteynik dr_ste_v0_build_tnl_mpls_init(struct mlx5dr_ste_build *sb,
612d65e841dSYevgeny Kliteynik 			      struct mlx5dr_match_param *mask)
613d65e841dSYevgeny Kliteynik {
614*46779098SYevgeny Kliteynik 	dr_ste_v0_build_tnl_mpls_tag(mask, sb, sb->bit_mask);
615d65e841dSYevgeny Kliteynik 
616d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_0;
617d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
618d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_tnl_mpls_tag;
619d65e841dSYevgeny Kliteynik }
620d65e841dSYevgeny Kliteynik 
621d65e841dSYevgeny Kliteynik #define ICMP_TYPE_OFFSET_FIRST_DW		24
622d65e841dSYevgeny Kliteynik #define ICMP_CODE_OFFSET_FIRST_DW		16
623d65e841dSYevgeny Kliteynik #define ICMP_HEADER_DATA_OFFSET_SECOND_DW	0
624d65e841dSYevgeny Kliteynik 
625d65e841dSYevgeny Kliteynik static int
626d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_tag(struct mlx5dr_match_param *value,
627d65e841dSYevgeny Kliteynik 			 struct mlx5dr_ste_build *sb,
628d65e841dSYevgeny Kliteynik 			 u8 *tag)
629d65e841dSYevgeny Kliteynik {
630d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc3 *misc_3 = &value->misc3;
631d65e841dSYevgeny Kliteynik 	u32 icmp_header_data;
632d65e841dSYevgeny Kliteynik 	int dw0_location;
633d65e841dSYevgeny Kliteynik 	int dw1_location;
634d65e841dSYevgeny Kliteynik 	u32 icmp_type;
635d65e841dSYevgeny Kliteynik 	u32 icmp_code;
636d65e841dSYevgeny Kliteynik 	bool is_ipv4;
637d65e841dSYevgeny Kliteynik 
638d65e841dSYevgeny Kliteynik 	is_ipv4 = DR_MASK_IS_ICMPV4_SET(misc_3);
639d65e841dSYevgeny Kliteynik 	if (is_ipv4) {
640d65e841dSYevgeny Kliteynik 		icmp_header_data	= misc_3->icmpv4_header_data;
641d65e841dSYevgeny Kliteynik 		icmp_type		= misc_3->icmpv4_type;
642d65e841dSYevgeny Kliteynik 		icmp_code		= misc_3->icmpv4_code;
643d65e841dSYevgeny Kliteynik 		dw0_location		= sb->caps->flex_parser_id_icmp_dw0;
644d65e841dSYevgeny Kliteynik 		dw1_location		= sb->caps->flex_parser_id_icmp_dw1;
645d65e841dSYevgeny Kliteynik 	} else {
646d65e841dSYevgeny Kliteynik 		icmp_header_data	= misc_3->icmpv6_header_data;
647d65e841dSYevgeny Kliteynik 		icmp_type		= misc_3->icmpv6_type;
648d65e841dSYevgeny Kliteynik 		icmp_code		= misc_3->icmpv6_code;
649d65e841dSYevgeny Kliteynik 		dw0_location		= sb->caps->flex_parser_id_icmpv6_dw0;
650d65e841dSYevgeny Kliteynik 		dw1_location		= sb->caps->flex_parser_id_icmpv6_dw1;
651d65e841dSYevgeny Kliteynik 	}
652d65e841dSYevgeny Kliteynik 
653d65e841dSYevgeny Kliteynik 	switch (dw0_location) {
654d65e841dSYevgeny Kliteynik 	case 4:
655d65e841dSYevgeny Kliteynik 		if (icmp_type) {
656d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_flex_parser_1, tag, flex_parser_4,
657d65e841dSYevgeny Kliteynik 				 (icmp_type << ICMP_TYPE_OFFSET_FIRST_DW));
658d65e841dSYevgeny Kliteynik 			if (is_ipv4)
659d65e841dSYevgeny Kliteynik 				misc_3->icmpv4_type = 0;
660d65e841dSYevgeny Kliteynik 			else
661d65e841dSYevgeny Kliteynik 				misc_3->icmpv6_type = 0;
662d65e841dSYevgeny Kliteynik 		}
663d65e841dSYevgeny Kliteynik 
664d65e841dSYevgeny Kliteynik 		if (icmp_code) {
665d65e841dSYevgeny Kliteynik 			u32 cur_val = MLX5_GET(ste_flex_parser_1, tag,
666d65e841dSYevgeny Kliteynik 					       flex_parser_4);
667d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_flex_parser_1, tag, flex_parser_4,
668d65e841dSYevgeny Kliteynik 				 cur_val | (icmp_code << ICMP_CODE_OFFSET_FIRST_DW));
669d65e841dSYevgeny Kliteynik 			if (is_ipv4)
670d65e841dSYevgeny Kliteynik 				misc_3->icmpv4_code = 0;
671d65e841dSYevgeny Kliteynik 			else
672d65e841dSYevgeny Kliteynik 				misc_3->icmpv6_code = 0;
673d65e841dSYevgeny Kliteynik 		}
674d65e841dSYevgeny Kliteynik 		break;
675d65e841dSYevgeny Kliteynik 	default:
676d65e841dSYevgeny Kliteynik 		return -EINVAL;
677d65e841dSYevgeny Kliteynik 	}
678d65e841dSYevgeny Kliteynik 
679d65e841dSYevgeny Kliteynik 	switch (dw1_location) {
680d65e841dSYevgeny Kliteynik 	case 5:
681d65e841dSYevgeny Kliteynik 		if (icmp_header_data) {
682d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_flex_parser_1, tag, flex_parser_5,
683d65e841dSYevgeny Kliteynik 				 (icmp_header_data << ICMP_HEADER_DATA_OFFSET_SECOND_DW));
684d65e841dSYevgeny Kliteynik 			if (is_ipv4)
685d65e841dSYevgeny Kliteynik 				misc_3->icmpv4_header_data = 0;
686d65e841dSYevgeny Kliteynik 			else
687d65e841dSYevgeny Kliteynik 				misc_3->icmpv6_header_data = 0;
688d65e841dSYevgeny Kliteynik 		}
689d65e841dSYevgeny Kliteynik 		break;
690d65e841dSYevgeny Kliteynik 	default:
691d65e841dSYevgeny Kliteynik 		return -EINVAL;
692d65e841dSYevgeny Kliteynik 	}
693d65e841dSYevgeny Kliteynik 
694d65e841dSYevgeny Kliteynik 	return 0;
695d65e841dSYevgeny Kliteynik }
696d65e841dSYevgeny Kliteynik 
697d65e841dSYevgeny Kliteynik static int
698d65e841dSYevgeny Kliteynik dr_ste_v0_build_icmp_init(struct mlx5dr_ste_build *sb,
699d65e841dSYevgeny Kliteynik 			  struct mlx5dr_match_param *mask)
700d65e841dSYevgeny Kliteynik {
701d65e841dSYevgeny Kliteynik 	int ret;
702d65e841dSYevgeny Kliteynik 
703*46779098SYevgeny Kliteynik 	ret = dr_ste_v0_build_icmp_tag(mask, sb, sb->bit_mask);
704d65e841dSYevgeny Kliteynik 	if (ret)
705d65e841dSYevgeny Kliteynik 		return ret;
706d65e841dSYevgeny Kliteynik 
707d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_1;
708d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
709d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_icmp_tag;
710d65e841dSYevgeny Kliteynik 
711d65e841dSYevgeny Kliteynik 	return 0;
712d65e841dSYevgeny Kliteynik }
713d65e841dSYevgeny Kliteynik 
714d65e841dSYevgeny Kliteynik static int
715d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_tag(struct mlx5dr_match_param *value,
716d65e841dSYevgeny Kliteynik 				    struct mlx5dr_ste_build *sb,
717d65e841dSYevgeny Kliteynik 				    u8 *tag)
718d65e841dSYevgeny Kliteynik {
719*46779098SYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc_2 = &value->misc2;
720d65e841dSYevgeny Kliteynik 
721d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(general_purpose, tag, general_purpose_lookup_field,
722*46779098SYevgeny Kliteynik 		       misc_2, metadata_reg_a);
723d65e841dSYevgeny Kliteynik 
724d65e841dSYevgeny Kliteynik 	return 0;
725d65e841dSYevgeny Kliteynik }
726d65e841dSYevgeny Kliteynik 
727d65e841dSYevgeny Kliteynik static void
728d65e841dSYevgeny Kliteynik dr_ste_v0_build_general_purpose_init(struct mlx5dr_ste_build *sb,
729d65e841dSYevgeny Kliteynik 				     struct mlx5dr_match_param *mask)
730d65e841dSYevgeny Kliteynik {
731*46779098SYevgeny Kliteynik 	dr_ste_v0_build_general_purpose_tag(mask, sb, sb->bit_mask);
732d65e841dSYevgeny Kliteynik 
733d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_GENERAL_PURPOSE;
734d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
735d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_general_purpose_tag;
736d65e841dSYevgeny Kliteynik }
737d65e841dSYevgeny Kliteynik 
738d65e841dSYevgeny Kliteynik static int
739d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_tag(struct mlx5dr_match_param *value,
740d65e841dSYevgeny Kliteynik 				struct mlx5dr_ste_build *sb,
741d65e841dSYevgeny Kliteynik 				u8 *tag)
742d65e841dSYevgeny Kliteynik {
743d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc3 *misc3 = &value->misc3;
744d65e841dSYevgeny Kliteynik 
745d65e841dSYevgeny Kliteynik 	if (sb->inner) {
746d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, inner_tcp_seq_num);
747d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, inner_tcp_ack_num);
748d65e841dSYevgeny Kliteynik 	} else {
749d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, seq_num, misc3, outer_tcp_seq_num);
750d65e841dSYevgeny Kliteynik 		DR_STE_SET_TAG(eth_l4_misc, tag, ack_num, misc3, outer_tcp_ack_num);
751d65e841dSYevgeny Kliteynik 	}
752d65e841dSYevgeny Kliteynik 
753d65e841dSYevgeny Kliteynik 	return 0;
754d65e841dSYevgeny Kliteynik }
755d65e841dSYevgeny Kliteynik 
756d65e841dSYevgeny Kliteynik static void
757d65e841dSYevgeny Kliteynik dr_ste_v0_build_eth_l4_misc_init(struct mlx5dr_ste_build *sb,
758d65e841dSYevgeny Kliteynik 				 struct mlx5dr_match_param *mask)
759d65e841dSYevgeny Kliteynik {
760*46779098SYevgeny Kliteynik 	dr_ste_v0_build_eth_l4_misc_tag(mask, sb, sb->bit_mask);
761d65e841dSYevgeny Kliteynik 
762d65e841dSYevgeny Kliteynik 	sb->lu_type = DR_STE_CALC_LU_TYPE(ETHL4_MISC, sb->rx, sb->inner);
763d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
764d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_eth_l4_misc_tag;
765d65e841dSYevgeny Kliteynik }
766d65e841dSYevgeny Kliteynik 
767d65e841dSYevgeny Kliteynik static int
768d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(struct mlx5dr_match_param *value,
769d65e841dSYevgeny Kliteynik 					      struct mlx5dr_ste_build *sb,
770d65e841dSYevgeny Kliteynik 					      u8 *tag)
771d65e841dSYevgeny Kliteynik {
772d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc3 *misc3 = &value->misc3;
773d65e841dSYevgeny Kliteynik 
774d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
775d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_flags, misc3,
776d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_flags);
777d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
778d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_next_protocol, misc3,
779d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_next_protocol);
780d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_vxlan_gpe, tag,
781d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_vni, misc3,
782d65e841dSYevgeny Kliteynik 		       outer_vxlan_gpe_vni);
783d65e841dSYevgeny Kliteynik 
784d65e841dSYevgeny Kliteynik 	return 0;
785d65e841dSYevgeny Kliteynik }
786d65e841dSYevgeny Kliteynik 
787d65e841dSYevgeny Kliteynik static void
788d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init(struct mlx5dr_ste_build *sb,
789d65e841dSYevgeny Kliteynik 					       struct mlx5dr_match_param *mask)
790d65e841dSYevgeny Kliteynik {
791*46779098SYevgeny Kliteynik 	dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag(mask, sb, sb->bit_mask);
792d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER;
793d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
794d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_tag;
795d65e841dSYevgeny Kliteynik }
796d65e841dSYevgeny Kliteynik 
797d65e841dSYevgeny Kliteynik static int
798d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_tag(struct mlx5dr_match_param *value,
799d65e841dSYevgeny Kliteynik 					   struct mlx5dr_ste_build *sb,
800d65e841dSYevgeny Kliteynik 					   u8 *tag)
801d65e841dSYevgeny Kliteynik {
802d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
803d65e841dSYevgeny Kliteynik 
804d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
805d65e841dSYevgeny Kliteynik 		       geneve_protocol_type, misc, geneve_protocol_type);
806d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
807d65e841dSYevgeny Kliteynik 		       geneve_oam, misc, geneve_oam);
808d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
809d65e841dSYevgeny Kliteynik 		       geneve_opt_len, misc, geneve_opt_len);
810d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(flex_parser_tnl_geneve, tag,
811d65e841dSYevgeny Kliteynik 		       geneve_vni, misc, geneve_vni);
812d65e841dSYevgeny Kliteynik 
813d65e841dSYevgeny Kliteynik 	return 0;
814d65e841dSYevgeny Kliteynik }
815d65e841dSYevgeny Kliteynik 
816d65e841dSYevgeny Kliteynik static void
817d65e841dSYevgeny Kliteynik dr_ste_v0_build_flex_parser_tnl_geneve_init(struct mlx5dr_ste_build *sb,
818d65e841dSYevgeny Kliteynik 					    struct mlx5dr_match_param *mask)
819d65e841dSYevgeny Kliteynik {
820*46779098SYevgeny Kliteynik 	dr_ste_v0_build_flex_parser_tnl_geneve_tag(mask, sb, sb->bit_mask);
821d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_FLEX_PARSER_TNL_HEADER;
822d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
823d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_flex_parser_tnl_geneve_tag;
824d65e841dSYevgeny Kliteynik }
825d65e841dSYevgeny Kliteynik 
826d65e841dSYevgeny Kliteynik static int
827d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_tag(struct mlx5dr_match_param *value,
828d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
829d65e841dSYevgeny Kliteynik 			       u8 *tag)
830d65e841dSYevgeny Kliteynik {
831d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc2 = &value->misc2;
832d65e841dSYevgeny Kliteynik 
833d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_0_h, misc2, metadata_reg_c_0);
834d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_0_l, misc2, metadata_reg_c_1);
835d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_1_h, misc2, metadata_reg_c_2);
836d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_0, tag, register_1_l, misc2, metadata_reg_c_3);
837d65e841dSYevgeny Kliteynik 
838d65e841dSYevgeny Kliteynik 	return 0;
839d65e841dSYevgeny Kliteynik }
840d65e841dSYevgeny Kliteynik 
841d65e841dSYevgeny Kliteynik static void
842d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_0_init(struct mlx5dr_ste_build *sb,
843d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
844d65e841dSYevgeny Kliteynik {
845*46779098SYevgeny Kliteynik 	dr_ste_v0_build_register_0_tag(mask, sb, sb->bit_mask);
846d65e841dSYevgeny Kliteynik 
847d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_STEERING_REGISTERS_0;
848d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
849d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_register_0_tag;
850d65e841dSYevgeny Kliteynik }
851d65e841dSYevgeny Kliteynik 
852d65e841dSYevgeny Kliteynik static int
853d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_tag(struct mlx5dr_match_param *value,
854d65e841dSYevgeny Kliteynik 			       struct mlx5dr_ste_build *sb,
855d65e841dSYevgeny Kliteynik 			       u8 *tag)
856d65e841dSYevgeny Kliteynik {
857d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc2 *misc2 = &value->misc2;
858d65e841dSYevgeny Kliteynik 
859d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_2_h, misc2, metadata_reg_c_4);
860d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_2_l, misc2, metadata_reg_c_5);
861d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_3_h, misc2, metadata_reg_c_6);
862d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(register_1, tag, register_3_l, misc2, metadata_reg_c_7);
863d65e841dSYevgeny Kliteynik 
864d65e841dSYevgeny Kliteynik 	return 0;
865d65e841dSYevgeny Kliteynik }
866d65e841dSYevgeny Kliteynik 
867d65e841dSYevgeny Kliteynik static void
868d65e841dSYevgeny Kliteynik dr_ste_v0_build_register_1_init(struct mlx5dr_ste_build *sb,
869d65e841dSYevgeny Kliteynik 				struct mlx5dr_match_param *mask)
870d65e841dSYevgeny Kliteynik {
871*46779098SYevgeny Kliteynik 	dr_ste_v0_build_register_1_tag(mask, sb, sb->bit_mask);
872d65e841dSYevgeny Kliteynik 
873d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_STEERING_REGISTERS_1;
874d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
875d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_register_1_tag;
876d65e841dSYevgeny Kliteynik }
877d65e841dSYevgeny Kliteynik 
878d65e841dSYevgeny Kliteynik static void
879d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_bit_mask(struct mlx5dr_match_param *value,
880d65e841dSYevgeny Kliteynik 				      u8 *bit_mask)
881d65e841dSYevgeny Kliteynik {
882d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc_mask = &value->misc;
883d65e841dSYevgeny Kliteynik 
884*46779098SYevgeny Kliteynik 	DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_gvmi, misc_mask, source_port);
885*46779098SYevgeny Kliteynik 	DR_STE_SET_ONES(src_gvmi_qp, bit_mask, source_qp, misc_mask, source_sqn);
886d65e841dSYevgeny Kliteynik 	misc_mask->source_eswitch_owner_vhca_id = 0;
887d65e841dSYevgeny Kliteynik }
888d65e841dSYevgeny Kliteynik 
889d65e841dSYevgeny Kliteynik static int
890d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_tag(struct mlx5dr_match_param *value,
891d65e841dSYevgeny Kliteynik 				 struct mlx5dr_ste_build *sb,
892d65e841dSYevgeny Kliteynik 				 u8 *tag)
893d65e841dSYevgeny Kliteynik {
894d65e841dSYevgeny Kliteynik 	struct mlx5dr_match_misc *misc = &value->misc;
895d65e841dSYevgeny Kliteynik 	struct mlx5dr_cmd_vport_cap *vport_cap;
896d65e841dSYevgeny Kliteynik 	struct mlx5dr_domain *dmn = sb->dmn;
897d65e841dSYevgeny Kliteynik 	struct mlx5dr_cmd_caps *caps;
898d65e841dSYevgeny Kliteynik 	u8 *bit_mask = sb->bit_mask;
899d65e841dSYevgeny Kliteynik 	bool source_gvmi_set;
900d65e841dSYevgeny Kliteynik 
901d65e841dSYevgeny Kliteynik 	DR_STE_SET_TAG(src_gvmi_qp, tag, source_qp, misc, source_sqn);
902d65e841dSYevgeny Kliteynik 
903d65e841dSYevgeny Kliteynik 	if (sb->vhca_id_valid) {
904d65e841dSYevgeny Kliteynik 		/* Find port GVMI based on the eswitch_owner_vhca_id */
905d65e841dSYevgeny Kliteynik 		if (misc->source_eswitch_owner_vhca_id == dmn->info.caps.gvmi)
906d65e841dSYevgeny Kliteynik 			caps = &dmn->info.caps;
907d65e841dSYevgeny Kliteynik 		else if (dmn->peer_dmn && (misc->source_eswitch_owner_vhca_id ==
908d65e841dSYevgeny Kliteynik 					   dmn->peer_dmn->info.caps.gvmi))
909d65e841dSYevgeny Kliteynik 			caps = &dmn->peer_dmn->info.caps;
910d65e841dSYevgeny Kliteynik 		else
911d65e841dSYevgeny Kliteynik 			return -EINVAL;
9127863c912SYevgeny Kliteynik 
9137863c912SYevgeny Kliteynik 		misc->source_eswitch_owner_vhca_id = 0;
914d65e841dSYevgeny Kliteynik 	} else {
915d65e841dSYevgeny Kliteynik 		caps = &dmn->info.caps;
916d65e841dSYevgeny Kliteynik 	}
917d65e841dSYevgeny Kliteynik 
9187863c912SYevgeny Kliteynik 	source_gvmi_set = MLX5_GET(ste_src_gvmi_qp, bit_mask, source_gvmi);
9197863c912SYevgeny Kliteynik 	if (source_gvmi_set) {
920d65e841dSYevgeny Kliteynik 		vport_cap = mlx5dr_get_vport_cap(caps, misc->source_port);
921d65e841dSYevgeny Kliteynik 		if (!vport_cap) {
922d65e841dSYevgeny Kliteynik 			mlx5dr_err(dmn, "Vport 0x%x is invalid\n",
923d65e841dSYevgeny Kliteynik 				   misc->source_port);
924d65e841dSYevgeny Kliteynik 			return -EINVAL;
925d65e841dSYevgeny Kliteynik 		}
926d65e841dSYevgeny Kliteynik 
9277863c912SYevgeny Kliteynik 		if (vport_cap->vport_gvmi)
928d65e841dSYevgeny Kliteynik 			MLX5_SET(ste_src_gvmi_qp, tag, source_gvmi, vport_cap->vport_gvmi);
929d65e841dSYevgeny Kliteynik 
930d65e841dSYevgeny Kliteynik 		misc->source_port = 0;
9317863c912SYevgeny Kliteynik 	}
932d65e841dSYevgeny Kliteynik 
933d65e841dSYevgeny Kliteynik 	return 0;
934d65e841dSYevgeny Kliteynik }
935d65e841dSYevgeny Kliteynik 
936d65e841dSYevgeny Kliteynik static void
937d65e841dSYevgeny Kliteynik dr_ste_v0_build_src_gvmi_qpn_init(struct mlx5dr_ste_build *sb,
938d65e841dSYevgeny Kliteynik 				  struct mlx5dr_match_param *mask)
939d65e841dSYevgeny Kliteynik {
940d65e841dSYevgeny Kliteynik 	dr_ste_v0_build_src_gvmi_qpn_bit_mask(mask, sb->bit_mask);
941d65e841dSYevgeny Kliteynik 
942d65e841dSYevgeny Kliteynik 	sb->lu_type = MLX5DR_STE_LU_TYPE_SRC_GVMI_AND_QP;
943d65e841dSYevgeny Kliteynik 	sb->byte_mask = mlx5dr_ste_conv_bit_to_byte_mask(sb->bit_mask);
944d65e841dSYevgeny Kliteynik 	sb->ste_build_tag_func = &dr_ste_v0_build_src_gvmi_qpn_tag;
945d65e841dSYevgeny Kliteynik }
946d65e841dSYevgeny Kliteynik 
947d65e841dSYevgeny Kliteynik struct mlx5dr_ste_ctx ste_ctx_v0 = {
948d65e841dSYevgeny Kliteynik 	.build_eth_l2_src_dst_init	= &dr_ste_v0_build_eth_l2_src_dst_init,
949d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv6_src_init	= &dr_ste_v0_build_eth_l3_ipv6_src_init,
950d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv6_dst_init	= &dr_ste_v0_build_eth_l3_ipv6_dst_init,
951d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv4_5_tuple_init	= &dr_ste_v0_build_eth_l3_ipv4_5_tuple_init,
952d65e841dSYevgeny Kliteynik 	.build_eth_l2_src_init		= &dr_ste_v0_build_eth_l2_src_init,
953d65e841dSYevgeny Kliteynik 	.build_eth_l2_dst_init		= &dr_ste_v0_build_eth_l2_dst_init,
954d65e841dSYevgeny Kliteynik 	.build_eth_l2_tnl_init		= &dr_ste_v0_build_eth_l2_tnl_init,
955d65e841dSYevgeny Kliteynik 	.build_eth_l3_ipv4_misc_init	= &dr_ste_v0_build_eth_l3_ipv4_misc_init,
956d65e841dSYevgeny Kliteynik 	.build_eth_ipv6_l3_l4_init	= &dr_ste_v0_build_eth_ipv6_l3_l4_init,
957d65e841dSYevgeny Kliteynik 	.build_mpls_init		= &dr_ste_v0_build_mpls_init,
958d65e841dSYevgeny Kliteynik 	.build_tnl_gre_init		= &dr_ste_v0_build_tnl_gre_init,
959d65e841dSYevgeny Kliteynik 	.build_tnl_mpls_init		= &dr_ste_v0_build_tnl_mpls_init,
960d65e841dSYevgeny Kliteynik 	.build_icmp_init		= &dr_ste_v0_build_icmp_init,
961d65e841dSYevgeny Kliteynik 	.build_general_purpose_init	= &dr_ste_v0_build_general_purpose_init,
962d65e841dSYevgeny Kliteynik 	.build_eth_l4_misc_init		= &dr_ste_v0_build_eth_l4_misc_init,
963d65e841dSYevgeny Kliteynik 	.build_tnl_vxlan_gpe_init	= &dr_ste_v0_build_flex_parser_tnl_vxlan_gpe_init,
964d65e841dSYevgeny Kliteynik 	.build_tnl_geneve_init		= &dr_ste_v0_build_flex_parser_tnl_geneve_init,
965d65e841dSYevgeny Kliteynik 	.build_register_0_init		= &dr_ste_v0_build_register_0_init,
966d65e841dSYevgeny Kliteynik 	.build_register_1_init		= &dr_ste_v0_build_register_1_init,
967d65e841dSYevgeny Kliteynik 	.build_src_gvmi_qpn_init	= &dr_ste_v0_build_src_gvmi_qpn_init,
968d65e841dSYevgeny Kliteynik };
969