xref: /dpdk/drivers/net/ice/base/ice_switch.c (revision ffb81dce)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2021 Intel Corporation
3  */
4 
5 #include "ice_switch.h"
6 #include "ice_flex_type.h"
7 #include "ice_flow.h"
8 
9 #define ICE_ETH_DA_OFFSET		0
10 #define ICE_ETH_ETHTYPE_OFFSET		12
11 #define ICE_ETH_VLAN_TCI_OFFSET		14
12 #define ICE_MAX_VLAN_ID			0xFFF
13 #define ICE_IPV4_NVGRE_PROTO_ID		0x002F
14 #define ICE_PPP_IPV6_PROTO_ID		0x0057
15 #define ICE_IPV6_ETHER_ID		0x86DD
16 #define ICE_TCP_PROTO_ID		0x06
17 #define ICE_GTPU_PROFILE		24
18 #define ICE_ETH_P_8021Q			0x8100
19 #define ICE_MPLS_ETHER_ID		0x8847
20 
21 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
22  * struct to configure any switch filter rules.
23  * {DA (6 bytes), SA(6 bytes),
24  * Ether type (2 bytes for header without VLAN tag) OR
25  * VLAN tag (4 bytes for header with VLAN tag) }
26  *
27  * Word on Hardcoded values
28  * byte 0 = 0x2: to identify it as locally administered DA MAC
29  * byte 6 = 0x2: to identify it as locally administered SA MAC
30  * byte 12 = 0x81 & byte 13 = 0x00:
31  *	In case of VLAN filter first two bytes defines ether type (0x8100)
32  *	and remaining two bytes are placeholder for programming a given VLAN ID
33  *	In case of Ether type filter it is treated as header without VLAN tag
34  *	and byte 12 and 13 is used to program a given Ether type instead
35  */
36 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
37 							0x2, 0, 0, 0, 0, 0,
38 							0x81, 0, 0, 0};
39 
40 struct ice_dummy_pkt_offsets {
41 	enum ice_protocol_type type;
42 	u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
43 };
44 
45 static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = {
46 	{ ICE_MAC_OFOS,		0 },
47 	{ ICE_ETYPE_OL,		12 },
48 	{ ICE_IPV4_OFOS,	14 },
49 	{ ICE_NVGRE,		34 },
50 	{ ICE_MAC_IL,		42 },
51 	{ ICE_IPV4_IL,		56 },
52 	{ ICE_TCP_IL,		76 },
53 	{ ICE_PROTOCOL_LAST,	0 },
54 };
55 
56 static const u8 dummy_gre_tcp_packet[] = {
57 	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
58 	0x00, 0x00, 0x00, 0x00,
59 	0x00, 0x00, 0x00, 0x00,
60 
61 	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
62 
63 	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
64 	0x00, 0x00, 0x00, 0x00,
65 	0x00, 0x2F, 0x00, 0x00,
66 	0x00, 0x00, 0x00, 0x00,
67 	0x00, 0x00, 0x00, 0x00,
68 
69 	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
70 	0x00, 0x00, 0x00, 0x00,
71 
72 	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
73 	0x00, 0x00, 0x00, 0x00,
74 	0x00, 0x00, 0x00, 0x00,
75 	0x08, 0x00,
76 
77 	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
78 	0x00, 0x00, 0x00, 0x00,
79 	0x00, 0x06, 0x00, 0x00,
80 	0x00, 0x00, 0x00, 0x00,
81 	0x00, 0x00, 0x00, 0x00,
82 
83 	0x00, 0x00, 0x00, 0x00,	/* ICE_TCP_IL 76 */
84 	0x00, 0x00, 0x00, 0x00,
85 	0x00, 0x00, 0x00, 0x00,
86 	0x50, 0x02, 0x20, 0x00,
87 	0x00, 0x00, 0x00, 0x00
88 };
89 
90 static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = {
91 	{ ICE_MAC_OFOS,		0 },
92 	{ ICE_ETYPE_OL,		12 },
93 	{ ICE_IPV4_OFOS,	14 },
94 	{ ICE_NVGRE,		34 },
95 	{ ICE_MAC_IL,		42 },
96 	{ ICE_IPV4_IL,		56 },
97 	{ ICE_UDP_ILOS,		76 },
98 	{ ICE_PROTOCOL_LAST,	0 },
99 };
100 
101 static const u8 dummy_gre_udp_packet[] = {
102 	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_OFOS 0 */
103 	0x00, 0x00, 0x00, 0x00,
104 	0x00, 0x00, 0x00, 0x00,
105 
106 	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
107 
108 	0x45, 0x00, 0x00, 0x3E,	/* ICE_IPV4_OFOS 14 */
109 	0x00, 0x00, 0x00, 0x00,
110 	0x00, 0x2F, 0x00, 0x00,
111 	0x00, 0x00, 0x00, 0x00,
112 	0x00, 0x00, 0x00, 0x00,
113 
114 	0x80, 0x00, 0x65, 0x58,	/* ICE_NVGRE 34 */
115 	0x00, 0x00, 0x00, 0x00,
116 
117 	0x00, 0x00, 0x00, 0x00,	/* ICE_MAC_IL 42 */
118 	0x00, 0x00, 0x00, 0x00,
119 	0x00, 0x00, 0x00, 0x00,
120 	0x08, 0x00,
121 
122 	0x45, 0x00, 0x00, 0x14,	/* ICE_IPV4_IL 56 */
123 	0x00, 0x00, 0x00, 0x00,
124 	0x00, 0x11, 0x00, 0x00,
125 	0x00, 0x00, 0x00, 0x00,
126 	0x00, 0x00, 0x00, 0x00,
127 
128 	0x00, 0x00, 0x00, 0x00,	/* ICE_UDP_ILOS 76 */
129 	0x00, 0x08, 0x00, 0x00,
130 };
131 
132 static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
133 	{ ICE_MAC_OFOS,		0 },
134 	{ ICE_ETYPE_OL,		12 },
135 	{ ICE_IPV4_OFOS,	14 },
136 	{ ICE_UDP_OF,		34 },
137 	{ ICE_VXLAN,		42 },
138 	{ ICE_GENEVE,		42 },
139 	{ ICE_VXLAN_GPE,	42 },
140 	{ ICE_MAC_IL,		50 },
141 	{ ICE_IPV4_IL,		64 },
142 	{ ICE_TCP_IL,		84 },
143 	{ ICE_PROTOCOL_LAST,	0 },
144 };
145 
146 static const u8 dummy_udp_tun_tcp_packet[] = {
147 	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
148 	0x00, 0x00, 0x00, 0x00,
149 	0x00, 0x00, 0x00, 0x00,
150 
151 	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
152 
153 	0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
154 	0x00, 0x01, 0x00, 0x00,
155 	0x40, 0x11, 0x00, 0x00,
156 	0x00, 0x00, 0x00, 0x00,
157 	0x00, 0x00, 0x00, 0x00,
158 
159 	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
160 	0x00, 0x46, 0x00, 0x00,
161 
162 	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
163 	0x00, 0x00, 0x00, 0x00,
164 
165 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
166 	0x00, 0x00, 0x00, 0x00,
167 	0x00, 0x00, 0x00, 0x00,
168 	0x08, 0x00,
169 
170 	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
171 	0x00, 0x01, 0x00, 0x00,
172 	0x40, 0x06, 0x00, 0x00,
173 	0x00, 0x00, 0x00, 0x00,
174 	0x00, 0x00, 0x00, 0x00,
175 
176 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
177 	0x00, 0x00, 0x00, 0x00,
178 	0x00, 0x00, 0x00, 0x00,
179 	0x50, 0x02, 0x20, 0x00,
180 	0x00, 0x00, 0x00, 0x00
181 };
182 
183 static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
184 	{ ICE_MAC_OFOS,		0 },
185 	{ ICE_ETYPE_OL,		12 },
186 	{ ICE_IPV4_OFOS,	14 },
187 	{ ICE_UDP_OF,		34 },
188 	{ ICE_VXLAN,		42 },
189 	{ ICE_GENEVE,		42 },
190 	{ ICE_VXLAN_GPE,	42 },
191 	{ ICE_MAC_IL,		50 },
192 	{ ICE_IPV4_IL,		64 },
193 	{ ICE_UDP_ILOS,		84 },
194 	{ ICE_PROTOCOL_LAST,	0 },
195 };
196 
197 static const u8 dummy_udp_tun_udp_packet[] = {
198 	0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
199 	0x00, 0x00, 0x00, 0x00,
200 	0x00, 0x00, 0x00, 0x00,
201 
202 	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
203 
204 	0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
205 	0x00, 0x01, 0x00, 0x00,
206 	0x00, 0x11, 0x00, 0x00,
207 	0x00, 0x00, 0x00, 0x00,
208 	0x00, 0x00, 0x00, 0x00,
209 
210 	0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
211 	0x00, 0x3a, 0x00, 0x00,
212 
213 	0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
214 	0x00, 0x00, 0x00, 0x00,
215 
216 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
217 	0x00, 0x00, 0x00, 0x00,
218 	0x00, 0x00, 0x00, 0x00,
219 	0x08, 0x00,
220 
221 	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
222 	0x00, 0x01, 0x00, 0x00,
223 	0x00, 0x11, 0x00, 0x00,
224 	0x00, 0x00, 0x00, 0x00,
225 	0x00, 0x00, 0x00, 0x00,
226 
227 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
228 	0x00, 0x08, 0x00, 0x00,
229 };
230 
231 /* offset info for MAC + IPv4 + UDP dummy packet */
232 static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
233 	{ ICE_MAC_OFOS,		0 },
234 	{ ICE_ETYPE_OL,		12 },
235 	{ ICE_IPV4_OFOS,	14 },
236 	{ ICE_UDP_ILOS,		34 },
237 	{ ICE_PROTOCOL_LAST,	0 },
238 };
239 
240 /* Dummy packet for MAC + IPv4 + UDP */
241 static const u8 dummy_udp_packet[] = {
242 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
243 	0x00, 0x00, 0x00, 0x00,
244 	0x00, 0x00, 0x00, 0x00,
245 
246 	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
247 
248 	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
249 	0x00, 0x01, 0x00, 0x00,
250 	0x00, 0x11, 0x00, 0x00,
251 	0x00, 0x00, 0x00, 0x00,
252 	0x00, 0x00, 0x00, 0x00,
253 
254 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
255 	0x00, 0x08, 0x00, 0x00,
256 
257 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
258 };
259 
260 /* offset info for MAC + VLAN + IPv4 + UDP dummy packet */
261 static const struct ice_dummy_pkt_offsets dummy_vlan_udp_packet_offsets[] = {
262 	{ ICE_MAC_OFOS,		0 },
263 	{ ICE_ETYPE_OL,		12 },
264 	{ ICE_VLAN_OFOS,	14 },
265 	{ ICE_IPV4_OFOS,	18 },
266 	{ ICE_UDP_ILOS,		38 },
267 	{ ICE_PROTOCOL_LAST,	0 },
268 };
269 
270 /* C-tag (801.1Q), IPv4:UDP dummy packet */
271 static const u8 dummy_vlan_udp_packet[] = {
272 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
273 	0x00, 0x00, 0x00, 0x00,
274 	0x00, 0x00, 0x00, 0x00,
275 
276 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
277 
278 	0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 14 */
279 
280 	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 18 */
281 	0x00, 0x01, 0x00, 0x00,
282 	0x00, 0x11, 0x00, 0x00,
283 	0x00, 0x00, 0x00, 0x00,
284 	0x00, 0x00, 0x00, 0x00,
285 
286 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 38 */
287 	0x00, 0x08, 0x00, 0x00,
288 
289 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
290 };
291 
292 /* offset info for MAC + IPv4 + TCP dummy packet */
293 static const struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = {
294 	{ ICE_MAC_OFOS,		0 },
295 	{ ICE_ETYPE_OL,		12 },
296 	{ ICE_IPV4_OFOS,	14 },
297 	{ ICE_TCP_IL,		34 },
298 	{ ICE_PROTOCOL_LAST,	0 },
299 };
300 
301 /* Dummy packet for MAC + IPv4 + TCP */
302 static const u8 dummy_tcp_packet[] = {
303 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
304 	0x00, 0x00, 0x00, 0x00,
305 	0x00, 0x00, 0x00, 0x00,
306 
307 	0x08, 0x00,		/* ICE_ETYPE_OL 12 */
308 
309 	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
310 	0x00, 0x01, 0x00, 0x00,
311 	0x00, 0x06, 0x00, 0x00,
312 	0x00, 0x00, 0x00, 0x00,
313 	0x00, 0x00, 0x00, 0x00,
314 
315 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
316 	0x00, 0x00, 0x00, 0x00,
317 	0x00, 0x00, 0x00, 0x00,
318 	0x50, 0x00, 0x00, 0x00,
319 	0x00, 0x00, 0x00, 0x00,
320 
321 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
322 };
323 
324 /* offset info for MAC + MPLS dummy packet */
325 static const struct ice_dummy_pkt_offsets dummy_mpls_packet_offsets[] = {
326 	{ ICE_MAC_OFOS,		0 },
327 	{ ICE_ETYPE_OL,		12 },
328 	{ ICE_PROTOCOL_LAST,	0 },
329 };
330 
331 /* Dummy packet for MAC + MPLS */
332 static const u8 dummy_mpls_packet[] = {
333 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
334 	0x00, 0x00, 0x00, 0x00,
335 	0x00, 0x00, 0x00, 0x00,
336 
337 	0x88, 0x47,		/* ICE_ETYPE_OL 12 */
338 	0x00, 0x00, 0x01, 0x00,
339 
340 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
341 };
342 
343 /* offset info for MAC + VLAN (C-tag, 802.1Q) + IPv4 + TCP dummy packet */
344 static const struct ice_dummy_pkt_offsets dummy_vlan_tcp_packet_offsets[] = {
345 	{ ICE_MAC_OFOS,		0 },
346 	{ ICE_ETYPE_OL,		12 },
347 	{ ICE_VLAN_OFOS,	14 },
348 	{ ICE_IPV4_OFOS,	18 },
349 	{ ICE_TCP_IL,		38 },
350 	{ ICE_PROTOCOL_LAST,	0 },
351 };
352 
353 /* C-tag (801.1Q), IPv4:TCP dummy packet */
354 static const u8 dummy_vlan_tcp_packet[] = {
355 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
356 	0x00, 0x00, 0x00, 0x00,
357 	0x00, 0x00, 0x00, 0x00,
358 
359 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
360 
361 	0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 14 */
362 
363 	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 18 */
364 	0x00, 0x01, 0x00, 0x00,
365 	0x00, 0x06, 0x00, 0x00,
366 	0x00, 0x00, 0x00, 0x00,
367 	0x00, 0x00, 0x00, 0x00,
368 
369 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 38 */
370 	0x00, 0x00, 0x00, 0x00,
371 	0x00, 0x00, 0x00, 0x00,
372 	0x50, 0x00, 0x00, 0x00,
373 	0x00, 0x00, 0x00, 0x00,
374 
375 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
376 };
377 
378 static const struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = {
379 	{ ICE_MAC_OFOS,		0 },
380 	{ ICE_ETYPE_OL,		12 },
381 	{ ICE_IPV6_OFOS,	14 },
382 	{ ICE_TCP_IL,		54 },
383 	{ ICE_PROTOCOL_LAST,	0 },
384 };
385 
386 static const u8 dummy_tcp_ipv6_packet[] = {
387 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
388 	0x00, 0x00, 0x00, 0x00,
389 	0x00, 0x00, 0x00, 0x00,
390 
391 	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */
392 
393 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
394 	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
395 	0x00, 0x00, 0x00, 0x00,
396 	0x00, 0x00, 0x00, 0x00,
397 	0x00, 0x00, 0x00, 0x00,
398 	0x00, 0x00, 0x00, 0x00,
399 	0x00, 0x00, 0x00, 0x00,
400 	0x00, 0x00, 0x00, 0x00,
401 	0x00, 0x00, 0x00, 0x00,
402 	0x00, 0x00, 0x00, 0x00,
403 
404 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
405 	0x00, 0x00, 0x00, 0x00,
406 	0x00, 0x00, 0x00, 0x00,
407 	0x50, 0x00, 0x00, 0x00,
408 	0x00, 0x00, 0x00, 0x00,
409 
410 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
411 };
412 
413 /* C-tag (802.1Q): IPv6 + TCP */
414 static const struct ice_dummy_pkt_offsets
415 dummy_vlan_tcp_ipv6_packet_offsets[] = {
416 	{ ICE_MAC_OFOS,		0 },
417 	{ ICE_ETYPE_OL,		12 },
418 	{ ICE_VLAN_OFOS,	14 },
419 	{ ICE_IPV6_OFOS,	18 },
420 	{ ICE_TCP_IL,		58 },
421 	{ ICE_PROTOCOL_LAST,	0 },
422 };
423 
424 /* C-tag (802.1Q), IPv6 + TCP dummy packet */
425 static const u8 dummy_vlan_tcp_ipv6_packet[] = {
426 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
427 	0x00, 0x00, 0x00, 0x00,
428 	0x00, 0x00, 0x00, 0x00,
429 
430 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
431 
432 	0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 14 */
433 
434 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
435 	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
436 	0x00, 0x00, 0x00, 0x00,
437 	0x00, 0x00, 0x00, 0x00,
438 	0x00, 0x00, 0x00, 0x00,
439 	0x00, 0x00, 0x00, 0x00,
440 	0x00, 0x00, 0x00, 0x00,
441 	0x00, 0x00, 0x00, 0x00,
442 	0x00, 0x00, 0x00, 0x00,
443 	0x00, 0x00, 0x00, 0x00,
444 
445 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 58 */
446 	0x00, 0x00, 0x00, 0x00,
447 	0x00, 0x00, 0x00, 0x00,
448 	0x50, 0x00, 0x00, 0x00,
449 	0x00, 0x00, 0x00, 0x00,
450 
451 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
452 };
453 
454 /* IPv6 + UDP */
455 static const struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = {
456 	{ ICE_MAC_OFOS,		0 },
457 	{ ICE_ETYPE_OL,		12 },
458 	{ ICE_IPV6_OFOS,	14 },
459 	{ ICE_UDP_ILOS,		54 },
460 	{ ICE_PROTOCOL_LAST,	0 },
461 };
462 
463 /* IPv6 + UDP dummy packet */
464 static const u8 dummy_udp_ipv6_packet[] = {
465 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
466 	0x00, 0x00, 0x00, 0x00,
467 	0x00, 0x00, 0x00, 0x00,
468 
469 	0x86, 0xDD,		/* ICE_ETYPE_OL 12 */
470 
471 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
472 	0x00, 0x10, 0x11, 0x00, /* Next header UDP */
473 	0x00, 0x00, 0x00, 0x00,
474 	0x00, 0x00, 0x00, 0x00,
475 	0x00, 0x00, 0x00, 0x00,
476 	0x00, 0x00, 0x00, 0x00,
477 	0x00, 0x00, 0x00, 0x00,
478 	0x00, 0x00, 0x00, 0x00,
479 	0x00, 0x00, 0x00, 0x00,
480 	0x00, 0x00, 0x00, 0x00,
481 
482 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
483 	0x00, 0x10, 0x00, 0x00,
484 
485 	0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
486 	0x00, 0x00, 0x00, 0x00,
487 
488 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
489 };
490 
491 /* C-tag (802.1Q): IPv6 + UDP */
492 static const struct ice_dummy_pkt_offsets
493 dummy_vlan_udp_ipv6_packet_offsets[] = {
494 	{ ICE_MAC_OFOS,		0 },
495 	{ ICE_ETYPE_OL,		12 },
496 	{ ICE_VLAN_OFOS,	14 },
497 	{ ICE_IPV6_OFOS,	18 },
498 	{ ICE_UDP_ILOS,		58 },
499 	{ ICE_PROTOCOL_LAST,	0 },
500 };
501 
502 /* C-tag (802.1Q), IPv6 + UDP dummy packet */
503 static const u8 dummy_vlan_udp_ipv6_packet[] = {
504 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
505 	0x00, 0x00, 0x00, 0x00,
506 	0x00, 0x00, 0x00, 0x00,
507 
508 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
509 
510 	0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 14 */
511 
512 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
513 	0x00, 0x08, 0x11, 0x00, /* Next header UDP */
514 	0x00, 0x00, 0x00, 0x00,
515 	0x00, 0x00, 0x00, 0x00,
516 	0x00, 0x00, 0x00, 0x00,
517 	0x00, 0x00, 0x00, 0x00,
518 	0x00, 0x00, 0x00, 0x00,
519 	0x00, 0x00, 0x00, 0x00,
520 	0x00, 0x00, 0x00, 0x00,
521 	0x00, 0x00, 0x00, 0x00,
522 
523 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 58 */
524 	0x00, 0x08, 0x00, 0x00,
525 
526 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
527 };
528 
529 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
530 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = {
531 	{ ICE_MAC_OFOS,		0 },
532 	{ ICE_IPV4_OFOS,	14 },
533 	{ ICE_UDP_OF,		34 },
534 	{ ICE_GTP,		42 },
535 	{ ICE_IPV4_IL,		62 },
536 	{ ICE_TCP_IL,		82 },
537 	{ ICE_PROTOCOL_LAST,	0 },
538 };
539 
540 static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = {
541 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
542 	0x00, 0x00, 0x00, 0x00,
543 	0x00, 0x00, 0x00, 0x00,
544 	0x08, 0x00,
545 
546 	0x45, 0x00, 0x00, 0x58, /* IP 14 */
547 	0x00, 0x00, 0x00, 0x00,
548 	0x00, 0x11, 0x00, 0x00,
549 	0x00, 0x00, 0x00, 0x00,
550 	0x00, 0x00, 0x00, 0x00,
551 
552 	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
553 	0x00, 0x44, 0x00, 0x00,
554 
555 	0x34, 0xff, 0x00, 0x34, /* GTP-U Header 42 */
556 	0x00, 0x00, 0x00, 0x00,
557 	0x00, 0x00, 0x00, 0x85,
558 
559 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
560 	0x00, 0x00, 0x00, 0x00,
561 
562 	0x45, 0x00, 0x00, 0x28, /* IP 62 */
563 	0x00, 0x00, 0x00, 0x00,
564 	0x00, 0x06, 0x00, 0x00,
565 	0x00, 0x00, 0x00, 0x00,
566 	0x00, 0x00, 0x00, 0x00,
567 
568 	0x00, 0x00, 0x00, 0x00, /* TCP 82 */
569 	0x00, 0x00, 0x00, 0x00,
570 	0x00, 0x00, 0x00, 0x00,
571 	0x50, 0x00, 0x00, 0x00,
572 	0x00, 0x00, 0x00, 0x00,
573 
574 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
575 };
576 
577 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
578 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = {
579 	{ ICE_MAC_OFOS,		0 },
580 	{ ICE_IPV4_OFOS,	14 },
581 	{ ICE_UDP_OF,		34 },
582 	{ ICE_GTP,		42 },
583 	{ ICE_IPV4_IL,		62 },
584 	{ ICE_UDP_ILOS,		82 },
585 	{ ICE_PROTOCOL_LAST,	0 },
586 };
587 
588 static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = {
589 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
590 	0x00, 0x00, 0x00, 0x00,
591 	0x00, 0x00, 0x00, 0x00,
592 	0x08, 0x00,
593 
594 	0x45, 0x00, 0x00, 0x4c, /* IP 14 */
595 	0x00, 0x00, 0x00, 0x00,
596 	0x00, 0x11, 0x00, 0x00,
597 	0x00, 0x00, 0x00, 0x00,
598 	0x00, 0x00, 0x00, 0x00,
599 
600 	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
601 	0x00, 0x38, 0x00, 0x00,
602 
603 	0x34, 0xff, 0x00, 0x28, /* GTP-U Header 42 */
604 	0x00, 0x00, 0x00, 0x00,
605 	0x00, 0x00, 0x00, 0x85,
606 
607 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
608 	0x00, 0x00, 0x00, 0x00,
609 
610 	0x45, 0x00, 0x00, 0x1c, /* IP 62 */
611 	0x00, 0x00, 0x00, 0x00,
612 	0x00, 0x11, 0x00, 0x00,
613 	0x00, 0x00, 0x00, 0x00,
614 	0x00, 0x00, 0x00, 0x00,
615 
616 	0x00, 0x00, 0x00, 0x00, /* UDP 82 */
617 	0x00, 0x08, 0x00, 0x00,
618 
619 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
620 };
621 
622 /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
623 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = {
624 	{ ICE_MAC_OFOS,		0 },
625 	{ ICE_IPV4_OFOS,	14 },
626 	{ ICE_UDP_OF,		34 },
627 	{ ICE_GTP,		42 },
628 	{ ICE_IPV6_IL,		62 },
629 	{ ICE_TCP_IL,		102 },
630 	{ ICE_PROTOCOL_LAST,	0 },
631 };
632 
633 static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = {
634 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
635 	0x00, 0x00, 0x00, 0x00,
636 	0x00, 0x00, 0x00, 0x00,
637 	0x08, 0x00,
638 
639 	0x45, 0x00, 0x00, 0x6c, /* IP 14 */
640 	0x00, 0x00, 0x00, 0x00,
641 	0x00, 0x11, 0x00, 0x00,
642 	0x00, 0x00, 0x00, 0x00,
643 	0x00, 0x00, 0x00, 0x00,
644 
645 	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
646 	0x00, 0x58, 0x00, 0x00,
647 
648 	0x34, 0xff, 0x00, 0x48, /* GTP-U Header 42 */
649 	0x00, 0x00, 0x00, 0x00,
650 	0x00, 0x00, 0x00, 0x85,
651 
652 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
653 	0x00, 0x00, 0x00, 0x00,
654 
655 	0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
656 	0x00, 0x14, 0x06, 0x00,
657 	0x00, 0x00, 0x00, 0x00,
658 	0x00, 0x00, 0x00, 0x00,
659 	0x00, 0x00, 0x00, 0x00,
660 	0x00, 0x00, 0x00, 0x00,
661 	0x00, 0x00, 0x00, 0x00,
662 	0x00, 0x00, 0x00, 0x00,
663 	0x00, 0x00, 0x00, 0x00,
664 	0x00, 0x00, 0x00, 0x00,
665 
666 	0x00, 0x00, 0x00, 0x00, /* TCP 102 */
667 	0x00, 0x00, 0x00, 0x00,
668 	0x00, 0x00, 0x00, 0x00,
669 	0x50, 0x00, 0x00, 0x00,
670 	0x00, 0x00, 0x00, 0x00,
671 
672 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
673 };
674 
675 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_udp_packet_offsets[] = {
676 	{ ICE_MAC_OFOS,		0 },
677 	{ ICE_IPV4_OFOS,	14 },
678 	{ ICE_UDP_OF,		34 },
679 	{ ICE_GTP,		42 },
680 	{ ICE_IPV6_IL,		62 },
681 	{ ICE_UDP_ILOS,		102 },
682 	{ ICE_PROTOCOL_LAST,	0 },
683 };
684 
685 static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = {
686 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
687 	0x00, 0x00, 0x00, 0x00,
688 	0x00, 0x00, 0x00, 0x00,
689 	0x08, 0x00,
690 
691 	0x45, 0x00, 0x00, 0x60, /* IP 14 */
692 	0x00, 0x00, 0x00, 0x00,
693 	0x00, 0x11, 0x00, 0x00,
694 	0x00, 0x00, 0x00, 0x00,
695 	0x00, 0x00, 0x00, 0x00,
696 
697 	0x00, 0x00, 0x08, 0x68, /* UDP 34 */
698 	0x00, 0x4c, 0x00, 0x00,
699 
700 	0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 42 */
701 	0x00, 0x00, 0x00, 0x00,
702 	0x00, 0x00, 0x00, 0x85,
703 
704 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
705 	0x00, 0x00, 0x00, 0x00,
706 
707 	0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
708 	0x00, 0x08, 0x11, 0x00,
709 	0x00, 0x00, 0x00, 0x00,
710 	0x00, 0x00, 0x00, 0x00,
711 	0x00, 0x00, 0x00, 0x00,
712 	0x00, 0x00, 0x00, 0x00,
713 	0x00, 0x00, 0x00, 0x00,
714 	0x00, 0x00, 0x00, 0x00,
715 	0x00, 0x00, 0x00, 0x00,
716 	0x00, 0x00, 0x00, 0x00,
717 
718 	0x00, 0x00, 0x00, 0x00, /* UDP 102 */
719 	0x00, 0x08, 0x00, 0x00,
720 
721 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
722 };
723 
724 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = {
725 	{ ICE_MAC_OFOS,		0 },
726 	{ ICE_IPV6_OFOS,	14 },
727 	{ ICE_UDP_OF,		54 },
728 	{ ICE_GTP,		62 },
729 	{ ICE_IPV4_IL,		82 },
730 	{ ICE_TCP_IL,		102 },
731 	{ ICE_PROTOCOL_LAST,	0 },
732 };
733 
734 static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = {
735 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
736 	0x00, 0x00, 0x00, 0x00,
737 	0x00, 0x00, 0x00, 0x00,
738 	0x86, 0xdd,
739 
740 	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
741 	0x00, 0x44, 0x11, 0x00,
742 	0x00, 0x00, 0x00, 0x00,
743 	0x00, 0x00, 0x00, 0x00,
744 	0x00, 0x00, 0x00, 0x00,
745 	0x00, 0x00, 0x00, 0x00,
746 	0x00, 0x00, 0x00, 0x00,
747 	0x00, 0x00, 0x00, 0x00,
748 	0x00, 0x00, 0x00, 0x00,
749 	0x00, 0x00, 0x00, 0x00,
750 
751 	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
752 	0x00, 0x44, 0x00, 0x00,
753 
754 	0x34, 0xff, 0x00, 0x34, /* GTP-U Header 62 */
755 	0x00, 0x00, 0x00, 0x00,
756 	0x00, 0x00, 0x00, 0x85,
757 
758 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
759 	0x00, 0x00, 0x00, 0x00,
760 
761 	0x45, 0x00, 0x00, 0x28, /* IP 82 */
762 	0x00, 0x00, 0x00, 0x00,
763 	0x00, 0x06, 0x00, 0x00,
764 	0x00, 0x00, 0x00, 0x00,
765 	0x00, 0x00, 0x00, 0x00,
766 
767 	0x00, 0x00, 0x00, 0x00, /* TCP 102 */
768 	0x00, 0x00, 0x00, 0x00,
769 	0x00, 0x00, 0x00, 0x00,
770 	0x50, 0x00, 0x00, 0x00,
771 	0x00, 0x00, 0x00, 0x00,
772 
773 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
774 };
775 
776 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_udp_packet_offsets[] = {
777 	{ ICE_MAC_OFOS,		0 },
778 	{ ICE_IPV6_OFOS,	14 },
779 	{ ICE_UDP_OF,		54 },
780 	{ ICE_GTP,		62 },
781 	{ ICE_IPV4_IL,		82 },
782 	{ ICE_UDP_ILOS,		102 },
783 	{ ICE_PROTOCOL_LAST,	0 },
784 };
785 
786 static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = {
787 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
788 	0x00, 0x00, 0x00, 0x00,
789 	0x00, 0x00, 0x00, 0x00,
790 	0x86, 0xdd,
791 
792 	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
793 	0x00, 0x38, 0x11, 0x00,
794 	0x00, 0x00, 0x00, 0x00,
795 	0x00, 0x00, 0x00, 0x00,
796 	0x00, 0x00, 0x00, 0x00,
797 	0x00, 0x00, 0x00, 0x00,
798 	0x00, 0x00, 0x00, 0x00,
799 	0x00, 0x00, 0x00, 0x00,
800 	0x00, 0x00, 0x00, 0x00,
801 	0x00, 0x00, 0x00, 0x00,
802 
803 	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
804 	0x00, 0x38, 0x00, 0x00,
805 
806 	0x34, 0xff, 0x00, 0x28, /* GTP-U Header 62 */
807 	0x00, 0x00, 0x00, 0x00,
808 	0x00, 0x00, 0x00, 0x85,
809 
810 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
811 	0x00, 0x00, 0x00, 0x00,
812 
813 	0x45, 0x00, 0x00, 0x1c, /* IP 82 */
814 	0x00, 0x00, 0x00, 0x00,
815 	0x00, 0x11, 0x00, 0x00,
816 	0x00, 0x00, 0x00, 0x00,
817 	0x00, 0x00, 0x00, 0x00,
818 
819 	0x00, 0x00, 0x00, 0x00, /* UDP 102 */
820 	0x00, 0x08, 0x00, 0x00,
821 
822 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
823 };
824 
825 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = {
826 	{ ICE_MAC_OFOS,		0 },
827 	{ ICE_IPV6_OFOS,	14 },
828 	{ ICE_UDP_OF,		54 },
829 	{ ICE_GTP,		62 },
830 	{ ICE_IPV6_IL,		82 },
831 	{ ICE_TCP_IL,		122 },
832 	{ ICE_PROTOCOL_LAST,	0 },
833 };
834 
835 static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = {
836 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
837 	0x00, 0x00, 0x00, 0x00,
838 	0x00, 0x00, 0x00, 0x00,
839 	0x86, 0xdd,
840 
841 	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
842 	0x00, 0x58, 0x11, 0x00,
843 	0x00, 0x00, 0x00, 0x00,
844 	0x00, 0x00, 0x00, 0x00,
845 	0x00, 0x00, 0x00, 0x00,
846 	0x00, 0x00, 0x00, 0x00,
847 	0x00, 0x00, 0x00, 0x00,
848 	0x00, 0x00, 0x00, 0x00,
849 	0x00, 0x00, 0x00, 0x00,
850 	0x00, 0x00, 0x00, 0x00,
851 
852 	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
853 	0x00, 0x58, 0x00, 0x00,
854 
855 	0x34, 0xff, 0x00, 0x48, /* GTP-U Header 62 */
856 	0x00, 0x00, 0x00, 0x00,
857 	0x00, 0x00, 0x00, 0x85,
858 
859 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
860 	0x00, 0x00, 0x00, 0x00,
861 
862 	0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
863 	0x00, 0x14, 0x06, 0x00,
864 	0x00, 0x00, 0x00, 0x00,
865 	0x00, 0x00, 0x00, 0x00,
866 	0x00, 0x00, 0x00, 0x00,
867 	0x00, 0x00, 0x00, 0x00,
868 	0x00, 0x00, 0x00, 0x00,
869 	0x00, 0x00, 0x00, 0x00,
870 	0x00, 0x00, 0x00, 0x00,
871 	0x00, 0x00, 0x00, 0x00,
872 
873 	0x00, 0x00, 0x00, 0x00, /* TCP 122 */
874 	0x00, 0x00, 0x00, 0x00,
875 	0x00, 0x00, 0x00, 0x00,
876 	0x50, 0x00, 0x00, 0x00,
877 	0x00, 0x00, 0x00, 0x00,
878 
879 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
880 };
881 
882 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_udp_packet_offsets[] = {
883 	{ ICE_MAC_OFOS,		0 },
884 	{ ICE_IPV6_OFOS,	14 },
885 	{ ICE_UDP_OF,		54 },
886 	{ ICE_GTP,		62 },
887 	{ ICE_IPV6_IL,		82 },
888 	{ ICE_UDP_ILOS,		122 },
889 	{ ICE_PROTOCOL_LAST,	0 },
890 };
891 
892 static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = {
893 	0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
894 	0x00, 0x00, 0x00, 0x00,
895 	0x00, 0x00, 0x00, 0x00,
896 	0x86, 0xdd,
897 
898 	0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
899 	0x00, 0x4c, 0x11, 0x00,
900 	0x00, 0x00, 0x00, 0x00,
901 	0x00, 0x00, 0x00, 0x00,
902 	0x00, 0x00, 0x00, 0x00,
903 	0x00, 0x00, 0x00, 0x00,
904 	0x00, 0x00, 0x00, 0x00,
905 	0x00, 0x00, 0x00, 0x00,
906 	0x00, 0x00, 0x00, 0x00,
907 	0x00, 0x00, 0x00, 0x00,
908 
909 	0x00, 0x00, 0x08, 0x68, /* UDP 54 */
910 	0x00, 0x4c, 0x00, 0x00,
911 
912 	0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 62 */
913 	0x00, 0x00, 0x00, 0x00,
914 	0x00, 0x00, 0x00, 0x85,
915 
916 	0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
917 	0x00, 0x00, 0x00, 0x00,
918 
919 	0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
920 	0x00, 0x08, 0x11, 0x00,
921 	0x00, 0x00, 0x00, 0x00,
922 	0x00, 0x00, 0x00, 0x00,
923 	0x00, 0x00, 0x00, 0x00,
924 	0x00, 0x00, 0x00, 0x00,
925 	0x00, 0x00, 0x00, 0x00,
926 	0x00, 0x00, 0x00, 0x00,
927 	0x00, 0x00, 0x00, 0x00,
928 	0x00, 0x00, 0x00, 0x00,
929 
930 	0x00, 0x00, 0x00, 0x00, /* UDP 122 */
931 	0x00, 0x08, 0x00, 0x00,
932 
933 	0x00, 0x00, /* 2 bytes for 4 byte alignment */
934 };
935 
936 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_packet_offsets[] = {
937 	{ ICE_MAC_OFOS,		0 },
938 	{ ICE_IPV4_OFOS,	14 },
939 	{ ICE_UDP_OF,		34 },
940 	{ ICE_GTP,		42 },
941 	{ ICE_IPV4_IL,		62 },
942 	{ ICE_PROTOCOL_LAST,	0 },
943 };
944 
945 static const u8 dummy_ipv4_gtpu_ipv4_packet[] = {
946 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
947 	0x00, 0x00, 0x00, 0x00,
948 	0x00, 0x00, 0x00, 0x00,
949 	0x08, 0x00,
950 
951 	0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
952 	0x00, 0x00, 0x40, 0x00,
953 	0x40, 0x11, 0x00, 0x00,
954 	0x00, 0x00, 0x00, 0x00,
955 	0x00, 0x00, 0x00, 0x00,
956 
957 	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
958 	0x00, 0x00, 0x00, 0x00,
959 
960 	0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 42 */
961 	0x00, 0x00, 0x00, 0x00,
962 	0x00, 0x00, 0x00, 0x85,
963 
964 	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
965 	0x00, 0x00, 0x00, 0x00,
966 
967 	0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
968 	0x00, 0x00, 0x40, 0x00,
969 	0x40, 0x00, 0x00, 0x00,
970 	0x00, 0x00, 0x00, 0x00,
971 	0x00, 0x00, 0x00, 0x00,
972 	0x00, 0x00,
973 };
974 
975 static const
976 struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_packet_offsets[] = {
977 	{ ICE_MAC_OFOS,		0 },
978 	{ ICE_IPV4_OFOS,	14 },
979 	{ ICE_UDP_OF,		34 },
980 	{ ICE_GTP,		42 },
981 	{ ICE_IPV6_IL,		62 },
982 	{ ICE_PROTOCOL_LAST,	0 },
983 };
984 
985 static const u8 dummy_ipv4_gtpu_ipv6_packet[] = {
986 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
987 	0x00, 0x00, 0x00, 0x00,
988 	0x00, 0x00, 0x00, 0x00,
989 	0x08, 0x00,
990 
991 	0x45, 0x00, 0x00, 0x58, /* ICE_IPV4_OFOS 14 */
992 	0x00, 0x00, 0x40, 0x00,
993 	0x40, 0x11, 0x00, 0x00,
994 	0x00, 0x00, 0x00, 0x00,
995 	0x00, 0x00, 0x00, 0x00,
996 
997 	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
998 	0x00, 0x00, 0x00, 0x00,
999 
1000 	0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 42 */
1001 	0x00, 0x00, 0x00, 0x00,
1002 	0x00, 0x00, 0x00, 0x85,
1003 
1004 	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1005 	0x00, 0x00, 0x00, 0x00,
1006 
1007 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 62 */
1008 	0x00, 0x00, 0x3b, 0x00,
1009 	0x00, 0x00, 0x00, 0x00,
1010 	0x00, 0x00, 0x00, 0x00,
1011 	0x00, 0x00, 0x00, 0x00,
1012 	0x00, 0x00, 0x00, 0x00,
1013 	0x00, 0x00, 0x00, 0x00,
1014 	0x00, 0x00, 0x00, 0x00,
1015 	0x00, 0x00, 0x00, 0x00,
1016 	0x00, 0x00, 0x00, 0x00,
1017 
1018 	0x00, 0x00,
1019 };
1020 
1021 static const
1022 struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_packet_offsets[] = {
1023 	{ ICE_MAC_OFOS,		0 },
1024 	{ ICE_IPV6_OFOS,	14 },
1025 	{ ICE_UDP_OF,		54 },
1026 	{ ICE_GTP,		62 },
1027 	{ ICE_IPV4_IL,		82 },
1028 	{ ICE_PROTOCOL_LAST,	0 },
1029 };
1030 
1031 static const u8 dummy_ipv6_gtpu_ipv4_packet[] = {
1032 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1033 	0x00, 0x00, 0x00, 0x00,
1034 	0x00, 0x00, 0x00, 0x00,
1035 	0x86, 0xdd,
1036 
1037 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1038 	0x00, 0x58, 0x11, 0x00, /* Next header UDP*/
1039 	0x00, 0x00, 0x00, 0x00,
1040 	0x00, 0x00, 0x00, 0x00,
1041 	0x00, 0x00, 0x00, 0x00,
1042 	0x00, 0x00, 0x00, 0x00,
1043 	0x00, 0x00, 0x00, 0x00,
1044 	0x00, 0x00, 0x00, 0x00,
1045 	0x00, 0x00, 0x00, 0x00,
1046 	0x00, 0x00, 0x00, 0x00,
1047 
1048 	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1049 	0x00, 0x00, 0x00, 0x00,
1050 
1051 	0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 62 */
1052 	0x00, 0x00, 0x00, 0x00,
1053 	0x00, 0x00, 0x00, 0x85,
1054 
1055 	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1056 	0x00, 0x00, 0x00, 0x00,
1057 
1058 	0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 82 */
1059 	0x00, 0x00, 0x40, 0x00,
1060 	0x40, 0x00, 0x00, 0x00,
1061 	0x00, 0x00, 0x00, 0x00,
1062 	0x00, 0x00, 0x00, 0x00,
1063 
1064 	0x00, 0x00,
1065 };
1066 
1067 static const
1068 struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_packet_offsets[] = {
1069 	{ ICE_MAC_OFOS,		0 },
1070 	{ ICE_IPV6_OFOS,	14 },
1071 	{ ICE_UDP_OF,		54 },
1072 	{ ICE_GTP,		62 },
1073 	{ ICE_IPV6_IL,		82 },
1074 	{ ICE_PROTOCOL_LAST,	0 },
1075 };
1076 
1077 static const u8 dummy_ipv6_gtpu_ipv6_packet[] = {
1078 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1079 	0x00, 0x00, 0x00, 0x00,
1080 	0x00, 0x00, 0x00, 0x00,
1081 	0x86, 0xdd,
1082 
1083 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1084 	0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1085 	0x00, 0x00, 0x00, 0x00,
1086 	0x00, 0x00, 0x00, 0x00,
1087 	0x00, 0x00, 0x00, 0x00,
1088 	0x00, 0x00, 0x00, 0x00,
1089 	0x00, 0x00, 0x00, 0x00,
1090 	0x00, 0x00, 0x00, 0x00,
1091 	0x00, 0x00, 0x00, 0x00,
1092 	0x00, 0x00, 0x00, 0x00,
1093 
1094 	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1095 	0x00, 0x00, 0x00, 0x00,
1096 
1097 	0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 62 */
1098 	0x00, 0x00, 0x00, 0x00,
1099 	0x00, 0x00, 0x00, 0x85,
1100 
1101 	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1102 	0x00, 0x00, 0x00, 0x00,
1103 
1104 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFIL 82 */
1105 	0x00, 0x00, 0x3b, 0x00,
1106 	0x00, 0x00, 0x00, 0x00,
1107 	0x00, 0x00, 0x00, 0x00,
1108 	0x00, 0x00, 0x00, 0x00,
1109 	0x00, 0x00, 0x00, 0x00,
1110 	0x00, 0x00, 0x00, 0x00,
1111 	0x00, 0x00, 0x00, 0x00,
1112 	0x00, 0x00, 0x00, 0x00,
1113 	0x00, 0x00, 0x00, 0x00,
1114 
1115 	0x00, 0x00,
1116 };
1117 
1118 static const struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = {
1119 	{ ICE_MAC_OFOS,		0 },
1120 	{ ICE_IPV4_OFOS,	14 },
1121 	{ ICE_UDP_OF,		34 },
1122 	{ ICE_GTP,		42 },
1123 	{ ICE_PROTOCOL_LAST,	0 },
1124 };
1125 
1126 static const u8 dummy_udp_gtp_packet[] = {
1127 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1128 	0x00, 0x00, 0x00, 0x00,
1129 	0x00, 0x00, 0x00, 0x00,
1130 	0x08, 0x00,
1131 
1132 	0x45, 0x00, 0x00, 0x30, /* ICE_IPV4_OFOS 14 */
1133 	0x00, 0x00, 0x00, 0x00,
1134 	0x00, 0x11, 0x00, 0x00,
1135 	0x00, 0x00, 0x00, 0x00,
1136 	0x00, 0x00, 0x00, 0x00,
1137 
1138 	0x00, 0x00, 0x08, 0x68, /* ICE_UDP_OF 34 */
1139 	0x00, 0x1c, 0x00, 0x00,
1140 
1141 	0x34, 0xff, 0x00, 0x0c, /* ICE_GTP 42 */
1142 	0x00, 0x00, 0x00, 0x00,
1143 	0x00, 0x00, 0x00, 0x85,
1144 
1145 	0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1146 	0x00, 0x00, 0x00, 0x00,
1147 
1148 };
1149 
1150 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtp_no_pay_packet_offsets[] = {
1151 	{ ICE_MAC_OFOS,		0 },
1152 	{ ICE_IPV4_OFOS,	14 },
1153 	{ ICE_UDP_OF,		34 },
1154 	{ ICE_GTP_NO_PAY,	42 },
1155 	{ ICE_PROTOCOL_LAST,	0 },
1156 };
1157 
1158 static const
1159 struct ice_dummy_pkt_offsets dummy_ipv6_gtp_no_pay_packet_offsets[] = {
1160 	{ ICE_MAC_OFOS,		0 },
1161 	{ ICE_IPV6_OFOS,	14 },
1162 	{ ICE_UDP_OF,		54 },
1163 	{ ICE_GTP_NO_PAY,	62 },
1164 	{ ICE_PROTOCOL_LAST,	0 },
1165 };
1166 
1167 static const u8 dummy_ipv6_gtp_packet[] = {
1168 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1169 	0x00, 0x00, 0x00, 0x00,
1170 	0x00, 0x00, 0x00, 0x00,
1171 	0x86, 0xdd,
1172 
1173 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1174 	0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1175 	0x00, 0x00, 0x00, 0x00,
1176 	0x00, 0x00, 0x00, 0x00,
1177 	0x00, 0x00, 0x00, 0x00,
1178 	0x00, 0x00, 0x00, 0x00,
1179 	0x00, 0x00, 0x00, 0x00,
1180 	0x00, 0x00, 0x00, 0x00,
1181 	0x00, 0x00, 0x00, 0x00,
1182 	0x00, 0x00, 0x00, 0x00,
1183 
1184 	0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1185 	0x00, 0x00, 0x00, 0x00,
1186 
1187 	0x30, 0x00, 0x00, 0x28,  /* ICE_GTP 62 */
1188 	0x00, 0x00, 0x00, 0x00,
1189 
1190 	0x00, 0x00,
1191 };
1192 
1193 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_offsets[] = {
1194 	{ ICE_MAC_OFOS,		0 },
1195 	{ ICE_ETYPE_OL,		12 },
1196 	{ ICE_VLAN_OFOS,	14},
1197 	{ ICE_PPPOE,		18 },
1198 	{ ICE_PROTOCOL_LAST,	0 },
1199 };
1200 
1201 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv4_offsets[] = {
1202 	{ ICE_MAC_OFOS,		0 },
1203 	{ ICE_ETYPE_OL,		12 },
1204 	{ ICE_VLAN_OFOS,	14},
1205 	{ ICE_PPPOE,		18 },
1206 	{ ICE_IPV4_OFOS,	26 },
1207 	{ ICE_PROTOCOL_LAST,	0 },
1208 };
1209 
1210 static const u8 dummy_pppoe_ipv4_packet[] = {
1211 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1212 	0x00, 0x00, 0x00, 0x00,
1213 	0x00, 0x00, 0x00, 0x00,
1214 
1215 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
1216 
1217 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1218 
1219 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1220 	0x00, 0x16,
1221 
1222 	0x00, 0x21,		/* PPP Link Layer 24 */
1223 
1224 	0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 26 */
1225 	0x00, 0x00, 0x00, 0x00,
1226 	0x00, 0x00, 0x00, 0x00,
1227 	0x00, 0x00, 0x00, 0x00,
1228 	0x00, 0x00, 0x00, 0x00,
1229 
1230 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1231 };
1232 
1233 static const
1234 struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_tcp_packet_offsets[] = {
1235 	{ ICE_MAC_OFOS,		0 },
1236 	{ ICE_ETYPE_OL,		12 },
1237 	{ ICE_VLAN_OFOS,	14},
1238 	{ ICE_PPPOE,		18 },
1239 	{ ICE_IPV4_OFOS,	26 },
1240 	{ ICE_TCP_IL,		46 },
1241 	{ ICE_PROTOCOL_LAST,	0 },
1242 };
1243 
1244 static const u8 dummy_pppoe_ipv4_tcp_packet[] = {
1245 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1246 	0x00, 0x00, 0x00, 0x00,
1247 	0x00, 0x00, 0x00, 0x00,
1248 
1249 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
1250 
1251 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1252 
1253 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1254 	0x00, 0x16,
1255 
1256 	0x00, 0x21,		/* PPP Link Layer 24 */
1257 
1258 	0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 26 */
1259 	0x00, 0x01, 0x00, 0x00,
1260 	0x00, 0x06, 0x00, 0x00,
1261 	0x00, 0x00, 0x00, 0x00,
1262 	0x00, 0x00, 0x00, 0x00,
1263 
1264 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 46 */
1265 	0x00, 0x00, 0x00, 0x00,
1266 	0x00, 0x00, 0x00, 0x00,
1267 	0x50, 0x00, 0x00, 0x00,
1268 	0x00, 0x00, 0x00, 0x00,
1269 
1270 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1271 };
1272 
1273 static const
1274 struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_udp_packet_offsets[] = {
1275 	{ ICE_MAC_OFOS,		0 },
1276 	{ ICE_ETYPE_OL,		12 },
1277 	{ ICE_VLAN_OFOS,	14},
1278 	{ ICE_PPPOE,		18 },
1279 	{ ICE_IPV4_OFOS,	26 },
1280 	{ ICE_UDP_ILOS,		46 },
1281 	{ ICE_PROTOCOL_LAST,	0 },
1282 };
1283 
1284 static const u8 dummy_pppoe_ipv4_udp_packet[] = {
1285 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1286 	0x00, 0x00, 0x00, 0x00,
1287 	0x00, 0x00, 0x00, 0x00,
1288 
1289 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
1290 
1291 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1292 
1293 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1294 	0x00, 0x16,
1295 
1296 	0x00, 0x21,		/* PPP Link Layer 24 */
1297 
1298 	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 26 */
1299 	0x00, 0x01, 0x00, 0x00,
1300 	0x00, 0x11, 0x00, 0x00,
1301 	0x00, 0x00, 0x00, 0x00,
1302 	0x00, 0x00, 0x00, 0x00,
1303 
1304 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 46 */
1305 	0x00, 0x08, 0x00, 0x00,
1306 
1307 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1308 };
1309 
1310 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_offsets[] = {
1311 	{ ICE_MAC_OFOS,		0 },
1312 	{ ICE_ETYPE_OL,		12 },
1313 	{ ICE_VLAN_OFOS,	14},
1314 	{ ICE_PPPOE,		18 },
1315 	{ ICE_IPV6_OFOS,	26 },
1316 	{ ICE_PROTOCOL_LAST,	0 },
1317 };
1318 
1319 static const u8 dummy_pppoe_ipv6_packet[] = {
1320 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1321 	0x00, 0x00, 0x00, 0x00,
1322 	0x00, 0x00, 0x00, 0x00,
1323 
1324 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
1325 
1326 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1327 
1328 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1329 	0x00, 0x2a,
1330 
1331 	0x00, 0x57,		/* PPP Link Layer 24 */
1332 
1333 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1334 	0x00, 0x00, 0x3b, 0x00,
1335 	0x00, 0x00, 0x00, 0x00,
1336 	0x00, 0x00, 0x00, 0x00,
1337 	0x00, 0x00, 0x00, 0x00,
1338 	0x00, 0x00, 0x00, 0x00,
1339 	0x00, 0x00, 0x00, 0x00,
1340 	0x00, 0x00, 0x00, 0x00,
1341 	0x00, 0x00, 0x00, 0x00,
1342 	0x00, 0x00, 0x00, 0x00,
1343 
1344 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1345 };
1346 
1347 static const
1348 struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_tcp_offsets[] = {
1349 	{ ICE_MAC_OFOS,		0 },
1350 	{ ICE_ETYPE_OL,		12 },
1351 	{ ICE_VLAN_OFOS,	14},
1352 	{ ICE_PPPOE,		18 },
1353 	{ ICE_IPV6_OFOS,	26 },
1354 	{ ICE_TCP_IL,		66 },
1355 	{ ICE_PROTOCOL_LAST,	0 },
1356 };
1357 
1358 static const u8 dummy_pppoe_ipv6_tcp_packet[] = {
1359 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1360 	0x00, 0x00, 0x00, 0x00,
1361 	0x00, 0x00, 0x00, 0x00,
1362 
1363 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
1364 
1365 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1366 
1367 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1368 	0x00, 0x2a,
1369 
1370 	0x00, 0x57,		/* PPP Link Layer 24 */
1371 
1372 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1373 	0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
1374 	0x00, 0x00, 0x00, 0x00,
1375 	0x00, 0x00, 0x00, 0x00,
1376 	0x00, 0x00, 0x00, 0x00,
1377 	0x00, 0x00, 0x00, 0x00,
1378 	0x00, 0x00, 0x00, 0x00,
1379 	0x00, 0x00, 0x00, 0x00,
1380 	0x00, 0x00, 0x00, 0x00,
1381 	0x00, 0x00, 0x00, 0x00,
1382 
1383 	0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 66 */
1384 	0x00, 0x00, 0x00, 0x00,
1385 	0x00, 0x00, 0x00, 0x00,
1386 	0x50, 0x00, 0x00, 0x00,
1387 	0x00, 0x00, 0x00, 0x00,
1388 
1389 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1390 };
1391 
1392 static const
1393 struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_udp_offsets[] = {
1394 	{ ICE_MAC_OFOS,		0 },
1395 	{ ICE_ETYPE_OL,		12 },
1396 	{ ICE_VLAN_OFOS,	14},
1397 	{ ICE_PPPOE,		18 },
1398 	{ ICE_IPV6_OFOS,	26 },
1399 	{ ICE_UDP_ILOS,		66 },
1400 	{ ICE_PROTOCOL_LAST,	0 },
1401 };
1402 
1403 static const u8 dummy_pppoe_ipv6_udp_packet[] = {
1404 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1405 	0x00, 0x00, 0x00, 0x00,
1406 	0x00, 0x00, 0x00, 0x00,
1407 
1408 	0x81, 0x00,		/* ICE_ETYPE_OL 12 */
1409 
1410 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1411 
1412 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1413 	0x00, 0x2a,
1414 
1415 	0x00, 0x57,		/* PPP Link Layer 24 */
1416 
1417 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1418 	0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
1419 	0x00, 0x00, 0x00, 0x00,
1420 	0x00, 0x00, 0x00, 0x00,
1421 	0x00, 0x00, 0x00, 0x00,
1422 	0x00, 0x00, 0x00, 0x00,
1423 	0x00, 0x00, 0x00, 0x00,
1424 	0x00, 0x00, 0x00, 0x00,
1425 	0x00, 0x00, 0x00, 0x00,
1426 	0x00, 0x00, 0x00, 0x00,
1427 
1428 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 66 */
1429 	0x00, 0x08, 0x00, 0x00,
1430 
1431 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1432 };
1433 
1434 static const struct ice_dummy_pkt_offsets dummy_ipv4_esp_packet_offsets[] = {
1435 	{ ICE_MAC_OFOS,		0 },
1436 	{ ICE_IPV4_OFOS,	14 },
1437 	{ ICE_ESP,			34 },
1438 	{ ICE_PROTOCOL_LAST,	0 },
1439 };
1440 
1441 static const u8 dummy_ipv4_esp_pkt[] = {
1442 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1443 	0x00, 0x00, 0x00, 0x00,
1444 	0x00, 0x00, 0x00, 0x00,
1445 	0x08, 0x00,
1446 
1447 	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 14 */
1448 	0x00, 0x00, 0x40, 0x00,
1449 	0x40, 0x32, 0x00, 0x00,
1450 	0x00, 0x00, 0x00, 0x00,
1451 	0x00, 0x00, 0x00, 0x00,
1452 
1453 	0x00, 0x00, 0x00, 0x00, /* ICE_ESP 34 */
1454 	0x00, 0x00, 0x00, 0x00,
1455 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1456 };
1457 
1458 static const struct ice_dummy_pkt_offsets dummy_ipv6_esp_packet_offsets[] = {
1459 	{ ICE_MAC_OFOS,		0 },
1460 	{ ICE_IPV6_OFOS,	14 },
1461 	{ ICE_ESP,			54 },
1462 	{ ICE_PROTOCOL_LAST,	0 },
1463 };
1464 
1465 static const u8 dummy_ipv6_esp_pkt[] = {
1466 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1467 	0x00, 0x00, 0x00, 0x00,
1468 	0x00, 0x00, 0x00, 0x00,
1469 	0x86, 0xDD,
1470 
1471 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1472 	0x00, 0x08, 0x32, 0x00, /* Next header ESP */
1473 	0x00, 0x00, 0x00, 0x00,
1474 	0x00, 0x00, 0x00, 0x00,
1475 	0x00, 0x00, 0x00, 0x00,
1476 	0x00, 0x00, 0x00, 0x00,
1477 	0x00, 0x00, 0x00, 0x00,
1478 	0x00, 0x00, 0x00, 0x00,
1479 	0x00, 0x00, 0x00, 0x00,
1480 	0x00, 0x00, 0x00, 0x00,
1481 
1482 	0x00, 0x00, 0x00, 0x00, /* ICE_ESP 54 */
1483 	0x00, 0x00, 0x00, 0x00,
1484 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1485 };
1486 
1487 static const struct ice_dummy_pkt_offsets dummy_ipv4_ah_packet_offsets[] = {
1488 	{ ICE_MAC_OFOS,		0 },
1489 	{ ICE_IPV4_OFOS,	14 },
1490 	{ ICE_AH,			34 },
1491 	{ ICE_PROTOCOL_LAST,	0 },
1492 };
1493 
1494 static const u8 dummy_ipv4_ah_pkt[] = {
1495 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1496 	0x00, 0x00, 0x00, 0x00,
1497 	0x00, 0x00, 0x00, 0x00,
1498 	0x08, 0x00,
1499 
1500 	0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1501 	0x00, 0x00, 0x40, 0x00,
1502 	0x40, 0x33, 0x00, 0x00,
1503 	0x00, 0x00, 0x00, 0x00,
1504 	0x00, 0x00, 0x00, 0x00,
1505 
1506 	0x00, 0x00, 0x00, 0x00, /* ICE_AH 34 */
1507 	0x00, 0x00, 0x00, 0x00,
1508 	0x00, 0x00, 0x00, 0x00,
1509 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1510 };
1511 
1512 static const struct ice_dummy_pkt_offsets dummy_ipv6_ah_packet_offsets[] = {
1513 	{ ICE_MAC_OFOS,		0 },
1514 	{ ICE_IPV6_OFOS,	14 },
1515 	{ ICE_AH,			54 },
1516 	{ ICE_PROTOCOL_LAST,	0 },
1517 };
1518 
1519 static const u8 dummy_ipv6_ah_pkt[] = {
1520 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1521 	0x00, 0x00, 0x00, 0x00,
1522 	0x00, 0x00, 0x00, 0x00,
1523 	0x86, 0xDD,
1524 
1525 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1526 	0x00, 0x0c, 0x33, 0x00, /* Next header AH */
1527 	0x00, 0x00, 0x00, 0x00,
1528 	0x00, 0x00, 0x00, 0x00,
1529 	0x00, 0x00, 0x00, 0x00,
1530 	0x00, 0x00, 0x00, 0x00,
1531 	0x00, 0x00, 0x00, 0x00,
1532 	0x00, 0x00, 0x00, 0x00,
1533 	0x00, 0x00, 0x00, 0x00,
1534 	0x00, 0x00, 0x00, 0x00,
1535 
1536 	0x00, 0x00, 0x00, 0x00, /* ICE_AH 54 */
1537 	0x00, 0x00, 0x00, 0x00,
1538 	0x00, 0x00, 0x00, 0x00,
1539 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1540 };
1541 
1542 static const struct ice_dummy_pkt_offsets dummy_ipv4_nat_packet_offsets[] = {
1543 	{ ICE_MAC_OFOS,		0 },
1544 	{ ICE_IPV4_OFOS,	14 },
1545 	{ ICE_UDP_ILOS,		34 },
1546 	{ ICE_NAT_T,		42 },
1547 	{ ICE_PROTOCOL_LAST,	0 },
1548 };
1549 
1550 static const u8 dummy_ipv4_nat_pkt[] = {
1551 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1552 	0x00, 0x00, 0x00, 0x00,
1553 	0x00, 0x00, 0x00, 0x00,
1554 	0x08, 0x00,
1555 
1556 	0x45, 0x00, 0x00, 0x24, /* ICE_IPV4_IL 14 */
1557 	0x00, 0x00, 0x40, 0x00,
1558 	0x40, 0x11, 0x00, 0x00,
1559 	0x00, 0x00, 0x00, 0x00,
1560 	0x00, 0x00, 0x00, 0x00,
1561 
1562 	0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 34 */
1563 	0x00, 0x00, 0x00, 0x00,
1564 
1565 	0x00, 0x00, 0x00, 0x00,
1566 	0x00, 0x00, 0x00, 0x00,
1567 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1568 };
1569 
1570 static const struct ice_dummy_pkt_offsets dummy_ipv6_nat_packet_offsets[] = {
1571 	{ ICE_MAC_OFOS,		0 },
1572 	{ ICE_IPV6_OFOS,	14 },
1573 	{ ICE_UDP_ILOS,		54 },
1574 	{ ICE_NAT_T,		62 },
1575 	{ ICE_PROTOCOL_LAST,	0 },
1576 };
1577 
1578 static const u8 dummy_ipv6_nat_pkt[] = {
1579 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1580 	0x00, 0x00, 0x00, 0x00,
1581 	0x00, 0x00, 0x00, 0x00,
1582 	0x86, 0xDD,
1583 
1584 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1585 	0x00, 0x10, 0x11, 0x00, /* Next header NAT_T */
1586 	0x00, 0x00, 0x00, 0x00,
1587 	0x00, 0x00, 0x00, 0x00,
1588 	0x00, 0x00, 0x00, 0x00,
1589 	0x00, 0x00, 0x00, 0x00,
1590 	0x00, 0x00, 0x00, 0x00,
1591 	0x00, 0x00, 0x00, 0x00,
1592 	0x00, 0x00, 0x00, 0x00,
1593 	0x00, 0x00, 0x00, 0x00,
1594 
1595 	0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 54 */
1596 	0x00, 0x00, 0x00, 0x00,
1597 
1598 	0x00, 0x00, 0x00, 0x00,
1599 	0x00, 0x00, 0x00, 0x00,
1600 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1601 
1602 };
1603 
1604 static const struct ice_dummy_pkt_offsets dummy_ipv4_l2tpv3_packet_offsets[] = {
1605 	{ ICE_MAC_OFOS,		0 },
1606 	{ ICE_IPV4_OFOS,	14 },
1607 	{ ICE_L2TPV3,		34 },
1608 	{ ICE_PROTOCOL_LAST,	0 },
1609 };
1610 
1611 static const u8 dummy_ipv4_l2tpv3_pkt[] = {
1612 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1613 	0x00, 0x00, 0x00, 0x00,
1614 	0x00, 0x00, 0x00, 0x00,
1615 	0x08, 0x00,
1616 
1617 	0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1618 	0x00, 0x00, 0x40, 0x00,
1619 	0x40, 0x73, 0x00, 0x00,
1620 	0x00, 0x00, 0x00, 0x00,
1621 	0x00, 0x00, 0x00, 0x00,
1622 
1623 	0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
1624 	0x00, 0x00, 0x00, 0x00,
1625 	0x00, 0x00, 0x00, 0x00,
1626 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1627 };
1628 
1629 static const struct ice_dummy_pkt_offsets dummy_ipv6_l2tpv3_packet_offsets[] = {
1630 	{ ICE_MAC_OFOS,		0 },
1631 	{ ICE_IPV6_OFOS,	14 },
1632 	{ ICE_L2TPV3,		54 },
1633 	{ ICE_PROTOCOL_LAST,	0 },
1634 };
1635 
1636 static const u8 dummy_ipv6_l2tpv3_pkt[] = {
1637 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1638 	0x00, 0x00, 0x00, 0x00,
1639 	0x00, 0x00, 0x00, 0x00,
1640 	0x86, 0xDD,
1641 
1642 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
1643 	0x00, 0x0c, 0x73, 0x40,
1644 	0x00, 0x00, 0x00, 0x00,
1645 	0x00, 0x00, 0x00, 0x00,
1646 	0x00, 0x00, 0x00, 0x00,
1647 	0x00, 0x00, 0x00, 0x00,
1648 	0x00, 0x00, 0x00, 0x00,
1649 	0x00, 0x00, 0x00, 0x00,
1650 	0x00, 0x00, 0x00, 0x00,
1651 	0x00, 0x00, 0x00, 0x00,
1652 
1653 	0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
1654 	0x00, 0x00, 0x00, 0x00,
1655 	0x00, 0x00, 0x00, 0x00,
1656 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1657 };
1658 
1659 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv4_packet_offsets[] = {
1660 	{ ICE_MAC_OFOS,		0 },
1661 	{ ICE_ETYPE_OL,         12 },
1662 	{ ICE_VLAN_EX,		14 },
1663 	{ ICE_VLAN_IN,		18 },
1664 	{ ICE_IPV4_OFOS,	22 },
1665 	{ ICE_PROTOCOL_LAST,	0 },
1666 };
1667 
1668 static const u8 dummy_qinq_ipv4_pkt[] = {
1669 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1670 	0x00, 0x00, 0x00, 0x00,
1671 	0x00, 0x00, 0x00, 0x00,
1672 
1673 	0x91, 0x00,		/* ICE_ETYPE_OL 12 */
1674 
1675 	0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1676 	0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_IN 18 */
1677 
1678 	0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
1679 	0x00, 0x01, 0x00, 0x00,
1680 	0x00, 0x11, 0x00, 0x00,
1681 	0x00, 0x00, 0x00, 0x00,
1682 	0x00, 0x00, 0x00, 0x00,
1683 
1684 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
1685 	0x00, 0x08, 0x00, 0x00,
1686 
1687 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
1688 };
1689 
1690 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv6_packet_offsets[] = {
1691 	{ ICE_MAC_OFOS,		0 },
1692 	{ ICE_ETYPE_OL,         12 },
1693 	{ ICE_VLAN_EX,		14 },
1694 	{ ICE_VLAN_IN,		18 },
1695 	{ ICE_IPV6_OFOS,	22 },
1696 	{ ICE_PROTOCOL_LAST,	0 },
1697 };
1698 
1699 static const u8 dummy_qinq_ipv6_pkt[] = {
1700 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1701 	0x00, 0x00, 0x00, 0x00,
1702 	0x00, 0x00, 0x00, 0x00,
1703 
1704 	0x91, 0x00,		/* ICE_ETYPE_OL 12 */
1705 
1706 	0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1707 	0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_IN 18 */
1708 
1709 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1710 	0x00, 0x10, 0x11, 0x00, /* Next header UDP */
1711 	0x00, 0x00, 0x00, 0x00,
1712 	0x00, 0x00, 0x00, 0x00,
1713 	0x00, 0x00, 0x00, 0x00,
1714 	0x00, 0x00, 0x00, 0x00,
1715 	0x00, 0x00, 0x00, 0x00,
1716 	0x00, 0x00, 0x00, 0x00,
1717 	0x00, 0x00, 0x00, 0x00,
1718 	0x00, 0x00, 0x00, 0x00,
1719 
1720 	0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
1721 	0x00, 0x10, 0x00, 0x00,
1722 
1723 	0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
1724 	0x00, 0x00, 0x00, 0x00,
1725 
1726 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
1727 };
1728 
1729 static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = {
1730 	{ ICE_MAC_OFOS,		0 },
1731 	{ ICE_ETYPE_OL,         12 },
1732 	{ ICE_VLAN_EX,		14 },
1733 	{ ICE_VLAN_IN,		18 },
1734 	{ ICE_PPPOE,		22 },
1735 	{ ICE_PROTOCOL_LAST,	0 },
1736 };
1737 
1738 static const
1739 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_ipv4_packet_offsets[] = {
1740 	{ ICE_MAC_OFOS,		0 },
1741 	{ ICE_ETYPE_OL,         12 },
1742 	{ ICE_VLAN_EX,		14 },
1743 	{ ICE_VLAN_IN,		18 },
1744 	{ ICE_PPPOE,		22 },
1745 	{ ICE_IPV4_OFOS,	30 },
1746 	{ ICE_PROTOCOL_LAST,	0 },
1747 };
1748 
1749 static const u8 dummy_qinq_pppoe_ipv4_pkt[] = {
1750 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1751 	0x00, 0x00, 0x00, 0x00,
1752 	0x00, 0x00, 0x00, 0x00,
1753 
1754 	0x91, 0x00,		/* ICE_ETYPE_OL 12 */
1755 
1756 	0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1757 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_IN 18 */
1758 
1759 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
1760 	0x00, 0x16,
1761 
1762 	0x00, 0x21,		/* PPP Link Layer 28 */
1763 
1764 	0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_OFOS 30 */
1765 	0x00, 0x00, 0x00, 0x00,
1766 	0x00, 0x00, 0x00, 0x00,
1767 	0x00, 0x00, 0x00, 0x00,
1768 	0x00, 0x00, 0x00, 0x00,
1769 
1770 	0x00, 0x00,	/* 2 bytes for 4 byte alignment */
1771 };
1772 
1773 static const
1774 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_ipv6_offsets[] = {
1775 	{ ICE_MAC_OFOS,		0 },
1776 	{ ICE_ETYPE_OL,		12 },
1777 	{ ICE_VLAN_EX,		14},
1778 	{ ICE_VLAN_IN,		18 },
1779 	{ ICE_PPPOE,		22 },
1780 	{ ICE_IPV6_OFOS,	30 },
1781 	{ ICE_PROTOCOL_LAST,	0 },
1782 };
1783 
1784 static const u8 dummy_qinq_pppoe_ipv6_packet[] = {
1785 	0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1786 	0x00, 0x00, 0x00, 0x00,
1787 	0x00, 0x00, 0x00, 0x00,
1788 
1789 	0x91, 0x00,		/* ICE_ETYPE_OL 12 */
1790 
1791 	0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1792 	0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_IN 18 */
1793 
1794 	0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
1795 	0x00, 0x2a,
1796 
1797 	0x00, 0x57,		/* PPP Link Layer 28*/
1798 
1799 	0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 30 */
1800 	0x00, 0x00, 0x3b, 0x00,
1801 	0x00, 0x00, 0x00, 0x00,
1802 	0x00, 0x00, 0x00, 0x00,
1803 	0x00, 0x00, 0x00, 0x00,
1804 	0x00, 0x00, 0x00, 0x00,
1805 	0x00, 0x00, 0x00, 0x00,
1806 	0x00, 0x00, 0x00, 0x00,
1807 	0x00, 0x00, 0x00, 0x00,
1808 	0x00, 0x00, 0x00, 0x00,
1809 
1810 	0x00, 0x00,		/* 2 bytes for 4 bytes alignment */
1811 };
1812 
1813 /* this is a recipe to profile association bitmap */
1814 static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES],
1815 			  ICE_MAX_NUM_PROFILES);
1816 
1817 /* this is a profile to recipe association bitmap */
1818 static ice_declare_bitmap(profile_to_recipe[ICE_MAX_NUM_PROFILES],
1819 			  ICE_MAX_NUM_RECIPES);
1820 
1821 static void ice_get_recp_to_prof_map(struct ice_hw *hw);
1822 
1823 /**
1824  * ice_collect_result_idx - copy result index values
1825  * @buf: buffer that contains the result index
1826  * @recp: the recipe struct to copy data into
1827  */
1828 static void ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
1829 				   struct ice_sw_recipe *recp)
1830 {
1831 	if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
1832 		ice_set_bit(buf->content.result_indx &
1833 			    ~ICE_AQ_RECIPE_RESULT_EN, recp->res_idxs);
1834 }
1835 
1836 static struct ice_prof_type_entry ice_prof_type_tbl[ICE_GTPU_PROFILE] = {
1837 	{ ICE_PROFID_IPV4_GTPU_IPV4_OTHER,    ICE_SW_TUN_IPV4_GTPU_IPV4},
1838 	{ ICE_PROFID_IPV4_GTPU_IPV4_UDP,      ICE_SW_TUN_IPV4_GTPU_IPV4_UDP},
1839 	{ ICE_PROFID_IPV4_GTPU_IPV4_TCP,      ICE_SW_TUN_IPV4_GTPU_IPV4_TCP},
1840 	{ ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, ICE_SW_TUN_IPV4_GTPU_EH_IPV4},
1841 	{ ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP,   ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP},
1842 	{ ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP,   ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP},
1843 	{ ICE_PROFID_IPV4_GTPU_IPV6_OTHER,    ICE_SW_TUN_IPV4_GTPU_IPV6},
1844 	{ ICE_PROFID_IPV4_GTPU_IPV6_UDP,      ICE_SW_TUN_IPV4_GTPU_IPV6_UDP},
1845 	{ ICE_PROFID_IPV4_GTPU_IPV6_TCP,      ICE_SW_TUN_IPV4_GTPU_IPV6_TCP},
1846 	{ ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, ICE_SW_TUN_IPV4_GTPU_EH_IPV6},
1847 	{ ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP,   ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP},
1848 	{ ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP,   ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP},
1849 	{ ICE_PROFID_IPV6_GTPU_IPV4_OTHER,    ICE_SW_TUN_IPV6_GTPU_IPV4},
1850 	{ ICE_PROFID_IPV6_GTPU_IPV4_UDP,      ICE_SW_TUN_IPV6_GTPU_IPV4_UDP},
1851 	{ ICE_PROFID_IPV6_GTPU_IPV4_TCP,      ICE_SW_TUN_IPV6_GTPU_IPV4_TCP},
1852 	{ ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, ICE_SW_TUN_IPV6_GTPU_EH_IPV4},
1853 	{ ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP,   ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP},
1854 	{ ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP,   ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP},
1855 	{ ICE_PROFID_IPV6_GTPU_IPV6_OTHER,    ICE_SW_TUN_IPV6_GTPU_IPV6},
1856 	{ ICE_PROFID_IPV6_GTPU_IPV6_UDP,      ICE_SW_TUN_IPV6_GTPU_IPV6_UDP},
1857 	{ ICE_PROFID_IPV6_GTPU_IPV6_TCP,      ICE_SW_TUN_IPV6_GTPU_IPV6_TCP},
1858 	{ ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, ICE_SW_TUN_IPV6_GTPU_EH_IPV6},
1859 	{ ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP,   ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP},
1860 	{ ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP,   ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP},
1861 };
1862 
1863 /**
1864  * ice_get_tun_type_for_recipe - get tunnel type for the recipe
1865  * @rid: recipe ID that we are populating
1866  */
1867 static enum ice_sw_tunnel_type ice_get_tun_type_for_recipe(u8 rid, bool vlan)
1868 {
1869 	u8 vxlan_profile[12] = {10, 11, 12, 16, 17, 18, 22, 23, 24, 25, 26, 27};
1870 	u8 gre_profile[12] = {13, 14, 15, 19, 20, 21, 28, 29, 30, 31, 32, 33};
1871 	u8 pppoe_profile[7] = {34, 35, 36, 37, 38, 39, 40};
1872 	u8 non_tun_profile[6] = {4, 5, 6, 7, 8, 9};
1873 	enum ice_sw_tunnel_type tun_type;
1874 	u16 i, j, k, profile_num = 0;
1875 	bool non_tun_valid = false;
1876 	bool pppoe_valid = false;
1877 	bool vxlan_valid = false;
1878 	bool gre_valid = false;
1879 	bool gtp_valid = false;
1880 	bool flag_valid = false;
1881 
1882 	for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) {
1883 		if (!ice_is_bit_set(recipe_to_profile[rid], j))
1884 			continue;
1885 		else
1886 			profile_num++;
1887 
1888 		for (i = 0; i < 12; i++) {
1889 			if (gre_profile[i] == j)
1890 				gre_valid = true;
1891 		}
1892 
1893 		for (i = 0; i < 12; i++) {
1894 			if (vxlan_profile[i] == j)
1895 				vxlan_valid = true;
1896 		}
1897 
1898 		for (i = 0; i < 7; i++) {
1899 			if (pppoe_profile[i] == j)
1900 				pppoe_valid = true;
1901 		}
1902 
1903 		for (i = 0; i < 6; i++) {
1904 			if (non_tun_profile[i] == j)
1905 				non_tun_valid = true;
1906 		}
1907 
1908 		if (j >= ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER &&
1909 		    j <= ICE_PROFID_IPV6_GTPU_IPV6_TCP)
1910 			gtp_valid = true;
1911 
1912 		if ((j >= ICE_PROFID_IPV4_ESP &&
1913 		     j <= ICE_PROFID_IPV6_PFCP_SESSION) ||
1914 		    (j >= ICE_PROFID_IPV4_GTPC_TEID &&
1915 		     j <= ICE_PROFID_IPV6_GTPU_TEID))
1916 			flag_valid = true;
1917 	}
1918 
1919 	if (!non_tun_valid && vxlan_valid)
1920 		tun_type = ICE_SW_TUN_VXLAN;
1921 	else if (!non_tun_valid && gre_valid)
1922 		tun_type = ICE_SW_TUN_NVGRE;
1923 	else if (!non_tun_valid && pppoe_valid)
1924 		tun_type = ICE_SW_TUN_PPPOE;
1925 	else if (!non_tun_valid && gtp_valid)
1926 		tun_type = ICE_SW_TUN_GTP;
1927 	else if (non_tun_valid &&
1928 		 (vxlan_valid || gre_valid || gtp_valid || pppoe_valid))
1929 		tun_type = ICE_SW_TUN_AND_NON_TUN;
1930 	else if (non_tun_valid && !vxlan_valid && !gre_valid && !gtp_valid &&
1931 		 !pppoe_valid)
1932 		tun_type = ICE_NON_TUN;
1933 	else
1934 		tun_type = ICE_NON_TUN;
1935 
1936 	if (profile_num > 1 && tun_type == ICE_SW_TUN_PPPOE) {
1937 		i = ice_is_bit_set(recipe_to_profile[rid],
1938 				   ICE_PROFID_PPPOE_IPV4_OTHER);
1939 		j = ice_is_bit_set(recipe_to_profile[rid],
1940 				   ICE_PROFID_PPPOE_IPV6_OTHER);
1941 		if (i && !j)
1942 			tun_type = ICE_SW_TUN_PPPOE_IPV4;
1943 		else if (!i && j)
1944 			tun_type = ICE_SW_TUN_PPPOE_IPV6;
1945 	}
1946 
1947 	if (tun_type == ICE_SW_TUN_GTP) {
1948 		for (k = 0; k < ARRAY_SIZE(ice_prof_type_tbl); k++)
1949 			if (ice_is_bit_set(recipe_to_profile[rid],
1950 					   ice_prof_type_tbl[k].prof_id)) {
1951 				tun_type = ice_prof_type_tbl[k].type;
1952 				break;
1953 			}
1954 	}
1955 
1956 	if (profile_num == 1 && (flag_valid || non_tun_valid || pppoe_valid)) {
1957 		for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) {
1958 			if (ice_is_bit_set(recipe_to_profile[rid], j)) {
1959 				switch (j) {
1960 				case ICE_PROFID_IPV4_TCP:
1961 					tun_type = ICE_SW_IPV4_TCP;
1962 					break;
1963 				case ICE_PROFID_IPV4_UDP:
1964 					tun_type = ICE_SW_IPV4_UDP;
1965 					break;
1966 				case ICE_PROFID_IPV6_TCP:
1967 					tun_type = ICE_SW_IPV6_TCP;
1968 					break;
1969 				case ICE_PROFID_IPV6_UDP:
1970 					tun_type = ICE_SW_IPV6_UDP;
1971 					break;
1972 				case ICE_PROFID_PPPOE_PAY:
1973 					tun_type = ICE_SW_TUN_PPPOE_PAY;
1974 					break;
1975 				case ICE_PROFID_PPPOE_IPV4_TCP:
1976 					tun_type = ICE_SW_TUN_PPPOE_IPV4_TCP;
1977 					break;
1978 				case ICE_PROFID_PPPOE_IPV4_UDP:
1979 					tun_type = ICE_SW_TUN_PPPOE_IPV4_UDP;
1980 					break;
1981 				case ICE_PROFID_PPPOE_IPV4_OTHER:
1982 					tun_type = ICE_SW_TUN_PPPOE_IPV4;
1983 					break;
1984 				case ICE_PROFID_PPPOE_IPV6_TCP:
1985 					tun_type = ICE_SW_TUN_PPPOE_IPV6_TCP;
1986 					break;
1987 				case ICE_PROFID_PPPOE_IPV6_UDP:
1988 					tun_type = ICE_SW_TUN_PPPOE_IPV6_UDP;
1989 					break;
1990 				case ICE_PROFID_PPPOE_IPV6_OTHER:
1991 					tun_type = ICE_SW_TUN_PPPOE_IPV6;
1992 					break;
1993 				case ICE_PROFID_IPV4_ESP:
1994 					tun_type = ICE_SW_TUN_IPV4_ESP;
1995 					break;
1996 				case ICE_PROFID_IPV6_ESP:
1997 					tun_type = ICE_SW_TUN_IPV6_ESP;
1998 					break;
1999 				case ICE_PROFID_IPV4_AH:
2000 					tun_type = ICE_SW_TUN_IPV4_AH;
2001 					break;
2002 				case ICE_PROFID_IPV6_AH:
2003 					tun_type = ICE_SW_TUN_IPV6_AH;
2004 					break;
2005 				case ICE_PROFID_IPV4_NAT_T:
2006 					tun_type = ICE_SW_TUN_IPV4_NAT_T;
2007 					break;
2008 				case ICE_PROFID_IPV6_NAT_T:
2009 					tun_type = ICE_SW_TUN_IPV6_NAT_T;
2010 					break;
2011 				case ICE_PROFID_IPV4_PFCP_NODE:
2012 					tun_type =
2013 					ICE_SW_TUN_PROFID_IPV4_PFCP_NODE;
2014 					break;
2015 				case ICE_PROFID_IPV6_PFCP_NODE:
2016 					tun_type =
2017 					ICE_SW_TUN_PROFID_IPV6_PFCP_NODE;
2018 					break;
2019 				case ICE_PROFID_IPV4_PFCP_SESSION:
2020 					tun_type =
2021 					ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION;
2022 					break;
2023 				case ICE_PROFID_IPV6_PFCP_SESSION:
2024 					tun_type =
2025 					ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION;
2026 					break;
2027 				case ICE_PROFID_MAC_IPV4_L2TPV3:
2028 					tun_type = ICE_SW_TUN_IPV4_L2TPV3;
2029 					break;
2030 				case ICE_PROFID_MAC_IPV6_L2TPV3:
2031 					tun_type = ICE_SW_TUN_IPV6_L2TPV3;
2032 					break;
2033 				case ICE_PROFID_IPV4_GTPU_TEID:
2034 					tun_type = ICE_SW_TUN_IPV4_GTPU_NO_PAY;
2035 					break;
2036 				case ICE_PROFID_IPV6_GTPU_TEID:
2037 					tun_type = ICE_SW_TUN_IPV6_GTPU_NO_PAY;
2038 					break;
2039 				default:
2040 					break;
2041 				}
2042 
2043 				return tun_type;
2044 			}
2045 		}
2046 	}
2047 
2048 	if (vlan && tun_type == ICE_SW_TUN_PPPOE)
2049 		tun_type = ICE_SW_TUN_PPPOE_QINQ;
2050 	else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV6)
2051 		tun_type = ICE_SW_TUN_PPPOE_IPV6_QINQ;
2052 	else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV4)
2053 		tun_type = ICE_SW_TUN_PPPOE_IPV4_QINQ;
2054 	else if (vlan && tun_type == ICE_SW_TUN_PPPOE_PAY)
2055 		tun_type = ICE_SW_TUN_PPPOE_PAY_QINQ;
2056 	else if (vlan && tun_type == ICE_SW_TUN_AND_NON_TUN)
2057 		tun_type = ICE_SW_TUN_AND_NON_TUN_QINQ;
2058 	else if (vlan && tun_type == ICE_NON_TUN)
2059 		tun_type = ICE_NON_TUN_QINQ;
2060 
2061 	return tun_type;
2062 }
2063 
2064 /**
2065  * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
2066  * @hw: pointer to hardware structure
2067  * @recps: struct that we need to populate
2068  * @rid: recipe ID that we are populating
2069  * @refresh_required: true if we should get recipe to profile mapping from FW
2070  *
2071  * This function is used to populate all the necessary entries into our
2072  * bookkeeping so that we have a current list of all the recipes that are
2073  * programmed in the firmware.
2074  */
2075 static enum ice_status
2076 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2077 		    bool *refresh_required)
2078 {
2079 	ice_declare_bitmap(result_bm, ICE_MAX_FV_WORDS);
2080 	struct ice_aqc_recipe_data_elem *tmp;
2081 	u16 num_recps = ICE_MAX_NUM_RECIPES;
2082 	struct ice_prot_lkup_ext *lkup_exts;
2083 	enum ice_status status;
2084 	u8 fv_word_idx = 0;
2085 	bool vlan = false;
2086 	u16 sub_recps;
2087 
2088 	ice_zero_bitmap(result_bm, ICE_MAX_FV_WORDS);
2089 
2090 	/* we need a buffer big enough to accommodate all the recipes */
2091 	tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
2092 		ICE_MAX_NUM_RECIPES, sizeof(*tmp));
2093 	if (!tmp)
2094 		return ICE_ERR_NO_MEMORY;
2095 
2096 	tmp[0].recipe_indx = rid;
2097 	status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2098 	/* non-zero status meaning recipe doesn't exist */
2099 	if (status)
2100 		goto err_unroll;
2101 
2102 	/* Get recipe to profile map so that we can get the fv from lkups that
2103 	 * we read for a recipe from FW. Since we want to minimize the number of
2104 	 * times we make this FW call, just make one call and cache the copy
2105 	 * until a new recipe is added. This operation is only required the
2106 	 * first time to get the changes from FW. Then to search existing
2107 	 * entries we don't need to update the cache again until another recipe
2108 	 * gets added.
2109 	 */
2110 	if (*refresh_required) {
2111 		ice_get_recp_to_prof_map(hw);
2112 		*refresh_required = false;
2113 	}
2114 
2115 	/* Start populating all the entries for recps[rid] based on lkups from
2116 	 * firmware. Note that we are only creating the root recipe in our
2117 	 * database.
2118 	 */
2119 	lkup_exts = &recps[rid].lkup_exts;
2120 
2121 	for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2122 		struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2123 		struct ice_recp_grp_entry *rg_entry;
2124 		u8 i, prof, idx, prot = 0;
2125 		bool is_root;
2126 		u16 off = 0;
2127 
2128 		rg_entry = (struct ice_recp_grp_entry *)
2129 			ice_malloc(hw, sizeof(*rg_entry));
2130 		if (!rg_entry) {
2131 			status = ICE_ERR_NO_MEMORY;
2132 			goto err_unroll;
2133 		}
2134 
2135 		idx = root_bufs.recipe_indx;
2136 		is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2137 
2138 		/* Mark all result indices in this chain */
2139 		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2140 			ice_set_bit(root_bufs.content.result_indx &
2141 				    ~ICE_AQ_RECIPE_RESULT_EN, result_bm);
2142 
2143 		/* get the first profile that is associated with rid */
2144 		prof = ice_find_first_bit(recipe_to_profile[idx],
2145 					  ICE_MAX_NUM_PROFILES);
2146 		for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2147 			u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2148 
2149 			rg_entry->fv_idx[i] = lkup_indx;
2150 			rg_entry->fv_mask[i] =
2151 				LE16_TO_CPU(root_bufs.content.mask[i + 1]);
2152 
2153 			/* If the recipe is a chained recipe then all its
2154 			 * child recipe's result will have a result index.
2155 			 * To fill fv_words we should not use those result
2156 			 * index, we only need the protocol ids and offsets.
2157 			 * We will skip all the fv_idx which stores result
2158 			 * index in them. We also need to skip any fv_idx which
2159 			 * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2160 			 * valid offset value.
2161 			 */
2162 			if (ice_is_bit_set(hw->switch_info->prof_res_bm[prof],
2163 					   rg_entry->fv_idx[i]) ||
2164 			    rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2165 			    rg_entry->fv_idx[i] == 0)
2166 				continue;
2167 
2168 			ice_find_prot_off(hw, ICE_BLK_SW, prof,
2169 					  rg_entry->fv_idx[i], &prot, &off);
2170 			lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2171 			lkup_exts->fv_words[fv_word_idx].off = off;
2172 			lkup_exts->field_mask[fv_word_idx] =
2173 				rg_entry->fv_mask[i];
2174 			if (prot == ICE_META_DATA_ID_HW &&
2175 			    off == ICE_TUN_FLAG_MDID_OFF)
2176 				vlan = true;
2177 			fv_word_idx++;
2178 		}
2179 		/* populate rg_list with the data from the child entry of this
2180 		 * recipe
2181 		 */
2182 		LIST_ADD(&rg_entry->l_entry, &recps[rid].rg_list);
2183 
2184 		/* Propagate some data to the recipe database */
2185 		recps[idx].is_root = !!is_root;
2186 		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2187 		ice_zero_bitmap(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2188 		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2189 			recps[idx].chain_idx = root_bufs.content.result_indx &
2190 				~ICE_AQ_RECIPE_RESULT_EN;
2191 			ice_set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2192 		} else {
2193 			recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2194 		}
2195 
2196 		if (!is_root)
2197 			continue;
2198 
2199 		/* Only do the following for root recipes entries */
2200 		ice_memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2201 			   sizeof(recps[idx].r_bitmap), ICE_NONDMA_TO_NONDMA);
2202 		recps[idx].root_rid = root_bufs.content.rid &
2203 			~ICE_AQ_RECIPE_ID_IS_ROOT;
2204 		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2205 	}
2206 
2207 	/* Complete initialization of the root recipe entry */
2208 	lkup_exts->n_val_words = fv_word_idx;
2209 	recps[rid].big_recp = (num_recps > 1);
2210 	recps[rid].n_grp_count = (u8)num_recps;
2211 	recps[rid].tun_type = ice_get_tun_type_for_recipe(rid, vlan);
2212 	recps[rid].root_buf = (struct ice_aqc_recipe_data_elem *)
2213 		ice_memdup(hw, tmp, recps[rid].n_grp_count *
2214 			   sizeof(*recps[rid].root_buf), ICE_NONDMA_TO_NONDMA);
2215 	if (!recps[rid].root_buf)
2216 		goto err_unroll;
2217 
2218 	/* Copy result indexes */
2219 	ice_cp_bitmap(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2220 	recps[rid].recp_created = true;
2221 
2222 err_unroll:
2223 	ice_free(hw, tmp);
2224 	return status;
2225 }
2226 
2227 /**
2228  * ice_get_recp_to_prof_map - updates recipe to profile mapping
2229  * @hw: pointer to hardware structure
2230  *
2231  * This function is used to populate recipe_to_profile matrix where index to
2232  * this array is the recipe ID and the element is the mapping of which profiles
2233  * is this recipe mapped to.
2234  */
2235 static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2236 {
2237 	ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2238 	u16 i;
2239 
2240 	for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2241 		u16 j;
2242 
2243 		ice_zero_bitmap(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2244 		ice_zero_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2245 		if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
2246 			continue;
2247 		ice_cp_bitmap(profile_to_recipe[i], r_bitmap,
2248 			      ICE_MAX_NUM_RECIPES);
2249 		ice_for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2250 			ice_set_bit(i, recipe_to_profile[j]);
2251 	}
2252 }
2253 
2254 /**
2255  * ice_init_def_sw_recp - initialize the recipe book keeping tables
2256  * @hw: pointer to the HW struct
2257  * @recp_list: pointer to sw recipe list
2258  *
2259  * Allocate memory for the entire recipe table and initialize the structures/
2260  * entries corresponding to basic recipes.
2261  */
2262 enum ice_status
2263 ice_init_def_sw_recp(struct ice_hw *hw, struct ice_sw_recipe **recp_list)
2264 {
2265 	struct ice_sw_recipe *recps;
2266 	u8 i;
2267 
2268 	recps = (struct ice_sw_recipe *)
2269 		ice_calloc(hw, ICE_MAX_NUM_RECIPES, sizeof(*recps));
2270 	if (!recps)
2271 		return ICE_ERR_NO_MEMORY;
2272 
2273 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
2274 		recps[i].root_rid = i;
2275 		INIT_LIST_HEAD(&recps[i].filt_rules);
2276 		INIT_LIST_HEAD(&recps[i].filt_replay_rules);
2277 		INIT_LIST_HEAD(&recps[i].rg_list);
2278 		ice_init_lock(&recps[i].filt_rule_lock);
2279 	}
2280 
2281 	*recp_list = recps;
2282 
2283 	return ICE_SUCCESS;
2284 }
2285 
2286 /**
2287  * ice_aq_get_sw_cfg - get switch configuration
2288  * @hw: pointer to the hardware structure
2289  * @buf: pointer to the result buffer
2290  * @buf_size: length of the buffer available for response
2291  * @req_desc: pointer to requested descriptor
2292  * @num_elems: pointer to number of elements
2293  * @cd: pointer to command details structure or NULL
2294  *
2295  * Get switch configuration (0x0200) to be placed in buf.
2296  * This admin command returns information such as initial VSI/port number
2297  * and switch ID it belongs to.
2298  *
2299  * NOTE: *req_desc is both an input/output parameter.
2300  * The caller of this function first calls this function with *request_desc set
2301  * to 0. If the response from f/w has *req_desc set to 0, all the switch
2302  * configuration information has been returned; if non-zero (meaning not all
2303  * the information was returned), the caller should call this function again
2304  * with *req_desc set to the previous value returned by f/w to get the
2305  * next block of switch configuration information.
2306  *
2307  * *num_elems is output only parameter. This reflects the number of elements
2308  * in response buffer. The caller of this function to use *num_elems while
2309  * parsing the response buffer.
2310  */
2311 static enum ice_status
2312 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
2313 		  u16 buf_size, u16 *req_desc, u16 *num_elems,
2314 		  struct ice_sq_cd *cd)
2315 {
2316 	struct ice_aqc_get_sw_cfg *cmd;
2317 	struct ice_aq_desc desc;
2318 	enum ice_status status;
2319 
2320 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
2321 	cmd = &desc.params.get_sw_conf;
2322 	cmd->element = CPU_TO_LE16(*req_desc);
2323 
2324 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
2325 	if (!status) {
2326 		*req_desc = LE16_TO_CPU(cmd->element);
2327 		*num_elems = LE16_TO_CPU(cmd->num_elems);
2328 	}
2329 
2330 	return status;
2331 }
2332 
2333 /**
2334  * ice_alloc_rss_global_lut - allocate a RSS global LUT
2335  * @hw: pointer to the HW struct
2336  * @shared_res: true to allocate as a shared resource and false to allocate as a dedicated resource
2337  * @global_lut_id: output parameter for the RSS global LUT's ID
2338  */
2339 enum ice_status ice_alloc_rss_global_lut(struct ice_hw *hw, bool shared_res, u16 *global_lut_id)
2340 {
2341 	struct ice_aqc_alloc_free_res_elem *sw_buf;
2342 	enum ice_status status;
2343 	u16 buf_len;
2344 
2345 	buf_len = ice_struct_size(sw_buf, elem, 1);
2346 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2347 	if (!sw_buf)
2348 		return ICE_ERR_NO_MEMORY;
2349 
2350 	sw_buf->num_elems = CPU_TO_LE16(1);
2351 	sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH |
2352 				       (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2353 				       ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2354 
2355 	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, ice_aqc_opc_alloc_res, NULL);
2356 	if (status) {
2357 		ice_debug(hw, ICE_DBG_RES, "Failed to allocate %s RSS global LUT, status %d\n",
2358 			  shared_res ? "shared" : "dedicated", status);
2359 		goto ice_alloc_global_lut_exit;
2360 	}
2361 
2362 	*global_lut_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
2363 
2364 ice_alloc_global_lut_exit:
2365 	ice_free(hw, sw_buf);
2366 	return status;
2367 }
2368 
2369 /**
2370  * ice_free_rss_global_lut - free a RSS global LUT
2371  * @hw: pointer to the HW struct
2372  * @global_lut_id: ID of the RSS global LUT to free
2373  */
2374 enum ice_status ice_free_rss_global_lut(struct ice_hw *hw, u16 global_lut_id)
2375 {
2376 	struct ice_aqc_alloc_free_res_elem *sw_buf;
2377 	u16 buf_len, num_elems = 1;
2378 	enum ice_status status;
2379 
2380 	buf_len = ice_struct_size(sw_buf, elem, num_elems);
2381 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2382 	if (!sw_buf)
2383 		return ICE_ERR_NO_MEMORY;
2384 
2385 	sw_buf->num_elems = CPU_TO_LE16(num_elems);
2386 	sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH);
2387 	sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(global_lut_id);
2388 
2389 	status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len, ice_aqc_opc_free_res, NULL);
2390 	if (status)
2391 		ice_debug(hw, ICE_DBG_RES, "Failed to free RSS global LUT %d, status %d\n",
2392 			  global_lut_id, status);
2393 
2394 	ice_free(hw, sw_buf);
2395 	return status;
2396 }
2397 
2398 /**
2399  * ice_alloc_sw - allocate resources specific to switch
2400  * @hw: pointer to the HW struct
2401  * @ena_stats: true to turn on VEB stats
2402  * @shared_res: true for shared resource, false for dedicated resource
2403  * @sw_id: switch ID returned
2404  * @counter_id: VEB counter ID returned
2405  *
2406  * allocates switch resources (SWID and VEB counter) (0x0208)
2407  */
2408 enum ice_status
2409 ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id,
2410 	     u16 *counter_id)
2411 {
2412 	struct ice_aqc_alloc_free_res_elem *sw_buf;
2413 	struct ice_aqc_res_elem *sw_ele;
2414 	enum ice_status status;
2415 	u16 buf_len;
2416 
2417 	buf_len = ice_struct_size(sw_buf, elem, 1);
2418 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2419 	if (!sw_buf)
2420 		return ICE_ERR_NO_MEMORY;
2421 
2422 	/* Prepare buffer for switch ID.
2423 	 * The number of resource entries in buffer is passed as 1 since only a
2424 	 * single switch/VEB instance is allocated, and hence a single sw_id
2425 	 * is requested.
2426 	 */
2427 	sw_buf->num_elems = CPU_TO_LE16(1);
2428 	sw_buf->res_type =
2429 		CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID |
2430 			    (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2431 			    ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2432 
2433 	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2434 				       ice_aqc_opc_alloc_res, NULL);
2435 
2436 	if (status)
2437 		goto ice_alloc_sw_exit;
2438 
2439 	sw_ele = &sw_buf->elem[0];
2440 	*sw_id = LE16_TO_CPU(sw_ele->e.sw_resp);
2441 
2442 	if (ena_stats) {
2443 		/* Prepare buffer for VEB Counter */
2444 		enum ice_adminq_opc opc = ice_aqc_opc_alloc_res;
2445 		struct ice_aqc_alloc_free_res_elem *counter_buf;
2446 		struct ice_aqc_res_elem *counter_ele;
2447 
2448 		counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2449 				ice_malloc(hw, buf_len);
2450 		if (!counter_buf) {
2451 			status = ICE_ERR_NO_MEMORY;
2452 			goto ice_alloc_sw_exit;
2453 		}
2454 
2455 		/* The number of resource entries in buffer is passed as 1 since
2456 		 * only a single switch/VEB instance is allocated, and hence a
2457 		 * single VEB counter is requested.
2458 		 */
2459 		counter_buf->num_elems = CPU_TO_LE16(1);
2460 		counter_buf->res_type =
2461 			CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER |
2462 				    ICE_AQC_RES_TYPE_FLAG_DEDICATED);
2463 		status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2464 					       opc, NULL);
2465 
2466 		if (status) {
2467 			ice_free(hw, counter_buf);
2468 			goto ice_alloc_sw_exit;
2469 		}
2470 		counter_ele = &counter_buf->elem[0];
2471 		*counter_id = LE16_TO_CPU(counter_ele->e.sw_resp);
2472 		ice_free(hw, counter_buf);
2473 	}
2474 
2475 ice_alloc_sw_exit:
2476 	ice_free(hw, sw_buf);
2477 	return status;
2478 }
2479 
2480 /**
2481  * ice_free_sw - free resources specific to switch
2482  * @hw: pointer to the HW struct
2483  * @sw_id: switch ID returned
2484  * @counter_id: VEB counter ID returned
2485  *
2486  * free switch resources (SWID and VEB counter) (0x0209)
2487  *
2488  * NOTE: This function frees multiple resources. It continues
2489  * releasing other resources even after it encounters error.
2490  * The error code returned is the last error it encountered.
2491  */
2492 enum ice_status ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id)
2493 {
2494 	struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf;
2495 	enum ice_status status, ret_status;
2496 	u16 buf_len;
2497 
2498 	buf_len = ice_struct_size(sw_buf, elem, 1);
2499 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2500 	if (!sw_buf)
2501 		return ICE_ERR_NO_MEMORY;
2502 
2503 	/* Prepare buffer to free for switch ID res.
2504 	 * The number of resource entries in buffer is passed as 1 since only a
2505 	 * single switch/VEB instance is freed, and hence a single sw_id
2506 	 * is released.
2507 	 */
2508 	sw_buf->num_elems = CPU_TO_LE16(1);
2509 	sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID);
2510 	sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id);
2511 
2512 	ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2513 					   ice_aqc_opc_free_res, NULL);
2514 
2515 	if (ret_status)
2516 		ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
2517 
2518 	/* Prepare buffer to free for VEB Counter resource */
2519 	counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2520 			ice_malloc(hw, buf_len);
2521 	if (!counter_buf) {
2522 		ice_free(hw, sw_buf);
2523 		return ICE_ERR_NO_MEMORY;
2524 	}
2525 
2526 	/* The number of resource entries in buffer is passed as 1 since only a
2527 	 * single switch/VEB instance is freed, and hence a single VEB counter
2528 	 * is released
2529 	 */
2530 	counter_buf->num_elems = CPU_TO_LE16(1);
2531 	counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER);
2532 	counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
2533 
2534 	status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2535 				       ice_aqc_opc_free_res, NULL);
2536 	if (status) {
2537 		ice_debug(hw, ICE_DBG_SW, "VEB counter resource could not be freed\n");
2538 		ret_status = status;
2539 	}
2540 
2541 	ice_free(hw, counter_buf);
2542 	ice_free(hw, sw_buf);
2543 	return ret_status;
2544 }
2545 
2546 /**
2547  * ice_aq_add_vsi
2548  * @hw: pointer to the HW struct
2549  * @vsi_ctx: pointer to a VSI context struct
2550  * @cd: pointer to command details structure or NULL
2551  *
2552  * Add a VSI context to the hardware (0x0210)
2553  */
2554 enum ice_status
2555 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2556 	       struct ice_sq_cd *cd)
2557 {
2558 	struct ice_aqc_add_update_free_vsi_resp *res;
2559 	struct ice_aqc_add_get_update_free_vsi *cmd;
2560 	struct ice_aq_desc desc;
2561 	enum ice_status status;
2562 
2563 	cmd = &desc.params.vsi_cmd;
2564 	res = &desc.params.add_update_free_vsi_res;
2565 
2566 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
2567 
2568 	if (!vsi_ctx->alloc_from_pool)
2569 		cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num |
2570 					   ICE_AQ_VSI_IS_VALID);
2571 
2572 	cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
2573 
2574 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2575 
2576 	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2577 				 sizeof(vsi_ctx->info), cd);
2578 
2579 	if (!status) {
2580 		vsi_ctx->vsi_num = LE16_TO_CPU(res->vsi_num) & ICE_AQ_VSI_NUM_M;
2581 		vsi_ctx->vsis_allocd = LE16_TO_CPU(res->vsi_used);
2582 		vsi_ctx->vsis_unallocated = LE16_TO_CPU(res->vsi_free);
2583 	}
2584 
2585 	return status;
2586 }
2587 
2588 /**
2589  * ice_aq_free_vsi
2590  * @hw: pointer to the HW struct
2591  * @vsi_ctx: pointer to a VSI context struct
2592  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
2593  * @cd: pointer to command details structure or NULL
2594  *
2595  * Free VSI context info from hardware (0x0213)
2596  */
2597 enum ice_status
2598 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2599 		bool keep_vsi_alloc, struct ice_sq_cd *cd)
2600 {
2601 	struct ice_aqc_add_update_free_vsi_resp *resp;
2602 	struct ice_aqc_add_get_update_free_vsi *cmd;
2603 	struct ice_aq_desc desc;
2604 	enum ice_status status;
2605 
2606 	cmd = &desc.params.vsi_cmd;
2607 	resp = &desc.params.add_update_free_vsi_res;
2608 
2609 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
2610 
2611 	cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
2612 	if (keep_vsi_alloc)
2613 		cmd->cmd_flags = CPU_TO_LE16(ICE_AQ_VSI_KEEP_ALLOC);
2614 
2615 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2616 	if (!status) {
2617 		vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
2618 		vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2619 	}
2620 
2621 	return status;
2622 }
2623 
2624 /**
2625  * ice_aq_update_vsi
2626  * @hw: pointer to the HW struct
2627  * @vsi_ctx: pointer to a VSI context struct
2628  * @cd: pointer to command details structure or NULL
2629  *
2630  * Update VSI context in the hardware (0x0211)
2631  */
2632 enum ice_status
2633 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2634 		  struct ice_sq_cd *cd)
2635 {
2636 	struct ice_aqc_add_update_free_vsi_resp *resp;
2637 	struct ice_aqc_add_get_update_free_vsi *cmd;
2638 	struct ice_aq_desc desc;
2639 	enum ice_status status;
2640 
2641 	cmd = &desc.params.vsi_cmd;
2642 	resp = &desc.params.add_update_free_vsi_res;
2643 
2644 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
2645 
2646 	cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
2647 
2648 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2649 
2650 	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2651 				 sizeof(vsi_ctx->info), cd);
2652 
2653 	if (!status) {
2654 		vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
2655 		vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2656 	}
2657 
2658 	return status;
2659 }
2660 
2661 /**
2662  * ice_is_vsi_valid - check whether the VSI is valid or not
2663  * @hw: pointer to the HW struct
2664  * @vsi_handle: VSI handle
2665  *
2666  * check whether the VSI is valid or not
2667  */
2668 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
2669 {
2670 	return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
2671 }
2672 
2673 /**
2674  * ice_get_hw_vsi_num - return the HW VSI number
2675  * @hw: pointer to the HW struct
2676  * @vsi_handle: VSI handle
2677  *
2678  * return the HW VSI number
2679  * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
2680  */
2681 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
2682 {
2683 	return hw->vsi_ctx[vsi_handle]->vsi_num;
2684 }
2685 
2686 /**
2687  * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
2688  * @hw: pointer to the HW struct
2689  * @vsi_handle: VSI handle
2690  *
2691  * return the VSI context entry for a given VSI handle
2692  */
2693 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
2694 {
2695 	return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
2696 }
2697 
2698 /**
2699  * ice_save_vsi_ctx - save the VSI context for a given VSI handle
2700  * @hw: pointer to the HW struct
2701  * @vsi_handle: VSI handle
2702  * @vsi: VSI context pointer
2703  *
2704  * save the VSI context entry for a given VSI handle
2705  */
2706 static void
2707 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
2708 {
2709 	hw->vsi_ctx[vsi_handle] = vsi;
2710 }
2711 
2712 /**
2713  * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
2714  * @hw: pointer to the HW struct
2715  * @vsi_handle: VSI handle
2716  */
2717 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
2718 {
2719 	struct ice_vsi_ctx *vsi;
2720 	u8 i;
2721 
2722 	vsi = ice_get_vsi_ctx(hw, vsi_handle);
2723 	if (!vsi)
2724 		return;
2725 	ice_for_each_traffic_class(i) {
2726 		if (vsi->lan_q_ctx[i]) {
2727 			ice_free(hw, vsi->lan_q_ctx[i]);
2728 			vsi->lan_q_ctx[i] = NULL;
2729 		}
2730 	}
2731 }
2732 
2733 /**
2734  * ice_clear_vsi_ctx - clear the VSI context entry
2735  * @hw: pointer to the HW struct
2736  * @vsi_handle: VSI handle
2737  *
2738  * clear the VSI context entry
2739  */
2740 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
2741 {
2742 	struct ice_vsi_ctx *vsi;
2743 
2744 	vsi = ice_get_vsi_ctx(hw, vsi_handle);
2745 	if (vsi) {
2746 		ice_clear_vsi_q_ctx(hw, vsi_handle);
2747 		ice_free(hw, vsi);
2748 		hw->vsi_ctx[vsi_handle] = NULL;
2749 	}
2750 }
2751 
2752 /**
2753  * ice_clear_all_vsi_ctx - clear all the VSI context entries
2754  * @hw: pointer to the HW struct
2755  */
2756 void ice_clear_all_vsi_ctx(struct ice_hw *hw)
2757 {
2758 	u16 i;
2759 
2760 	for (i = 0; i < ICE_MAX_VSI; i++)
2761 		ice_clear_vsi_ctx(hw, i);
2762 }
2763 
2764 /**
2765  * ice_add_vsi - add VSI context to the hardware and VSI handle list
2766  * @hw: pointer to the HW struct
2767  * @vsi_handle: unique VSI handle provided by drivers
2768  * @vsi_ctx: pointer to a VSI context struct
2769  * @cd: pointer to command details structure or NULL
2770  *
2771  * Add a VSI context to the hardware also add it into the VSI handle list.
2772  * If this function gets called after reset for existing VSIs then update
2773  * with the new HW VSI number in the corresponding VSI handle list entry.
2774  */
2775 enum ice_status
2776 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
2777 	    struct ice_sq_cd *cd)
2778 {
2779 	struct ice_vsi_ctx *tmp_vsi_ctx;
2780 	enum ice_status status;
2781 
2782 	if (vsi_handle >= ICE_MAX_VSI)
2783 		return ICE_ERR_PARAM;
2784 	status = ice_aq_add_vsi(hw, vsi_ctx, cd);
2785 	if (status)
2786 		return status;
2787 	tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
2788 	if (!tmp_vsi_ctx) {
2789 		/* Create a new VSI context */
2790 		tmp_vsi_ctx = (struct ice_vsi_ctx *)
2791 			ice_malloc(hw, sizeof(*tmp_vsi_ctx));
2792 		if (!tmp_vsi_ctx) {
2793 			ice_aq_free_vsi(hw, vsi_ctx, false, cd);
2794 			return ICE_ERR_NO_MEMORY;
2795 		}
2796 		*tmp_vsi_ctx = *vsi_ctx;
2797 
2798 		ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
2799 	} else {
2800 		/* update with new HW VSI num */
2801 		tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
2802 	}
2803 
2804 	return ICE_SUCCESS;
2805 }
2806 
2807 /**
2808  * ice_free_vsi- free VSI context from hardware and VSI handle list
2809  * @hw: pointer to the HW struct
2810  * @vsi_handle: unique VSI handle
2811  * @vsi_ctx: pointer to a VSI context struct
2812  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
2813  * @cd: pointer to command details structure or NULL
2814  *
2815  * Free VSI context info from hardware as well as from VSI handle list
2816  */
2817 enum ice_status
2818 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
2819 	     bool keep_vsi_alloc, struct ice_sq_cd *cd)
2820 {
2821 	enum ice_status status;
2822 
2823 	if (!ice_is_vsi_valid(hw, vsi_handle))
2824 		return ICE_ERR_PARAM;
2825 	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
2826 	status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
2827 	if (!status)
2828 		ice_clear_vsi_ctx(hw, vsi_handle);
2829 	return status;
2830 }
2831 
2832 /**
2833  * ice_update_vsi
2834  * @hw: pointer to the HW struct
2835  * @vsi_handle: unique VSI handle
2836  * @vsi_ctx: pointer to a VSI context struct
2837  * @cd: pointer to command details structure or NULL
2838  *
2839  * Update VSI context in the hardware
2840  */
2841 enum ice_status
2842 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
2843 	       struct ice_sq_cd *cd)
2844 {
2845 	if (!ice_is_vsi_valid(hw, vsi_handle))
2846 		return ICE_ERR_PARAM;
2847 	vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
2848 	return ice_aq_update_vsi(hw, vsi_ctx, cd);
2849 }
2850 
2851 /**
2852  * ice_aq_get_vsi_params
2853  * @hw: pointer to the HW struct
2854  * @vsi_ctx: pointer to a VSI context struct
2855  * @cd: pointer to command details structure or NULL
2856  *
2857  * Get VSI context info from hardware (0x0212)
2858  */
2859 enum ice_status
2860 ice_aq_get_vsi_params(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2861 		      struct ice_sq_cd *cd)
2862 {
2863 	struct ice_aqc_add_get_update_free_vsi *cmd;
2864 	struct ice_aqc_get_vsi_resp *resp;
2865 	struct ice_aq_desc desc;
2866 	enum ice_status status;
2867 
2868 	cmd = &desc.params.vsi_cmd;
2869 	resp = &desc.params.get_vsi_resp;
2870 
2871 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_vsi_params);
2872 
2873 	cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
2874 
2875 	status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2876 				 sizeof(vsi_ctx->info), cd);
2877 	if (!status) {
2878 		vsi_ctx->vsi_num = LE16_TO_CPU(resp->vsi_num) &
2879 					ICE_AQ_VSI_NUM_M;
2880 		vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
2881 		vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2882 	}
2883 
2884 	return status;
2885 }
2886 
2887 /**
2888  * ice_aq_add_update_mir_rule - add/update a mirror rule
2889  * @hw: pointer to the HW struct
2890  * @rule_type: Rule Type
2891  * @dest_vsi: VSI number to which packets will be mirrored
2892  * @count: length of the list
2893  * @mr_buf: buffer for list of mirrored VSI numbers
2894  * @cd: pointer to command details structure or NULL
2895  * @rule_id: Rule ID
2896  *
2897  * Add/Update Mirror Rule (0x260).
2898  */
2899 enum ice_status
2900 ice_aq_add_update_mir_rule(struct ice_hw *hw, u16 rule_type, u16 dest_vsi,
2901 			   u16 count, struct ice_mir_rule_buf *mr_buf,
2902 			   struct ice_sq_cd *cd, u16 *rule_id)
2903 {
2904 	struct ice_aqc_add_update_mir_rule *cmd;
2905 	struct ice_aq_desc desc;
2906 	enum ice_status status;
2907 	__le16 *mr_list = NULL;
2908 	u16 buf_size = 0;
2909 
2910 	switch (rule_type) {
2911 	case ICE_AQC_RULE_TYPE_VPORT_INGRESS:
2912 	case ICE_AQC_RULE_TYPE_VPORT_EGRESS:
2913 		/* Make sure count and mr_buf are set for these rule_types */
2914 		if (!(count && mr_buf))
2915 			return ICE_ERR_PARAM;
2916 
2917 		buf_size = count * sizeof(__le16);
2918 		mr_list = (_FORCE_ __le16 *)ice_malloc(hw, buf_size);
2919 		if (!mr_list)
2920 			return ICE_ERR_NO_MEMORY;
2921 		break;
2922 	case ICE_AQC_RULE_TYPE_PPORT_INGRESS:
2923 	case ICE_AQC_RULE_TYPE_PPORT_EGRESS:
2924 		/* Make sure count and mr_buf are not set for these
2925 		 * rule_types
2926 		 */
2927 		if (count || mr_buf)
2928 			return ICE_ERR_PARAM;
2929 		break;
2930 	default:
2931 		ice_debug(hw, ICE_DBG_SW, "Error due to unsupported rule_type %u\n", rule_type);
2932 		return ICE_ERR_OUT_OF_RANGE;
2933 	}
2934 
2935 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_update_mir_rule);
2936 
2937 	/* Pre-process 'mr_buf' items for add/update of virtual port
2938 	 * ingress/egress mirroring (but not physical port ingress/egress
2939 	 * mirroring)
2940 	 */
2941 	if (mr_buf) {
2942 		int i;
2943 
2944 		for (i = 0; i < count; i++) {
2945 			u16 id;
2946 
2947 			id = mr_buf[i].vsi_idx & ICE_AQC_RULE_MIRRORED_VSI_M;
2948 
2949 			/* Validate specified VSI number, make sure it is less
2950 			 * than ICE_MAX_VSI, if not return with error.
2951 			 */
2952 			if (id >= ICE_MAX_VSI) {
2953 				ice_debug(hw, ICE_DBG_SW, "Error VSI index (%u) out-of-range\n",
2954 					  id);
2955 				ice_free(hw, mr_list);
2956 				return ICE_ERR_OUT_OF_RANGE;
2957 			}
2958 
2959 			/* add VSI to mirror rule */
2960 			if (mr_buf[i].add)
2961 				mr_list[i] =
2962 					CPU_TO_LE16(id | ICE_AQC_RULE_ACT_M);
2963 			else /* remove VSI from mirror rule */
2964 				mr_list[i] = CPU_TO_LE16(id);
2965 		}
2966 	}
2967 
2968 	cmd = &desc.params.add_update_rule;
2969 	if ((*rule_id) != ICE_INVAL_MIRROR_RULE_ID)
2970 		cmd->rule_id = CPU_TO_LE16(((*rule_id) & ICE_AQC_RULE_ID_M) |
2971 					   ICE_AQC_RULE_ID_VALID_M);
2972 	cmd->rule_type = CPU_TO_LE16(rule_type & ICE_AQC_RULE_TYPE_M);
2973 	cmd->num_entries = CPU_TO_LE16(count);
2974 	cmd->dest = CPU_TO_LE16(dest_vsi);
2975 
2976 	status = ice_aq_send_cmd(hw, &desc, mr_list, buf_size, cd);
2977 	if (!status)
2978 		*rule_id = LE16_TO_CPU(cmd->rule_id) & ICE_AQC_RULE_ID_M;
2979 
2980 	ice_free(hw, mr_list);
2981 
2982 	return status;
2983 }
2984 
2985 /**
2986  * ice_aq_delete_mir_rule - delete a mirror rule
2987  * @hw: pointer to the HW struct
2988  * @rule_id: Mirror rule ID (to be deleted)
2989  * @keep_allocd: if set, the VSI stays part of the PF allocated res,
2990  *		 otherwise it is returned to the shared pool
2991  * @cd: pointer to command details structure or NULL
2992  *
2993  * Delete Mirror Rule (0x261).
2994  */
2995 enum ice_status
2996 ice_aq_delete_mir_rule(struct ice_hw *hw, u16 rule_id, bool keep_allocd,
2997 		       struct ice_sq_cd *cd)
2998 {
2999 	struct ice_aqc_delete_mir_rule *cmd;
3000 	struct ice_aq_desc desc;
3001 
3002 	/* rule_id should be in the range 0...63 */
3003 	if (rule_id >= ICE_MAX_NUM_MIRROR_RULES)
3004 		return ICE_ERR_OUT_OF_RANGE;
3005 
3006 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_del_mir_rule);
3007 
3008 	cmd = &desc.params.del_rule;
3009 	rule_id |= ICE_AQC_RULE_ID_VALID_M;
3010 	cmd->rule_id = CPU_TO_LE16(rule_id);
3011 
3012 	if (keep_allocd)
3013 		cmd->flags = CPU_TO_LE16(ICE_AQC_FLAG_KEEP_ALLOCD_M);
3014 
3015 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3016 }
3017 
3018 /**
3019  * ice_aq_alloc_free_vsi_list
3020  * @hw: pointer to the HW struct
3021  * @vsi_list_id: VSI list ID returned or used for lookup
3022  * @lkup_type: switch rule filter lookup type
3023  * @opc: switch rules population command type - pass in the command opcode
3024  *
3025  * allocates or free a VSI list resource
3026  */
3027 static enum ice_status
3028 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
3029 			   enum ice_sw_lkup_type lkup_type,
3030 			   enum ice_adminq_opc opc)
3031 {
3032 	struct ice_aqc_alloc_free_res_elem *sw_buf;
3033 	struct ice_aqc_res_elem *vsi_ele;
3034 	enum ice_status status;
3035 	u16 buf_len;
3036 
3037 	buf_len = ice_struct_size(sw_buf, elem, 1);
3038 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3039 	if (!sw_buf)
3040 		return ICE_ERR_NO_MEMORY;
3041 	sw_buf->num_elems = CPU_TO_LE16(1);
3042 
3043 	if (lkup_type == ICE_SW_LKUP_MAC ||
3044 	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
3045 	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3046 	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3047 	    lkup_type == ICE_SW_LKUP_PROMISC ||
3048 	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3049 	    lkup_type == ICE_SW_LKUP_LAST) {
3050 		sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
3051 	} else if (lkup_type == ICE_SW_LKUP_VLAN) {
3052 		sw_buf->res_type =
3053 			CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
3054 	} else {
3055 		status = ICE_ERR_PARAM;
3056 		goto ice_aq_alloc_free_vsi_list_exit;
3057 	}
3058 
3059 	if (opc == ice_aqc_opc_free_res)
3060 		sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(*vsi_list_id);
3061 
3062 	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
3063 	if (status)
3064 		goto ice_aq_alloc_free_vsi_list_exit;
3065 
3066 	if (opc == ice_aqc_opc_alloc_res) {
3067 		vsi_ele = &sw_buf->elem[0];
3068 		*vsi_list_id = LE16_TO_CPU(vsi_ele->e.sw_resp);
3069 	}
3070 
3071 ice_aq_alloc_free_vsi_list_exit:
3072 	ice_free(hw, sw_buf);
3073 	return status;
3074 }
3075 
3076 /**
3077  * ice_aq_set_storm_ctrl - Sets storm control configuration
3078  * @hw: pointer to the HW struct
3079  * @bcast_thresh: represents the upper threshold for broadcast storm control
3080  * @mcast_thresh: represents the upper threshold for multicast storm control
3081  * @ctl_bitmask: storm control knobs
3082  *
3083  * Sets the storm control configuration (0x0280)
3084  */
3085 enum ice_status
3086 ice_aq_set_storm_ctrl(struct ice_hw *hw, u32 bcast_thresh, u32 mcast_thresh,
3087 		      u32 ctl_bitmask)
3088 {
3089 	struct ice_aqc_storm_cfg *cmd;
3090 	struct ice_aq_desc desc;
3091 
3092 	cmd = &desc.params.storm_conf;
3093 
3094 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_storm_cfg);
3095 
3096 	cmd->bcast_thresh_size = CPU_TO_LE32(bcast_thresh & ICE_AQ_THRESHOLD_M);
3097 	cmd->mcast_thresh_size = CPU_TO_LE32(mcast_thresh & ICE_AQ_THRESHOLD_M);
3098 	cmd->storm_ctrl_ctrl = CPU_TO_LE32(ctl_bitmask);
3099 
3100 	return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3101 }
3102 
3103 /**
3104  * ice_aq_get_storm_ctrl - gets storm control configuration
3105  * @hw: pointer to the HW struct
3106  * @bcast_thresh: represents the upper threshold for broadcast storm control
3107  * @mcast_thresh: represents the upper threshold for multicast storm control
3108  * @ctl_bitmask: storm control knobs
3109  *
3110  * Gets the storm control configuration (0x0281)
3111  */
3112 enum ice_status
3113 ice_aq_get_storm_ctrl(struct ice_hw *hw, u32 *bcast_thresh, u32 *mcast_thresh,
3114 		      u32 *ctl_bitmask)
3115 {
3116 	enum ice_status status;
3117 	struct ice_aq_desc desc;
3118 
3119 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_storm_cfg);
3120 
3121 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3122 	if (!status) {
3123 		struct ice_aqc_storm_cfg *resp = &desc.params.storm_conf;
3124 
3125 		if (bcast_thresh)
3126 			*bcast_thresh = LE32_TO_CPU(resp->bcast_thresh_size) &
3127 				ICE_AQ_THRESHOLD_M;
3128 		if (mcast_thresh)
3129 			*mcast_thresh = LE32_TO_CPU(resp->mcast_thresh_size) &
3130 				ICE_AQ_THRESHOLD_M;
3131 		if (ctl_bitmask)
3132 			*ctl_bitmask = LE32_TO_CPU(resp->storm_ctrl_ctrl);
3133 	}
3134 
3135 	return status;
3136 }
3137 
3138 /**
3139  * ice_aq_sw_rules - add/update/remove switch rules
3140  * @hw: pointer to the HW struct
3141  * @rule_list: pointer to switch rule population list
3142  * @rule_list_sz: total size of the rule list in bytes
3143  * @num_rules: number of switch rules in the rule_list
3144  * @opc: switch rules population command type - pass in the command opcode
3145  * @cd: pointer to command details structure or NULL
3146  *
3147  * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
3148  */
3149 static enum ice_status
3150 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
3151 		u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
3152 {
3153 	struct ice_aq_desc desc;
3154 	enum ice_status status;
3155 
3156 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3157 
3158 	if (opc != ice_aqc_opc_add_sw_rules &&
3159 	    opc != ice_aqc_opc_update_sw_rules &&
3160 	    opc != ice_aqc_opc_remove_sw_rules)
3161 		return ICE_ERR_PARAM;
3162 
3163 	ice_fill_dflt_direct_cmd_desc(&desc, opc);
3164 
3165 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3166 	desc.params.sw_rules.num_rules_fltr_entry_index =
3167 		CPU_TO_LE16(num_rules);
3168 	status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
3169 	if (opc != ice_aqc_opc_add_sw_rules &&
3170 	    hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
3171 		status = ICE_ERR_DOES_NOT_EXIST;
3172 
3173 	return status;
3174 }
3175 
3176 /**
3177  * ice_aq_add_recipe - add switch recipe
3178  * @hw: pointer to the HW struct
3179  * @s_recipe_list: pointer to switch rule population list
3180  * @num_recipes: number of switch recipes in the list
3181  * @cd: pointer to command details structure or NULL
3182  *
3183  * Add(0x0290)
3184  */
3185 enum ice_status
3186 ice_aq_add_recipe(struct ice_hw *hw,
3187 		  struct ice_aqc_recipe_data_elem *s_recipe_list,
3188 		  u16 num_recipes, struct ice_sq_cd *cd)
3189 {
3190 	struct ice_aqc_add_get_recipe *cmd;
3191 	struct ice_aq_desc desc;
3192 	u16 buf_size;
3193 
3194 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3195 	cmd = &desc.params.add_get_recipe;
3196 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
3197 
3198 	cmd->num_sub_recipes = CPU_TO_LE16(num_recipes);
3199 	desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3200 
3201 	buf_size = num_recipes * sizeof(*s_recipe_list);
3202 
3203 	return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3204 }
3205 
3206 /**
3207  * ice_aq_get_recipe - get switch recipe
3208  * @hw: pointer to the HW struct
3209  * @s_recipe_list: pointer to switch rule population list
3210  * @num_recipes: pointer to the number of recipes (input and output)
3211  * @recipe_root: root recipe number of recipe(s) to retrieve
3212  * @cd: pointer to command details structure or NULL
3213  *
3214  * Get(0x0292)
3215  *
3216  * On input, *num_recipes should equal the number of entries in s_recipe_list.
3217  * On output, *num_recipes will equal the number of entries returned in
3218  * s_recipe_list.
3219  *
3220  * The caller must supply enough space in s_recipe_list to hold all possible
3221  * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
3222  */
3223 enum ice_status
3224 ice_aq_get_recipe(struct ice_hw *hw,
3225 		  struct ice_aqc_recipe_data_elem *s_recipe_list,
3226 		  u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
3227 {
3228 	struct ice_aqc_add_get_recipe *cmd;
3229 	struct ice_aq_desc desc;
3230 	enum ice_status status;
3231 	u16 buf_size;
3232 
3233 	if (*num_recipes != ICE_MAX_NUM_RECIPES)
3234 		return ICE_ERR_PARAM;
3235 
3236 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3237 	cmd = &desc.params.add_get_recipe;
3238 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
3239 
3240 	cmd->return_index = CPU_TO_LE16(recipe_root);
3241 	cmd->num_sub_recipes = 0;
3242 
3243 	buf_size = *num_recipes * sizeof(*s_recipe_list);
3244 
3245 	status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3246 	*num_recipes = LE16_TO_CPU(cmd->num_sub_recipes);
3247 
3248 	return status;
3249 }
3250 
3251 /**
3252  * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
3253  * @hw: pointer to the HW struct
3254  * @params: parameters used to update the default recipe
3255  *
3256  * This function only supports updating default recipes and it only supports
3257  * updating a single recipe based on the lkup_idx at a time.
3258  *
3259  * This is done as a read-modify-write operation. First, get the current recipe
3260  * contents based on the recipe's ID. Then modify the field vector index and
3261  * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
3262  * the pre-existing recipe with the modifications.
3263  */
3264 enum ice_status
3265 ice_update_recipe_lkup_idx(struct ice_hw *hw,
3266 			   struct ice_update_recipe_lkup_idx_params *params)
3267 {
3268 	struct ice_aqc_recipe_data_elem *rcp_list;
3269 	u16 num_recps = ICE_MAX_NUM_RECIPES;
3270 	enum ice_status status;
3271 
3272 	rcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));
3273 	if (!rcp_list)
3274 		return ICE_ERR_NO_MEMORY;
3275 
3276 	/* read current recipe list from firmware */
3277 	rcp_list->recipe_indx = params->rid;
3278 	status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
3279 	if (status) {
3280 		ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
3281 			  params->rid, status);
3282 		goto error_out;
3283 	}
3284 
3285 	/* only modify existing recipe's lkup_idx and mask if valid, while
3286 	 * leaving all other fields the same, then update the recipe firmware
3287 	 */
3288 	rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
3289 	if (params->mask_valid)
3290 		rcp_list->content.mask[params->lkup_idx] =
3291 			CPU_TO_LE16(params->mask);
3292 
3293 	if (params->ignore_valid)
3294 		rcp_list->content.lkup_indx[params->lkup_idx] |=
3295 			ICE_AQ_RECIPE_LKUP_IGNORE;
3296 
3297 	status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
3298 	if (status)
3299 		ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
3300 			  params->rid, params->lkup_idx, params->fv_idx,
3301 			  params->mask, params->mask_valid ? "true" : "false",
3302 			  status);
3303 
3304 error_out:
3305 	ice_free(hw, rcp_list);
3306 	return status;
3307 }
3308 
3309 /**
3310  * ice_aq_map_recipe_to_profile - Map recipe to packet profile
3311  * @hw: pointer to the HW struct
3312  * @profile_id: package profile ID to associate the recipe with
3313  * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3314  * @cd: pointer to command details structure or NULL
3315  * Recipe to profile association (0x0291)
3316  */
3317 enum ice_status
3318 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3319 			     struct ice_sq_cd *cd)
3320 {
3321 	struct ice_aqc_recipe_to_profile *cmd;
3322 	struct ice_aq_desc desc;
3323 
3324 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3325 	cmd = &desc.params.recipe_to_profile;
3326 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
3327 	cmd->profile_id = CPU_TO_LE16(profile_id);
3328 	/* Set the recipe ID bit in the bitmask to let the device know which
3329 	 * profile we are associating the recipe to
3330 	 */
3331 	ice_memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc),
3332 		   ICE_NONDMA_TO_NONDMA);
3333 
3334 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3335 }
3336 
3337 /**
3338  * ice_aq_get_recipe_to_profile - Map recipe to packet profile
3339  * @hw: pointer to the HW struct
3340  * @profile_id: package profile ID to associate the recipe with
3341  * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3342  * @cd: pointer to command details structure or NULL
3343  * Associate profile ID with given recipe (0x0293)
3344  */
3345 enum ice_status
3346 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3347 			     struct ice_sq_cd *cd)
3348 {
3349 	struct ice_aqc_recipe_to_profile *cmd;
3350 	struct ice_aq_desc desc;
3351 	enum ice_status status;
3352 
3353 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3354 	cmd = &desc.params.recipe_to_profile;
3355 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
3356 	cmd->profile_id = CPU_TO_LE16(profile_id);
3357 
3358 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3359 	if (!status)
3360 		ice_memcpy(r_bitmap, cmd->recipe_assoc,
3361 			   sizeof(cmd->recipe_assoc), ICE_NONDMA_TO_NONDMA);
3362 
3363 	return status;
3364 }
3365 
3366 /**
3367  * ice_alloc_recipe - add recipe resource
3368  * @hw: pointer to the hardware structure
3369  * @rid: recipe ID returned as response to AQ call
3370  */
3371 enum ice_status ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
3372 {
3373 	struct ice_aqc_alloc_free_res_elem *sw_buf;
3374 	enum ice_status status;
3375 	u16 buf_len;
3376 
3377 	buf_len = ice_struct_size(sw_buf, elem, 1);
3378 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3379 	if (!sw_buf)
3380 		return ICE_ERR_NO_MEMORY;
3381 
3382 	sw_buf->num_elems = CPU_TO_LE16(1);
3383 	sw_buf->res_type = CPU_TO_LE16((ICE_AQC_RES_TYPE_RECIPE <<
3384 					ICE_AQC_RES_TYPE_S) |
3385 					ICE_AQC_RES_TYPE_FLAG_SHARED);
3386 	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
3387 				       ice_aqc_opc_alloc_res, NULL);
3388 	if (!status)
3389 		*rid = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
3390 	ice_free(hw, sw_buf);
3391 
3392 	return status;
3393 }
3394 
3395 /* ice_init_port_info - Initialize port_info with switch configuration data
3396  * @pi: pointer to port_info
3397  * @vsi_port_num: VSI number or port number
3398  * @type: Type of switch element (port or VSI)
3399  * @swid: switch ID of the switch the element is attached to
3400  * @pf_vf_num: PF or VF number
3401  * @is_vf: true if the element is a VF, false otherwise
3402  */
3403 static void
3404 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
3405 		   u16 swid, u16 pf_vf_num, bool is_vf)
3406 {
3407 	switch (type) {
3408 	case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3409 		pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
3410 		pi->sw_id = swid;
3411 		pi->pf_vf_num = pf_vf_num;
3412 		pi->is_vf = is_vf;
3413 		pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
3414 		pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
3415 		break;
3416 	default:
3417 		ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
3418 		break;
3419 	}
3420 }
3421 
3422 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
3423  * @hw: pointer to the hardware structure
3424  */
3425 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
3426 {
3427 	struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
3428 	enum ice_status status;
3429 	u8 num_total_ports;
3430 	u16 req_desc = 0;
3431 	u16 num_elems;
3432 	u8 j = 0;
3433 	u16 i;
3434 
3435 	num_total_ports = 1;
3436 
3437 	rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *)
3438 		ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN);
3439 
3440 	if (!rbuf)
3441 		return ICE_ERR_NO_MEMORY;
3442 
3443 	/* Multiple calls to ice_aq_get_sw_cfg may be required
3444 	 * to get all the switch configuration information. The need
3445 	 * for additional calls is indicated by ice_aq_get_sw_cfg
3446 	 * writing a non-zero value in req_desc
3447 	 */
3448 	do {
3449 		struct ice_aqc_get_sw_cfg_resp_elem *ele;
3450 
3451 		status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
3452 					   &req_desc, &num_elems, NULL);
3453 
3454 		if (status)
3455 			break;
3456 
3457 		for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
3458 			u16 pf_vf_num, swid, vsi_port_num;
3459 			bool is_vf = false;
3460 			u8 res_type;
3461 
3462 			vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) &
3463 				ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
3464 
3465 			pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) &
3466 				ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
3467 
3468 			swid = LE16_TO_CPU(ele->swid);
3469 
3470 			if (LE16_TO_CPU(ele->pf_vf_num) &
3471 			    ICE_AQC_GET_SW_CONF_RESP_IS_VF)
3472 				is_vf = true;
3473 
3474 			res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >>
3475 					ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
3476 
3477 			switch (res_type) {
3478 			case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3479 			case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT:
3480 				if (j == num_total_ports) {
3481 					ice_debug(hw, ICE_DBG_SW, "more ports than expected\n");
3482 					status = ICE_ERR_CFG;
3483 					goto out;
3484 				}
3485 				ice_init_port_info(hw->port_info,
3486 						   vsi_port_num, res_type, swid,
3487 						   pf_vf_num, is_vf);
3488 				j++;
3489 				break;
3490 			default:
3491 				break;
3492 			}
3493 		}
3494 	} while (req_desc && !status);
3495 
3496 out:
3497 	ice_free(hw, rbuf);
3498 	return status;
3499 }
3500 
3501 /**
3502  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
3503  * @hw: pointer to the hardware structure
3504  * @fi: filter info structure to fill/update
3505  *
3506  * This helper function populates the lb_en and lan_en elements of the provided
3507  * ice_fltr_info struct using the switch's type and characteristics of the
3508  * switch rule being configured.
3509  */
3510 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
3511 {
3512 	if ((fi->flag & ICE_FLTR_RX) &&
3513 	    (fi->fltr_act == ICE_FWD_TO_VSI ||
3514 	     fi->fltr_act == ICE_FWD_TO_VSI_LIST) &&
3515 	    fi->lkup_type == ICE_SW_LKUP_LAST)
3516 		fi->lan_en = true;
3517 	fi->lb_en = false;
3518 	fi->lan_en = false;
3519 	if ((fi->flag & ICE_FLTR_TX) &&
3520 	    (fi->fltr_act == ICE_FWD_TO_VSI ||
3521 	     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
3522 	     fi->fltr_act == ICE_FWD_TO_Q ||
3523 	     fi->fltr_act == ICE_FWD_TO_QGRP)) {
3524 		/* Setting LB for prune actions will result in replicated
3525 		 * packets to the internal switch that will be dropped.
3526 		 */
3527 		if (fi->lkup_type != ICE_SW_LKUP_VLAN)
3528 			fi->lb_en = true;
3529 
3530 		/* Set lan_en to TRUE if
3531 		 * 1. The switch is a VEB AND
3532 		 * 2
3533 		 * 2.1 The lookup is a directional lookup like ethertype,
3534 		 * promiscuous, ethertype-MAC, promiscuous-VLAN
3535 		 * and default-port OR
3536 		 * 2.2 The lookup is VLAN, OR
3537 		 * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
3538 		 * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
3539 		 *
3540 		 * OR
3541 		 *
3542 		 * The switch is a VEPA.
3543 		 *
3544 		 * In all other cases, the LAN enable has to be set to false.
3545 		 */
3546 		if (hw->evb_veb) {
3547 			if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3548 			    fi->lkup_type == ICE_SW_LKUP_PROMISC ||
3549 			    fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3550 			    fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3551 			    fi->lkup_type == ICE_SW_LKUP_DFLT ||
3552 			    fi->lkup_type == ICE_SW_LKUP_VLAN ||
3553 			    (fi->lkup_type == ICE_SW_LKUP_MAC &&
3554 			     !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) ||
3555 			    (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
3556 			     !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)))
3557 				fi->lan_en = true;
3558 		} else {
3559 			fi->lan_en = true;
3560 		}
3561 	}
3562 }
3563 
3564 /**
3565  * ice_fill_sw_rule - Helper function to fill switch rule structure
3566  * @hw: pointer to the hardware structure
3567  * @f_info: entry containing packet forwarding information
3568  * @s_rule: switch rule structure to be filled in based on mac_entry
3569  * @opc: switch rules population command type - pass in the command opcode
3570  */
3571 static void
3572 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
3573 		 struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
3574 {
3575 	u16 vlan_id = ICE_MAX_VLAN_ID + 1;
3576 	u16 vlan_tpid = ICE_ETH_P_8021Q;
3577 	void *daddr = NULL;
3578 	u16 eth_hdr_sz;
3579 	u8 *eth_hdr;
3580 	u32 act = 0;
3581 	__be16 *off;
3582 	u8 q_rgn;
3583 
3584 	if (opc == ice_aqc_opc_remove_sw_rules) {
3585 		s_rule->pdata.lkup_tx_rx.act = 0;
3586 		s_rule->pdata.lkup_tx_rx.index =
3587 			CPU_TO_LE16(f_info->fltr_rule_id);
3588 		s_rule->pdata.lkup_tx_rx.hdr_len = 0;
3589 		return;
3590 	}
3591 
3592 	eth_hdr_sz = sizeof(dummy_eth_header);
3593 	eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
3594 
3595 	/* initialize the ether header with a dummy header */
3596 	ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA);
3597 	ice_fill_sw_info(hw, f_info);
3598 
3599 	switch (f_info->fltr_act) {
3600 	case ICE_FWD_TO_VSI:
3601 		act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
3602 			ICE_SINGLE_ACT_VSI_ID_M;
3603 		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
3604 			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
3605 				ICE_SINGLE_ACT_VALID_BIT;
3606 		break;
3607 	case ICE_FWD_TO_VSI_LIST:
3608 		act |= ICE_SINGLE_ACT_VSI_LIST;
3609 		act |= (f_info->fwd_id.vsi_list_id <<
3610 			ICE_SINGLE_ACT_VSI_LIST_ID_S) &
3611 			ICE_SINGLE_ACT_VSI_LIST_ID_M;
3612 		if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
3613 			act |= ICE_SINGLE_ACT_VSI_FORWARDING |
3614 				ICE_SINGLE_ACT_VALID_BIT;
3615 		break;
3616 	case ICE_FWD_TO_Q:
3617 		act |= ICE_SINGLE_ACT_TO_Q;
3618 		act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
3619 			ICE_SINGLE_ACT_Q_INDEX_M;
3620 		break;
3621 	case ICE_DROP_PACKET:
3622 		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
3623 			ICE_SINGLE_ACT_VALID_BIT;
3624 		break;
3625 	case ICE_FWD_TO_QGRP:
3626 		q_rgn = f_info->qgrp_size > 0 ?
3627 			(u8)ice_ilog2(f_info->qgrp_size) : 0;
3628 		act |= ICE_SINGLE_ACT_TO_Q;
3629 		act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
3630 			ICE_SINGLE_ACT_Q_INDEX_M;
3631 		act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
3632 			ICE_SINGLE_ACT_Q_REGION_M;
3633 		break;
3634 	default:
3635 		return;
3636 	}
3637 
3638 	if (f_info->lb_en)
3639 		act |= ICE_SINGLE_ACT_LB_ENABLE;
3640 	if (f_info->lan_en)
3641 		act |= ICE_SINGLE_ACT_LAN_ENABLE;
3642 
3643 	switch (f_info->lkup_type) {
3644 	case ICE_SW_LKUP_MAC:
3645 		daddr = f_info->l_data.mac.mac_addr;
3646 		break;
3647 	case ICE_SW_LKUP_VLAN:
3648 		vlan_id = f_info->l_data.vlan.vlan_id;
3649 		if (f_info->l_data.vlan.tpid_valid)
3650 			vlan_tpid = f_info->l_data.vlan.tpid;
3651 		if (f_info->fltr_act == ICE_FWD_TO_VSI ||
3652 		    f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3653 			act |= ICE_SINGLE_ACT_PRUNE;
3654 			act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
3655 		}
3656 		break;
3657 	case ICE_SW_LKUP_ETHERTYPE_MAC:
3658 		daddr = f_info->l_data.ethertype_mac.mac_addr;
3659 		/* fall-through */
3660 	case ICE_SW_LKUP_ETHERTYPE:
3661 		off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
3662 		*off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype);
3663 		break;
3664 	case ICE_SW_LKUP_MAC_VLAN:
3665 		daddr = f_info->l_data.mac_vlan.mac_addr;
3666 		vlan_id = f_info->l_data.mac_vlan.vlan_id;
3667 		break;
3668 	case ICE_SW_LKUP_PROMISC_VLAN:
3669 		vlan_id = f_info->l_data.mac_vlan.vlan_id;
3670 		/* fall-through */
3671 	case ICE_SW_LKUP_PROMISC:
3672 		daddr = f_info->l_data.mac_vlan.mac_addr;
3673 		break;
3674 	default:
3675 		break;
3676 	}
3677 
3678 	s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
3679 		CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) :
3680 		CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
3681 
3682 	/* Recipe set depending on lookup type */
3683 	s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(f_info->lkup_type);
3684 	s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(f_info->src);
3685 	s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
3686 
3687 	if (daddr)
3688 		ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN,
3689 			   ICE_NONDMA_TO_NONDMA);
3690 
3691 	if (!(vlan_id > ICE_MAX_VLAN_ID)) {
3692 		off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
3693 		*off = CPU_TO_BE16(vlan_id);
3694 		off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
3695 		*off = CPU_TO_BE16(vlan_tpid);
3696 	}
3697 
3698 	/* Create the switch rule with the final dummy Ethernet header */
3699 	if (opc != ice_aqc_opc_update_sw_rules)
3700 		s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(eth_hdr_sz);
3701 }
3702 
3703 /**
3704  * ice_add_marker_act
3705  * @hw: pointer to the hardware structure
3706  * @m_ent: the management entry for which sw marker needs to be added
3707  * @sw_marker: sw marker to tag the Rx descriptor with
3708  * @l_id: large action resource ID
3709  *
3710  * Create a large action to hold software marker and update the switch rule
3711  * entry pointed by m_ent with newly created large action
3712  */
3713 static enum ice_status
3714 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
3715 		   u16 sw_marker, u16 l_id)
3716 {
3717 	struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
3718 	/* For software marker we need 3 large actions
3719 	 * 1. FWD action: FWD TO VSI or VSI LIST
3720 	 * 2. GENERIC VALUE action to hold the profile ID
3721 	 * 3. GENERIC VALUE action to hold the software marker ID
3722 	 */
3723 	const u16 num_lg_acts = 3;
3724 	enum ice_status status;
3725 	u16 lg_act_size;
3726 	u16 rules_size;
3727 	u32 act;
3728 	u16 id;
3729 
3730 	if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
3731 		return ICE_ERR_PARAM;
3732 
3733 	/* Create two back-to-back switch rules and submit them to the HW using
3734 	 * one memory buffer:
3735 	 *    1. Large Action
3736 	 *    2. Look up Tx Rx
3737 	 */
3738 	lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
3739 	rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
3740 	lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
3741 	if (!lg_act)
3742 		return ICE_ERR_NO_MEMORY;
3743 
3744 	rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
3745 
3746 	/* Fill in the first switch rule i.e. large action */
3747 	lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
3748 	lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
3749 	lg_act->pdata.lg_act.size = CPU_TO_LE16(num_lg_acts);
3750 
3751 	/* First action VSI forwarding or VSI list forwarding depending on how
3752 	 * many VSIs
3753 	 */
3754 	id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
3755 		m_ent->fltr_info.fwd_id.hw_vsi_id;
3756 
3757 	act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
3758 	act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
3759 	if (m_ent->vsi_count > 1)
3760 		act |= ICE_LG_ACT_VSI_LIST;
3761 	lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
3762 
3763 	/* Second action descriptor type */
3764 	act = ICE_LG_ACT_GENERIC;
3765 
3766 	act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
3767 	lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
3768 
3769 	act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
3770 	       ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
3771 
3772 	/* Third action Marker value */
3773 	act |= ICE_LG_ACT_GENERIC;
3774 	act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
3775 		ICE_LG_ACT_GENERIC_VALUE_M;
3776 
3777 	lg_act->pdata.lg_act.act[2] = CPU_TO_LE32(act);
3778 
3779 	/* call the fill switch rule to fill the lookup Tx Rx structure */
3780 	ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
3781 			 ice_aqc_opc_update_sw_rules);
3782 
3783 	/* Update the action to point to the large action ID */
3784 	rx_tx->pdata.lkup_tx_rx.act =
3785 		CPU_TO_LE32(ICE_SINGLE_ACT_PTR |
3786 			    ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
3787 			     ICE_SINGLE_ACT_PTR_VAL_M));
3788 
3789 	/* Use the filter rule ID of the previously created rule with single
3790 	 * act. Once the update happens, hardware will treat this as large
3791 	 * action
3792 	 */
3793 	rx_tx->pdata.lkup_tx_rx.index =
3794 		CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id);
3795 
3796 	status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
3797 				 ice_aqc_opc_update_sw_rules, NULL);
3798 	if (!status) {
3799 		m_ent->lg_act_idx = l_id;
3800 		m_ent->sw_marker_id = sw_marker;
3801 	}
3802 
3803 	ice_free(hw, lg_act);
3804 	return status;
3805 }
3806 
3807 /**
3808  * ice_add_counter_act - add/update filter rule with counter action
3809  * @hw: pointer to the hardware structure
3810  * @m_ent: the management entry for which counter needs to be added
3811  * @counter_id: VLAN counter ID returned as part of allocate resource
3812  * @l_id: large action resource ID
3813  */
3814 static enum ice_status
3815 ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
3816 		    u16 counter_id, u16 l_id)
3817 {
3818 	struct ice_aqc_sw_rules_elem *lg_act;
3819 	struct ice_aqc_sw_rules_elem *rx_tx;
3820 	enum ice_status status;
3821 	/* 2 actions will be added while adding a large action counter */
3822 	const int num_acts = 2;
3823 	u16 lg_act_size;
3824 	u16 rules_size;
3825 	u16 f_rule_id;
3826 	u32 act;
3827 	u16 id;
3828 
3829 	if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
3830 		return ICE_ERR_PARAM;
3831 
3832 	/* Create two back-to-back switch rules and submit them to the HW using
3833 	 * one memory buffer:
3834 	 * 1. Large Action
3835 	 * 2. Look up Tx Rx
3836 	 */
3837 	lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_acts);
3838 	rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
3839 	lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
3840 	if (!lg_act)
3841 		return ICE_ERR_NO_MEMORY;
3842 
3843 	rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
3844 
3845 	/* Fill in the first switch rule i.e. large action */
3846 	lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
3847 	lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
3848 	lg_act->pdata.lg_act.size = CPU_TO_LE16(num_acts);
3849 
3850 	/* First action VSI forwarding or VSI list forwarding depending on how
3851 	 * many VSIs
3852 	 */
3853 	id = (m_ent->vsi_count > 1) ?  m_ent->fltr_info.fwd_id.vsi_list_id :
3854 		m_ent->fltr_info.fwd_id.hw_vsi_id;
3855 
3856 	act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
3857 	act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
3858 		ICE_LG_ACT_VSI_LIST_ID_M;
3859 	if (m_ent->vsi_count > 1)
3860 		act |= ICE_LG_ACT_VSI_LIST;
3861 	lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
3862 
3863 	/* Second action counter ID */
3864 	act = ICE_LG_ACT_STAT_COUNT;
3865 	act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) &
3866 		ICE_LG_ACT_STAT_COUNT_M;
3867 	lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
3868 
3869 	/* call the fill switch rule to fill the lookup Tx Rx structure */
3870 	ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
3871 			 ice_aqc_opc_update_sw_rules);
3872 
3873 	act = ICE_SINGLE_ACT_PTR;
3874 	act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M;
3875 	rx_tx->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
3876 
3877 	/* Use the filter rule ID of the previously created rule with single
3878 	 * act. Once the update happens, hardware will treat this as large
3879 	 * action
3880 	 */
3881 	f_rule_id = m_ent->fltr_info.fltr_rule_id;
3882 	rx_tx->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_rule_id);
3883 
3884 	status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
3885 				 ice_aqc_opc_update_sw_rules, NULL);
3886 	if (!status) {
3887 		m_ent->lg_act_idx = l_id;
3888 		m_ent->counter_index = counter_id;
3889 	}
3890 
3891 	ice_free(hw, lg_act);
3892 	return status;
3893 }
3894 
3895 /**
3896  * ice_create_vsi_list_map
3897  * @hw: pointer to the hardware structure
3898  * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
3899  * @num_vsi: number of VSI handles in the array
3900  * @vsi_list_id: VSI list ID generated as part of allocate resource
3901  *
3902  * Helper function to create a new entry of VSI list ID to VSI mapping
3903  * using the given VSI list ID
3904  */
3905 static struct ice_vsi_list_map_info *
3906 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3907 			u16 vsi_list_id)
3908 {
3909 	struct ice_switch_info *sw = hw->switch_info;
3910 	struct ice_vsi_list_map_info *v_map;
3911 	int i;
3912 
3913 	v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map));
3914 	if (!v_map)
3915 		return NULL;
3916 
3917 	v_map->vsi_list_id = vsi_list_id;
3918 	v_map->ref_cnt = 1;
3919 	for (i = 0; i < num_vsi; i++)
3920 		ice_set_bit(vsi_handle_arr[i], v_map->vsi_map);
3921 
3922 	LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head);
3923 	return v_map;
3924 }
3925 
3926 /**
3927  * ice_update_vsi_list_rule
3928  * @hw: pointer to the hardware structure
3929  * @vsi_handle_arr: array of VSI handles to form a VSI list
3930  * @num_vsi: number of VSI handles in the array
3931  * @vsi_list_id: VSI list ID generated as part of allocate resource
3932  * @remove: Boolean value to indicate if this is a remove action
3933  * @opc: switch rules population command type - pass in the command opcode
3934  * @lkup_type: lookup type of the filter
3935  *
3936  * Call AQ command to add a new switch rule or update existing switch rule
3937  * using the given VSI list ID
3938  */
3939 static enum ice_status
3940 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3941 			 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
3942 			 enum ice_sw_lkup_type lkup_type)
3943 {
3944 	struct ice_aqc_sw_rules_elem *s_rule;
3945 	enum ice_status status;
3946 	u16 s_rule_size;
3947 	u16 rule_type;
3948 	int i;
3949 
3950 	if (!num_vsi)
3951 		return ICE_ERR_PARAM;
3952 
3953 	if (lkup_type == ICE_SW_LKUP_MAC ||
3954 	    lkup_type == ICE_SW_LKUP_MAC_VLAN ||
3955 	    lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3956 	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3957 	    lkup_type == ICE_SW_LKUP_PROMISC ||
3958 	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3959 	    lkup_type == ICE_SW_LKUP_LAST)
3960 		rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
3961 			ICE_AQC_SW_RULES_T_VSI_LIST_SET;
3962 	else if (lkup_type == ICE_SW_LKUP_VLAN)
3963 		rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
3964 			ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
3965 	else
3966 		return ICE_ERR_PARAM;
3967 
3968 	s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
3969 	s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
3970 	if (!s_rule)
3971 		return ICE_ERR_NO_MEMORY;
3972 	for (i = 0; i < num_vsi; i++) {
3973 		if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
3974 			status = ICE_ERR_PARAM;
3975 			goto exit;
3976 		}
3977 		/* AQ call requires hw_vsi_id(s) */
3978 		s_rule->pdata.vsi_list.vsi[i] =
3979 			CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
3980 	}
3981 
3982 	s_rule->type = CPU_TO_LE16(rule_type);
3983 	s_rule->pdata.vsi_list.number_vsi = CPU_TO_LE16(num_vsi);
3984 	s_rule->pdata.vsi_list.index = CPU_TO_LE16(vsi_list_id);
3985 
3986 	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
3987 
3988 exit:
3989 	ice_free(hw, s_rule);
3990 	return status;
3991 }
3992 
3993 /**
3994  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
3995  * @hw: pointer to the HW struct
3996  * @vsi_handle_arr: array of VSI handles to form a VSI list
3997  * @num_vsi: number of VSI handles in the array
3998  * @vsi_list_id: stores the ID of the VSI list to be created
3999  * @lkup_type: switch rule filter's lookup type
4000  */
4001 static enum ice_status
4002 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4003 			 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
4004 {
4005 	enum ice_status status;
4006 
4007 	status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
4008 					    ice_aqc_opc_alloc_res);
4009 	if (status)
4010 		return status;
4011 
4012 	/* Update the newly created VSI list to include the specified VSIs */
4013 	return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
4014 					*vsi_list_id, false,
4015 					ice_aqc_opc_add_sw_rules, lkup_type);
4016 }
4017 
4018 /**
4019  * ice_create_pkt_fwd_rule
4020  * @hw: pointer to the hardware structure
4021  * @recp_list: corresponding filter management list
4022  * @f_entry: entry containing packet forwarding information
4023  *
4024  * Create switch rule with given filter information and add an entry
4025  * to the corresponding filter management list to track this switch rule
4026  * and VSI mapping
4027  */
4028 static enum ice_status
4029 ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4030 			struct ice_fltr_list_entry *f_entry)
4031 {
4032 	struct ice_fltr_mgmt_list_entry *fm_entry;
4033 	struct ice_aqc_sw_rules_elem *s_rule;
4034 	enum ice_status status;
4035 
4036 	s_rule = (struct ice_aqc_sw_rules_elem *)
4037 		ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
4038 	if (!s_rule)
4039 		return ICE_ERR_NO_MEMORY;
4040 	fm_entry = (struct ice_fltr_mgmt_list_entry *)
4041 		   ice_malloc(hw, sizeof(*fm_entry));
4042 	if (!fm_entry) {
4043 		status = ICE_ERR_NO_MEMORY;
4044 		goto ice_create_pkt_fwd_rule_exit;
4045 	}
4046 
4047 	fm_entry->fltr_info = f_entry->fltr_info;
4048 
4049 	/* Initialize all the fields for the management entry */
4050 	fm_entry->vsi_count = 1;
4051 	fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
4052 	fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
4053 	fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
4054 
4055 	ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
4056 			 ice_aqc_opc_add_sw_rules);
4057 
4058 	status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
4059 				 ice_aqc_opc_add_sw_rules, NULL);
4060 	if (status) {
4061 		ice_free(hw, fm_entry);
4062 		goto ice_create_pkt_fwd_rule_exit;
4063 	}
4064 
4065 	f_entry->fltr_info.fltr_rule_id =
4066 		LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
4067 	fm_entry->fltr_info.fltr_rule_id =
4068 		LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
4069 
4070 	/* The book keeping entries will get removed when base driver
4071 	 * calls remove filter AQ command
4072 	 */
4073 	LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules);
4074 
4075 ice_create_pkt_fwd_rule_exit:
4076 	ice_free(hw, s_rule);
4077 	return status;
4078 }
4079 
4080 /**
4081  * ice_update_pkt_fwd_rule
4082  * @hw: pointer to the hardware structure
4083  * @f_info: filter information for switch rule
4084  *
4085  * Call AQ command to update a previously created switch rule with a
4086  * VSI list ID
4087  */
4088 static enum ice_status
4089 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
4090 {
4091 	struct ice_aqc_sw_rules_elem *s_rule;
4092 	enum ice_status status;
4093 
4094 	s_rule = (struct ice_aqc_sw_rules_elem *)
4095 		ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
4096 	if (!s_rule)
4097 		return ICE_ERR_NO_MEMORY;
4098 
4099 	ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
4100 
4101 	s_rule->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_info->fltr_rule_id);
4102 
4103 	/* Update switch rule with new rule set to forward VSI list */
4104 	status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
4105 				 ice_aqc_opc_update_sw_rules, NULL);
4106 
4107 	ice_free(hw, s_rule);
4108 	return status;
4109 }
4110 
4111 /**
4112  * ice_update_sw_rule_bridge_mode
4113  * @hw: pointer to the HW struct
4114  *
4115  * Updates unicast switch filter rules based on VEB/VEPA mode
4116  */
4117 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
4118 {
4119 	struct ice_switch_info *sw = hw->switch_info;
4120 	struct ice_fltr_mgmt_list_entry *fm_entry;
4121 	enum ice_status status = ICE_SUCCESS;
4122 	struct LIST_HEAD_TYPE *rule_head;
4123 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4124 
4125 	rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
4126 	rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4127 
4128 	ice_acquire_lock(rule_lock);
4129 	LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry,
4130 			    list_entry) {
4131 		struct ice_fltr_info *fi = &fm_entry->fltr_info;
4132 		u8 *addr = fi->l_data.mac.mac_addr;
4133 
4134 		/* Update unicast Tx rules to reflect the selected
4135 		 * VEB/VEPA mode
4136 		 */
4137 		if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) &&
4138 		    (fi->fltr_act == ICE_FWD_TO_VSI ||
4139 		     fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
4140 		     fi->fltr_act == ICE_FWD_TO_Q ||
4141 		     fi->fltr_act == ICE_FWD_TO_QGRP)) {
4142 			status = ice_update_pkt_fwd_rule(hw, fi);
4143 			if (status)
4144 				break;
4145 		}
4146 	}
4147 
4148 	ice_release_lock(rule_lock);
4149 
4150 	return status;
4151 }
4152 
4153 /**
4154  * ice_add_update_vsi_list
4155  * @hw: pointer to the hardware structure
4156  * @m_entry: pointer to current filter management list entry
4157  * @cur_fltr: filter information from the book keeping entry
4158  * @new_fltr: filter information with the new VSI to be added
4159  *
4160  * Call AQ command to add or update previously created VSI list with new VSI.
4161  *
4162  * Helper function to do book keeping associated with adding filter information
4163  * The algorithm to do the book keeping is described below :
4164  * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
4165  *	if only one VSI has been added till now
4166  *		Allocate a new VSI list and add two VSIs
4167  *		to this list using switch rule command
4168  *		Update the previously created switch rule with the
4169  *		newly created VSI list ID
4170  *	if a VSI list was previously created
4171  *		Add the new VSI to the previously created VSI list set
4172  *		using the update switch rule command
4173  */
4174 static enum ice_status
4175 ice_add_update_vsi_list(struct ice_hw *hw,
4176 			struct ice_fltr_mgmt_list_entry *m_entry,
4177 			struct ice_fltr_info *cur_fltr,
4178 			struct ice_fltr_info *new_fltr)
4179 {
4180 	enum ice_status status = ICE_SUCCESS;
4181 	u16 vsi_list_id = 0;
4182 
4183 	if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
4184 	     cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
4185 		return ICE_ERR_NOT_IMPL;
4186 
4187 	if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
4188 	     new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
4189 	    (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
4190 	     cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
4191 		return ICE_ERR_NOT_IMPL;
4192 
4193 	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
4194 		/* Only one entry existed in the mapping and it was not already
4195 		 * a part of a VSI list. So, create a VSI list with the old and
4196 		 * new VSIs.
4197 		 */
4198 		struct ice_fltr_info tmp_fltr;
4199 		u16 vsi_handle_arr[2];
4200 
4201 		/* A rule already exists with the new VSI being added */
4202 		if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
4203 			return ICE_ERR_ALREADY_EXISTS;
4204 
4205 		vsi_handle_arr[0] = cur_fltr->vsi_handle;
4206 		vsi_handle_arr[1] = new_fltr->vsi_handle;
4207 		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4208 						  &vsi_list_id,
4209 						  new_fltr->lkup_type);
4210 		if (status)
4211 			return status;
4212 
4213 		tmp_fltr = *new_fltr;
4214 		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
4215 		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4216 		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4217 		/* Update the previous switch rule of "MAC forward to VSI" to
4218 		 * "MAC fwd to VSI list"
4219 		 */
4220 		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4221 		if (status)
4222 			return status;
4223 
4224 		cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
4225 		cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4226 		m_entry->vsi_list_info =
4227 			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4228 						vsi_list_id);
4229 
4230 		if (!m_entry->vsi_list_info)
4231 			return ICE_ERR_NO_MEMORY;
4232 
4233 		/* If this entry was large action then the large action needs
4234 		 * to be updated to point to FWD to VSI list
4235 		 */
4236 		if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
4237 			status =
4238 			    ice_add_marker_act(hw, m_entry,
4239 					       m_entry->sw_marker_id,
4240 					       m_entry->lg_act_idx);
4241 	} else {
4242 		u16 vsi_handle = new_fltr->vsi_handle;
4243 		enum ice_adminq_opc opcode;
4244 
4245 		if (!m_entry->vsi_list_info)
4246 			return ICE_ERR_CFG;
4247 
4248 		/* A rule already exists with the new VSI being added */
4249 		if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
4250 			return ICE_SUCCESS;
4251 
4252 		/* Update the previously created VSI list set with
4253 		 * the new VSI ID passed in
4254 		 */
4255 		vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
4256 		opcode = ice_aqc_opc_update_sw_rules;
4257 
4258 		status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
4259 						  vsi_list_id, false, opcode,
4260 						  new_fltr->lkup_type);
4261 		/* update VSI list mapping info with new VSI ID */
4262 		if (!status)
4263 			ice_set_bit(vsi_handle,
4264 				    m_entry->vsi_list_info->vsi_map);
4265 	}
4266 	if (!status)
4267 		m_entry->vsi_count++;
4268 	return status;
4269 }
4270 
4271 /**
4272  * ice_find_rule_entry - Search a rule entry
4273  * @list_head: head of rule list
4274  * @f_info: rule information
4275  *
4276  * Helper function to search for a given rule entry
4277  * Returns pointer to entry storing the rule if found
4278  */
4279 static struct ice_fltr_mgmt_list_entry *
4280 ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head,
4281 		    struct ice_fltr_info *f_info)
4282 {
4283 	struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
4284 
4285 	LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
4286 			    list_entry) {
4287 		if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
4288 			    sizeof(f_info->l_data)) &&
4289 		    f_info->flag == list_itr->fltr_info.flag) {
4290 			ret = list_itr;
4291 			break;
4292 		}
4293 	}
4294 	return ret;
4295 }
4296 
4297 /**
4298  * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
4299  * @recp_list: VSI lists needs to be searched
4300  * @vsi_handle: VSI handle to be found in VSI list
4301  * @vsi_list_id: VSI list ID found containing vsi_handle
4302  *
4303  * Helper function to search a VSI list with single entry containing given VSI
4304  * handle element. This can be extended further to search VSI list with more
4305  * than 1 vsi_count. Returns pointer to VSI list entry if found.
4306  */
4307 static struct ice_vsi_list_map_info *
4308 ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle,
4309 			u16 *vsi_list_id)
4310 {
4311 	struct ice_vsi_list_map_info *map_info = NULL;
4312 	struct LIST_HEAD_TYPE *list_head;
4313 
4314 	list_head = &recp_list->filt_rules;
4315 	if (recp_list->adv_rule) {
4316 		struct ice_adv_fltr_mgmt_list_entry *list_itr;
4317 
4318 		LIST_FOR_EACH_ENTRY(list_itr, list_head,
4319 				    ice_adv_fltr_mgmt_list_entry,
4320 				    list_entry) {
4321 			if (list_itr->vsi_list_info) {
4322 				map_info = list_itr->vsi_list_info;
4323 				if (ice_is_bit_set(map_info->vsi_map,
4324 						   vsi_handle)) {
4325 					*vsi_list_id = map_info->vsi_list_id;
4326 					return map_info;
4327 				}
4328 			}
4329 		}
4330 	} else {
4331 		struct ice_fltr_mgmt_list_entry *list_itr;
4332 
4333 		LIST_FOR_EACH_ENTRY(list_itr, list_head,
4334 				    ice_fltr_mgmt_list_entry,
4335 				    list_entry) {
4336 			if (list_itr->vsi_count == 1 &&
4337 			    list_itr->vsi_list_info) {
4338 				map_info = list_itr->vsi_list_info;
4339 				if (ice_is_bit_set(map_info->vsi_map,
4340 						   vsi_handle)) {
4341 					*vsi_list_id = map_info->vsi_list_id;
4342 					return map_info;
4343 				}
4344 			}
4345 		}
4346 	}
4347 	return NULL;
4348 }
4349 
4350 /**
4351  * ice_add_rule_internal - add rule for a given lookup type
4352  * @hw: pointer to the hardware structure
4353  * @recp_list: recipe list for which rule has to be added
4354  * @lport: logic port number on which function add rule
4355  * @f_entry: structure containing MAC forwarding information
4356  *
4357  * Adds or updates the rule lists for a given recipe
4358  */
4359 static enum ice_status
4360 ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4361 		      u8 lport, struct ice_fltr_list_entry *f_entry)
4362 {
4363 	struct ice_fltr_info *new_fltr, *cur_fltr;
4364 	struct ice_fltr_mgmt_list_entry *m_entry;
4365 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4366 	enum ice_status status = ICE_SUCCESS;
4367 
4368 	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4369 		return ICE_ERR_PARAM;
4370 
4371 	/* Load the hw_vsi_id only if the fwd action is fwd to VSI */
4372 	if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI)
4373 		f_entry->fltr_info.fwd_id.hw_vsi_id =
4374 			ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4375 
4376 	rule_lock = &recp_list->filt_rule_lock;
4377 
4378 	ice_acquire_lock(rule_lock);
4379 	new_fltr = &f_entry->fltr_info;
4380 	if (new_fltr->flag & ICE_FLTR_RX)
4381 		new_fltr->src = lport;
4382 	else if (new_fltr->flag & ICE_FLTR_TX)
4383 		new_fltr->src =
4384 			ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4385 
4386 	m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4387 	if (!m_entry) {
4388 		status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4389 		goto exit_add_rule_internal;
4390 	}
4391 
4392 	cur_fltr = &m_entry->fltr_info;
4393 	status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
4394 
4395 exit_add_rule_internal:
4396 	ice_release_lock(rule_lock);
4397 	return status;
4398 }
4399 
4400 /**
4401  * ice_remove_vsi_list_rule
4402  * @hw: pointer to the hardware structure
4403  * @vsi_list_id: VSI list ID generated as part of allocate resource
4404  * @lkup_type: switch rule filter lookup type
4405  *
4406  * The VSI list should be emptied before this function is called to remove the
4407  * VSI list.
4408  */
4409 static enum ice_status
4410 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
4411 			 enum ice_sw_lkup_type lkup_type)
4412 {
4413 	/* Free the vsi_list resource that we allocated. It is assumed that the
4414 	 * list is empty at this point.
4415 	 */
4416 	return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
4417 					    ice_aqc_opc_free_res);
4418 }
4419 
4420 /**
4421  * ice_rem_update_vsi_list
4422  * @hw: pointer to the hardware structure
4423  * @vsi_handle: VSI handle of the VSI to remove
4424  * @fm_list: filter management entry for which the VSI list management needs to
4425  *	     be done
4426  */
4427 static enum ice_status
4428 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
4429 			struct ice_fltr_mgmt_list_entry *fm_list)
4430 {
4431 	enum ice_sw_lkup_type lkup_type;
4432 	enum ice_status status = ICE_SUCCESS;
4433 	u16 vsi_list_id;
4434 
4435 	if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
4436 	    fm_list->vsi_count == 0)
4437 		return ICE_ERR_PARAM;
4438 
4439 	/* A rule with the VSI being removed does not exist */
4440 	if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
4441 		return ICE_ERR_DOES_NOT_EXIST;
4442 
4443 	lkup_type = fm_list->fltr_info.lkup_type;
4444 	vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
4445 	status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
4446 					  ice_aqc_opc_update_sw_rules,
4447 					  lkup_type);
4448 	if (status)
4449 		return status;
4450 
4451 	fm_list->vsi_count--;
4452 	ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
4453 
4454 	if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
4455 		struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
4456 		struct ice_vsi_list_map_info *vsi_list_info =
4457 			fm_list->vsi_list_info;
4458 		u16 rem_vsi_handle;
4459 
4460 		rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
4461 						    ICE_MAX_VSI);
4462 		if (!ice_is_vsi_valid(hw, rem_vsi_handle))
4463 			return ICE_ERR_OUT_OF_RANGE;
4464 
4465 		/* Make sure VSI list is empty before removing it below */
4466 		status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
4467 						  vsi_list_id, true,
4468 						  ice_aqc_opc_update_sw_rules,
4469 						  lkup_type);
4470 		if (status)
4471 			return status;
4472 
4473 		tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
4474 		tmp_fltr_info.fwd_id.hw_vsi_id =
4475 			ice_get_hw_vsi_num(hw, rem_vsi_handle);
4476 		tmp_fltr_info.vsi_handle = rem_vsi_handle;
4477 		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
4478 		if (status) {
4479 			ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
4480 				  tmp_fltr_info.fwd_id.hw_vsi_id, status);
4481 			return status;
4482 		}
4483 
4484 		fm_list->fltr_info = tmp_fltr_info;
4485 	}
4486 
4487 	if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
4488 	    (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
4489 		struct ice_vsi_list_map_info *vsi_list_info =
4490 			fm_list->vsi_list_info;
4491 
4492 		/* Remove the VSI list since it is no longer used */
4493 		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
4494 		if (status) {
4495 			ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
4496 				  vsi_list_id, status);
4497 			return status;
4498 		}
4499 
4500 		LIST_DEL(&vsi_list_info->list_entry);
4501 		ice_free(hw, vsi_list_info);
4502 		fm_list->vsi_list_info = NULL;
4503 	}
4504 
4505 	return status;
4506 }
4507 
4508 /**
4509  * ice_remove_rule_internal - Remove a filter rule of a given type
4510  *
4511  * @hw: pointer to the hardware structure
4512  * @recp_list: recipe list for which the rule needs to removed
4513  * @f_entry: rule entry containing filter information
4514  */
4515 static enum ice_status
4516 ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4517 			 struct ice_fltr_list_entry *f_entry)
4518 {
4519 	struct ice_fltr_mgmt_list_entry *list_elem;
4520 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4521 	enum ice_status status = ICE_SUCCESS;
4522 	bool remove_rule = false;
4523 	u16 vsi_handle;
4524 
4525 	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4526 		return ICE_ERR_PARAM;
4527 	f_entry->fltr_info.fwd_id.hw_vsi_id =
4528 		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4529 
4530 	rule_lock = &recp_list->filt_rule_lock;
4531 	ice_acquire_lock(rule_lock);
4532 	list_elem = ice_find_rule_entry(&recp_list->filt_rules,
4533 					&f_entry->fltr_info);
4534 	if (!list_elem) {
4535 		status = ICE_ERR_DOES_NOT_EXIST;
4536 		goto exit;
4537 	}
4538 
4539 	if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
4540 		remove_rule = true;
4541 	} else if (!list_elem->vsi_list_info) {
4542 		status = ICE_ERR_DOES_NOT_EXIST;
4543 		goto exit;
4544 	} else if (list_elem->vsi_list_info->ref_cnt > 1) {
4545 		/* a ref_cnt > 1 indicates that the vsi_list is being
4546 		 * shared by multiple rules. Decrement the ref_cnt and
4547 		 * remove this rule, but do not modify the list, as it
4548 		 * is in-use by other rules.
4549 		 */
4550 		list_elem->vsi_list_info->ref_cnt--;
4551 		remove_rule = true;
4552 	} else {
4553 		/* a ref_cnt of 1 indicates the vsi_list is only used
4554 		 * by one rule. However, the original removal request is only
4555 		 * for a single VSI. Update the vsi_list first, and only
4556 		 * remove the rule if there are no further VSIs in this list.
4557 		 */
4558 		vsi_handle = f_entry->fltr_info.vsi_handle;
4559 		status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
4560 		if (status)
4561 			goto exit;
4562 		/* if VSI count goes to zero after updating the VSI list */
4563 		if (list_elem->vsi_count == 0)
4564 			remove_rule = true;
4565 	}
4566 
4567 	if (remove_rule) {
4568 		/* Remove the lookup rule */
4569 		struct ice_aqc_sw_rules_elem *s_rule;
4570 
4571 		s_rule = (struct ice_aqc_sw_rules_elem *)
4572 			ice_malloc(hw, ICE_SW_RULE_RX_TX_NO_HDR_SIZE);
4573 		if (!s_rule) {
4574 			status = ICE_ERR_NO_MEMORY;
4575 			goto exit;
4576 		}
4577 
4578 		ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
4579 				 ice_aqc_opc_remove_sw_rules);
4580 
4581 		status = ice_aq_sw_rules(hw, s_rule,
4582 					 ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
4583 					 ice_aqc_opc_remove_sw_rules, NULL);
4584 
4585 		/* Remove a book keeping from the list */
4586 		ice_free(hw, s_rule);
4587 
4588 		if (status)
4589 			goto exit;
4590 
4591 		LIST_DEL(&list_elem->list_entry);
4592 		ice_free(hw, list_elem);
4593 	}
4594 exit:
4595 	ice_release_lock(rule_lock);
4596 	return status;
4597 }
4598 
4599 /**
4600  * ice_aq_get_res_alloc - get allocated resources
4601  * @hw: pointer to the HW struct
4602  * @num_entries: pointer to u16 to store the number of resource entries returned
4603  * @buf: pointer to buffer
4604  * @buf_size: size of buf
4605  * @cd: pointer to command details structure or NULL
4606  *
4607  * The caller-supplied buffer must be large enough to store the resource
4608  * information for all resource types. Each resource type is an
4609  * ice_aqc_get_res_resp_elem structure.
4610  */
4611 enum ice_status
4612 ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries,
4613 		     struct ice_aqc_get_res_resp_elem *buf, u16 buf_size,
4614 		     struct ice_sq_cd *cd)
4615 {
4616 	struct ice_aqc_get_res_alloc *resp;
4617 	enum ice_status status;
4618 	struct ice_aq_desc desc;
4619 
4620 	if (!buf)
4621 		return ICE_ERR_BAD_PTR;
4622 
4623 	if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN)
4624 		return ICE_ERR_INVAL_SIZE;
4625 
4626 	resp = &desc.params.get_res;
4627 
4628 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc);
4629 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4630 
4631 	if (!status && num_entries)
4632 		*num_entries = LE16_TO_CPU(resp->resp_elem_num);
4633 
4634 	return status;
4635 }
4636 
4637 /**
4638  * ice_aq_get_res_descs - get allocated resource descriptors
4639  * @hw: pointer to the hardware structure
4640  * @num_entries: number of resource entries in buffer
4641  * @buf: structure to hold response data buffer
4642  * @buf_size: size of buffer
4643  * @res_type: resource type
4644  * @res_shared: is resource shared
4645  * @desc_id: input - first desc ID to start; output - next desc ID
4646  * @cd: pointer to command details structure or NULL
4647  */
4648 enum ice_status
4649 ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries,
4650 		     struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type,
4651 		     bool res_shared, u16 *desc_id, struct ice_sq_cd *cd)
4652 {
4653 	struct ice_aqc_get_allocd_res_desc *cmd;
4654 	struct ice_aq_desc desc;
4655 	enum ice_status status;
4656 
4657 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
4658 
4659 	cmd = &desc.params.get_res_desc;
4660 
4661 	if (!buf)
4662 		return ICE_ERR_PARAM;
4663 
4664 	if (buf_size != (num_entries * sizeof(*buf)))
4665 		return ICE_ERR_PARAM;
4666 
4667 	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc);
4668 
4669 	cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) &
4670 					 ICE_AQC_RES_TYPE_M) | (res_shared ?
4671 					ICE_AQC_RES_TYPE_FLAG_SHARED : 0));
4672 	cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id);
4673 
4674 	status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4675 	if (!status)
4676 		*desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc);
4677 
4678 	return status;
4679 }
4680 
4681 /**
4682  * ice_add_mac_rule - Add a MAC address based filter rule
4683  * @hw: pointer to the hardware structure
4684  * @m_list: list of MAC addresses and forwarding information
4685  * @sw: pointer to switch info struct for which function add rule
4686  * @lport: logic port number on which function add rule
4687  *
4688  * IMPORTANT: When the ucast_shared flag is set to false and m_list has
4689  * multiple unicast addresses, the function assumes that all the
4690  * addresses are unique in a given add_mac call. It doesn't
4691  * check for duplicates in this case, removing duplicates from a given
4692  * list should be taken care of in the caller of this function.
4693  */
4694 static enum ice_status
4695 ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
4696 		 struct ice_switch_info *sw, u8 lport)
4697 {
4698 	struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC];
4699 	struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
4700 	struct ice_fltr_list_entry *m_list_itr;
4701 	struct LIST_HEAD_TYPE *rule_head;
4702 	u16 total_elem_left, s_rule_size;
4703 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4704 	enum ice_status status = ICE_SUCCESS;
4705 	u16 num_unicast = 0;
4706 	u8 elem_sent;
4707 
4708 	s_rule = NULL;
4709 	rule_lock = &recp_list->filt_rule_lock;
4710 	rule_head = &recp_list->filt_rules;
4711 
4712 	LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4713 			    list_entry) {
4714 		u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
4715 		u16 vsi_handle;
4716 		u16 hw_vsi_id;
4717 
4718 		m_list_itr->fltr_info.flag = ICE_FLTR_TX;
4719 		vsi_handle = m_list_itr->fltr_info.vsi_handle;
4720 		if (!ice_is_vsi_valid(hw, vsi_handle))
4721 			return ICE_ERR_PARAM;
4722 		hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4723 		m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
4724 		/* update the src in case it is VSI num */
4725 		if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
4726 			return ICE_ERR_PARAM;
4727 		m_list_itr->fltr_info.src = hw_vsi_id;
4728 		if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
4729 		    IS_ZERO_ETHER_ADDR(add))
4730 			return ICE_ERR_PARAM;
4731 		if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) {
4732 			/* Don't overwrite the unicast address */
4733 			ice_acquire_lock(rule_lock);
4734 			if (ice_find_rule_entry(rule_head,
4735 						&m_list_itr->fltr_info)) {
4736 				ice_release_lock(rule_lock);
4737 				return ICE_ERR_ALREADY_EXISTS;
4738 			}
4739 			ice_release_lock(rule_lock);
4740 			num_unicast++;
4741 		} else if (IS_MULTICAST_ETHER_ADDR(add) ||
4742 			   (IS_UNICAST_ETHER_ADDR(add) && hw->ucast_shared)) {
4743 			m_list_itr->status =
4744 				ice_add_rule_internal(hw, recp_list, lport,
4745 						      m_list_itr);
4746 			if (m_list_itr->status)
4747 				return m_list_itr->status;
4748 		}
4749 	}
4750 
4751 	ice_acquire_lock(rule_lock);
4752 	/* Exit if no suitable entries were found for adding bulk switch rule */
4753 	if (!num_unicast) {
4754 		status = ICE_SUCCESS;
4755 		goto ice_add_mac_exit;
4756 	}
4757 
4758 	/* Allocate switch rule buffer for the bulk update for unicast */
4759 	s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
4760 	s_rule = (struct ice_aqc_sw_rules_elem *)
4761 		ice_calloc(hw, num_unicast, s_rule_size);
4762 	if (!s_rule) {
4763 		status = ICE_ERR_NO_MEMORY;
4764 		goto ice_add_mac_exit;
4765 	}
4766 
4767 	r_iter = s_rule;
4768 	LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4769 			    list_entry) {
4770 		struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
4771 		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
4772 
4773 		if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
4774 			ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
4775 					 ice_aqc_opc_add_sw_rules);
4776 			r_iter = (struct ice_aqc_sw_rules_elem *)
4777 				((u8 *)r_iter + s_rule_size);
4778 		}
4779 	}
4780 
4781 	/* Call AQ bulk switch rule update for all unicast addresses */
4782 	r_iter = s_rule;
4783 	/* Call AQ switch rule in AQ_MAX chunk */
4784 	for (total_elem_left = num_unicast; total_elem_left > 0;
4785 	     total_elem_left -= elem_sent) {
4786 		struct ice_aqc_sw_rules_elem *entry = r_iter;
4787 
4788 		elem_sent = MIN_T(u8, total_elem_left,
4789 				  (ICE_AQ_MAX_BUF_LEN / s_rule_size));
4790 		status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
4791 					 elem_sent, ice_aqc_opc_add_sw_rules,
4792 					 NULL);
4793 		if (status)
4794 			goto ice_add_mac_exit;
4795 		r_iter = (struct ice_aqc_sw_rules_elem *)
4796 			((u8 *)r_iter + (elem_sent * s_rule_size));
4797 	}
4798 
4799 	/* Fill up rule ID based on the value returned from FW */
4800 	r_iter = s_rule;
4801 	LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4802 			    list_entry) {
4803 		struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
4804 		u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
4805 		struct ice_fltr_mgmt_list_entry *fm_entry;
4806 
4807 		if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
4808 			f_info->fltr_rule_id =
4809 				LE16_TO_CPU(r_iter->pdata.lkup_tx_rx.index);
4810 			f_info->fltr_act = ICE_FWD_TO_VSI;
4811 			/* Create an entry to track this MAC address */
4812 			fm_entry = (struct ice_fltr_mgmt_list_entry *)
4813 				ice_malloc(hw, sizeof(*fm_entry));
4814 			if (!fm_entry) {
4815 				status = ICE_ERR_NO_MEMORY;
4816 				goto ice_add_mac_exit;
4817 			}
4818 			fm_entry->fltr_info = *f_info;
4819 			fm_entry->vsi_count = 1;
4820 			/* The book keeping entries will get removed when
4821 			 * base driver calls remove filter AQ command
4822 			 */
4823 
4824 			LIST_ADD(&fm_entry->list_entry, rule_head);
4825 			r_iter = (struct ice_aqc_sw_rules_elem *)
4826 				((u8 *)r_iter + s_rule_size);
4827 		}
4828 	}
4829 
4830 ice_add_mac_exit:
4831 	ice_release_lock(rule_lock);
4832 	if (s_rule)
4833 		ice_free(hw, s_rule);
4834 	return status;
4835 }
4836 
4837 /**
4838  * ice_add_mac - Add a MAC address based filter rule
4839  * @hw: pointer to the hardware structure
4840  * @m_list: list of MAC addresses and forwarding information
4841  *
4842  * Function add MAC rule for logical port from HW struct
4843  */
4844 enum ice_status ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
4845 {
4846 	if (!m_list || !hw)
4847 		return ICE_ERR_PARAM;
4848 
4849 	return ice_add_mac_rule(hw, m_list, hw->switch_info,
4850 				hw->port_info->lport);
4851 }
4852 
4853 /**
4854  * ice_add_vlan_internal - Add one VLAN based filter rule
4855  * @hw: pointer to the hardware structure
4856  * @recp_list: recipe list for which rule has to be added
4857  * @f_entry: filter entry containing one VLAN information
4858  */
4859 static enum ice_status
4860 ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4861 		      struct ice_fltr_list_entry *f_entry)
4862 {
4863 	struct ice_fltr_mgmt_list_entry *v_list_itr;
4864 	struct ice_fltr_info *new_fltr, *cur_fltr;
4865 	enum ice_sw_lkup_type lkup_type;
4866 	u16 vsi_list_id = 0, vsi_handle;
4867 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4868 	enum ice_status status = ICE_SUCCESS;
4869 
4870 	if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4871 		return ICE_ERR_PARAM;
4872 
4873 	f_entry->fltr_info.fwd_id.hw_vsi_id =
4874 		ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4875 	new_fltr = &f_entry->fltr_info;
4876 
4877 	/* VLAN ID should only be 12 bits */
4878 	if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
4879 		return ICE_ERR_PARAM;
4880 
4881 	if (new_fltr->src_id != ICE_SRC_ID_VSI)
4882 		return ICE_ERR_PARAM;
4883 
4884 	new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
4885 	lkup_type = new_fltr->lkup_type;
4886 	vsi_handle = new_fltr->vsi_handle;
4887 	rule_lock = &recp_list->filt_rule_lock;
4888 	ice_acquire_lock(rule_lock);
4889 	v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4890 	if (!v_list_itr) {
4891 		struct ice_vsi_list_map_info *map_info = NULL;
4892 
4893 		if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
4894 			/* All VLAN pruning rules use a VSI list. Check if
4895 			 * there is already a VSI list containing VSI that we
4896 			 * want to add. If found, use the same vsi_list_id for
4897 			 * this new VLAN rule or else create a new list.
4898 			 */
4899 			map_info = ice_find_vsi_list_entry(recp_list,
4900 							   vsi_handle,
4901 							   &vsi_list_id);
4902 			if (!map_info) {
4903 				status = ice_create_vsi_list_rule(hw,
4904 								  &vsi_handle,
4905 								  1,
4906 								  &vsi_list_id,
4907 								  lkup_type);
4908 				if (status)
4909 					goto exit;
4910 			}
4911 			/* Convert the action to forwarding to a VSI list. */
4912 			new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4913 			new_fltr->fwd_id.vsi_list_id = vsi_list_id;
4914 		}
4915 
4916 		status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4917 		if (!status) {
4918 			v_list_itr = ice_find_rule_entry(&recp_list->filt_rules,
4919 							 new_fltr);
4920 			if (!v_list_itr) {
4921 				status = ICE_ERR_DOES_NOT_EXIST;
4922 				goto exit;
4923 			}
4924 			/* reuse VSI list for new rule and increment ref_cnt */
4925 			if (map_info) {
4926 				v_list_itr->vsi_list_info = map_info;
4927 				map_info->ref_cnt++;
4928 			} else {
4929 				v_list_itr->vsi_list_info =
4930 					ice_create_vsi_list_map(hw, &vsi_handle,
4931 								1, vsi_list_id);
4932 			}
4933 		}
4934 	} else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
4935 		/* Update existing VSI list to add new VSI ID only if it used
4936 		 * by one VLAN rule.
4937 		 */
4938 		cur_fltr = &v_list_itr->fltr_info;
4939 		status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
4940 						 new_fltr);
4941 	} else {
4942 		/* If VLAN rule exists and VSI list being used by this rule is
4943 		 * referenced by more than 1 VLAN rule. Then create a new VSI
4944 		 * list appending previous VSI with new VSI and update existing
4945 		 * VLAN rule to point to new VSI list ID
4946 		 */
4947 		struct ice_fltr_info tmp_fltr;
4948 		u16 vsi_handle_arr[2];
4949 		u16 cur_handle;
4950 
4951 		/* Current implementation only supports reusing VSI list with
4952 		 * one VSI count. We should never hit below condition
4953 		 */
4954 		if (v_list_itr->vsi_count > 1 &&
4955 		    v_list_itr->vsi_list_info->ref_cnt > 1) {
4956 			ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
4957 			status = ICE_ERR_CFG;
4958 			goto exit;
4959 		}
4960 
4961 		cur_handle =
4962 			ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map,
4963 					   ICE_MAX_VSI);
4964 
4965 		/* A rule already exists with the new VSI being added */
4966 		if (cur_handle == vsi_handle) {
4967 			status = ICE_ERR_ALREADY_EXISTS;
4968 			goto exit;
4969 		}
4970 
4971 		vsi_handle_arr[0] = cur_handle;
4972 		vsi_handle_arr[1] = vsi_handle;
4973 		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4974 						  &vsi_list_id, lkup_type);
4975 		if (status)
4976 			goto exit;
4977 
4978 		tmp_fltr = v_list_itr->fltr_info;
4979 		tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
4980 		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4981 		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4982 		/* Update the previous switch rule to a new VSI list which
4983 		 * includes current VSI that is requested
4984 		 */
4985 		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4986 		if (status)
4987 			goto exit;
4988 
4989 		/* before overriding VSI list map info. decrement ref_cnt of
4990 		 * previous VSI list
4991 		 */
4992 		v_list_itr->vsi_list_info->ref_cnt--;
4993 
4994 		/* now update to newly created list */
4995 		v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
4996 		v_list_itr->vsi_list_info =
4997 			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4998 						vsi_list_id);
4999 		v_list_itr->vsi_count++;
5000 	}
5001 
5002 exit:
5003 	ice_release_lock(rule_lock);
5004 	return status;
5005 }
5006 
5007 /**
5008  * ice_add_vlan_rule - Add VLAN based filter rule
5009  * @hw: pointer to the hardware structure
5010  * @v_list: list of VLAN entries and forwarding information
5011  * @sw: pointer to switch info struct for which function add rule
5012  */
5013 static enum ice_status
5014 ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5015 		  struct ice_switch_info *sw)
5016 {
5017 	struct ice_fltr_list_entry *v_list_itr;
5018 	struct ice_sw_recipe *recp_list;
5019 
5020 	recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN];
5021 	LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry,
5022 			    list_entry) {
5023 		if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
5024 			return ICE_ERR_PARAM;
5025 		v_list_itr->fltr_info.flag = ICE_FLTR_TX;
5026 		v_list_itr->status = ice_add_vlan_internal(hw, recp_list,
5027 							   v_list_itr);
5028 		if (v_list_itr->status)
5029 			return v_list_itr->status;
5030 	}
5031 	return ICE_SUCCESS;
5032 }
5033 
5034 /**
5035  * ice_add_vlan - Add a VLAN based filter rule
5036  * @hw: pointer to the hardware structure
5037  * @v_list: list of VLAN and forwarding information
5038  *
5039  * Function add VLAN rule for logical port from HW struct
5040  */
5041 enum ice_status ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5042 {
5043 	if (!v_list || !hw)
5044 		return ICE_ERR_PARAM;
5045 
5046 	return ice_add_vlan_rule(hw, v_list, hw->switch_info);
5047 }
5048 
5049 /**
5050  * ice_add_mac_vlan_rule - Add MAC and VLAN pair based filter rule
5051  * @hw: pointer to the hardware structure
5052  * @mv_list: list of MAC and VLAN filters
5053  * @sw: pointer to switch info struct for which function add rule
5054  * @lport: logic port number on which function add rule
5055  *
5056  * If the VSI on which the MAC-VLAN pair has to be added has Rx and Tx VLAN
5057  * pruning bits enabled, then it is the responsibility of the caller to make
5058  * sure to add a VLAN only filter on the same VSI. Packets belonging to that
5059  * VLAN won't be received on that VSI otherwise.
5060  */
5061 static enum ice_status
5062 ice_add_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list,
5063 		      struct ice_switch_info *sw, u8 lport)
5064 {
5065 	struct ice_fltr_list_entry *mv_list_itr;
5066 	struct ice_sw_recipe *recp_list;
5067 
5068 	if (!mv_list || !hw)
5069 		return ICE_ERR_PARAM;
5070 
5071 	recp_list = &sw->recp_list[ICE_SW_LKUP_MAC_VLAN];
5072 	LIST_FOR_EACH_ENTRY(mv_list_itr, mv_list, ice_fltr_list_entry,
5073 			    list_entry) {
5074 		enum ice_sw_lkup_type l_type =
5075 			mv_list_itr->fltr_info.lkup_type;
5076 
5077 		if (l_type != ICE_SW_LKUP_MAC_VLAN)
5078 			return ICE_ERR_PARAM;
5079 		mv_list_itr->fltr_info.flag = ICE_FLTR_TX;
5080 		mv_list_itr->status =
5081 			ice_add_rule_internal(hw, recp_list, lport,
5082 					      mv_list_itr);
5083 		if (mv_list_itr->status)
5084 			return mv_list_itr->status;
5085 	}
5086 	return ICE_SUCCESS;
5087 }
5088 
5089 /**
5090  * ice_add_mac_vlan - Add a MAC VLAN address based filter rule
5091  * @hw: pointer to the hardware structure
5092  * @mv_list: list of MAC VLAN addresses and forwarding information
5093  *
5094  * Function add MAC VLAN rule for logical port from HW struct
5095  */
5096 enum ice_status
5097 ice_add_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5098 {
5099 	if (!mv_list || !hw)
5100 		return ICE_ERR_PARAM;
5101 
5102 	return ice_add_mac_vlan_rule(hw, mv_list, hw->switch_info,
5103 				     hw->port_info->lport);
5104 }
5105 
5106 /**
5107  * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule
5108  * @hw: pointer to the hardware structure
5109  * @em_list: list of ether type MAC filter, MAC is optional
5110  * @sw: pointer to switch info struct for which function add rule
5111  * @lport: logic port number on which function add rule
5112  *
5113  * This function requires the caller to populate the entries in
5114  * the filter list with the necessary fields (including flags to
5115  * indicate Tx or Rx rules).
5116  */
5117 static enum ice_status
5118 ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5119 		     struct ice_switch_info *sw, u8 lport)
5120 {
5121 	struct ice_fltr_list_entry *em_list_itr;
5122 
5123 	LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry,
5124 			    list_entry) {
5125 		struct ice_sw_recipe *recp_list;
5126 		enum ice_sw_lkup_type l_type;
5127 
5128 		l_type = em_list_itr->fltr_info.lkup_type;
5129 		recp_list = &sw->recp_list[l_type];
5130 
5131 		if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5132 		    l_type != ICE_SW_LKUP_ETHERTYPE)
5133 			return ICE_ERR_PARAM;
5134 
5135 		em_list_itr->status = ice_add_rule_internal(hw, recp_list,
5136 							    lport,
5137 							    em_list_itr);
5138 		if (em_list_itr->status)
5139 			return em_list_itr->status;
5140 	}
5141 	return ICE_SUCCESS;
5142 }
5143 
5144 /**
5145  * ice_add_eth_mac - Add a ethertype based filter rule
5146  * @hw: pointer to the hardware structure
5147  * @em_list: list of ethertype and forwarding information
5148  *
5149  * Function add ethertype rule for logical port from HW struct
5150  */
5151 enum ice_status
5152 ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5153 {
5154 	if (!em_list || !hw)
5155 		return ICE_ERR_PARAM;
5156 
5157 	return ice_add_eth_mac_rule(hw, em_list, hw->switch_info,
5158 				    hw->port_info->lport);
5159 }
5160 
5161 /**
5162  * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule
5163  * @hw: pointer to the hardware structure
5164  * @em_list: list of ethertype or ethertype MAC entries
5165  * @sw: pointer to switch info struct for which function add rule
5166  */
5167 static enum ice_status
5168 ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5169 			struct ice_switch_info *sw)
5170 {
5171 	struct ice_fltr_list_entry *em_list_itr, *tmp;
5172 
5173 	LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry,
5174 				 list_entry) {
5175 		struct ice_sw_recipe *recp_list;
5176 		enum ice_sw_lkup_type l_type;
5177 
5178 		l_type = em_list_itr->fltr_info.lkup_type;
5179 
5180 		if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5181 		    l_type != ICE_SW_LKUP_ETHERTYPE)
5182 			return ICE_ERR_PARAM;
5183 
5184 		recp_list = &sw->recp_list[l_type];
5185 		em_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5186 							       em_list_itr);
5187 		if (em_list_itr->status)
5188 			return em_list_itr->status;
5189 	}
5190 	return ICE_SUCCESS;
5191 }
5192 
5193 /**
5194  * ice_remove_eth_mac - remove a ethertype based filter rule
5195  * @hw: pointer to the hardware structure
5196  * @em_list: list of ethertype and forwarding information
5197  *
5198  */
5199 enum ice_status
5200 ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5201 {
5202 	if (!em_list || !hw)
5203 		return ICE_ERR_PARAM;
5204 
5205 	return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info);
5206 }
5207 
5208 /**
5209  * ice_rem_sw_rule_info
5210  * @hw: pointer to the hardware structure
5211  * @rule_head: pointer to the switch list structure that we want to delete
5212  */
5213 static void
5214 ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5215 {
5216 	if (!LIST_EMPTY(rule_head)) {
5217 		struct ice_fltr_mgmt_list_entry *entry;
5218 		struct ice_fltr_mgmt_list_entry *tmp;
5219 
5220 		LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head,
5221 					 ice_fltr_mgmt_list_entry, list_entry) {
5222 			LIST_DEL(&entry->list_entry);
5223 			ice_free(hw, entry);
5224 		}
5225 	}
5226 }
5227 
5228 /**
5229  * ice_rem_adv_rule_info
5230  * @hw: pointer to the hardware structure
5231  * @rule_head: pointer to the switch list structure that we want to delete
5232  */
5233 static void
5234 ice_rem_adv_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5235 {
5236 	struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
5237 	struct ice_adv_fltr_mgmt_list_entry *lst_itr;
5238 
5239 	if (LIST_EMPTY(rule_head))
5240 		return;
5241 
5242 	LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry, rule_head,
5243 				 ice_adv_fltr_mgmt_list_entry, list_entry) {
5244 		LIST_DEL(&lst_itr->list_entry);
5245 		ice_free(hw, lst_itr->lkups);
5246 		ice_free(hw, lst_itr);
5247 	}
5248 }
5249 
5250 /**
5251  * ice_rem_all_sw_rules_info
5252  * @hw: pointer to the hardware structure
5253  */
5254 void ice_rem_all_sw_rules_info(struct ice_hw *hw)
5255 {
5256 	struct ice_switch_info *sw = hw->switch_info;
5257 	u8 i;
5258 
5259 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
5260 		struct LIST_HEAD_TYPE *rule_head;
5261 
5262 		rule_head = &sw->recp_list[i].filt_rules;
5263 		if (!sw->recp_list[i].adv_rule)
5264 			ice_rem_sw_rule_info(hw, rule_head);
5265 		else
5266 			ice_rem_adv_rule_info(hw, rule_head);
5267 		if (sw->recp_list[i].adv_rule &&
5268 		    LIST_EMPTY(&sw->recp_list[i].filt_rules))
5269 			sw->recp_list[i].adv_rule = false;
5270 	}
5271 }
5272 
5273 /**
5274  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
5275  * @pi: pointer to the port_info structure
5276  * @vsi_handle: VSI handle to set as default
5277  * @set: true to add the above mentioned switch rule, false to remove it
5278  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
5279  *
5280  * add filter rule to set/unset given VSI as default VSI for the switch
5281  * (represented by swid)
5282  */
5283 enum ice_status
5284 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
5285 		 u8 direction)
5286 {
5287 	struct ice_aqc_sw_rules_elem *s_rule;
5288 	struct ice_fltr_info f_info;
5289 	struct ice_hw *hw = pi->hw;
5290 	enum ice_adminq_opc opcode;
5291 	enum ice_status status;
5292 	u16 s_rule_size;
5293 	u16 hw_vsi_id;
5294 
5295 	if (!ice_is_vsi_valid(hw, vsi_handle))
5296 		return ICE_ERR_PARAM;
5297 	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5298 
5299 	s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
5300 		ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
5301 
5302 	s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
5303 	if (!s_rule)
5304 		return ICE_ERR_NO_MEMORY;
5305 
5306 	ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM);
5307 
5308 	f_info.lkup_type = ICE_SW_LKUP_DFLT;
5309 	f_info.flag = direction;
5310 	f_info.fltr_act = ICE_FWD_TO_VSI;
5311 	f_info.fwd_id.hw_vsi_id = hw_vsi_id;
5312 
5313 	if (f_info.flag & ICE_FLTR_RX) {
5314 		f_info.src = pi->lport;
5315 		f_info.src_id = ICE_SRC_ID_LPORT;
5316 		if (!set)
5317 			f_info.fltr_rule_id =
5318 				pi->dflt_rx_vsi_rule_id;
5319 	} else if (f_info.flag & ICE_FLTR_TX) {
5320 		f_info.src_id = ICE_SRC_ID_VSI;
5321 		f_info.src = hw_vsi_id;
5322 		if (!set)
5323 			f_info.fltr_rule_id =
5324 				pi->dflt_tx_vsi_rule_id;
5325 	}
5326 
5327 	if (set)
5328 		opcode = ice_aqc_opc_add_sw_rules;
5329 	else
5330 		opcode = ice_aqc_opc_remove_sw_rules;
5331 
5332 	ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
5333 
5334 	status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
5335 	if (status || !(f_info.flag & ICE_FLTR_TX_RX))
5336 		goto out;
5337 	if (set) {
5338 		u16 index = LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
5339 
5340 		if (f_info.flag & ICE_FLTR_TX) {
5341 			pi->dflt_tx_vsi_num = hw_vsi_id;
5342 			pi->dflt_tx_vsi_rule_id = index;
5343 		} else if (f_info.flag & ICE_FLTR_RX) {
5344 			pi->dflt_rx_vsi_num = hw_vsi_id;
5345 			pi->dflt_rx_vsi_rule_id = index;
5346 		}
5347 	} else {
5348 		if (f_info.flag & ICE_FLTR_TX) {
5349 			pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
5350 			pi->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
5351 		} else if (f_info.flag & ICE_FLTR_RX) {
5352 			pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
5353 			pi->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
5354 		}
5355 	}
5356 
5357 out:
5358 	ice_free(hw, s_rule);
5359 	return status;
5360 }
5361 
5362 /**
5363  * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
5364  * @list_head: head of rule list
5365  * @f_info: rule information
5366  *
5367  * Helper function to search for a unicast rule entry - this is to be used
5368  * to remove unicast MAC filter that is not shared with other VSIs on the
5369  * PF switch.
5370  *
5371  * Returns pointer to entry storing the rule if found
5372  */
5373 static struct ice_fltr_mgmt_list_entry *
5374 ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head,
5375 			  struct ice_fltr_info *f_info)
5376 {
5377 	struct ice_fltr_mgmt_list_entry *list_itr;
5378 
5379 	LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
5380 			    list_entry) {
5381 		if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
5382 			    sizeof(f_info->l_data)) &&
5383 		    f_info->fwd_id.hw_vsi_id ==
5384 		    list_itr->fltr_info.fwd_id.hw_vsi_id &&
5385 		    f_info->flag == list_itr->fltr_info.flag)
5386 			return list_itr;
5387 	}
5388 	return NULL;
5389 }
5390 
5391 /**
5392  * ice_remove_mac_rule - remove a MAC based filter rule
5393  * @hw: pointer to the hardware structure
5394  * @m_list: list of MAC addresses and forwarding information
5395  * @recp_list: list from which function remove MAC address
5396  *
5397  * This function removes either a MAC filter rule or a specific VSI from a
5398  * VSI list for a multicast MAC address.
5399  *
5400  * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
5401  * ice_add_mac. Caller should be aware that this call will only work if all
5402  * the entries passed into m_list were added previously. It will not attempt to
5403  * do a partial remove of entries that were found.
5404  */
5405 static enum ice_status
5406 ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5407 		    struct ice_sw_recipe *recp_list)
5408 {
5409 	struct ice_fltr_list_entry *list_itr, *tmp;
5410 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5411 
5412 	if (!m_list)
5413 		return ICE_ERR_PARAM;
5414 
5415 	rule_lock = &recp_list->filt_rule_lock;
5416 	LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry,
5417 				 list_entry) {
5418 		enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
5419 		u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
5420 		u16 vsi_handle;
5421 
5422 		if (l_type != ICE_SW_LKUP_MAC)
5423 			return ICE_ERR_PARAM;
5424 
5425 		vsi_handle = list_itr->fltr_info.vsi_handle;
5426 		if (!ice_is_vsi_valid(hw, vsi_handle))
5427 			return ICE_ERR_PARAM;
5428 
5429 		list_itr->fltr_info.fwd_id.hw_vsi_id =
5430 					ice_get_hw_vsi_num(hw, vsi_handle);
5431 		if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) {
5432 			/* Don't remove the unicast address that belongs to
5433 			 * another VSI on the switch, since it is not being
5434 			 * shared...
5435 			 */
5436 			ice_acquire_lock(rule_lock);
5437 			if (!ice_find_ucast_rule_entry(&recp_list->filt_rules,
5438 						       &list_itr->fltr_info)) {
5439 				ice_release_lock(rule_lock);
5440 				return ICE_ERR_DOES_NOT_EXIST;
5441 			}
5442 			ice_release_lock(rule_lock);
5443 		}
5444 		list_itr->status = ice_remove_rule_internal(hw, recp_list,
5445 							    list_itr);
5446 		if (list_itr->status)
5447 			return list_itr->status;
5448 	}
5449 	return ICE_SUCCESS;
5450 }
5451 
5452 /**
5453  * ice_remove_mac - remove a MAC address based filter rule
5454  * @hw: pointer to the hardware structure
5455  * @m_list: list of MAC addresses and forwarding information
5456  *
5457  */
5458 enum ice_status ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5459 {
5460 	struct ice_sw_recipe *recp_list;
5461 
5462 	recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
5463 	return ice_remove_mac_rule(hw, m_list, recp_list);
5464 }
5465 
5466 /**
5467  * ice_remove_vlan_rule - Remove VLAN based filter rule
5468  * @hw: pointer to the hardware structure
5469  * @v_list: list of VLAN entries and forwarding information
5470  * @recp_list: list from which function remove VLAN
5471  */
5472 static enum ice_status
5473 ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5474 		     struct ice_sw_recipe *recp_list)
5475 {
5476 	struct ice_fltr_list_entry *v_list_itr, *tmp;
5477 
5478 	LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5479 				 list_entry) {
5480 		enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5481 
5482 		if (l_type != ICE_SW_LKUP_VLAN)
5483 			return ICE_ERR_PARAM;
5484 		v_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5485 							      v_list_itr);
5486 		if (v_list_itr->status)
5487 			return v_list_itr->status;
5488 	}
5489 	return ICE_SUCCESS;
5490 }
5491 
5492 /**
5493  * ice_remove_vlan - remove a VLAN address based filter rule
5494  * @hw: pointer to the hardware structure
5495  * @v_list: list of VLAN and forwarding information
5496  *
5497  */
5498 enum ice_status
5499 ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5500 {
5501 	struct ice_sw_recipe *recp_list;
5502 
5503 	if (!v_list || !hw)
5504 		return ICE_ERR_PARAM;
5505 
5506 	recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN];
5507 	return ice_remove_vlan_rule(hw, v_list, recp_list);
5508 }
5509 
5510 /**
5511  * ice_remove_mac_vlan_rule - Remove MAC VLAN based filter rule
5512  * @hw: pointer to the hardware structure
5513  * @v_list: list of MAC VLAN entries and forwarding information
5514  * @recp_list: list from which function remove MAC VLAN
5515  */
5516 static enum ice_status
5517 ice_remove_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5518 			 struct ice_sw_recipe *recp_list)
5519 {
5520 	struct ice_fltr_list_entry *v_list_itr, *tmp;
5521 
5522 	recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
5523 	LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5524 				 list_entry) {
5525 		enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5526 
5527 		if (l_type != ICE_SW_LKUP_MAC_VLAN)
5528 			return ICE_ERR_PARAM;
5529 		v_list_itr->status =
5530 			ice_remove_rule_internal(hw, recp_list,
5531 						 v_list_itr);
5532 		if (v_list_itr->status)
5533 			return v_list_itr->status;
5534 	}
5535 	return ICE_SUCCESS;
5536 }
5537 
5538 /**
5539  * ice_remove_mac_vlan - remove a MAC VLAN address based filter rule
5540  * @hw: pointer to the hardware structure
5541  * @mv_list: list of MAC VLAN and forwarding information
5542  */
5543 enum ice_status
5544 ice_remove_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5545 {
5546 	struct ice_sw_recipe *recp_list;
5547 
5548 	if (!mv_list || !hw)
5549 		return ICE_ERR_PARAM;
5550 
5551 	recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
5552 	return ice_remove_mac_vlan_rule(hw, mv_list, recp_list);
5553 }
5554 
5555 /**
5556  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
5557  * @fm_entry: filter entry to inspect
5558  * @vsi_handle: VSI handle to compare with filter info
5559  */
5560 static bool
5561 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
5562 {
5563 	return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
5564 		 fm_entry->fltr_info.vsi_handle == vsi_handle) ||
5565 		(fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
5566 		 fm_entry->vsi_list_info &&
5567 		 (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map,
5568 				 vsi_handle))));
5569 }
5570 
5571 /**
5572  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
5573  * @hw: pointer to the hardware structure
5574  * @vsi_handle: VSI handle to remove filters from
5575  * @vsi_list_head: pointer to the list to add entry to
5576  * @fi: pointer to fltr_info of filter entry to copy & add
5577  *
5578  * Helper function, used when creating a list of filters to remove from
5579  * a specific VSI. The entry added to vsi_list_head is a COPY of the
5580  * original filter entry, with the exception of fltr_info.fltr_act and
5581  * fltr_info.fwd_id fields. These are set such that later logic can
5582  * extract which VSI to remove the fltr from, and pass on that information.
5583  */
5584 static enum ice_status
5585 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
5586 			       struct LIST_HEAD_TYPE *vsi_list_head,
5587 			       struct ice_fltr_info *fi)
5588 {
5589 	struct ice_fltr_list_entry *tmp;
5590 
5591 	/* this memory is freed up in the caller function
5592 	 * once filters for this VSI are removed
5593 	 */
5594 	tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp));
5595 	if (!tmp)
5596 		return ICE_ERR_NO_MEMORY;
5597 
5598 	tmp->fltr_info = *fi;
5599 
5600 	/* Overwrite these fields to indicate which VSI to remove filter from,
5601 	 * so find and remove logic can extract the information from the
5602 	 * list entries. Note that original entries will still have proper
5603 	 * values.
5604 	 */
5605 	tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
5606 	tmp->fltr_info.vsi_handle = vsi_handle;
5607 	tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5608 
5609 	LIST_ADD(&tmp->list_entry, vsi_list_head);
5610 
5611 	return ICE_SUCCESS;
5612 }
5613 
5614 /**
5615  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
5616  * @hw: pointer to the hardware structure
5617  * @vsi_handle: VSI handle to remove filters from
5618  * @lkup_list_head: pointer to the list that has certain lookup type filters
5619  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
5620  *
5621  * Locates all filters in lkup_list_head that are used by the given VSI,
5622  * and adds COPIES of those entries to vsi_list_head (intended to be used
5623  * to remove the listed filters).
5624  * Note that this means all entries in vsi_list_head must be explicitly
5625  * deallocated by the caller when done with list.
5626  */
5627 static enum ice_status
5628 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
5629 			 struct LIST_HEAD_TYPE *lkup_list_head,
5630 			 struct LIST_HEAD_TYPE *vsi_list_head)
5631 {
5632 	struct ice_fltr_mgmt_list_entry *fm_entry;
5633 	enum ice_status status = ICE_SUCCESS;
5634 
5635 	/* check to make sure VSI ID is valid and within boundary */
5636 	if (!ice_is_vsi_valid(hw, vsi_handle))
5637 		return ICE_ERR_PARAM;
5638 
5639 	LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head,
5640 			    ice_fltr_mgmt_list_entry, list_entry) {
5641 		if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
5642 			continue;
5643 
5644 		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
5645 							vsi_list_head,
5646 							&fm_entry->fltr_info);
5647 		if (status)
5648 			return status;
5649 	}
5650 	return status;
5651 }
5652 
5653 /**
5654  * ice_determine_promisc_mask
5655  * @fi: filter info to parse
5656  *
5657  * Helper function to determine which ICE_PROMISC_ mask corresponds
5658  * to given filter into.
5659  */
5660 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
5661 {
5662 	u16 vid = fi->l_data.mac_vlan.vlan_id;
5663 	u8 *macaddr = fi->l_data.mac.mac_addr;
5664 	bool is_tx_fltr = false;
5665 	u8 promisc_mask = 0;
5666 
5667 	if (fi->flag == ICE_FLTR_TX)
5668 		is_tx_fltr = true;
5669 
5670 	if (IS_BROADCAST_ETHER_ADDR(macaddr))
5671 		promisc_mask |= is_tx_fltr ?
5672 			ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
5673 	else if (IS_MULTICAST_ETHER_ADDR(macaddr))
5674 		promisc_mask |= is_tx_fltr ?
5675 			ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
5676 	else if (IS_UNICAST_ETHER_ADDR(macaddr))
5677 		promisc_mask |= is_tx_fltr ?
5678 			ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
5679 	if (vid)
5680 		promisc_mask |= is_tx_fltr ?
5681 			ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
5682 
5683 	return promisc_mask;
5684 }
5685 
5686 /**
5687  * _ice_get_vsi_promisc - get promiscuous mode of given VSI
5688  * @hw: pointer to the hardware structure
5689  * @vsi_handle: VSI handle to retrieve info from
5690  * @promisc_mask: pointer to mask to be filled in
5691  * @vid: VLAN ID of promisc VLAN VSI
5692  * @sw: pointer to switch info struct for which function add rule
5693  */
5694 static enum ice_status
5695 _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5696 		     u16 *vid, struct ice_switch_info *sw)
5697 {
5698 	struct ice_fltr_mgmt_list_entry *itr;
5699 	struct LIST_HEAD_TYPE *rule_head;
5700 	struct ice_lock *rule_lock;	/* Lock to protect filter rule list */
5701 
5702 	if (!ice_is_vsi_valid(hw, vsi_handle))
5703 		return ICE_ERR_PARAM;
5704 
5705 	*vid = 0;
5706 	*promisc_mask = 0;
5707 	rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rules;
5708 	rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rule_lock;
5709 
5710 	ice_acquire_lock(rule_lock);
5711 	LIST_FOR_EACH_ENTRY(itr, rule_head,
5712 			    ice_fltr_mgmt_list_entry, list_entry) {
5713 		/* Continue if this filter doesn't apply to this VSI or the
5714 		 * VSI ID is not in the VSI map for this filter
5715 		 */
5716 		if (!ice_vsi_uses_fltr(itr, vsi_handle))
5717 			continue;
5718 
5719 		*promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
5720 	}
5721 	ice_release_lock(rule_lock);
5722 
5723 	return ICE_SUCCESS;
5724 }
5725 
5726 /**
5727  * ice_get_vsi_promisc - get promiscuous mode of given VSI
5728  * @hw: pointer to the hardware structure
5729  * @vsi_handle: VSI handle to retrieve info from
5730  * @promisc_mask: pointer to mask to be filled in
5731  * @vid: VLAN ID of promisc VLAN VSI
5732  */
5733 enum ice_status
5734 ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5735 		    u16 *vid)
5736 {
5737 	return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
5738 				    vid, hw->switch_info);
5739 }
5740 
5741 /**
5742  * _ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
5743  * @hw: pointer to the hardware structure
5744  * @vsi_handle: VSI handle to retrieve info from
5745  * @promisc_mask: pointer to mask to be filled in
5746  * @vid: VLAN ID of promisc VLAN VSI
5747  * @sw: pointer to switch info struct for which function add rule
5748  */
5749 static enum ice_status
5750 _ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5751 			  u16 *vid, struct ice_switch_info *sw)
5752 {
5753 	struct ice_fltr_mgmt_list_entry *itr;
5754 	struct LIST_HEAD_TYPE *rule_head;
5755 	struct ice_lock *rule_lock;	/* Lock to protect filter rule list */
5756 
5757 	if (!ice_is_vsi_valid(hw, vsi_handle))
5758 		return ICE_ERR_PARAM;
5759 
5760 	*vid = 0;
5761 	*promisc_mask = 0;
5762 	rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rules;
5763 	rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rule_lock;
5764 
5765 	ice_acquire_lock(rule_lock);
5766 	LIST_FOR_EACH_ENTRY(itr, rule_head, ice_fltr_mgmt_list_entry,
5767 			    list_entry) {
5768 		/* Continue if this filter doesn't apply to this VSI or the
5769 		 * VSI ID is not in the VSI map for this filter
5770 		 */
5771 		if (!ice_vsi_uses_fltr(itr, vsi_handle))
5772 			continue;
5773 
5774 		*promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
5775 	}
5776 	ice_release_lock(rule_lock);
5777 
5778 	return ICE_SUCCESS;
5779 }
5780 
5781 /**
5782  * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
5783  * @hw: pointer to the hardware structure
5784  * @vsi_handle: VSI handle to retrieve info from
5785  * @promisc_mask: pointer to mask to be filled in
5786  * @vid: VLAN ID of promisc VLAN VSI
5787  */
5788 enum ice_status
5789 ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5790 			 u16 *vid)
5791 {
5792 	return _ice_get_vsi_vlan_promisc(hw, vsi_handle, promisc_mask,
5793 					 vid, hw->switch_info);
5794 }
5795 
5796 /**
5797  * ice_remove_promisc - Remove promisc based filter rules
5798  * @hw: pointer to the hardware structure
5799  * @recp_id: recipe ID for which the rule needs to removed
5800  * @v_list: list of promisc entries
5801  */
5802 static enum ice_status
5803 ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
5804 		   struct LIST_HEAD_TYPE *v_list)
5805 {
5806 	struct ice_fltr_list_entry *v_list_itr, *tmp;
5807 	struct ice_sw_recipe *recp_list;
5808 
5809 	recp_list = &hw->switch_info->recp_list[recp_id];
5810 	LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5811 				 list_entry) {
5812 		v_list_itr->status =
5813 			ice_remove_rule_internal(hw, recp_list, v_list_itr);
5814 		if (v_list_itr->status)
5815 			return v_list_itr->status;
5816 	}
5817 	return ICE_SUCCESS;
5818 }
5819 
5820 /**
5821  * _ice_clear_vsi_promisc - clear specified promiscuous mode(s)
5822  * @hw: pointer to the hardware structure
5823  * @vsi_handle: VSI handle to clear mode
5824  * @promisc_mask: mask of promiscuous config bits to clear
5825  * @vid: VLAN ID to clear VLAN promiscuous
5826  * @sw: pointer to switch info struct for which function add rule
5827  */
5828 static enum ice_status
5829 _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5830 		       u16 vid, struct ice_switch_info *sw)
5831 {
5832 	struct ice_fltr_list_entry *fm_entry, *tmp;
5833 	struct LIST_HEAD_TYPE remove_list_head;
5834 	struct ice_fltr_mgmt_list_entry *itr;
5835 	struct LIST_HEAD_TYPE *rule_head;
5836 	struct ice_lock *rule_lock;	/* Lock to protect filter rule list */
5837 	enum ice_status status = ICE_SUCCESS;
5838 	u8 recipe_id;
5839 
5840 	if (!ice_is_vsi_valid(hw, vsi_handle))
5841 		return ICE_ERR_PARAM;
5842 
5843 	if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
5844 		recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
5845 	else
5846 		recipe_id = ICE_SW_LKUP_PROMISC;
5847 
5848 	rule_head = &sw->recp_list[recipe_id].filt_rules;
5849 	rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
5850 
5851 	INIT_LIST_HEAD(&remove_list_head);
5852 
5853 	ice_acquire_lock(rule_lock);
5854 	LIST_FOR_EACH_ENTRY(itr, rule_head,
5855 			    ice_fltr_mgmt_list_entry, list_entry) {
5856 		struct ice_fltr_info *fltr_info;
5857 		u8 fltr_promisc_mask = 0;
5858 
5859 		if (!ice_vsi_uses_fltr(itr, vsi_handle))
5860 			continue;
5861 		fltr_info = &itr->fltr_info;
5862 
5863 		if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
5864 		    vid != fltr_info->l_data.mac_vlan.vlan_id)
5865 			continue;
5866 
5867 		fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
5868 
5869 		/* Skip if filter is not completely specified by given mask */
5870 		if (fltr_promisc_mask & ~promisc_mask)
5871 			continue;
5872 
5873 		status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
5874 							&remove_list_head,
5875 							fltr_info);
5876 		if (status) {
5877 			ice_release_lock(rule_lock);
5878 			goto free_fltr_list;
5879 		}
5880 	}
5881 	ice_release_lock(rule_lock);
5882 
5883 	status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
5884 
5885 free_fltr_list:
5886 	LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
5887 				 ice_fltr_list_entry, list_entry) {
5888 		LIST_DEL(&fm_entry->list_entry);
5889 		ice_free(hw, fm_entry);
5890 	}
5891 
5892 	return status;
5893 }
5894 
5895 /**
5896  * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
5897  * @hw: pointer to the hardware structure
5898  * @vsi_handle: VSI handle to clear mode
5899  * @promisc_mask: mask of promiscuous config bits to clear
5900  * @vid: VLAN ID to clear VLAN promiscuous
5901  */
5902 enum ice_status
5903 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
5904 		      u8 promisc_mask, u16 vid)
5905 {
5906 	return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask,
5907 				      vid, hw->switch_info);
5908 }
5909 
5910 /**
5911  * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
5912  * @hw: pointer to the hardware structure
5913  * @vsi_handle: VSI handle to configure
5914  * @promisc_mask: mask of promiscuous config bits
5915  * @vid: VLAN ID to set VLAN promiscuous
5916  * @lport: logical port number to configure promisc mode
5917  * @sw: pointer to switch info struct for which function add rule
5918  */
5919 static enum ice_status
5920 _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5921 		     u16 vid, u8 lport, struct ice_switch_info *sw)
5922 {
5923 	enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
5924 	struct ice_fltr_list_entry f_list_entry;
5925 	struct ice_fltr_info new_fltr;
5926 	enum ice_status status = ICE_SUCCESS;
5927 	bool is_tx_fltr;
5928 	u16 hw_vsi_id;
5929 	int pkt_type;
5930 	u8 recipe_id;
5931 
5932 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
5933 
5934 	if (!ice_is_vsi_valid(hw, vsi_handle))
5935 		return ICE_ERR_PARAM;
5936 	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5937 
5938 	ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM);
5939 
5940 	if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
5941 		new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
5942 		new_fltr.l_data.mac_vlan.vlan_id = vid;
5943 		recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
5944 	} else {
5945 		new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
5946 		recipe_id = ICE_SW_LKUP_PROMISC;
5947 	}
5948 
5949 	/* Separate filters must be set for each direction/packet type
5950 	 * combination, so we will loop over the mask value, store the
5951 	 * individual type, and clear it out in the input mask as it
5952 	 * is found.
5953 	 */
5954 	while (promisc_mask) {
5955 		struct ice_sw_recipe *recp_list;
5956 		u8 *mac_addr;
5957 
5958 		pkt_type = 0;
5959 		is_tx_fltr = false;
5960 
5961 		if (promisc_mask & ICE_PROMISC_UCAST_RX) {
5962 			promisc_mask &= ~ICE_PROMISC_UCAST_RX;
5963 			pkt_type = UCAST_FLTR;
5964 		} else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
5965 			promisc_mask &= ~ICE_PROMISC_UCAST_TX;
5966 			pkt_type = UCAST_FLTR;
5967 			is_tx_fltr = true;
5968 		} else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
5969 			promisc_mask &= ~ICE_PROMISC_MCAST_RX;
5970 			pkt_type = MCAST_FLTR;
5971 		} else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
5972 			promisc_mask &= ~ICE_PROMISC_MCAST_TX;
5973 			pkt_type = MCAST_FLTR;
5974 			is_tx_fltr = true;
5975 		} else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
5976 			promisc_mask &= ~ICE_PROMISC_BCAST_RX;
5977 			pkt_type = BCAST_FLTR;
5978 		} else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
5979 			promisc_mask &= ~ICE_PROMISC_BCAST_TX;
5980 			pkt_type = BCAST_FLTR;
5981 			is_tx_fltr = true;
5982 		}
5983 
5984 		/* Check for VLAN promiscuous flag */
5985 		if (promisc_mask & ICE_PROMISC_VLAN_RX) {
5986 			promisc_mask &= ~ICE_PROMISC_VLAN_RX;
5987 		} else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
5988 			promisc_mask &= ~ICE_PROMISC_VLAN_TX;
5989 			is_tx_fltr = true;
5990 		}
5991 
5992 		/* Set filter DA based on packet type */
5993 		mac_addr = new_fltr.l_data.mac.mac_addr;
5994 		if (pkt_type == BCAST_FLTR) {
5995 			ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM);
5996 		} else if (pkt_type == MCAST_FLTR ||
5997 			   pkt_type == UCAST_FLTR) {
5998 			/* Use the dummy ether header DA */
5999 			ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN,
6000 				   ICE_NONDMA_TO_NONDMA);
6001 			if (pkt_type == MCAST_FLTR)
6002 				mac_addr[0] |= 0x1;	/* Set multicast bit */
6003 		}
6004 
6005 		/* Need to reset this to zero for all iterations */
6006 		new_fltr.flag = 0;
6007 		if (is_tx_fltr) {
6008 			new_fltr.flag |= ICE_FLTR_TX;
6009 			new_fltr.src = hw_vsi_id;
6010 		} else {
6011 			new_fltr.flag |= ICE_FLTR_RX;
6012 			new_fltr.src = lport;
6013 		}
6014 
6015 		new_fltr.fltr_act = ICE_FWD_TO_VSI;
6016 		new_fltr.vsi_handle = vsi_handle;
6017 		new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
6018 		f_list_entry.fltr_info = new_fltr;
6019 		recp_list = &sw->recp_list[recipe_id];
6020 
6021 		status = ice_add_rule_internal(hw, recp_list, lport,
6022 					       &f_list_entry);
6023 		if (status != ICE_SUCCESS)
6024 			goto set_promisc_exit;
6025 	}
6026 
6027 set_promisc_exit:
6028 	return status;
6029 }
6030 
6031 /**
6032  * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
6033  * @hw: pointer to the hardware structure
6034  * @vsi_handle: VSI handle to configure
6035  * @promisc_mask: mask of promiscuous config bits
6036  * @vid: VLAN ID to set VLAN promiscuous
6037  */
6038 enum ice_status
6039 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6040 		    u16 vid)
6041 {
6042 	return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid,
6043 				    hw->port_info->lport,
6044 				    hw->switch_info);
6045 }
6046 
6047 /**
6048  * _ice_set_vlan_vsi_promisc
6049  * @hw: pointer to the hardware structure
6050  * @vsi_handle: VSI handle to configure
6051  * @promisc_mask: mask of promiscuous config bits
6052  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6053  * @lport: logical port number to configure promisc mode
6054  * @sw: pointer to switch info struct for which function add rule
6055  *
6056  * Configure VSI with all associated VLANs to given promiscuous mode(s)
6057  */
6058 static enum ice_status
6059 _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6060 			  bool rm_vlan_promisc, u8 lport,
6061 			  struct ice_switch_info *sw)
6062 {
6063 	struct ice_fltr_list_entry *list_itr, *tmp;
6064 	struct LIST_HEAD_TYPE vsi_list_head;
6065 	struct LIST_HEAD_TYPE *vlan_head;
6066 	struct ice_lock *vlan_lock; /* Lock to protect filter rule list */
6067 	enum ice_status status;
6068 	u16 vlan_id;
6069 
6070 	INIT_LIST_HEAD(&vsi_list_head);
6071 	vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
6072 	vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
6073 	ice_acquire_lock(vlan_lock);
6074 	status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
6075 					  &vsi_list_head);
6076 	ice_release_lock(vlan_lock);
6077 	if (status)
6078 		goto free_fltr_list;
6079 
6080 	LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry,
6081 			    list_entry) {
6082 		vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
6083 		if (rm_vlan_promisc)
6084 			status =  _ice_clear_vsi_promisc(hw, vsi_handle,
6085 							 promisc_mask,
6086 							 vlan_id, sw);
6087 		else
6088 			status =  _ice_set_vsi_promisc(hw, vsi_handle,
6089 						       promisc_mask, vlan_id,
6090 						       lport, sw);
6091 		if (status)
6092 			break;
6093 	}
6094 
6095 free_fltr_list:
6096 	LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head,
6097 				 ice_fltr_list_entry, list_entry) {
6098 		LIST_DEL(&list_itr->list_entry);
6099 		ice_free(hw, list_itr);
6100 	}
6101 	return status;
6102 }
6103 
6104 /**
6105  * ice_set_vlan_vsi_promisc
6106  * @hw: pointer to the hardware structure
6107  * @vsi_handle: VSI handle to configure
6108  * @promisc_mask: mask of promiscuous config bits
6109  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6110  *
6111  * Configure VSI with all associated VLANs to given promiscuous mode(s)
6112  */
6113 enum ice_status
6114 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6115 			 bool rm_vlan_promisc)
6116 {
6117 	return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask,
6118 					 rm_vlan_promisc, hw->port_info->lport,
6119 					 hw->switch_info);
6120 }
6121 
6122 /**
6123  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
6124  * @hw: pointer to the hardware structure
6125  * @vsi_handle: VSI handle to remove filters from
6126  * @recp_list: recipe list from which function remove fltr
6127  * @lkup: switch rule filter lookup type
6128  */
6129 static void
6130 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
6131 			 struct ice_sw_recipe *recp_list,
6132 			 enum ice_sw_lkup_type lkup)
6133 {
6134 	struct ice_fltr_list_entry *fm_entry;
6135 	struct LIST_HEAD_TYPE remove_list_head;
6136 	struct LIST_HEAD_TYPE *rule_head;
6137 	struct ice_fltr_list_entry *tmp;
6138 	struct ice_lock *rule_lock;	/* Lock to protect filter rule list */
6139 	enum ice_status status;
6140 
6141 	INIT_LIST_HEAD(&remove_list_head);
6142 	rule_lock = &recp_list[lkup].filt_rule_lock;
6143 	rule_head = &recp_list[lkup].filt_rules;
6144 	ice_acquire_lock(rule_lock);
6145 	status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
6146 					  &remove_list_head);
6147 	ice_release_lock(rule_lock);
6148 	if (status)
6149 		goto free_fltr_list;
6150 
6151 	switch (lkup) {
6152 	case ICE_SW_LKUP_MAC:
6153 		ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]);
6154 		break;
6155 	case ICE_SW_LKUP_VLAN:
6156 		ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]);
6157 		break;
6158 	case ICE_SW_LKUP_PROMISC:
6159 	case ICE_SW_LKUP_PROMISC_VLAN:
6160 		ice_remove_promisc(hw, lkup, &remove_list_head);
6161 		break;
6162 	case ICE_SW_LKUP_MAC_VLAN:
6163 		ice_remove_mac_vlan(hw, &remove_list_head);
6164 		break;
6165 	case ICE_SW_LKUP_ETHERTYPE:
6166 	case ICE_SW_LKUP_ETHERTYPE_MAC:
6167 		ice_remove_eth_mac(hw, &remove_list_head);
6168 		break;
6169 	case ICE_SW_LKUP_DFLT:
6170 		ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n");
6171 		break;
6172 	case ICE_SW_LKUP_LAST:
6173 		ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n");
6174 		break;
6175 	}
6176 
6177 free_fltr_list:
6178 	LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
6179 				 ice_fltr_list_entry, list_entry) {
6180 		LIST_DEL(&fm_entry->list_entry);
6181 		ice_free(hw, fm_entry);
6182 	}
6183 }
6184 
6185 /**
6186  * ice_remove_vsi_fltr_rule - Remove all filters for a VSI
6187  * @hw: pointer to the hardware structure
6188  * @vsi_handle: VSI handle to remove filters from
6189  * @sw: pointer to switch info struct
6190  */
6191 static void
6192 ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle,
6193 			 struct ice_switch_info *sw)
6194 {
6195 	ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6196 
6197 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6198 				 sw->recp_list, ICE_SW_LKUP_MAC);
6199 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6200 				 sw->recp_list, ICE_SW_LKUP_MAC_VLAN);
6201 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6202 				 sw->recp_list, ICE_SW_LKUP_PROMISC);
6203 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6204 				 sw->recp_list, ICE_SW_LKUP_VLAN);
6205 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6206 				 sw->recp_list, ICE_SW_LKUP_DFLT);
6207 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6208 				 sw->recp_list, ICE_SW_LKUP_ETHERTYPE);
6209 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6210 				 sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC);
6211 	ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6212 				 sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN);
6213 }
6214 
6215 /**
6216  * ice_remove_vsi_fltr - Remove all filters for a VSI
6217  * @hw: pointer to the hardware structure
6218  * @vsi_handle: VSI handle to remove filters from
6219  */
6220 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
6221 {
6222 	ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info);
6223 }
6224 
6225 /**
6226  * ice_alloc_res_cntr - allocating resource counter
6227  * @hw: pointer to the hardware structure
6228  * @type: type of resource
6229  * @alloc_shared: if set it is shared else dedicated
6230  * @num_items: number of entries requested for FD resource type
6231  * @counter_id: counter index returned by AQ call
6232  */
6233 enum ice_status
6234 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6235 		   u16 *counter_id)
6236 {
6237 	struct ice_aqc_alloc_free_res_elem *buf;
6238 	enum ice_status status;
6239 	u16 buf_len;
6240 
6241 	/* Allocate resource */
6242 	buf_len = ice_struct_size(buf, elem, 1);
6243 	buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6244 	if (!buf)
6245 		return ICE_ERR_NO_MEMORY;
6246 
6247 	buf->num_elems = CPU_TO_LE16(num_items);
6248 	buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6249 				      ICE_AQC_RES_TYPE_M) | alloc_shared);
6250 
6251 	status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6252 				       ice_aqc_opc_alloc_res, NULL);
6253 	if (status)
6254 		goto exit;
6255 
6256 	*counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp);
6257 
6258 exit:
6259 	ice_free(hw, buf);
6260 	return status;
6261 }
6262 
6263 /**
6264  * ice_free_res_cntr - free resource counter
6265  * @hw: pointer to the hardware structure
6266  * @type: type of resource
6267  * @alloc_shared: if set it is shared else dedicated
6268  * @num_items: number of entries to be freed for FD resource type
6269  * @counter_id: counter ID resource which needs to be freed
6270  */
6271 enum ice_status
6272 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6273 		  u16 counter_id)
6274 {
6275 	struct ice_aqc_alloc_free_res_elem *buf;
6276 	enum ice_status status;
6277 	u16 buf_len;
6278 
6279 	/* Free resource */
6280 	buf_len = ice_struct_size(buf, elem, 1);
6281 	buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6282 	if (!buf)
6283 		return ICE_ERR_NO_MEMORY;
6284 
6285 	buf->num_elems = CPU_TO_LE16(num_items);
6286 	buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6287 				      ICE_AQC_RES_TYPE_M) | alloc_shared);
6288 	buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
6289 
6290 	status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6291 				       ice_aqc_opc_free_res, NULL);
6292 	if (status)
6293 		ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
6294 
6295 	ice_free(hw, buf);
6296 	return status;
6297 }
6298 
6299 /**
6300  * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type
6301  * @hw: pointer to the hardware structure
6302  * @counter_id: returns counter index
6303  */
6304 enum ice_status ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id)
6305 {
6306 	return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6307 				  ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6308 				  counter_id);
6309 }
6310 
6311 /**
6312  * ice_free_vlan_res_counter - Free counter resource for VLAN type
6313  * @hw: pointer to the hardware structure
6314  * @counter_id: counter index to be freed
6315  */
6316 enum ice_status ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id)
6317 {
6318 	return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6319 				 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6320 				 counter_id);
6321 }
6322 
6323 /**
6324  * ice_alloc_res_lg_act - add large action resource
6325  * @hw: pointer to the hardware structure
6326  * @l_id: large action ID to fill it in
6327  * @num_acts: number of actions to hold with a large action entry
6328  */
6329 static enum ice_status
6330 ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts)
6331 {
6332 	struct ice_aqc_alloc_free_res_elem *sw_buf;
6333 	enum ice_status status;
6334 	u16 buf_len;
6335 
6336 	if (num_acts > ICE_MAX_LG_ACT || num_acts == 0)
6337 		return ICE_ERR_PARAM;
6338 
6339 	/* Allocate resource for large action */
6340 	buf_len = ice_struct_size(sw_buf, elem, 1);
6341 	sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6342 	if (!sw_buf)
6343 		return ICE_ERR_NO_MEMORY;
6344 
6345 	sw_buf->num_elems = CPU_TO_LE16(1);
6346 
6347 	/* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1.
6348 	 * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3.
6349 	 * If num_acts is greater than 2, then use
6350 	 * ICE_AQC_RES_TYPE_WIDE_TABLE_4.
6351 	 * The num_acts cannot exceed 4. This was ensured at the
6352 	 * beginning of the function.
6353 	 */
6354 	if (num_acts == 1)
6355 		sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_1);
6356 	else if (num_acts == 2)
6357 		sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_2);
6358 	else
6359 		sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_4);
6360 
6361 	status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
6362 				       ice_aqc_opc_alloc_res, NULL);
6363 	if (!status)
6364 		*l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
6365 
6366 	ice_free(hw, sw_buf);
6367 	return status;
6368 }
6369 
6370 /**
6371  * ice_add_mac_with_sw_marker - add filter with sw marker
6372  * @hw: pointer to the hardware structure
6373  * @f_info: filter info structure containing the MAC filter information
6374  * @sw_marker: sw marker to tag the Rx descriptor with
6375  */
6376 enum ice_status
6377 ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info,
6378 			   u16 sw_marker)
6379 {
6380 	struct ice_fltr_mgmt_list_entry *m_entry;
6381 	struct ice_fltr_list_entry fl_info;
6382 	struct ice_sw_recipe *recp_list;
6383 	struct LIST_HEAD_TYPE l_head;
6384 	struct ice_lock *rule_lock;	/* Lock to protect filter rule list */
6385 	enum ice_status ret;
6386 	bool entry_exists;
6387 	u16 lg_act_id;
6388 
6389 	if (f_info->fltr_act != ICE_FWD_TO_VSI)
6390 		return ICE_ERR_PARAM;
6391 
6392 	if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6393 		return ICE_ERR_PARAM;
6394 
6395 	if (sw_marker == ICE_INVAL_SW_MARKER_ID)
6396 		return ICE_ERR_PARAM;
6397 
6398 	if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6399 		return ICE_ERR_PARAM;
6400 	f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6401 
6402 	/* Add filter if it doesn't exist so then the adding of large
6403 	 * action always results in update
6404 	 */
6405 
6406 	INIT_LIST_HEAD(&l_head);
6407 	fl_info.fltr_info = *f_info;
6408 	LIST_ADD(&fl_info.list_entry, &l_head);
6409 
6410 	entry_exists = false;
6411 	ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6412 			       hw->port_info->lport);
6413 	if (ret == ICE_ERR_ALREADY_EXISTS)
6414 		entry_exists = true;
6415 	else if (ret)
6416 		return ret;
6417 
6418 	recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6419 	rule_lock = &recp_list->filt_rule_lock;
6420 	ice_acquire_lock(rule_lock);
6421 	/* Get the book keeping entry for the filter */
6422 	m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6423 	if (!m_entry)
6424 		goto exit_error;
6425 
6426 	/* If counter action was enabled for this rule then don't enable
6427 	 * sw marker large action
6428 	 */
6429 	if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6430 		ret = ICE_ERR_PARAM;
6431 		goto exit_error;
6432 	}
6433 
6434 	/* if same marker was added before */
6435 	if (m_entry->sw_marker_id == sw_marker) {
6436 		ret = ICE_ERR_ALREADY_EXISTS;
6437 		goto exit_error;
6438 	}
6439 
6440 	/* Allocate a hardware table entry to hold large act. Three actions
6441 	 * for marker based large action
6442 	 */
6443 	ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3);
6444 	if (ret)
6445 		goto exit_error;
6446 
6447 	if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6448 		goto exit_error;
6449 
6450 	/* Update the switch rule to add the marker action */
6451 	ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id);
6452 	if (!ret) {
6453 		ice_release_lock(rule_lock);
6454 		return ret;
6455 	}
6456 
6457 exit_error:
6458 	ice_release_lock(rule_lock);
6459 	/* only remove entry if it did not exist previously */
6460 	if (!entry_exists)
6461 		ret = ice_remove_mac(hw, &l_head);
6462 
6463 	return ret;
6464 }
6465 
6466 /**
6467  * ice_add_mac_with_counter - add filter with counter enabled
6468  * @hw: pointer to the hardware structure
6469  * @f_info: pointer to filter info structure containing the MAC filter
6470  *          information
6471  */
6472 enum ice_status
6473 ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info)
6474 {
6475 	struct ice_fltr_mgmt_list_entry *m_entry;
6476 	struct ice_fltr_list_entry fl_info;
6477 	struct ice_sw_recipe *recp_list;
6478 	struct LIST_HEAD_TYPE l_head;
6479 	struct ice_lock *rule_lock;	/* Lock to protect filter rule list */
6480 	enum ice_status ret;
6481 	bool entry_exist;
6482 	u16 counter_id;
6483 	u16 lg_act_id;
6484 
6485 	if (f_info->fltr_act != ICE_FWD_TO_VSI)
6486 		return ICE_ERR_PARAM;
6487 
6488 	if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6489 		return ICE_ERR_PARAM;
6490 
6491 	if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6492 		return ICE_ERR_PARAM;
6493 	f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6494 	recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6495 
6496 	entry_exist = false;
6497 
6498 	rule_lock = &recp_list->filt_rule_lock;
6499 
6500 	/* Add filter if it doesn't exist so then the adding of large
6501 	 * action always results in update
6502 	 */
6503 	INIT_LIST_HEAD(&l_head);
6504 
6505 	fl_info.fltr_info = *f_info;
6506 	LIST_ADD(&fl_info.list_entry, &l_head);
6507 
6508 	ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6509 			       hw->port_info->lport);
6510 	if (ret == ICE_ERR_ALREADY_EXISTS)
6511 		entry_exist = true;
6512 	else if (ret)
6513 		return ret;
6514 
6515 	ice_acquire_lock(rule_lock);
6516 	m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6517 	if (!m_entry) {
6518 		ret = ICE_ERR_BAD_PTR;
6519 		goto exit_error;
6520 	}
6521 
6522 	/* Don't enable counter for a filter for which sw marker was enabled */
6523 	if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) {
6524 		ret = ICE_ERR_PARAM;
6525 		goto exit_error;
6526 	}
6527 
6528 	/* If a counter was already enabled then don't need to add again */
6529 	if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6530 		ret = ICE_ERR_ALREADY_EXISTS;
6531 		goto exit_error;
6532 	}
6533 
6534 	/* Allocate a hardware table entry to VLAN counter */
6535 	ret = ice_alloc_vlan_res_counter(hw, &counter_id);
6536 	if (ret)
6537 		goto exit_error;
6538 
6539 	/* Allocate a hardware table entry to hold large act. Two actions for
6540 	 * counter based large action
6541 	 */
6542 	ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2);
6543 	if (ret)
6544 		goto exit_error;
6545 
6546 	if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6547 		goto exit_error;
6548 
6549 	/* Update the switch rule to add the counter action */
6550 	ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id);
6551 	if (!ret) {
6552 		ice_release_lock(rule_lock);
6553 		return ret;
6554 	}
6555 
6556 exit_error:
6557 	ice_release_lock(rule_lock);
6558 	/* only remove entry if it did not exist previously */
6559 	if (!entry_exist)
6560 		ret = ice_remove_mac(hw, &l_head);
6561 
6562 	return ret;
6563 }
6564 
6565 /* This is mapping table entry that maps every word within a given protocol
6566  * structure to the real byte offset as per the specification of that
6567  * protocol header.
6568  * for example dst address is 3 words in ethertype header and corresponding
6569  * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
6570  * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
6571  * matching entry describing its field. This needs to be updated if new
6572  * structure is added to that union.
6573  */
6574 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
6575 	{ ICE_MAC_OFOS,		{ 0, 2, 4, 6, 8, 10, 12 } },
6576 	{ ICE_MAC_IL,		{ 0, 2, 4, 6, 8, 10, 12 } },
6577 	{ ICE_ETYPE_OL,		{ 0 } },
6578 	{ ICE_VLAN_OFOS,	{ 0, 2 } },
6579 	{ ICE_IPV4_OFOS,	{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6580 	{ ICE_IPV4_IL,		{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6581 	{ ICE_IPV6_OFOS,	{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6582 				 26, 28, 30, 32, 34, 36, 38 } },
6583 	{ ICE_IPV6_IL,		{ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6584 				 26, 28, 30, 32, 34, 36, 38 } },
6585 	{ ICE_TCP_IL,		{ 0, 2 } },
6586 	{ ICE_UDP_OF,		{ 0, 2 } },
6587 	{ ICE_UDP_ILOS,		{ 0, 2 } },
6588 	{ ICE_SCTP_IL,		{ 0, 2 } },
6589 	{ ICE_VXLAN,		{ 8, 10, 12, 14 } },
6590 	{ ICE_GENEVE,		{ 8, 10, 12, 14 } },
6591 	{ ICE_VXLAN_GPE,	{ 8, 10, 12, 14 } },
6592 	{ ICE_NVGRE,		{ 0, 2, 4, 6 } },
6593 	{ ICE_GTP,		{ 8, 10, 12, 14, 16, 18, 20, 22 } },
6594 	{ ICE_PPPOE,		{ 0, 2, 4, 6 } },
6595 	{ ICE_PFCP,		{ 8, 10, 12, 14, 16, 18, 20, 22 } },
6596 	{ ICE_L2TPV3,		{ 0, 2, 4, 6, 8, 10 } },
6597 	{ ICE_ESP,		{ 0, 2, 4, 6 } },
6598 	{ ICE_AH,		{ 0, 2, 4, 6, 8, 10 } },
6599 	{ ICE_NAT_T,		{ 8, 10, 12, 14 } },
6600 	{ ICE_GTP_NO_PAY,	{ 8, 10, 12, 14 } },
6601 	{ ICE_VLAN_EX,		{ 0, 2 } },
6602 	{ ICE_VLAN_IN,		{ 0, 2 } },
6603 };
6604 
6605 /* The following table describes preferred grouping of recipes.
6606  * If a recipe that needs to be programmed is a superset or matches one of the
6607  * following combinations, then the recipe needs to be chained as per the
6608  * following policy.
6609  */
6610 
6611 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
6612 	{ ICE_MAC_OFOS,		ICE_MAC_OFOS_HW },
6613 	{ ICE_MAC_IL,		ICE_MAC_IL_HW },
6614 	{ ICE_ETYPE_OL,		ICE_ETYPE_OL_HW },
6615 	{ ICE_VLAN_OFOS,	ICE_VLAN_OL_HW },
6616 	{ ICE_IPV4_OFOS,	ICE_IPV4_OFOS_HW },
6617 	{ ICE_IPV4_IL,		ICE_IPV4_IL_HW },
6618 	{ ICE_IPV6_OFOS,	ICE_IPV6_OFOS_HW },
6619 	{ ICE_IPV6_IL,		ICE_IPV6_IL_HW },
6620 	{ ICE_TCP_IL,		ICE_TCP_IL_HW },
6621 	{ ICE_UDP_OF,		ICE_UDP_OF_HW },
6622 	{ ICE_UDP_ILOS,		ICE_UDP_ILOS_HW },
6623 	{ ICE_SCTP_IL,		ICE_SCTP_IL_HW },
6624 	{ ICE_VXLAN,		ICE_UDP_OF_HW },
6625 	{ ICE_GENEVE,		ICE_UDP_OF_HW },
6626 	{ ICE_VXLAN_GPE,	ICE_UDP_OF_HW },
6627 	{ ICE_NVGRE,		ICE_GRE_OF_HW },
6628 	{ ICE_GTP,		ICE_UDP_OF_HW },
6629 	{ ICE_PPPOE,		ICE_PPPOE_HW },
6630 	{ ICE_PFCP,		ICE_UDP_ILOS_HW },
6631 	{ ICE_L2TPV3,		ICE_L2TPV3_HW },
6632 	{ ICE_ESP,		ICE_ESP_HW },
6633 	{ ICE_AH,		ICE_AH_HW },
6634 	{ ICE_NAT_T,		ICE_UDP_ILOS_HW },
6635 	{ ICE_GTP_NO_PAY,	ICE_UDP_ILOS_HW },
6636 	{ ICE_VLAN_EX,		ICE_VLAN_OF_HW },
6637 	{ ICE_VLAN_IN,		ICE_VLAN_OL_HW },
6638 };
6639 
6640 /**
6641  * ice_find_recp - find a recipe
6642  * @hw: pointer to the hardware structure
6643  * @lkup_exts: extension sequence to match
6644  *
6645  * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
6646  */
6647 static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
6648 			 enum ice_sw_tunnel_type tun_type, u32 priority)
6649 {
6650 	bool refresh_required = true;
6651 	struct ice_sw_recipe *recp;
6652 	u8 i;
6653 
6654 	/* Walk through existing recipes to find a match */
6655 	recp = hw->switch_info->recp_list;
6656 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6657 		/* If recipe was not created for this ID, in SW bookkeeping,
6658 		 * check if FW has an entry for this recipe. If the FW has an
6659 		 * entry update it in our SW bookkeeping and continue with the
6660 		 * matching.
6661 		 */
6662 		if (!recp[i].recp_created)
6663 			if (ice_get_recp_frm_fw(hw,
6664 						hw->switch_info->recp_list, i,
6665 						&refresh_required))
6666 				continue;
6667 
6668 		/* Skip inverse action recipes */
6669 		if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
6670 		    ICE_AQ_RECIPE_ACT_INV_ACT)
6671 			continue;
6672 
6673 		/* if number of words we are looking for match */
6674 		if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
6675 			struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
6676 			struct ice_fv_word *be = lkup_exts->fv_words;
6677 			u16 *cr = recp[i].lkup_exts.field_mask;
6678 			u16 *de = lkup_exts->field_mask;
6679 			bool found = true;
6680 			u8 pe, qr;
6681 
6682 			/* ar, cr, and qr are related to the recipe words, while
6683 			 * be, de, and pe are related to the lookup words
6684 			 */
6685 			for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
6686 				for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
6687 				     qr++) {
6688 					if (ar[qr].off == be[pe].off &&
6689 					    ar[qr].prot_id == be[pe].prot_id &&
6690 					    cr[qr] == de[pe])
6691 						/* Found the "pe"th word in the
6692 						 * given recipe
6693 						 */
6694 						break;
6695 				}
6696 				/* After walking through all the words in the
6697 				 * "i"th recipe if "p"th word was not found then
6698 				 * this recipe is not what we are looking for.
6699 				 * So break out from this loop and try the next
6700 				 * recipe
6701 				 */
6702 				if (qr >= recp[i].lkup_exts.n_val_words) {
6703 					found = false;
6704 					break;
6705 				}
6706 			}
6707 			/* If for "i"th recipe the found was never set to false
6708 			 * then it means we found our match
6709 			 */
6710 			if (tun_type == recp[i].tun_type && found &&
6711 			    priority == recp[i].priority)
6712 				return i; /* Return the recipe ID */
6713 		}
6714 	}
6715 	return ICE_MAX_NUM_RECIPES;
6716 }
6717 
6718 /**
6719  * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
6720  *
6721  * As protocol id for outer vlan is different in dvm and svm, if dvm is
6722  * supported protocol array record for outer vlan has to be modified to
6723  * reflect the value proper for DVM.
6724  */
6725 void ice_change_proto_id_to_dvm(void)
6726 {
6727 	u8 i;
6728 
6729 	for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
6730 		if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
6731 		    ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
6732 			ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
6733 }
6734 
6735 /**
6736  * ice_prot_type_to_id - get protocol ID from protocol type
6737  * @type: protocol type
6738  * @id: pointer to variable that will receive the ID
6739  *
6740  * Returns true if found, false otherwise
6741  */
6742 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
6743 {
6744 	u8 i;
6745 
6746 	for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
6747 		if (ice_prot_id_tbl[i].type == type) {
6748 			*id = ice_prot_id_tbl[i].protocol_id;
6749 			return true;
6750 		}
6751 	return false;
6752 }
6753 
6754 /**
6755  * ice_fill_valid_words - count valid words
6756  * @rule: advanced rule with lookup information
6757  * @lkup_exts: byte offset extractions of the words that are valid
6758  *
6759  * calculate valid words in a lookup rule using mask value
6760  */
6761 static u8
6762 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
6763 		     struct ice_prot_lkup_ext *lkup_exts)
6764 {
6765 	u8 j, word, prot_id, ret_val;
6766 
6767 	if (!ice_prot_type_to_id(rule->type, &prot_id))
6768 		return 0;
6769 
6770 	word = lkup_exts->n_val_words;
6771 
6772 	for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
6773 		if (((u16 *)&rule->m_u)[j] &&
6774 		    (size_t)rule->type < ARRAY_SIZE(ice_prot_ext)) {
6775 			/* No more space to accommodate */
6776 			if (word >= ICE_MAX_CHAIN_WORDS)
6777 				return 0;
6778 			lkup_exts->fv_words[word].off =
6779 				ice_prot_ext[rule->type].offs[j];
6780 			lkup_exts->fv_words[word].prot_id =
6781 				ice_prot_id_tbl[rule->type].protocol_id;
6782 			lkup_exts->field_mask[word] =
6783 				BE16_TO_CPU(((_FORCE_ __be16 *)&rule->m_u)[j]);
6784 			word++;
6785 		}
6786 
6787 	ret_val = word - lkup_exts->n_val_words;
6788 	lkup_exts->n_val_words = word;
6789 
6790 	return ret_val;
6791 }
6792 
6793 /**
6794  * ice_create_first_fit_recp_def - Create a recipe grouping
6795  * @hw: pointer to the hardware structure
6796  * @lkup_exts: an array of protocol header extractions
6797  * @rg_list: pointer to a list that stores new recipe groups
6798  * @recp_cnt: pointer to a variable that stores returned number of recipe groups
6799  *
6800  * Using first fit algorithm, take all the words that are still not done
6801  * and start grouping them in 4-word groups. Each group makes up one
6802  * recipe.
6803  */
6804 static enum ice_status
6805 ice_create_first_fit_recp_def(struct ice_hw *hw,
6806 			      struct ice_prot_lkup_ext *lkup_exts,
6807 			      struct LIST_HEAD_TYPE *rg_list,
6808 			      u8 *recp_cnt)
6809 {
6810 	struct ice_pref_recipe_group *grp = NULL;
6811 	u8 j;
6812 
6813 	*recp_cnt = 0;
6814 
6815 	if (!lkup_exts->n_val_words) {
6816 		struct ice_recp_grp_entry *entry;
6817 
6818 		entry = (struct ice_recp_grp_entry *)
6819 			ice_malloc(hw, sizeof(*entry));
6820 		if (!entry)
6821 			return ICE_ERR_NO_MEMORY;
6822 		LIST_ADD(&entry->l_entry, rg_list);
6823 		grp = &entry->r_group;
6824 		(*recp_cnt)++;
6825 		grp->n_val_pairs = 0;
6826 	}
6827 
6828 	/* Walk through every word in the rule to check if it is not done. If so
6829 	 * then this word needs to be part of a new recipe.
6830 	 */
6831 	for (j = 0; j < lkup_exts->n_val_words; j++)
6832 		if (!ice_is_bit_set(lkup_exts->done, j)) {
6833 			if (!grp ||
6834 			    grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
6835 				struct ice_recp_grp_entry *entry;
6836 
6837 				entry = (struct ice_recp_grp_entry *)
6838 					ice_malloc(hw, sizeof(*entry));
6839 				if (!entry)
6840 					return ICE_ERR_NO_MEMORY;
6841 				LIST_ADD(&entry->l_entry, rg_list);
6842 				grp = &entry->r_group;
6843 				(*recp_cnt)++;
6844 			}
6845 
6846 			grp->pairs[grp->n_val_pairs].prot_id =
6847 				lkup_exts->fv_words[j].prot_id;
6848 			grp->pairs[grp->n_val_pairs].off =
6849 				lkup_exts->fv_words[j].off;
6850 			grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
6851 			grp->n_val_pairs++;
6852 		}
6853 
6854 	return ICE_SUCCESS;
6855 }
6856 
6857 /**
6858  * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
6859  * @hw: pointer to the hardware structure
6860  * @fv_list: field vector with the extraction sequence information
6861  * @rg_list: recipe groupings with protocol-offset pairs
6862  *
6863  * Helper function to fill in the field vector indices for protocol-offset
6864  * pairs. These indexes are then ultimately programmed into a recipe.
6865  */
6866 static enum ice_status
6867 ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,
6868 		       struct LIST_HEAD_TYPE *rg_list)
6869 {
6870 	struct ice_sw_fv_list_entry *fv;
6871 	struct ice_recp_grp_entry *rg;
6872 	struct ice_fv_word *fv_ext;
6873 
6874 	if (LIST_EMPTY(fv_list))
6875 		return ICE_SUCCESS;
6876 
6877 	fv = LIST_FIRST_ENTRY(fv_list, struct ice_sw_fv_list_entry, list_entry);
6878 	fv_ext = fv->fv_ptr->ew;
6879 
6880 	LIST_FOR_EACH_ENTRY(rg, rg_list, ice_recp_grp_entry, l_entry) {
6881 		u8 i;
6882 
6883 		for (i = 0; i < rg->r_group.n_val_pairs; i++) {
6884 			struct ice_fv_word *pr;
6885 			bool found = false;
6886 			u16 mask;
6887 			u8 j;
6888 
6889 			pr = &rg->r_group.pairs[i];
6890 			mask = rg->r_group.mask[i];
6891 
6892 			for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
6893 				if (fv_ext[j].prot_id == pr->prot_id &&
6894 				    fv_ext[j].off == pr->off) {
6895 					found = true;
6896 
6897 					/* Store index of field vector */
6898 					rg->fv_idx[i] = j;
6899 					rg->fv_mask[i] = mask;
6900 					break;
6901 				}
6902 
6903 			/* Protocol/offset could not be found, caller gave an
6904 			 * invalid pair
6905 			 */
6906 			if (!found)
6907 				return ICE_ERR_PARAM;
6908 		}
6909 	}
6910 
6911 	return ICE_SUCCESS;
6912 }
6913 
6914 /**
6915  * ice_find_free_recp_res_idx - find free result indexes for recipe
6916  * @hw: pointer to hardware structure
6917  * @profiles: bitmap of profiles that will be associated with the new recipe
6918  * @free_idx: pointer to variable to receive the free index bitmap
6919  *
6920  * The algorithm used here is:
6921  *	1. When creating a new recipe, create a set P which contains all
6922  *	   Profiles that will be associated with our new recipe
6923  *
6924  *	2. For each Profile p in set P:
6925  *	    a. Add all recipes associated with Profile p into set R
6926  *	    b. Optional : PossibleIndexes &= profile[p].possibleIndexes
6927  *		[initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
6928  *		i. Or just assume they all have the same possible indexes:
6929  *			44, 45, 46, 47
6930  *			i.e., PossibleIndexes = 0x0000F00000000000
6931  *
6932  *	3. For each Recipe r in set R:
6933  *	    a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
6934  *	    b. FreeIndexes = UsedIndexes ^ PossibleIndexes
6935  *
6936  *	FreeIndexes will contain the bits indicating the indexes free for use,
6937  *      then the code needs to update the recipe[r].used_result_idx_bits to
6938  *      indicate which indexes were selected for use by this recipe.
6939  */
6940 static u16
6941 ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles,
6942 			   ice_bitmap_t *free_idx)
6943 {
6944 	ice_declare_bitmap(possible_idx, ICE_MAX_FV_WORDS);
6945 	ice_declare_bitmap(recipes, ICE_MAX_NUM_RECIPES);
6946 	ice_declare_bitmap(used_idx, ICE_MAX_FV_WORDS);
6947 	u16 bit;
6948 
6949 	ice_zero_bitmap(possible_idx, ICE_MAX_FV_WORDS);
6950 	ice_zero_bitmap(recipes, ICE_MAX_NUM_RECIPES);
6951 	ice_zero_bitmap(used_idx, ICE_MAX_FV_WORDS);
6952 	ice_zero_bitmap(free_idx, ICE_MAX_FV_WORDS);
6953 
6954 	ice_bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);
6955 
6956 	/* For each profile we are going to associate the recipe with, add the
6957 	 * recipes that are associated with that profile. This will give us
6958 	 * the set of recipes that our recipe may collide with. Also, determine
6959 	 * what possible result indexes are usable given this set of profiles.
6960 	 */
6961 	ice_for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
6962 		ice_or_bitmap(recipes, recipes, profile_to_recipe[bit],
6963 			      ICE_MAX_NUM_RECIPES);
6964 		ice_and_bitmap(possible_idx, possible_idx,
6965 			       hw->switch_info->prof_res_bm[bit],
6966 			       ICE_MAX_FV_WORDS);
6967 	}
6968 
6969 	/* For each recipe that our new recipe may collide with, determine
6970 	 * which indexes have been used.
6971 	 */
6972 	ice_for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
6973 		ice_or_bitmap(used_idx, used_idx,
6974 			      hw->switch_info->recp_list[bit].res_idxs,
6975 			      ICE_MAX_FV_WORDS);
6976 
6977 	ice_xor_bitmap(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
6978 
6979 	/* return number of free indexes */
6980 	return (u16)ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS);
6981 }
6982 
6983 /**
6984  * ice_add_sw_recipe - function to call AQ calls to create switch recipe
6985  * @hw: pointer to hardware structure
6986  * @rm: recipe management list entry
6987  * @profiles: bitmap of profiles that will be associated.
6988  */
6989 static enum ice_status
6990 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
6991 		  ice_bitmap_t *profiles)
6992 {
6993 	ice_declare_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
6994 	struct ice_aqc_recipe_data_elem *tmp;
6995 	struct ice_aqc_recipe_data_elem *buf;
6996 	struct ice_recp_grp_entry *entry;
6997 	enum ice_status status;
6998 	u16 free_res_idx;
6999 	u16 recipe_count;
7000 	u8 chain_idx;
7001 	u8 recps = 0;
7002 
7003 	/* When more than one recipe are required, another recipe is needed to
7004 	 * chain them together. Matching a tunnel metadata ID takes up one of
7005 	 * the match fields in the chaining recipe reducing the number of
7006 	 * chained recipes by one.
7007 	 */
7008 	 /* check number of free result indices */
7009 	ice_zero_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
7010 	free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
7011 
7012 	ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
7013 		  free_res_idx, rm->n_grp_count);
7014 
7015 	if (rm->n_grp_count > 1) {
7016 		if (rm->n_grp_count > free_res_idx)
7017 			return ICE_ERR_MAX_LIMIT;
7018 
7019 		rm->n_grp_count++;
7020 	}
7021 
7022 	if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
7023 		return ICE_ERR_MAX_LIMIT;
7024 
7025 	tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
7026 							    ICE_MAX_NUM_RECIPES,
7027 							    sizeof(*tmp));
7028 	if (!tmp)
7029 		return ICE_ERR_NO_MEMORY;
7030 
7031 	buf = (struct ice_aqc_recipe_data_elem *)
7032 		ice_calloc(hw, rm->n_grp_count, sizeof(*buf));
7033 	if (!buf) {
7034 		status = ICE_ERR_NO_MEMORY;
7035 		goto err_mem;
7036 	}
7037 
7038 	ice_zero_bitmap(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
7039 	recipe_count = ICE_MAX_NUM_RECIPES;
7040 	status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
7041 				   NULL);
7042 	if (status || recipe_count == 0)
7043 		goto err_unroll;
7044 
7045 	/* Allocate the recipe resources, and configure them according to the
7046 	 * match fields from protocol headers and extracted field vectors.
7047 	 */
7048 	chain_idx = ice_find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
7049 	LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7050 		u8 i;
7051 
7052 		status = ice_alloc_recipe(hw, &entry->rid);
7053 		if (status)
7054 			goto err_unroll;
7055 
7056 		/* Clear the result index of the located recipe, as this will be
7057 		 * updated, if needed, later in the recipe creation process.
7058 		 */
7059 		tmp[0].content.result_indx = 0;
7060 
7061 		buf[recps] = tmp[0];
7062 		buf[recps].recipe_indx = (u8)entry->rid;
7063 		/* if the recipe is a non-root recipe RID should be programmed
7064 		 * as 0 for the rules to be applied correctly.
7065 		 */
7066 		buf[recps].content.rid = 0;
7067 		ice_memset(&buf[recps].content.lkup_indx, 0,
7068 			   sizeof(buf[recps].content.lkup_indx),
7069 			   ICE_NONDMA_MEM);
7070 
7071 		/* All recipes use look-up index 0 to match switch ID. */
7072 		buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7073 		buf[recps].content.mask[0] =
7074 			CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7075 		/* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
7076 		 * to be 0
7077 		 */
7078 		for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7079 			buf[recps].content.lkup_indx[i] = 0x80;
7080 			buf[recps].content.mask[i] = 0;
7081 		}
7082 
7083 		for (i = 0; i < entry->r_group.n_val_pairs; i++) {
7084 			buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
7085 			buf[recps].content.mask[i + 1] =
7086 				CPU_TO_LE16(entry->fv_mask[i]);
7087 		}
7088 
7089 		if (rm->n_grp_count > 1) {
7090 			/* Checks to see if there really is a valid result index
7091 			 * that can be used.
7092 			 */
7093 			if (chain_idx >= ICE_MAX_FV_WORDS) {
7094 				ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
7095 				status = ICE_ERR_MAX_LIMIT;
7096 				goto err_unroll;
7097 			}
7098 
7099 			entry->chain_idx = chain_idx;
7100 			buf[recps].content.result_indx =
7101 				ICE_AQ_RECIPE_RESULT_EN |
7102 				((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
7103 				 ICE_AQ_RECIPE_RESULT_DATA_M);
7104 			ice_clear_bit(chain_idx, result_idx_bm);
7105 			chain_idx = ice_find_first_bit(result_idx_bm,
7106 						       ICE_MAX_FV_WORDS);
7107 		}
7108 
7109 		/* fill recipe dependencies */
7110 		ice_zero_bitmap((ice_bitmap_t *)buf[recps].recipe_bitmap,
7111 				ICE_MAX_NUM_RECIPES);
7112 		ice_set_bit(buf[recps].recipe_indx,
7113 			    (ice_bitmap_t *)buf[recps].recipe_bitmap);
7114 		buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7115 		recps++;
7116 	}
7117 
7118 	if (rm->n_grp_count == 1) {
7119 		rm->root_rid = buf[0].recipe_indx;
7120 		ice_set_bit(buf[0].recipe_indx, rm->r_bitmap);
7121 		buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
7122 		if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
7123 			ice_memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
7124 				   sizeof(buf[0].recipe_bitmap),
7125 				   ICE_NONDMA_TO_NONDMA);
7126 		} else {
7127 			status = ICE_ERR_BAD_PTR;
7128 			goto err_unroll;
7129 		}
7130 		/* Applicable only for ROOT_RECIPE, set the fwd_priority for
7131 		 * the recipe which is getting created if specified
7132 		 * by user. Usually any advanced switch filter, which results
7133 		 * into new extraction sequence, ended up creating a new recipe
7134 		 * of type ROOT and usually recipes are associated with profiles
7135 		 * Switch rule referreing newly created recipe, needs to have
7136 		 * either/or 'fwd' or 'join' priority, otherwise switch rule
7137 		 * evaluation will not happen correctly. In other words, if
7138 		 * switch rule to be evaluated on priority basis, then recipe
7139 		 * needs to have priority, otherwise it will be evaluated last.
7140 		 */
7141 		buf[0].content.act_ctrl_fwd_priority = rm->priority;
7142 	} else {
7143 		struct ice_recp_grp_entry *last_chain_entry;
7144 		u16 rid, i;
7145 
7146 		/* Allocate the last recipe that will chain the outcomes of the
7147 		 * other recipes together
7148 		 */
7149 		status = ice_alloc_recipe(hw, &rid);
7150 		if (status)
7151 			goto err_unroll;
7152 
7153 		buf[recps].recipe_indx = (u8)rid;
7154 		buf[recps].content.rid = (u8)rid;
7155 		buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
7156 		/* the new entry created should also be part of rg_list to
7157 		 * make sure we have complete recipe
7158 		 */
7159 		last_chain_entry = (struct ice_recp_grp_entry *)ice_malloc(hw,
7160 			sizeof(*last_chain_entry));
7161 		if (!last_chain_entry) {
7162 			status = ICE_ERR_NO_MEMORY;
7163 			goto err_unroll;
7164 		}
7165 		last_chain_entry->rid = rid;
7166 		ice_memset(&buf[recps].content.lkup_indx, 0,
7167 			   sizeof(buf[recps].content.lkup_indx),
7168 			   ICE_NONDMA_MEM);
7169 		/* All recipes use look-up index 0 to match switch ID. */
7170 		buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7171 		buf[recps].content.mask[0] =
7172 			CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7173 		for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7174 			buf[recps].content.lkup_indx[i] =
7175 				ICE_AQ_RECIPE_LKUP_IGNORE;
7176 			buf[recps].content.mask[i] = 0;
7177 		}
7178 
7179 		i = 1;
7180 		/* update r_bitmap with the recp that is used for chaining */
7181 		ice_set_bit(rid, rm->r_bitmap);
7182 		/* this is the recipe that chains all the other recipes so it
7183 		 * should not have a chaining ID to indicate the same
7184 		 */
7185 		last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
7186 		LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry,
7187 				    l_entry) {
7188 			last_chain_entry->fv_idx[i] = entry->chain_idx;
7189 			buf[recps].content.lkup_indx[i] = entry->chain_idx;
7190 			buf[recps].content.mask[i++] = CPU_TO_LE16(0xFFFF);
7191 			ice_set_bit(entry->rid, rm->r_bitmap);
7192 		}
7193 		LIST_ADD(&last_chain_entry->l_entry, &rm->rg_list);
7194 		if (sizeof(buf[recps].recipe_bitmap) >=
7195 		    sizeof(rm->r_bitmap)) {
7196 			ice_memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
7197 				   sizeof(buf[recps].recipe_bitmap),
7198 				   ICE_NONDMA_TO_NONDMA);
7199 		} else {
7200 			status = ICE_ERR_BAD_PTR;
7201 			goto err_unroll;
7202 		}
7203 		buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7204 
7205 		recps++;
7206 		rm->root_rid = (u8)rid;
7207 	}
7208 	status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7209 	if (status)
7210 		goto err_unroll;
7211 
7212 	status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
7213 	ice_release_change_lock(hw);
7214 	if (status)
7215 		goto err_unroll;
7216 
7217 	/* Every recipe that just got created add it to the recipe
7218 	 * book keeping list
7219 	 */
7220 	LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7221 		struct ice_switch_info *sw = hw->switch_info;
7222 		bool is_root, idx_found = false;
7223 		struct ice_sw_recipe *recp;
7224 		u16 idx, buf_idx = 0;
7225 
7226 		/* find buffer index for copying some data */
7227 		for (idx = 0; idx < rm->n_grp_count; idx++)
7228 			if (buf[idx].recipe_indx == entry->rid) {
7229 				buf_idx = idx;
7230 				idx_found = true;
7231 			}
7232 
7233 		if (!idx_found) {
7234 			status = ICE_ERR_OUT_OF_RANGE;
7235 			goto err_unroll;
7236 		}
7237 
7238 		recp = &sw->recp_list[entry->rid];
7239 		is_root = (rm->root_rid == entry->rid);
7240 		recp->is_root = is_root;
7241 
7242 		recp->root_rid = entry->rid;
7243 		recp->big_recp = (is_root && rm->n_grp_count > 1);
7244 
7245 		ice_memcpy(&recp->ext_words, entry->r_group.pairs,
7246 			   entry->r_group.n_val_pairs *
7247 			   sizeof(struct ice_fv_word),
7248 			   ICE_NONDMA_TO_NONDMA);
7249 
7250 		ice_memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
7251 			   sizeof(recp->r_bitmap), ICE_NONDMA_TO_NONDMA);
7252 
7253 		/* Copy non-result fv index values and masks to recipe. This
7254 		 * call will also update the result recipe bitmask.
7255 		 */
7256 		ice_collect_result_idx(&buf[buf_idx], recp);
7257 
7258 		/* for non-root recipes, also copy to the root, this allows
7259 		 * easier matching of a complete chained recipe
7260 		 */
7261 		if (!is_root)
7262 			ice_collect_result_idx(&buf[buf_idx],
7263 					       &sw->recp_list[rm->root_rid]);
7264 
7265 		recp->n_ext_words = entry->r_group.n_val_pairs;
7266 		recp->chain_idx = entry->chain_idx;
7267 		recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
7268 		recp->n_grp_count = rm->n_grp_count;
7269 		recp->tun_type = rm->tun_type;
7270 		recp->recp_created = true;
7271 	}
7272 	rm->root_buf = buf;
7273 	ice_free(hw, tmp);
7274 	return status;
7275 
7276 err_unroll:
7277 err_mem:
7278 	ice_free(hw, tmp);
7279 	ice_free(hw, buf);
7280 	return status;
7281 }
7282 
7283 /**
7284  * ice_create_recipe_group - creates recipe group
7285  * @hw: pointer to hardware structure
7286  * @rm: recipe management list entry
7287  * @lkup_exts: lookup elements
7288  */
7289 static enum ice_status
7290 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
7291 			struct ice_prot_lkup_ext *lkup_exts)
7292 {
7293 	enum ice_status status;
7294 	u8 recp_count = 0;
7295 
7296 	rm->n_grp_count = 0;
7297 
7298 	/* Create recipes for words that are marked not done by packing them
7299 	 * as best fit.
7300 	 */
7301 	status = ice_create_first_fit_recp_def(hw, lkup_exts,
7302 					       &rm->rg_list, &recp_count);
7303 	if (!status) {
7304 		rm->n_grp_count += recp_count;
7305 		rm->n_ext_words = lkup_exts->n_val_words;
7306 		ice_memcpy(&rm->ext_words, lkup_exts->fv_words,
7307 			   sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA);
7308 		ice_memcpy(rm->word_masks, lkup_exts->field_mask,
7309 			   sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA);
7310 	}
7311 
7312 	return status;
7313 }
7314 
7315 /**
7316  * ice_get_fv - get field vectors/extraction sequences for spec. lookup types
7317  * @hw: pointer to hardware structure
7318  * @lkups: lookup elements or match criteria for the advanced recipe, one
7319  *	   structure per protocol header
7320  * @lkups_cnt: number of protocols
7321  * @bm: bitmap of field vectors to consider
7322  * @fv_list: pointer to a list that holds the returned field vectors
7323  */
7324 static enum ice_status
7325 ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
7326 	   ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)
7327 {
7328 	enum ice_status status;
7329 	u8 *prot_ids;
7330 	u16 i;
7331 
7332 	if (!lkups_cnt)
7333 		return ICE_SUCCESS;
7334 
7335 	prot_ids = (u8 *)ice_calloc(hw, lkups_cnt, sizeof(*prot_ids));
7336 	if (!prot_ids)
7337 		return ICE_ERR_NO_MEMORY;
7338 
7339 	for (i = 0; i < lkups_cnt; i++)
7340 		if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {
7341 			status = ICE_ERR_CFG;
7342 			goto free_mem;
7343 		}
7344 
7345 	/* Find field vectors that include all specified protocol types */
7346 	status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);
7347 
7348 free_mem:
7349 	ice_free(hw, prot_ids);
7350 	return status;
7351 }
7352 
7353 /**
7354  * ice_tun_type_match_word - determine if tun type needs a match mask
7355  * @tun_type: tunnel type
7356  * @mask: mask to be used for the tunnel
7357  */
7358 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
7359 {
7360 	switch (tun_type) {
7361 	case ICE_SW_TUN_VXLAN_GPE:
7362 	case ICE_SW_TUN_GENEVE:
7363 	case ICE_SW_TUN_VXLAN:
7364 	case ICE_SW_TUN_NVGRE:
7365 	case ICE_SW_TUN_UDP:
7366 	case ICE_ALL_TUNNELS:
7367 	case ICE_SW_TUN_AND_NON_TUN_QINQ:
7368 	case ICE_NON_TUN_QINQ:
7369 	case ICE_SW_TUN_PPPOE_QINQ:
7370 	case ICE_SW_TUN_PPPOE_PAY_QINQ:
7371 	case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7372 	case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7373 		*mask = ICE_TUN_FLAG_MASK;
7374 		return true;
7375 
7376 	case ICE_SW_TUN_GENEVE_VLAN:
7377 	case ICE_SW_TUN_VXLAN_VLAN:
7378 		*mask = ICE_TUN_FLAG_MASK & ~ICE_TUN_FLAG_VLAN_MASK;
7379 		return true;
7380 
7381 	default:
7382 		*mask = 0;
7383 		return false;
7384 	}
7385 }
7386 
7387 /**
7388  * ice_add_special_words - Add words that are not protocols, such as metadata
7389  * @rinfo: other information regarding the rule e.g. priority and action info
7390  * @lkup_exts: lookup word structure
7391  */
7392 static enum ice_status
7393 ice_add_special_words(struct ice_adv_rule_info *rinfo,
7394 		      struct ice_prot_lkup_ext *lkup_exts)
7395 {
7396 	u16 mask;
7397 
7398 	/* If this is a tunneled packet, then add recipe index to match the
7399 	 * tunnel bit in the packet metadata flags.
7400 	 */
7401 	if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
7402 		if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7403 			u8 word = lkup_exts->n_val_words++;
7404 
7405 			lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7406 			lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
7407 			lkup_exts->field_mask[word] = mask;
7408 		} else {
7409 			return ICE_ERR_MAX_LIMIT;
7410 		}
7411 	}
7412 
7413 	return ICE_SUCCESS;
7414 }
7415 
7416 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
7417  * @hw: pointer to hardware structure
7418  * @rinfo: other information regarding the rule e.g. priority and action info
7419  * @bm: pointer to memory for returning the bitmap of field vectors
7420  */
7421 static void
7422 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
7423 			 ice_bitmap_t *bm)
7424 {
7425 	enum ice_prof_type prof_type;
7426 
7427 	ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
7428 
7429 	switch (rinfo->tun_type) {
7430 	case ICE_NON_TUN:
7431 	case ICE_NON_TUN_QINQ:
7432 		prof_type = ICE_PROF_NON_TUN;
7433 		break;
7434 	case ICE_ALL_TUNNELS:
7435 		prof_type = ICE_PROF_TUN_ALL;
7436 		break;
7437 	case ICE_SW_TUN_VXLAN_GPE:
7438 	case ICE_SW_TUN_GENEVE:
7439 	case ICE_SW_TUN_GENEVE_VLAN:
7440 	case ICE_SW_TUN_VXLAN:
7441 	case ICE_SW_TUN_VXLAN_VLAN:
7442 	case ICE_SW_TUN_UDP:
7443 	case ICE_SW_TUN_GTP:
7444 		prof_type = ICE_PROF_TUN_UDP;
7445 		break;
7446 	case ICE_SW_TUN_NVGRE:
7447 		prof_type = ICE_PROF_TUN_GRE;
7448 		break;
7449 	case ICE_SW_TUN_PPPOE:
7450 	case ICE_SW_TUN_PPPOE_QINQ:
7451 		prof_type = ICE_PROF_TUN_PPPOE;
7452 		break;
7453 	case ICE_SW_TUN_PPPOE_PAY:
7454 	case ICE_SW_TUN_PPPOE_PAY_QINQ:
7455 		ice_set_bit(ICE_PROFID_PPPOE_PAY, bm);
7456 		return;
7457 	case ICE_SW_TUN_PPPOE_IPV4:
7458 	case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7459 		ice_set_bit(ICE_PROFID_PPPOE_IPV4_OTHER, bm);
7460 		ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7461 		ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7462 		return;
7463 	case ICE_SW_TUN_PPPOE_IPV4_TCP:
7464 		ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7465 		return;
7466 	case ICE_SW_TUN_PPPOE_IPV4_UDP:
7467 		ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7468 		return;
7469 	case ICE_SW_TUN_PPPOE_IPV6:
7470 	case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7471 		ice_set_bit(ICE_PROFID_PPPOE_IPV6_OTHER, bm);
7472 		ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7473 		ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7474 		return;
7475 	case ICE_SW_TUN_PPPOE_IPV6_TCP:
7476 		ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7477 		return;
7478 	case ICE_SW_TUN_PPPOE_IPV6_UDP:
7479 		ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7480 		return;
7481 	case ICE_SW_TUN_PROFID_IPV6_ESP:
7482 	case ICE_SW_TUN_IPV6_ESP:
7483 		ice_set_bit(ICE_PROFID_IPV6_ESP, bm);
7484 		return;
7485 	case ICE_SW_TUN_PROFID_IPV6_AH:
7486 	case ICE_SW_TUN_IPV6_AH:
7487 		ice_set_bit(ICE_PROFID_IPV6_AH, bm);
7488 		return;
7489 	case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7490 	case ICE_SW_TUN_IPV6_L2TPV3:
7491 		ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm);
7492 		return;
7493 	case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7494 	case ICE_SW_TUN_IPV6_NAT_T:
7495 		ice_set_bit(ICE_PROFID_IPV6_NAT_T, bm);
7496 		return;
7497 	case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7498 		ice_set_bit(ICE_PROFID_IPV4_PFCP_NODE, bm);
7499 		return;
7500 	case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7501 		ice_set_bit(ICE_PROFID_IPV4_PFCP_SESSION, bm);
7502 		return;
7503 	case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7504 		ice_set_bit(ICE_PROFID_IPV6_PFCP_NODE, bm);
7505 		return;
7506 	case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7507 		ice_set_bit(ICE_PROFID_IPV6_PFCP_SESSION, bm);
7508 		return;
7509 	case ICE_SW_TUN_IPV4_NAT_T:
7510 		ice_set_bit(ICE_PROFID_IPV4_NAT_T, bm);
7511 		return;
7512 	case ICE_SW_TUN_IPV4_L2TPV3:
7513 		ice_set_bit(ICE_PROFID_MAC_IPV4_L2TPV3, bm);
7514 		return;
7515 	case ICE_SW_TUN_IPV4_ESP:
7516 		ice_set_bit(ICE_PROFID_IPV4_ESP, bm);
7517 		return;
7518 	case ICE_SW_TUN_IPV4_AH:
7519 		ice_set_bit(ICE_PROFID_IPV4_AH, bm);
7520 		return;
7521 	case ICE_SW_IPV4_TCP:
7522 		ice_set_bit(ICE_PROFID_IPV4_TCP, bm);
7523 		return;
7524 	case ICE_SW_IPV4_UDP:
7525 		ice_set_bit(ICE_PROFID_IPV4_UDP, bm);
7526 		return;
7527 	case ICE_SW_IPV6_TCP:
7528 		ice_set_bit(ICE_PROFID_IPV6_TCP, bm);
7529 		return;
7530 	case ICE_SW_IPV6_UDP:
7531 		ice_set_bit(ICE_PROFID_IPV6_UDP, bm);
7532 		return;
7533 	case ICE_SW_TUN_IPV4_GTPU_NO_PAY:
7534 		ice_set_bit(ICE_PROFID_IPV4_GTPU_TEID, bm);
7535 		return;
7536 	case ICE_SW_TUN_IPV6_GTPU_NO_PAY:
7537 		ice_set_bit(ICE_PROFID_IPV6_GTPU_TEID, bm);
7538 		return;
7539 	case ICE_SW_TUN_IPV4_GTPU_IPV4:
7540 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_OTHER, bm);
7541 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
7542 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
7543 		return;
7544 	case ICE_SW_TUN_IPV4_GTPU_IPV4_UDP:
7545 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
7546 		return;
7547 	case ICE_SW_TUN_IPV4_GTPU_IPV4_TCP:
7548 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
7549 		return;
7550 	case ICE_SW_TUN_IPV4_GTPU_EH_IPV4:
7551 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, bm);
7552 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
7553 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
7554 		return;
7555 	case ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP:
7556 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
7557 		return;
7558 	case ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP:
7559 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
7560 		return;
7561 	case ICE_SW_TUN_IPV6_GTPU_IPV4:
7562 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_OTHER, bm);
7563 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
7564 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
7565 		return;
7566 	case ICE_SW_TUN_IPV6_GTPU_IPV4_UDP:
7567 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
7568 		return;
7569 	case ICE_SW_TUN_IPV6_GTPU_IPV4_TCP:
7570 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
7571 		return;
7572 	case ICE_SW_TUN_IPV6_GTPU_EH_IPV4:
7573 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, bm);
7574 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
7575 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
7576 		return;
7577 	case ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP:
7578 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
7579 		return;
7580 	case ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP:
7581 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
7582 		return;
7583 	case ICE_SW_TUN_IPV4_GTPU_IPV6:
7584 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_OTHER, bm);
7585 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
7586 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
7587 		return;
7588 	case ICE_SW_TUN_IPV4_GTPU_IPV6_UDP:
7589 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
7590 		return;
7591 	case ICE_SW_TUN_IPV4_GTPU_IPV6_TCP:
7592 		ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
7593 		return;
7594 	case ICE_SW_TUN_IPV4_GTPU_EH_IPV6:
7595 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, bm);
7596 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
7597 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
7598 		return;
7599 	case ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP:
7600 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
7601 		return;
7602 	case ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP:
7603 		ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
7604 		return;
7605 	case ICE_SW_TUN_IPV6_GTPU_IPV6:
7606 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_OTHER, bm);
7607 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
7608 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
7609 		return;
7610 	case ICE_SW_TUN_IPV6_GTPU_IPV6_UDP:
7611 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
7612 		return;
7613 	case ICE_SW_TUN_IPV6_GTPU_IPV6_TCP:
7614 		ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
7615 		return;
7616 	case ICE_SW_TUN_IPV6_GTPU_EH_IPV6:
7617 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, bm);
7618 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
7619 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
7620 		return;
7621 	case ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP:
7622 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
7623 		return;
7624 	case ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP:
7625 		ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
7626 		return;
7627 	case ICE_SW_TUN_AND_NON_TUN:
7628 	case ICE_SW_TUN_AND_NON_TUN_QINQ:
7629 	default:
7630 		prof_type = ICE_PROF_ALL;
7631 		break;
7632 	}
7633 
7634 	ice_get_sw_fv_bitmap(hw, prof_type, bm);
7635 }
7636 
7637 /**
7638  * ice_is_prof_rule - determine if rule type is a profile rule
7639  * @type: the rule type
7640  *
7641  * if the rule type is a profile rule, that means that there no field value
7642  * match required, in this case just a profile hit is required.
7643  */
7644 bool ice_is_prof_rule(enum ice_sw_tunnel_type type)
7645 {
7646 	switch (type) {
7647 	case ICE_SW_TUN_PROFID_IPV6_ESP:
7648 	case ICE_SW_TUN_PROFID_IPV6_AH:
7649 	case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7650 	case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7651 	case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7652 	case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7653 	case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7654 	case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7655 		return true;
7656 	default:
7657 		break;
7658 	}
7659 
7660 	return false;
7661 }
7662 
7663 /**
7664  * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
7665  * @hw: pointer to hardware structure
7666  * @lkups: lookup elements or match criteria for the advanced recipe, one
7667  *  structure per protocol header
7668  * @lkups_cnt: number of protocols
7669  * @rinfo: other information regarding the rule e.g. priority and action info
7670  * @rid: return the recipe ID of the recipe created
7671  */
7672 static enum ice_status
7673 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
7674 		   u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
7675 {
7676 	ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES);
7677 	ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES);
7678 	struct ice_prot_lkup_ext *lkup_exts;
7679 	struct ice_recp_grp_entry *r_entry;
7680 	struct ice_sw_fv_list_entry *fvit;
7681 	struct ice_recp_grp_entry *r_tmp;
7682 	struct ice_sw_fv_list_entry *tmp;
7683 	enum ice_status status = ICE_SUCCESS;
7684 	struct ice_sw_recipe *rm;
7685 	u8 i;
7686 
7687 	if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt)
7688 		return ICE_ERR_PARAM;
7689 
7690 	lkup_exts = (struct ice_prot_lkup_ext *)
7691 		ice_malloc(hw, sizeof(*lkup_exts));
7692 	if (!lkup_exts)
7693 		return ICE_ERR_NO_MEMORY;
7694 
7695 	/* Determine the number of words to be matched and if it exceeds a
7696 	 * recipe's restrictions
7697 	 */
7698 	for (i = 0; i < lkups_cnt; i++) {
7699 		u16 count;
7700 
7701 		if (lkups[i].type >= ICE_PROTOCOL_LAST) {
7702 			status = ICE_ERR_CFG;
7703 			goto err_free_lkup_exts;
7704 		}
7705 
7706 		count = ice_fill_valid_words(&lkups[i], lkup_exts);
7707 		if (!count) {
7708 			status = ICE_ERR_CFG;
7709 			goto err_free_lkup_exts;
7710 		}
7711 	}
7712 
7713 	rm = (struct ice_sw_recipe *)ice_malloc(hw, sizeof(*rm));
7714 	if (!rm) {
7715 		status = ICE_ERR_NO_MEMORY;
7716 		goto err_free_lkup_exts;
7717 	}
7718 
7719 	/* Get field vectors that contain fields extracted from all the protocol
7720 	 * headers being programmed.
7721 	 */
7722 	INIT_LIST_HEAD(&rm->fv_list);
7723 	INIT_LIST_HEAD(&rm->rg_list);
7724 
7725 	/* Get bitmap of field vectors (profiles) that are compatible with the
7726 	 * rule request; only these will be searched in the subsequent call to
7727 	 * ice_get_fv.
7728 	 */
7729 	ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
7730 
7731 	status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);
7732 	if (status)
7733 		goto err_unroll;
7734 
7735 	/* Create any special protocol/offset pairs, such as looking at tunnel
7736 	 * bits by extracting metadata
7737 	 */
7738 	status = ice_add_special_words(rinfo, lkup_exts);
7739 	if (status)
7740 		goto err_free_lkup_exts;
7741 
7742 	/* Group match words into recipes using preferred recipe grouping
7743 	 * criteria.
7744 	 */
7745 	status = ice_create_recipe_group(hw, rm, lkup_exts);
7746 	if (status)
7747 		goto err_unroll;
7748 
7749 	/* set the recipe priority if specified */
7750 	rm->priority = (u8)rinfo->priority;
7751 
7752 	/* Find offsets from the field vector. Pick the first one for all the
7753 	 * recipes.
7754 	 */
7755 	status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
7756 	if (status)
7757 		goto err_unroll;
7758 
7759 	/* An empty FV list means to use all the profiles returned in the
7760 	 * profile bitmap
7761 	 */
7762 	if (LIST_EMPTY(&rm->fv_list)) {
7763 		u16 j;
7764 
7765 		ice_for_each_set_bit(j, fv_bitmap, ICE_MAX_NUM_PROFILES) {
7766 			struct ice_sw_fv_list_entry *fvl;
7767 
7768 			fvl = (struct ice_sw_fv_list_entry *)
7769 				ice_malloc(hw, sizeof(*fvl));
7770 			if (!fvl)
7771 				goto err_unroll;
7772 			fvl->fv_ptr = NULL;
7773 			fvl->profile_id = j;
7774 			LIST_ADD(&fvl->list_entry, &rm->fv_list);
7775 		}
7776 	}
7777 
7778 	/* get bitmap of all profiles the recipe will be associated with */
7779 	ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES);
7780 	LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
7781 			    list_entry) {
7782 		ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
7783 		ice_set_bit((u16)fvit->profile_id, profiles);
7784 	}
7785 
7786 	/* Look for a recipe which matches our requested fv / mask list */
7787 	*rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type, rinfo->priority);
7788 	if (*rid < ICE_MAX_NUM_RECIPES)
7789 		/* Success if found a recipe that match the existing criteria */
7790 		goto err_unroll;
7791 
7792 	rm->tun_type = rinfo->tun_type;
7793 	/* Recipe we need does not exist, add a recipe */
7794 	status = ice_add_sw_recipe(hw, rm, profiles);
7795 	if (status)
7796 		goto err_unroll;
7797 
7798 	/* Associate all the recipes created with all the profiles in the
7799 	 * common field vector.
7800 	 */
7801 	LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
7802 			    list_entry) {
7803 		ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
7804 		u16 j;
7805 
7806 		status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
7807 						      (u8 *)r_bitmap, NULL);
7808 		if (status)
7809 			goto err_unroll;
7810 
7811 		ice_or_bitmap(r_bitmap, r_bitmap, rm->r_bitmap,
7812 			      ICE_MAX_NUM_RECIPES);
7813 		status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7814 		if (status)
7815 			goto err_unroll;
7816 
7817 		status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
7818 						      (u8 *)r_bitmap,
7819 						      NULL);
7820 		ice_release_change_lock(hw);
7821 
7822 		if (status)
7823 			goto err_unroll;
7824 
7825 		/* Update profile to recipe bitmap array */
7826 		ice_cp_bitmap(profile_to_recipe[fvit->profile_id], r_bitmap,
7827 			      ICE_MAX_NUM_RECIPES);
7828 
7829 		/* Update recipe to profile bitmap array */
7830 		ice_for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
7831 			ice_set_bit((u16)fvit->profile_id,
7832 				    recipe_to_profile[j]);
7833 	}
7834 
7835 	*rid = rm->root_rid;
7836 	ice_memcpy(&hw->switch_info->recp_list[*rid].lkup_exts,
7837 		   lkup_exts, sizeof(*lkup_exts), ICE_NONDMA_TO_NONDMA);
7838 err_unroll:
7839 	LIST_FOR_EACH_ENTRY_SAFE(r_entry, r_tmp, &rm->rg_list,
7840 				 ice_recp_grp_entry, l_entry) {
7841 		LIST_DEL(&r_entry->l_entry);
7842 		ice_free(hw, r_entry);
7843 	}
7844 
7845 	LIST_FOR_EACH_ENTRY_SAFE(fvit, tmp, &rm->fv_list, ice_sw_fv_list_entry,
7846 				 list_entry) {
7847 		LIST_DEL(&fvit->list_entry);
7848 		ice_free(hw, fvit);
7849 	}
7850 
7851 	if (rm->root_buf)
7852 		ice_free(hw, rm->root_buf);
7853 
7854 	ice_free(hw, rm);
7855 
7856 err_free_lkup_exts:
7857 	ice_free(hw, lkup_exts);
7858 
7859 	return status;
7860 }
7861 
7862 /**
7863  * ice_find_dummy_packet - find dummy packet by tunnel type
7864  *
7865  * @lkups: lookup elements or match criteria for the advanced recipe, one
7866  *	   structure per protocol header
7867  * @lkups_cnt: number of protocols
7868  * @tun_type: tunnel type from the match criteria
7869  * @pkt: dummy packet to fill according to filter match criteria
7870  * @pkt_len: packet length of dummy packet
7871  * @offsets: pointer to receive the pointer to the offsets for the packet
7872  */
7873 static void
7874 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
7875 		      enum ice_sw_tunnel_type tun_type, const u8 **pkt,
7876 		      u16 *pkt_len,
7877 		      const struct ice_dummy_pkt_offsets **offsets)
7878 {
7879 	bool tcp = false, udp = false, ipv6 = false, vlan = false;
7880 	bool gre = false, mpls = false;
7881 	u16 i;
7882 
7883 	for (i = 0; i < lkups_cnt; i++) {
7884 		if (lkups[i].type == ICE_UDP_ILOS)
7885 			udp = true;
7886 		else if (lkups[i].type == ICE_TCP_IL)
7887 			tcp = true;
7888 		else if (lkups[i].type == ICE_IPV6_OFOS)
7889 			ipv6 = true;
7890 		else if (lkups[i].type == ICE_VLAN_OFOS)
7891 			vlan = true;
7892 		else if (lkups[i].type == ICE_IPV4_OFOS &&
7893 			 lkups[i].h_u.ipv4_hdr.protocol ==
7894 				ICE_IPV4_NVGRE_PROTO_ID &&
7895 			 lkups[i].m_u.ipv4_hdr.protocol ==
7896 				0xFF)
7897 			gre = true;
7898 		else if (lkups[i].type == ICE_PPPOE &&
7899 			 lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
7900 				CPU_TO_BE16(ICE_PPP_IPV6_PROTO_ID) &&
7901 			 lkups[i].m_u.pppoe_hdr.ppp_prot_id ==
7902 				0xFFFF)
7903 			ipv6 = true;
7904 		else if (lkups[i].type == ICE_ETYPE_OL &&
7905 			 lkups[i].h_u.ethertype.ethtype_id ==
7906 				CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
7907 			 lkups[i].m_u.ethertype.ethtype_id ==
7908 					0xFFFF)
7909 			ipv6 = true;
7910 		else if (lkups[i].type == ICE_IPV4_IL &&
7911 			 lkups[i].h_u.ipv4_hdr.protocol ==
7912 				ICE_TCP_PROTO_ID &&
7913 			 lkups[i].m_u.ipv4_hdr.protocol ==
7914 				0xFF)
7915 			tcp = true;
7916 		else if (lkups[i].type == ICE_ETYPE_OL &&
7917 			 lkups[i].h_u.ethertype.ethtype_id ==
7918 				CPU_TO_BE16(ICE_MPLS_ETHER_ID) &&
7919 			 lkups[i].m_u.ethertype.ethtype_id == 0xFFFF)
7920 			mpls = true;
7921 	}
7922 
7923 	if ((tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
7924 	     tun_type == ICE_NON_TUN_QINQ) && ipv6) {
7925 		*pkt = dummy_qinq_ipv6_pkt;
7926 		*pkt_len = sizeof(dummy_qinq_ipv6_pkt);
7927 		*offsets = dummy_qinq_ipv6_packet_offsets;
7928 		return;
7929 	} else if (tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
7930 			   tun_type == ICE_NON_TUN_QINQ) {
7931 		*pkt = dummy_qinq_ipv4_pkt;
7932 		*pkt_len = sizeof(dummy_qinq_ipv4_pkt);
7933 		*offsets = dummy_qinq_ipv4_packet_offsets;
7934 		return;
7935 	}
7936 
7937 	if (tun_type == ICE_SW_TUN_PPPOE_IPV6_QINQ) {
7938 		*pkt = dummy_qinq_pppoe_ipv6_packet;
7939 		*pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
7940 		*offsets = dummy_qinq_pppoe_packet_ipv6_offsets;
7941 		return;
7942 	} else if (tun_type == ICE_SW_TUN_PPPOE_IPV4_QINQ) {
7943 		*pkt = dummy_qinq_pppoe_ipv4_pkt;
7944 		*pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
7945 		*offsets = dummy_qinq_pppoe_ipv4_packet_offsets;
7946 		return;
7947 	} else if (tun_type == ICE_SW_TUN_PPPOE_QINQ && ipv6) {
7948 		*pkt = dummy_qinq_pppoe_ipv6_packet;
7949 		*pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
7950 		*offsets = dummy_qinq_pppoe_packet_offsets;
7951 		return;
7952 	} else if (tun_type == ICE_SW_TUN_PPPOE_QINQ ||
7953 			tun_type == ICE_SW_TUN_PPPOE_PAY_QINQ) {
7954 		*pkt = dummy_qinq_pppoe_ipv4_pkt;
7955 		*pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
7956 		*offsets = dummy_qinq_pppoe_packet_offsets;
7957 		return;
7958 	}
7959 
7960 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_NO_PAY) {
7961 		*pkt = dummy_ipv4_gtpu_ipv4_packet;
7962 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
7963 		*offsets = dummy_ipv4_gtp_no_pay_packet_offsets;
7964 		return;
7965 	} else if (tun_type == ICE_SW_TUN_IPV6_GTPU_NO_PAY) {
7966 		*pkt = dummy_ipv6_gtp_packet;
7967 		*pkt_len = sizeof(dummy_ipv6_gtp_packet);
7968 		*offsets = dummy_ipv6_gtp_no_pay_packet_offsets;
7969 		return;
7970 	}
7971 
7972 	if (tun_type == ICE_SW_TUN_IPV4_ESP) {
7973 		*pkt = dummy_ipv4_esp_pkt;
7974 		*pkt_len = sizeof(dummy_ipv4_esp_pkt);
7975 		*offsets = dummy_ipv4_esp_packet_offsets;
7976 		return;
7977 	}
7978 
7979 	if (tun_type == ICE_SW_TUN_IPV6_ESP) {
7980 		*pkt = dummy_ipv6_esp_pkt;
7981 		*pkt_len = sizeof(dummy_ipv6_esp_pkt);
7982 		*offsets = dummy_ipv6_esp_packet_offsets;
7983 		return;
7984 	}
7985 
7986 	if (tun_type == ICE_SW_TUN_IPV4_AH) {
7987 		*pkt = dummy_ipv4_ah_pkt;
7988 		*pkt_len = sizeof(dummy_ipv4_ah_pkt);
7989 		*offsets = dummy_ipv4_ah_packet_offsets;
7990 		return;
7991 	}
7992 
7993 	if (tun_type == ICE_SW_TUN_IPV6_AH) {
7994 		*pkt = dummy_ipv6_ah_pkt;
7995 		*pkt_len = sizeof(dummy_ipv6_ah_pkt);
7996 		*offsets = dummy_ipv6_ah_packet_offsets;
7997 		return;
7998 	}
7999 
8000 	if (tun_type == ICE_SW_TUN_IPV4_NAT_T) {
8001 		*pkt = dummy_ipv4_nat_pkt;
8002 		*pkt_len = sizeof(dummy_ipv4_nat_pkt);
8003 		*offsets = dummy_ipv4_nat_packet_offsets;
8004 		return;
8005 	}
8006 
8007 	if (tun_type == ICE_SW_TUN_IPV6_NAT_T) {
8008 		*pkt = dummy_ipv6_nat_pkt;
8009 		*pkt_len = sizeof(dummy_ipv6_nat_pkt);
8010 		*offsets = dummy_ipv6_nat_packet_offsets;
8011 		return;
8012 	}
8013 
8014 	if (tun_type == ICE_SW_TUN_IPV4_L2TPV3) {
8015 		*pkt = dummy_ipv4_l2tpv3_pkt;
8016 		*pkt_len = sizeof(dummy_ipv4_l2tpv3_pkt);
8017 		*offsets = dummy_ipv4_l2tpv3_packet_offsets;
8018 		return;
8019 	}
8020 
8021 	if (tun_type == ICE_SW_TUN_IPV6_L2TPV3) {
8022 		*pkt = dummy_ipv6_l2tpv3_pkt;
8023 		*pkt_len = sizeof(dummy_ipv6_l2tpv3_pkt);
8024 		*offsets = dummy_ipv6_l2tpv3_packet_offsets;
8025 		return;
8026 	}
8027 
8028 	if (tun_type == ICE_SW_TUN_GTP) {
8029 		*pkt = dummy_udp_gtp_packet;
8030 		*pkt_len = sizeof(dummy_udp_gtp_packet);
8031 		*offsets = dummy_udp_gtp_packet_offsets;
8032 		return;
8033 	}
8034 
8035 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4 ||
8036 	    tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4) {
8037 		*pkt = dummy_ipv4_gtpu_ipv4_packet;
8038 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
8039 		*offsets = dummy_ipv4_gtpu_ipv4_packet_offsets;
8040 		return;
8041 	}
8042 
8043 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4_UDP ||
8044 	    tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP) {
8045 		*pkt = dummy_ipv4_gtpu_ipv4_udp_packet;
8046 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_udp_packet);
8047 		*offsets = dummy_ipv4_gtpu_ipv4_udp_packet_offsets;
8048 		return;
8049 	}
8050 
8051 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4_TCP ||
8052 	    tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP) {
8053 		*pkt = dummy_ipv4_gtpu_ipv4_tcp_packet;
8054 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_tcp_packet);
8055 		*offsets = dummy_ipv4_gtpu_ipv4_tcp_packet_offsets;
8056 		return;
8057 	}
8058 
8059 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6 ||
8060 	    tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6) {
8061 		*pkt = dummy_ipv4_gtpu_ipv6_packet;
8062 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_packet);
8063 		*offsets = dummy_ipv4_gtpu_ipv6_packet_offsets;
8064 		return;
8065 	}
8066 
8067 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6_UDP ||
8068 	    tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP) {
8069 		*pkt = dummy_ipv4_gtpu_ipv6_udp_packet;
8070 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_udp_packet);
8071 		*offsets = dummy_ipv4_gtpu_ipv6_udp_packet_offsets;
8072 		return;
8073 	}
8074 
8075 	if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6_TCP ||
8076 	    tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP) {
8077 		*pkt = dummy_ipv4_gtpu_ipv6_tcp_packet;
8078 		*pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_tcp_packet);
8079 		*offsets = dummy_ipv4_gtpu_ipv6_tcp_packet_offsets;
8080 		return;
8081 	}
8082 
8083 	if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4 ||
8084 	    tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4) {
8085 		*pkt = dummy_ipv6_gtpu_ipv4_packet;
8086 		*pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_packet);
8087 		*offsets = dummy_ipv6_gtpu_ipv4_packet_offsets;
8088 		return;
8089 	}
8090 
8091 	if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4_UDP ||
8092 	    tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP) {
8093 		*pkt = dummy_ipv6_gtpu_ipv4_udp_packet;
8094 		*pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_udp_packet);
8095 		*offsets = dummy_ipv6_gtpu_ipv4_udp_packet_offsets;
8096 		return;
8097 	}
8098 
8099 	if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4_TCP ||
8100 	    tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP) {
8101 		*pkt = dummy_ipv6_gtpu_ipv4_tcp_packet;
8102 		*pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_tcp_packet);
8103 		*offsets = dummy_ipv6_gtpu_ipv4_tcp_packet_offsets;
8104 		return;
8105 	}
8106 
8107 	if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6 ||
8108 	    tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6) {
8109 		*pkt = dummy_ipv6_gtpu_ipv6_packet;
8110 		*pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
8111 		*offsets = dummy_ipv6_gtpu_ipv6_packet_offsets;
8112 		return;
8113 	}
8114 
8115 	if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6_UDP ||
8116 	    tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP) {
8117 		*pkt = dummy_ipv6_gtpu_ipv6_udp_packet;
8118 		*pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_udp_packet);
8119 		*offsets = dummy_ipv6_gtpu_ipv6_udp_packet_offsets;
8120 		return;
8121 	}
8122 
8123 	if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6_TCP ||
8124 	    tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP) {
8125 		*pkt = dummy_ipv6_gtpu_ipv6_tcp_packet;
8126 		*pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_tcp_packet);
8127 		*offsets = dummy_ipv6_gtpu_ipv6_tcp_packet_offsets;
8128 		return;
8129 	}
8130 
8131 	if (tun_type == ICE_SW_TUN_PPPOE && ipv6) {
8132 		*pkt = dummy_pppoe_ipv6_packet;
8133 		*pkt_len = sizeof(dummy_pppoe_ipv6_packet);
8134 		*offsets = dummy_pppoe_packet_offsets;
8135 		return;
8136 	} else if (tun_type == ICE_SW_TUN_PPPOE ||
8137 		tun_type == ICE_SW_TUN_PPPOE_PAY) {
8138 		*pkt = dummy_pppoe_ipv4_packet;
8139 		*pkt_len = sizeof(dummy_pppoe_ipv4_packet);
8140 		*offsets = dummy_pppoe_packet_offsets;
8141 		return;
8142 	}
8143 
8144 	if (tun_type == ICE_SW_TUN_PPPOE_IPV4) {
8145 		*pkt = dummy_pppoe_ipv4_packet;
8146 		*pkt_len = sizeof(dummy_pppoe_ipv4_packet);
8147 		*offsets = dummy_pppoe_packet_ipv4_offsets;
8148 		return;
8149 	}
8150 
8151 	if (tun_type == ICE_SW_TUN_PPPOE_IPV4_TCP) {
8152 		*pkt = dummy_pppoe_ipv4_tcp_packet;
8153 		*pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
8154 		*offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
8155 		return;
8156 	}
8157 
8158 	if (tun_type == ICE_SW_TUN_PPPOE_IPV4_UDP) {
8159 		*pkt = dummy_pppoe_ipv4_udp_packet;
8160 		*pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
8161 		*offsets = dummy_pppoe_ipv4_udp_packet_offsets;
8162 		return;
8163 	}
8164 
8165 	if (tun_type == ICE_SW_TUN_PPPOE_IPV6) {
8166 		*pkt = dummy_pppoe_ipv6_packet;
8167 		*pkt_len = sizeof(dummy_pppoe_ipv6_packet);
8168 		*offsets = dummy_pppoe_packet_ipv6_offsets;
8169 		return;
8170 	}
8171 
8172 	if (tun_type == ICE_SW_TUN_PPPOE_IPV6_TCP) {
8173 		*pkt = dummy_pppoe_ipv6_tcp_packet;
8174 		*pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
8175 		*offsets = dummy_pppoe_packet_ipv6_tcp_offsets;
8176 		return;
8177 	}
8178 
8179 	if (tun_type == ICE_SW_TUN_PPPOE_IPV6_UDP) {
8180 		*pkt = dummy_pppoe_ipv6_udp_packet;
8181 		*pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
8182 		*offsets = dummy_pppoe_packet_ipv6_udp_offsets;
8183 		return;
8184 	}
8185 
8186 	if (tun_type == ICE_SW_IPV4_TCP) {
8187 		*pkt = dummy_tcp_packet;
8188 		*pkt_len = sizeof(dummy_tcp_packet);
8189 		*offsets = dummy_tcp_packet_offsets;
8190 		return;
8191 	}
8192 
8193 	if (tun_type == ICE_SW_IPV4_UDP) {
8194 		*pkt = dummy_udp_packet;
8195 		*pkt_len = sizeof(dummy_udp_packet);
8196 		*offsets = dummy_udp_packet_offsets;
8197 		return;
8198 	}
8199 
8200 	if (tun_type == ICE_SW_IPV6_TCP) {
8201 		*pkt = dummy_tcp_ipv6_packet;
8202 		*pkt_len = sizeof(dummy_tcp_ipv6_packet);
8203 		*offsets = dummy_tcp_ipv6_packet_offsets;
8204 		return;
8205 	}
8206 
8207 	if (tun_type == ICE_SW_IPV6_UDP) {
8208 		*pkt = dummy_udp_ipv6_packet;
8209 		*pkt_len = sizeof(dummy_udp_ipv6_packet);
8210 		*offsets = dummy_udp_ipv6_packet_offsets;
8211 		return;
8212 	}
8213 
8214 	if (tun_type == ICE_ALL_TUNNELS) {
8215 		*pkt = dummy_gre_udp_packet;
8216 		*pkt_len = sizeof(dummy_gre_udp_packet);
8217 		*offsets = dummy_gre_udp_packet_offsets;
8218 		return;
8219 	}
8220 
8221 	if (tun_type == ICE_SW_TUN_NVGRE || gre) {
8222 		if (tcp) {
8223 			*pkt = dummy_gre_tcp_packet;
8224 			*pkt_len = sizeof(dummy_gre_tcp_packet);
8225 			*offsets = dummy_gre_tcp_packet_offsets;
8226 			return;
8227 		}
8228 
8229 		*pkt = dummy_gre_udp_packet;
8230 		*pkt_len = sizeof(dummy_gre_udp_packet);
8231 		*offsets = dummy_gre_udp_packet_offsets;
8232 		return;
8233 	}
8234 
8235 	if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE ||
8236 	    tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP ||
8237 	    tun_type == ICE_SW_TUN_GENEVE_VLAN ||
8238 	    tun_type == ICE_SW_TUN_VXLAN_VLAN) {
8239 		if (tcp) {
8240 			*pkt = dummy_udp_tun_tcp_packet;
8241 			*pkt_len = sizeof(dummy_udp_tun_tcp_packet);
8242 			*offsets = dummy_udp_tun_tcp_packet_offsets;
8243 			return;
8244 		}
8245 
8246 		*pkt = dummy_udp_tun_udp_packet;
8247 		*pkt_len = sizeof(dummy_udp_tun_udp_packet);
8248 		*offsets = dummy_udp_tun_udp_packet_offsets;
8249 		return;
8250 	}
8251 
8252 	if (udp && !ipv6) {
8253 		if (vlan) {
8254 			*pkt = dummy_vlan_udp_packet;
8255 			*pkt_len = sizeof(dummy_vlan_udp_packet);
8256 			*offsets = dummy_vlan_udp_packet_offsets;
8257 			return;
8258 		}
8259 		*pkt = dummy_udp_packet;
8260 		*pkt_len = sizeof(dummy_udp_packet);
8261 		*offsets = dummy_udp_packet_offsets;
8262 		return;
8263 	} else if (udp && ipv6) {
8264 		if (vlan) {
8265 			*pkt = dummy_vlan_udp_ipv6_packet;
8266 			*pkt_len = sizeof(dummy_vlan_udp_ipv6_packet);
8267 			*offsets = dummy_vlan_udp_ipv6_packet_offsets;
8268 			return;
8269 		}
8270 		*pkt = dummy_udp_ipv6_packet;
8271 		*pkt_len = sizeof(dummy_udp_ipv6_packet);
8272 		*offsets = dummy_udp_ipv6_packet_offsets;
8273 		return;
8274 	} else if ((tcp && ipv6) || ipv6) {
8275 		if (vlan) {
8276 			*pkt = dummy_vlan_tcp_ipv6_packet;
8277 			*pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet);
8278 			*offsets = dummy_vlan_tcp_ipv6_packet_offsets;
8279 			return;
8280 		}
8281 		*pkt = dummy_tcp_ipv6_packet;
8282 		*pkt_len = sizeof(dummy_tcp_ipv6_packet);
8283 		*offsets = dummy_tcp_ipv6_packet_offsets;
8284 		return;
8285 	}
8286 
8287 	if (vlan) {
8288 		*pkt = dummy_vlan_tcp_packet;
8289 		*pkt_len = sizeof(dummy_vlan_tcp_packet);
8290 		*offsets = dummy_vlan_tcp_packet_offsets;
8291 	}  else if (mpls) {
8292 		*pkt = dummy_mpls_packet;
8293 		*pkt_len = sizeof(dummy_mpls_packet);
8294 		*offsets = dummy_mpls_packet_offsets;
8295 	} else {
8296 		*pkt = dummy_tcp_packet;
8297 		*pkt_len = sizeof(dummy_tcp_packet);
8298 		*offsets = dummy_tcp_packet_offsets;
8299 	}
8300 }
8301 
8302 /**
8303  * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
8304  *
8305  * @lkups: lookup elements or match criteria for the advanced recipe, one
8306  *	   structure per protocol header
8307  * @lkups_cnt: number of protocols
8308  * @s_rule: stores rule information from the match criteria
8309  * @dummy_pkt: dummy packet to fill according to filter match criteria
8310  * @pkt_len: packet length of dummy packet
8311  * @offsets: offset info for the dummy packet
8312  */
8313 static enum ice_status
8314 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8315 			  struct ice_aqc_sw_rules_elem *s_rule,
8316 			  const u8 *dummy_pkt, u16 pkt_len,
8317 			  const struct ice_dummy_pkt_offsets *offsets)
8318 {
8319 	u8 *pkt;
8320 	u16 i;
8321 
8322 	/* Start with a packet with a pre-defined/dummy content. Then, fill
8323 	 * in the header values to be looked up or matched.
8324 	 */
8325 	pkt = s_rule->pdata.lkup_tx_rx.hdr;
8326 
8327 	ice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA);
8328 
8329 	for (i = 0; i < lkups_cnt; i++) {
8330 		enum ice_protocol_type type;
8331 		u16 offset = 0, len = 0, j;
8332 		bool found = false;
8333 
8334 		/* find the start of this layer; it should be found since this
8335 		 * was already checked when search for the dummy packet
8336 		 */
8337 		type = lkups[i].type;
8338 		for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
8339 			if (type == offsets[j].type) {
8340 				offset = offsets[j].offset;
8341 				found = true;
8342 				break;
8343 			}
8344 		}
8345 		/* this should never happen in a correct calling sequence */
8346 		if (!found)
8347 			return ICE_ERR_PARAM;
8348 
8349 		switch (lkups[i].type) {
8350 		case ICE_MAC_OFOS:
8351 		case ICE_MAC_IL:
8352 			len = sizeof(struct ice_ether_hdr);
8353 			break;
8354 		case ICE_ETYPE_OL:
8355 			len = sizeof(struct ice_ethtype_hdr);
8356 			break;
8357 		case ICE_VLAN_OFOS:
8358 		case ICE_VLAN_EX:
8359 		case ICE_VLAN_IN:
8360 			len = sizeof(struct ice_vlan_hdr);
8361 			break;
8362 		case ICE_IPV4_OFOS:
8363 		case ICE_IPV4_IL:
8364 			len = sizeof(struct ice_ipv4_hdr);
8365 			break;
8366 		case ICE_IPV6_OFOS:
8367 		case ICE_IPV6_IL:
8368 			len = sizeof(struct ice_ipv6_hdr);
8369 			break;
8370 		case ICE_TCP_IL:
8371 		case ICE_UDP_OF:
8372 		case ICE_UDP_ILOS:
8373 			len = sizeof(struct ice_l4_hdr);
8374 			break;
8375 		case ICE_SCTP_IL:
8376 			len = sizeof(struct ice_sctp_hdr);
8377 			break;
8378 		case ICE_NVGRE:
8379 			len = sizeof(struct ice_nvgre);
8380 			break;
8381 		case ICE_VXLAN:
8382 		case ICE_GENEVE:
8383 		case ICE_VXLAN_GPE:
8384 			len = sizeof(struct ice_udp_tnl_hdr);
8385 			break;
8386 
8387 		case ICE_GTP:
8388 		case ICE_GTP_NO_PAY:
8389 			len = sizeof(struct ice_udp_gtp_hdr);
8390 			break;
8391 		case ICE_PPPOE:
8392 			len = sizeof(struct ice_pppoe_hdr);
8393 			break;
8394 		case ICE_ESP:
8395 			len = sizeof(struct ice_esp_hdr);
8396 			break;
8397 		case ICE_NAT_T:
8398 			len = sizeof(struct ice_nat_t_hdr);
8399 			break;
8400 		case ICE_AH:
8401 			len = sizeof(struct ice_ah_hdr);
8402 			break;
8403 		case ICE_L2TPV3:
8404 			len = sizeof(struct ice_l2tpv3_sess_hdr);
8405 			break;
8406 		default:
8407 			return ICE_ERR_PARAM;
8408 		}
8409 
8410 		/* the length should be a word multiple */
8411 		if (len % ICE_BYTES_PER_WORD)
8412 			return ICE_ERR_CFG;
8413 
8414 		/* We have the offset to the header start, the length, the
8415 		 * caller's header values and mask. Use this information to
8416 		 * copy the data into the dummy packet appropriately based on
8417 		 * the mask. Note that we need to only write the bits as
8418 		 * indicated by the mask to make sure we don't improperly write
8419 		 * over any significant packet data.
8420 		 */
8421 		for (j = 0; j < len / sizeof(u16); j++)
8422 			if (((u16 *)&lkups[i].m_u)[j])
8423 				((u16 *)(pkt + offset))[j] =
8424 					(((u16 *)(pkt + offset))[j] &
8425 					 ~((u16 *)&lkups[i].m_u)[j]) |
8426 					(((u16 *)&lkups[i].h_u)[j] &
8427 					 ((u16 *)&lkups[i].m_u)[j]);
8428 	}
8429 
8430 	s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(pkt_len);
8431 
8432 	return ICE_SUCCESS;
8433 }
8434 
8435 /**
8436  * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
8437  * @hw: pointer to the hardware structure
8438  * @tun_type: tunnel type
8439  * @pkt: dummy packet to fill in
8440  * @offsets: offset info for the dummy packet
8441  */
8442 static enum ice_status
8443 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
8444 			u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
8445 {
8446 	u16 open_port, i;
8447 
8448 	switch (tun_type) {
8449 	case ICE_SW_TUN_AND_NON_TUN:
8450 	case ICE_SW_TUN_VXLAN_GPE:
8451 	case ICE_SW_TUN_VXLAN:
8452 	case ICE_SW_TUN_VXLAN_VLAN:
8453 	case ICE_SW_TUN_UDP:
8454 		if (!ice_get_open_tunnel_port(hw, TNL_VXLAN, &open_port))
8455 			return ICE_ERR_CFG;
8456 		break;
8457 
8458 	case ICE_SW_TUN_GENEVE:
8459 	case ICE_SW_TUN_GENEVE_VLAN:
8460 		if (!ice_get_open_tunnel_port(hw, TNL_GENEVE, &open_port))
8461 			return ICE_ERR_CFG;
8462 		break;
8463 
8464 	default:
8465 		/* Nothing needs to be done for this tunnel type */
8466 		return ICE_SUCCESS;
8467 	}
8468 
8469 	/* Find the outer UDP protocol header and insert the port number */
8470 	for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
8471 		if (offsets[i].type == ICE_UDP_OF) {
8472 			struct ice_l4_hdr *hdr;
8473 			u16 offset;
8474 
8475 			offset = offsets[i].offset;
8476 			hdr = (struct ice_l4_hdr *)&pkt[offset];
8477 			hdr->dst_port = CPU_TO_BE16(open_port);
8478 
8479 			return ICE_SUCCESS;
8480 		}
8481 	}
8482 
8483 	return ICE_ERR_CFG;
8484 }
8485 
8486 /**
8487  * ice_find_adv_rule_entry - Search a rule entry
8488  * @hw: pointer to the hardware structure
8489  * @lkups: lookup elements or match criteria for the advanced recipe, one
8490  *	   structure per protocol header
8491  * @lkups_cnt: number of protocols
8492  * @recp_id: recipe ID for which we are finding the rule
8493  * @rinfo: other information regarding the rule e.g. priority and action info
8494  *
8495  * Helper function to search for a given advance rule entry
8496  * Returns pointer to entry storing the rule if found
8497  */
8498 static struct ice_adv_fltr_mgmt_list_entry *
8499 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8500 			u16 lkups_cnt, u16 recp_id,
8501 			struct ice_adv_rule_info *rinfo)
8502 {
8503 	struct ice_adv_fltr_mgmt_list_entry *list_itr;
8504 	struct ice_switch_info *sw = hw->switch_info;
8505 	int i;
8506 
8507 	LIST_FOR_EACH_ENTRY(list_itr, &sw->recp_list[recp_id].filt_rules,
8508 			    ice_adv_fltr_mgmt_list_entry, list_entry) {
8509 		bool lkups_matched = true;
8510 
8511 		if (lkups_cnt != list_itr->lkups_cnt)
8512 			continue;
8513 		for (i = 0; i < list_itr->lkups_cnt; i++)
8514 			if (memcmp(&list_itr->lkups[i], &lkups[i],
8515 				   sizeof(*lkups))) {
8516 				lkups_matched = false;
8517 				break;
8518 			}
8519 		if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
8520 		    rinfo->tun_type == list_itr->rule_info.tun_type &&
8521 		    lkups_matched)
8522 			return list_itr;
8523 	}
8524 	return NULL;
8525 }
8526 
8527 /**
8528  * ice_adv_add_update_vsi_list
8529  * @hw: pointer to the hardware structure
8530  * @m_entry: pointer to current adv filter management list entry
8531  * @cur_fltr: filter information from the book keeping entry
8532  * @new_fltr: filter information with the new VSI to be added
8533  *
8534  * Call AQ command to add or update previously created VSI list with new VSI.
8535  *
8536  * Helper function to do book keeping associated with adding filter information
8537  * The algorithm to do the booking keeping is described below :
8538  * When a VSI needs to subscribe to a given advanced filter
8539  *	if only one VSI has been added till now
8540  *		Allocate a new VSI list and add two VSIs
8541  *		to this list using switch rule command
8542  *		Update the previously created switch rule with the
8543  *		newly created VSI list ID
8544  *	if a VSI list was previously created
8545  *		Add the new VSI to the previously created VSI list set
8546  *		using the update switch rule command
8547  */
8548 static enum ice_status
8549 ice_adv_add_update_vsi_list(struct ice_hw *hw,
8550 			    struct ice_adv_fltr_mgmt_list_entry *m_entry,
8551 			    struct ice_adv_rule_info *cur_fltr,
8552 			    struct ice_adv_rule_info *new_fltr)
8553 {
8554 	enum ice_status status;
8555 	u16 vsi_list_id = 0;
8556 
8557 	if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
8558 	    cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
8559 	    cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
8560 		return ICE_ERR_NOT_IMPL;
8561 
8562 	if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
8563 	     new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
8564 	    (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
8565 	     cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
8566 		return ICE_ERR_NOT_IMPL;
8567 
8568 	if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
8569 		 /* Only one entry existed in the mapping and it was not already
8570 		  * a part of a VSI list. So, create a VSI list with the old and
8571 		  * new VSIs.
8572 		  */
8573 		struct ice_fltr_info tmp_fltr;
8574 		u16 vsi_handle_arr[2];
8575 
8576 		/* A rule already exists with the new VSI being added */
8577 		if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
8578 		    new_fltr->sw_act.fwd_id.hw_vsi_id)
8579 			return ICE_ERR_ALREADY_EXISTS;
8580 
8581 		vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
8582 		vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
8583 		status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
8584 						  &vsi_list_id,
8585 						  ICE_SW_LKUP_LAST);
8586 		if (status)
8587 			return status;
8588 
8589 		ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
8590 		tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
8591 		tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
8592 		tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
8593 		tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
8594 		tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
8595 
8596 		/* Update the previous switch rule of "forward to VSI" to
8597 		 * "fwd to VSI list"
8598 		 */
8599 		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
8600 		if (status)
8601 			return status;
8602 
8603 		cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
8604 		cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
8605 		m_entry->vsi_list_info =
8606 			ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
8607 						vsi_list_id);
8608 	} else {
8609 		u16 vsi_handle = new_fltr->sw_act.vsi_handle;
8610 
8611 		if (!m_entry->vsi_list_info)
8612 			return ICE_ERR_CFG;
8613 
8614 		/* A rule already exists with the new VSI being added */
8615 		if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
8616 			return ICE_SUCCESS;
8617 
8618 		/* Update the previously created VSI list set with
8619 		 * the new VSI ID passed in
8620 		 */
8621 		vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
8622 
8623 		status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
8624 						  vsi_list_id, false,
8625 						  ice_aqc_opc_update_sw_rules,
8626 						  ICE_SW_LKUP_LAST);
8627 		/* update VSI list mapping info with new VSI ID */
8628 		if (!status)
8629 			ice_set_bit(vsi_handle,
8630 				    m_entry->vsi_list_info->vsi_map);
8631 	}
8632 	if (!status)
8633 		m_entry->vsi_count++;
8634 	return status;
8635 }
8636 
8637 /**
8638  * ice_add_adv_rule - helper function to create an advanced switch rule
8639  * @hw: pointer to the hardware structure
8640  * @lkups: information on the words that needs to be looked up. All words
8641  * together makes one recipe
8642  * @lkups_cnt: num of entries in the lkups array
8643  * @rinfo: other information related to the rule that needs to be programmed
8644  * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
8645  *               ignored is case of error.
8646  *
8647  * This function can program only 1 rule at a time. The lkups is used to
8648  * describe the all the words that forms the "lookup" portion of the recipe.
8649  * These words can span multiple protocols. Callers to this function need to
8650  * pass in a list of protocol headers with lookup information along and mask
8651  * that determines which words are valid from the given protocol header.
8652  * rinfo describes other information related to this rule such as forwarding
8653  * IDs, priority of this rule, etc.
8654  */
8655 enum ice_status
8656 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8657 		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
8658 		 struct ice_rule_query_data *added_entry)
8659 {
8660 	struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
8661 	u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;
8662 	const struct ice_dummy_pkt_offsets *pkt_offsets;
8663 	struct ice_aqc_sw_rules_elem *s_rule = NULL;
8664 	struct LIST_HEAD_TYPE *rule_head;
8665 	struct ice_switch_info *sw;
8666 	enum ice_status status;
8667 	const u8 *pkt = NULL;
8668 	bool prof_rule;
8669 	u16 word_cnt;
8670 	u32 act = 0;
8671 	u8 q_rgn;
8672 
8673 	/* Initialize profile to result index bitmap */
8674 	if (!hw->switch_info->prof_res_bm_init) {
8675 		hw->switch_info->prof_res_bm_init = 1;
8676 		ice_init_prof_result_bm(hw);
8677 	}
8678 
8679 	prof_rule = ice_is_prof_rule(rinfo->tun_type);
8680 	if (!prof_rule && !lkups_cnt)
8681 		return ICE_ERR_PARAM;
8682 
8683 	/* get # of words we need to match */
8684 	word_cnt = 0;
8685 	for (i = 0; i < lkups_cnt; i++) {
8686 		u16 j, *ptr;
8687 
8688 		ptr = (u16 *)&lkups[i].m_u;
8689 		for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)
8690 			if (ptr[j] != 0)
8691 				word_cnt++;
8692 	}
8693 
8694 	if (prof_rule) {
8695 		if (word_cnt > ICE_MAX_CHAIN_WORDS)
8696 			return ICE_ERR_PARAM;
8697 	} else {
8698 		if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS)
8699 			return ICE_ERR_PARAM;
8700 	}
8701 
8702 	/* make sure that we can locate a dummy packet */
8703 	ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
8704 			      &pkt_offsets);
8705 	if (!pkt) {
8706 		status = ICE_ERR_PARAM;
8707 		goto err_ice_add_adv_rule;
8708 	}
8709 
8710 	if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
8711 	      rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
8712 	      rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
8713 	      rinfo->sw_act.fltr_act == ICE_DROP_PACKET))
8714 		return ICE_ERR_CFG;
8715 
8716 	vsi_handle = rinfo->sw_act.vsi_handle;
8717 	if (!ice_is_vsi_valid(hw, vsi_handle))
8718 		return ICE_ERR_PARAM;
8719 
8720 	if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
8721 		rinfo->sw_act.fwd_id.hw_vsi_id =
8722 			ice_get_hw_vsi_num(hw, vsi_handle);
8723 	if (rinfo->sw_act.flag & ICE_FLTR_TX)
8724 		rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
8725 
8726 	status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
8727 	if (status)
8728 		return status;
8729 	m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
8730 	if (m_entry) {
8731 		/* we have to add VSI to VSI_LIST and increment vsi_count.
8732 		 * Also Update VSI list so that we can change forwarding rule
8733 		 * if the rule already exists, we will check if it exists with
8734 		 * same vsi_id, if not then add it to the VSI list if it already
8735 		 * exists if not then create a VSI list and add the existing VSI
8736 		 * ID and the new VSI ID to the list
8737 		 * We will add that VSI to the list
8738 		 */
8739 		status = ice_adv_add_update_vsi_list(hw, m_entry,
8740 						     &m_entry->rule_info,
8741 						     rinfo);
8742 		if (added_entry) {
8743 			added_entry->rid = rid;
8744 			added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
8745 			added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
8746 		}
8747 		return status;
8748 	}
8749 	rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;
8750 	s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rule_buf_sz);
8751 	if (!s_rule)
8752 		return ICE_ERR_NO_MEMORY;
8753 	act |= ICE_SINGLE_ACT_LAN_ENABLE;
8754 	switch (rinfo->sw_act.fltr_act) {
8755 	case ICE_FWD_TO_VSI:
8756 		act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
8757 			ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
8758 		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
8759 		break;
8760 	case ICE_FWD_TO_Q:
8761 		act |= ICE_SINGLE_ACT_TO_Q;
8762 		act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
8763 		       ICE_SINGLE_ACT_Q_INDEX_M;
8764 		break;
8765 	case ICE_FWD_TO_QGRP:
8766 		q_rgn = rinfo->sw_act.qgrp_size > 0 ?
8767 			(u8)ice_ilog2(rinfo->sw_act.qgrp_size) : 0;
8768 		act |= ICE_SINGLE_ACT_TO_Q;
8769 		act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
8770 		       ICE_SINGLE_ACT_Q_INDEX_M;
8771 		act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
8772 		       ICE_SINGLE_ACT_Q_REGION_M;
8773 		break;
8774 	case ICE_DROP_PACKET:
8775 		act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
8776 		       ICE_SINGLE_ACT_VALID_BIT;
8777 		break;
8778 	default:
8779 		status = ICE_ERR_CFG;
8780 		goto err_ice_add_adv_rule;
8781 	}
8782 
8783 	/* set the rule LOOKUP type based on caller specified 'RX'
8784 	 * instead of hardcoding it to be either LOOKUP_TX/RX
8785 	 *
8786 	 * for 'RX' set the source to be the port number
8787 	 * for 'TX' set the source to be the source HW VSI number (determined
8788 	 * by caller)
8789 	 */
8790 	if (rinfo->rx) {
8791 		s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX);
8792 		s_rule->pdata.lkup_tx_rx.src =
8793 			CPU_TO_LE16(hw->port_info->lport);
8794 	} else {
8795 		s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
8796 		s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(rinfo->sw_act.src);
8797 	}
8798 
8799 	s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(rid);
8800 	s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
8801 
8802 	status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt,
8803 					   pkt_len, pkt_offsets);
8804 	if (status)
8805 		goto err_ice_add_adv_rule;
8806 
8807 	if (rinfo->tun_type != ICE_NON_TUN &&
8808 	    rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
8809 		status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
8810 						 s_rule->pdata.lkup_tx_rx.hdr,
8811 						 pkt_offsets);
8812 		if (status)
8813 			goto err_ice_add_adv_rule;
8814 	}
8815 
8816 	status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
8817 				 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
8818 				 NULL);
8819 	if (status)
8820 		goto err_ice_add_adv_rule;
8821 	adv_fltr = (struct ice_adv_fltr_mgmt_list_entry *)
8822 		ice_malloc(hw, sizeof(struct ice_adv_fltr_mgmt_list_entry));
8823 	if (!adv_fltr) {
8824 		status = ICE_ERR_NO_MEMORY;
8825 		goto err_ice_add_adv_rule;
8826 	}
8827 
8828 	adv_fltr->lkups = (struct ice_adv_lkup_elem *)
8829 		ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups),
8830 			   ICE_NONDMA_TO_NONDMA);
8831 	if (!adv_fltr->lkups && !prof_rule) {
8832 		status = ICE_ERR_NO_MEMORY;
8833 		goto err_ice_add_adv_rule;
8834 	}
8835 
8836 	adv_fltr->lkups_cnt = lkups_cnt;
8837 	adv_fltr->rule_info = *rinfo;
8838 	adv_fltr->rule_info.fltr_rule_id =
8839 		LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
8840 	sw = hw->switch_info;
8841 	sw->recp_list[rid].adv_rule = true;
8842 	rule_head = &sw->recp_list[rid].filt_rules;
8843 
8844 	if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
8845 		adv_fltr->vsi_count = 1;
8846 
8847 	/* Add rule entry to book keeping list */
8848 	LIST_ADD(&adv_fltr->list_entry, rule_head);
8849 	if (added_entry) {
8850 		added_entry->rid = rid;
8851 		added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
8852 		added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
8853 	}
8854 err_ice_add_adv_rule:
8855 	if (status && adv_fltr) {
8856 		ice_free(hw, adv_fltr->lkups);
8857 		ice_free(hw, adv_fltr);
8858 	}
8859 
8860 	ice_free(hw, s_rule);
8861 
8862 	return status;
8863 }
8864 
8865 /**
8866  * ice_adv_rem_update_vsi_list
8867  * @hw: pointer to the hardware structure
8868  * @vsi_handle: VSI handle of the VSI to remove
8869  * @fm_list: filter management entry for which the VSI list management needs to
8870  *	     be done
8871  */
8872 static enum ice_status
8873 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
8874 			    struct ice_adv_fltr_mgmt_list_entry *fm_list)
8875 {
8876 	struct ice_vsi_list_map_info *vsi_list_info;
8877 	enum ice_sw_lkup_type lkup_type;
8878 	enum ice_status status;
8879 	u16 vsi_list_id;
8880 
8881 	if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
8882 	    fm_list->vsi_count == 0)
8883 		return ICE_ERR_PARAM;
8884 
8885 	/* A rule with the VSI being removed does not exist */
8886 	if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
8887 		return ICE_ERR_DOES_NOT_EXIST;
8888 
8889 	lkup_type = ICE_SW_LKUP_LAST;
8890 	vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
8891 	status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
8892 					  ice_aqc_opc_update_sw_rules,
8893 					  lkup_type);
8894 	if (status)
8895 		return status;
8896 
8897 	fm_list->vsi_count--;
8898 	ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
8899 	vsi_list_info = fm_list->vsi_list_info;
8900 	if (fm_list->vsi_count == 1) {
8901 		struct ice_fltr_info tmp_fltr;
8902 		u16 rem_vsi_handle;
8903 
8904 		rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
8905 						    ICE_MAX_VSI);
8906 		if (!ice_is_vsi_valid(hw, rem_vsi_handle))
8907 			return ICE_ERR_OUT_OF_RANGE;
8908 
8909 		/* Make sure VSI list is empty before removing it below */
8910 		status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
8911 						  vsi_list_id, true,
8912 						  ice_aqc_opc_update_sw_rules,
8913 						  lkup_type);
8914 		if (status)
8915 			return status;
8916 
8917 		ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
8918 		tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
8919 		tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
8920 		fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
8921 		tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
8922 		tmp_fltr.fwd_id.hw_vsi_id =
8923 			ice_get_hw_vsi_num(hw, rem_vsi_handle);
8924 		fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
8925 			ice_get_hw_vsi_num(hw, rem_vsi_handle);
8926 		fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
8927 
8928 		/* Update the previous switch rule of "MAC forward to VSI" to
8929 		 * "MAC fwd to VSI list"
8930 		 */
8931 		status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
8932 		if (status) {
8933 			ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
8934 				  tmp_fltr.fwd_id.hw_vsi_id, status);
8935 			return status;
8936 		}
8937 		fm_list->vsi_list_info->ref_cnt--;
8938 
8939 		/* Remove the VSI list since it is no longer used */
8940 		status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
8941 		if (status) {
8942 			ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
8943 				  vsi_list_id, status);
8944 			return status;
8945 		}
8946 
8947 		LIST_DEL(&vsi_list_info->list_entry);
8948 		ice_free(hw, vsi_list_info);
8949 		fm_list->vsi_list_info = NULL;
8950 	}
8951 
8952 	return status;
8953 }
8954 
8955 /**
8956  * ice_rem_adv_rule - removes existing advanced switch rule
8957  * @hw: pointer to the hardware structure
8958  * @lkups: information on the words that needs to be looked up. All words
8959  *         together makes one recipe
8960  * @lkups_cnt: num of entries in the lkups array
8961  * @rinfo: Its the pointer to the rule information for the rule
8962  *
8963  * This function can be used to remove 1 rule at a time. The lkups is
8964  * used to describe all the words that forms the "lookup" portion of the
8965  * rule. These words can span multiple protocols. Callers to this function
8966  * need to pass in a list of protocol headers with lookup information along
8967  * and mask that determines which words are valid from the given protocol
8968  * header. rinfo describes other information related to this rule such as
8969  * forwarding IDs, priority of this rule, etc.
8970  */
8971 enum ice_status
8972 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8973 		 u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
8974 {
8975 	struct ice_adv_fltr_mgmt_list_entry *list_elem;
8976 	struct ice_prot_lkup_ext lkup_exts;
8977 	struct ice_lock *rule_lock; /* Lock to protect filter rule list */
8978 	enum ice_status status = ICE_SUCCESS;
8979 	bool remove_rule = false;
8980 	u16 i, rid, vsi_handle;
8981 
8982 	ice_memset(&lkup_exts, 0, sizeof(lkup_exts), ICE_NONDMA_MEM);
8983 	for (i = 0; i < lkups_cnt; i++) {
8984 		u16 count;
8985 
8986 		if (lkups[i].type >= ICE_PROTOCOL_LAST)
8987 			return ICE_ERR_CFG;
8988 
8989 		count = ice_fill_valid_words(&lkups[i], &lkup_exts);
8990 		if (!count)
8991 			return ICE_ERR_CFG;
8992 	}
8993 
8994 	/* Create any special protocol/offset pairs, such as looking at tunnel
8995 	 * bits by extracting metadata
8996 	 */
8997 	status = ice_add_special_words(rinfo, &lkup_exts);
8998 	if (status)
8999 		return status;
9000 
9001 	rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type, rinfo->priority);
9002 	/* If did not find a recipe that match the existing criteria */
9003 	if (rid == ICE_MAX_NUM_RECIPES)
9004 		return ICE_ERR_PARAM;
9005 
9006 	rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
9007 	list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
9008 	/* the rule is already removed */
9009 	if (!list_elem)
9010 		return ICE_SUCCESS;
9011 	ice_acquire_lock(rule_lock);
9012 	if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
9013 		remove_rule = true;
9014 	} else if (list_elem->vsi_count > 1) {
9015 		remove_rule = false;
9016 		vsi_handle = rinfo->sw_act.vsi_handle;
9017 		status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
9018 	} else {
9019 		vsi_handle = rinfo->sw_act.vsi_handle;
9020 		status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
9021 		if (status) {
9022 			ice_release_lock(rule_lock);
9023 			return status;
9024 		}
9025 		if (list_elem->vsi_count == 0)
9026 			remove_rule = true;
9027 	}
9028 	ice_release_lock(rule_lock);
9029 	if (remove_rule) {
9030 		struct ice_aqc_sw_rules_elem *s_rule;
9031 		u16 rule_buf_sz;
9032 
9033 		rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
9034 		s_rule = (struct ice_aqc_sw_rules_elem *)
9035 			ice_malloc(hw, rule_buf_sz);
9036 		if (!s_rule)
9037 			return ICE_ERR_NO_MEMORY;
9038 		s_rule->pdata.lkup_tx_rx.act = 0;
9039 		s_rule->pdata.lkup_tx_rx.index =
9040 			CPU_TO_LE16(list_elem->rule_info.fltr_rule_id);
9041 		s_rule->pdata.lkup_tx_rx.hdr_len = 0;
9042 		status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
9043 					 rule_buf_sz, 1,
9044 					 ice_aqc_opc_remove_sw_rules, NULL);
9045 		if (status == ICE_SUCCESS || status == ICE_ERR_DOES_NOT_EXIST) {
9046 			struct ice_switch_info *sw = hw->switch_info;
9047 
9048 			ice_acquire_lock(rule_lock);
9049 			LIST_DEL(&list_elem->list_entry);
9050 			ice_free(hw, list_elem->lkups);
9051 			ice_free(hw, list_elem);
9052 			ice_release_lock(rule_lock);
9053 			if (LIST_EMPTY(&sw->recp_list[rid].filt_rules))
9054 				sw->recp_list[rid].adv_rule = false;
9055 		}
9056 		ice_free(hw, s_rule);
9057 	}
9058 	return status;
9059 }
9060 
9061 /**
9062  * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
9063  * @hw: pointer to the hardware structure
9064  * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
9065  *
9066  * This function is used to remove 1 rule at a time. The removal is based on
9067  * the remove_entry parameter. This function will remove rule for a given
9068  * vsi_handle with a given rule_id which is passed as parameter in remove_entry
9069  */
9070 enum ice_status
9071 ice_rem_adv_rule_by_id(struct ice_hw *hw,
9072 		       struct ice_rule_query_data *remove_entry)
9073 {
9074 	struct ice_adv_fltr_mgmt_list_entry *list_itr;
9075 	struct LIST_HEAD_TYPE *list_head;
9076 	struct ice_adv_rule_info rinfo;
9077 	struct ice_switch_info *sw;
9078 
9079 	sw = hw->switch_info;
9080 	if (!sw->recp_list[remove_entry->rid].recp_created)
9081 		return ICE_ERR_PARAM;
9082 	list_head = &sw->recp_list[remove_entry->rid].filt_rules;
9083 	LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_adv_fltr_mgmt_list_entry,
9084 			    list_entry) {
9085 		if (list_itr->rule_info.fltr_rule_id ==
9086 		    remove_entry->rule_id) {
9087 			rinfo = list_itr->rule_info;
9088 			rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
9089 			return ice_rem_adv_rule(hw, list_itr->lkups,
9090 						list_itr->lkups_cnt, &rinfo);
9091 		}
9092 	}
9093 	/* either list is empty or unable to find rule */
9094 	return ICE_ERR_DOES_NOT_EXIST;
9095 }
9096 
9097 /**
9098  * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a
9099  *                       given VSI handle
9100  * @hw: pointer to the hardware structure
9101  * @vsi_handle: VSI handle for which we are supposed to remove all the rules.
9102  *
9103  * This function is used to remove all the rules for a given VSI and as soon
9104  * as removing a rule fails, it will return immediately with the error code,
9105  * else it will return ICE_SUCCESS
9106  */
9107 enum ice_status ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
9108 {
9109 	struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
9110 	struct ice_vsi_list_map_info *map_info;
9111 	struct LIST_HEAD_TYPE *list_head;
9112 	struct ice_adv_rule_info rinfo;
9113 	struct ice_switch_info *sw;
9114 	enum ice_status status;
9115 	u8 rid;
9116 
9117 	sw = hw->switch_info;
9118 	for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
9119 		if (!sw->recp_list[rid].recp_created)
9120 			continue;
9121 		if (!sw->recp_list[rid].adv_rule)
9122 			continue;
9123 
9124 		list_head = &sw->recp_list[rid].filt_rules;
9125 		LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp_entry, list_head,
9126 					 ice_adv_fltr_mgmt_list_entry,
9127 					 list_entry) {
9128 			rinfo = list_itr->rule_info;
9129 
9130 			if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
9131 				map_info = list_itr->vsi_list_info;
9132 				if (!map_info)
9133 					continue;
9134 
9135 				if (!ice_is_bit_set(map_info->vsi_map,
9136 						    vsi_handle))
9137 					continue;
9138 			} else if (rinfo.sw_act.vsi_handle != vsi_handle) {
9139 				continue;
9140 			}
9141 
9142 			rinfo.sw_act.vsi_handle = vsi_handle;
9143 			status = ice_rem_adv_rule(hw, list_itr->lkups,
9144 						  list_itr->lkups_cnt, &rinfo);
9145 
9146 			if (status)
9147 				return status;
9148 		}
9149 	}
9150 	return ICE_SUCCESS;
9151 }
9152 
9153 /**
9154  * ice_replay_fltr - Replay all the filters stored by a specific list head
9155  * @hw: pointer to the hardware structure
9156  * @list_head: list for which filters needs to be replayed
9157  * @recp_id: Recipe ID for which rules need to be replayed
9158  */
9159 static enum ice_status
9160 ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head)
9161 {
9162 	struct ice_fltr_mgmt_list_entry *itr;
9163 	enum ice_status status = ICE_SUCCESS;
9164 	struct ice_sw_recipe *recp_list;
9165 	u8 lport = hw->port_info->lport;
9166 	struct LIST_HEAD_TYPE l_head;
9167 
9168 	if (LIST_EMPTY(list_head))
9169 		return status;
9170 
9171 	recp_list = &hw->switch_info->recp_list[recp_id];
9172 	/* Move entries from the given list_head to a temporary l_head so that
9173 	 * they can be replayed. Otherwise when trying to re-add the same
9174 	 * filter, the function will return already exists
9175 	 */
9176 	LIST_REPLACE_INIT(list_head, &l_head);
9177 
9178 	/* Mark the given list_head empty by reinitializing it so filters
9179 	 * could be added again by *handler
9180 	 */
9181 	LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry,
9182 			    list_entry) {
9183 		struct ice_fltr_list_entry f_entry;
9184 		u16 vsi_handle;
9185 
9186 		f_entry.fltr_info = itr->fltr_info;
9187 		if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
9188 			status = ice_add_rule_internal(hw, recp_list, lport,
9189 						       &f_entry);
9190 			if (status != ICE_SUCCESS)
9191 				goto end;
9192 			continue;
9193 		}
9194 
9195 		/* Add a filter per VSI separately */
9196 		ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map,
9197 				     ICE_MAX_VSI) {
9198 			if (!ice_is_vsi_valid(hw, vsi_handle))
9199 				break;
9200 
9201 			ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
9202 			f_entry.fltr_info.vsi_handle = vsi_handle;
9203 			f_entry.fltr_info.fwd_id.hw_vsi_id =
9204 				ice_get_hw_vsi_num(hw, vsi_handle);
9205 			f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
9206 			if (recp_id == ICE_SW_LKUP_VLAN)
9207 				status = ice_add_vlan_internal(hw, recp_list,
9208 							       &f_entry);
9209 			else
9210 				status = ice_add_rule_internal(hw, recp_list,
9211 							       lport,
9212 							       &f_entry);
9213 			if (status != ICE_SUCCESS)
9214 				goto end;
9215 		}
9216 	}
9217 end:
9218 	/* Clear the filter management list */
9219 	ice_rem_sw_rule_info(hw, &l_head);
9220 	return status;
9221 }
9222 
9223 /**
9224  * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
9225  * @hw: pointer to the hardware structure
9226  *
9227  * NOTE: This function does not clean up partially added filters on error.
9228  * It is up to caller of the function to issue a reset or fail early.
9229  */
9230 enum ice_status ice_replay_all_fltr(struct ice_hw *hw)
9231 {
9232 	struct ice_switch_info *sw = hw->switch_info;
9233 	enum ice_status status = ICE_SUCCESS;
9234 	u8 i;
9235 
9236 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9237 		struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules;
9238 
9239 		status = ice_replay_fltr(hw, i, head);
9240 		if (status != ICE_SUCCESS)
9241 			return status;
9242 	}
9243 	return status;
9244 }
9245 
9246 /**
9247  * ice_replay_vsi_fltr - Replay filters for requested VSI
9248  * @hw: pointer to the hardware structure
9249  * @pi: pointer to port information structure
9250  * @sw: pointer to switch info struct for which function replays filters
9251  * @vsi_handle: driver VSI handle
9252  * @recp_id: Recipe ID for which rules need to be replayed
9253  * @list_head: list for which filters need to be replayed
9254  *
9255  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
9256  * It is required to pass valid VSI handle.
9257  */
9258 static enum ice_status
9259 ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9260 		    struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id,
9261 		    struct LIST_HEAD_TYPE *list_head)
9262 {
9263 	struct ice_fltr_mgmt_list_entry *itr;
9264 	enum ice_status status = ICE_SUCCESS;
9265 	struct ice_sw_recipe *recp_list;
9266 	u16 hw_vsi_id;
9267 
9268 	if (LIST_EMPTY(list_head))
9269 		return status;
9270 	recp_list = &sw->recp_list[recp_id];
9271 	hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
9272 
9273 	LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry,
9274 			    list_entry) {
9275 		struct ice_fltr_list_entry f_entry;
9276 
9277 		f_entry.fltr_info = itr->fltr_info;
9278 		if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
9279 		    itr->fltr_info.vsi_handle == vsi_handle) {
9280 			/* update the src in case it is VSI num */
9281 			if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
9282 				f_entry.fltr_info.src = hw_vsi_id;
9283 			status = ice_add_rule_internal(hw, recp_list,
9284 						       pi->lport,
9285 						       &f_entry);
9286 			if (status != ICE_SUCCESS)
9287 				goto end;
9288 			continue;
9289 		}
9290 		if (!itr->vsi_list_info ||
9291 		    !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle))
9292 			continue;
9293 		/* Clearing it so that the logic can add it back */
9294 		ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
9295 		f_entry.fltr_info.vsi_handle = vsi_handle;
9296 		f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
9297 		/* update the src in case it is VSI num */
9298 		if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
9299 			f_entry.fltr_info.src = hw_vsi_id;
9300 		if (recp_id == ICE_SW_LKUP_VLAN)
9301 			status = ice_add_vlan_internal(hw, recp_list, &f_entry);
9302 		else
9303 			status = ice_add_rule_internal(hw, recp_list,
9304 						       pi->lport,
9305 						       &f_entry);
9306 		if (status != ICE_SUCCESS)
9307 			goto end;
9308 	}
9309 end:
9310 	return status;
9311 }
9312 
9313 /**
9314  * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
9315  * @hw: pointer to the hardware structure
9316  * @vsi_handle: driver VSI handle
9317  * @list_head: list for which filters need to be replayed
9318  *
9319  * Replay the advanced rule for the given VSI.
9320  */
9321 static enum ice_status
9322 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
9323 			struct LIST_HEAD_TYPE *list_head)
9324 {
9325 	struct ice_rule_query_data added_entry = { 0 };
9326 	struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
9327 	enum ice_status status = ICE_SUCCESS;
9328 
9329 	if (LIST_EMPTY(list_head))
9330 		return status;
9331 	LIST_FOR_EACH_ENTRY(adv_fltr, list_head, ice_adv_fltr_mgmt_list_entry,
9332 			    list_entry) {
9333 		struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
9334 		u16 lk_cnt = adv_fltr->lkups_cnt;
9335 
9336 		if (vsi_handle != rinfo->sw_act.vsi_handle)
9337 			continue;
9338 		status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
9339 					  &added_entry);
9340 		if (status)
9341 			break;
9342 	}
9343 	return status;
9344 }
9345 
9346 /**
9347  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
9348  * @hw: pointer to the hardware structure
9349  * @pi: pointer to port information structure
9350  * @vsi_handle: driver VSI handle
9351  *
9352  * Replays filters for requested VSI via vsi_handle.
9353  */
9354 enum ice_status
9355 ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9356 			u16 vsi_handle)
9357 {
9358 	struct ice_switch_info *sw = hw->switch_info;
9359 	enum ice_status status;
9360 	u8 i;
9361 
9362 	/* Update the recipes that were created */
9363 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9364 		struct LIST_HEAD_TYPE *head;
9365 
9366 		head = &sw->recp_list[i].filt_replay_rules;
9367 		if (!sw->recp_list[i].adv_rule)
9368 			status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i,
9369 						     head);
9370 		else
9371 			status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
9372 		if (status != ICE_SUCCESS)
9373 			return status;
9374 	}
9375 
9376 	return ICE_SUCCESS;
9377 }
9378 
9379 /**
9380  * ice_rm_sw_replay_rule_info - helper function to delete filter replay rules
9381  * @hw: pointer to the HW struct
9382  * @sw: pointer to switch info struct for which function removes filters
9383  *
9384  * Deletes the filter replay rules for given switch
9385  */
9386 void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw)
9387 {
9388 	u8 i;
9389 
9390 	if (!sw)
9391 		return;
9392 
9393 	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9394 		if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) {
9395 			struct LIST_HEAD_TYPE *l_head;
9396 
9397 			l_head = &sw->recp_list[i].filt_replay_rules;
9398 			if (!sw->recp_list[i].adv_rule)
9399 				ice_rem_sw_rule_info(hw, l_head);
9400 			else
9401 				ice_rem_adv_rule_info(hw, l_head);
9402 		}
9403 	}
9404 }
9405 
9406 /**
9407  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
9408  * @hw: pointer to the HW struct
9409  *
9410  * Deletes the filter replay rules.
9411  */
9412 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
9413 {
9414 	ice_rm_sw_replay_rule_info(hw, hw->switch_info);
9415 }
9416