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