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