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