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