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