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