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