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