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