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