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