net/ice/base: fix QinQ PPPoE dummy packet selection
[dpdk.git] / drivers / net / ice / base / ice_switch.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2021 Intel Corporation
3  */
4
5 #include "ice_switch.h"
6 #include "ice_flex_type.h"
7 #include "ice_flow.h"
8
9 #define ICE_ETH_DA_OFFSET               0
10 #define ICE_ETH_ETHTYPE_OFFSET          12
11 #define ICE_ETH_VLAN_TCI_OFFSET         14
12 #define ICE_MAX_VLAN_ID                 0xFFF
13 #define ICE_IPV4_NVGRE_PROTO_ID         0x002F
14 #define ICE_PPP_IPV6_PROTO_ID           0x0057
15 #define ICE_IPV6_ETHER_ID               0x86DD
16 #define ICE_TCP_PROTO_ID                0x06
17 #define ICE_ETH_P_8021Q                 0x8100
18
19 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
20  * struct to configure any switch filter rules.
21  * {DA (6 bytes), SA(6 bytes),
22  * Ether type (2 bytes for header without VLAN tag) OR
23  * VLAN tag (4 bytes for header with VLAN tag) }
24  *
25  * Word on Hardcoded values
26  * byte 0 = 0x2: to identify it as locally administered DA MAC
27  * byte 6 = 0x2: to identify it as locally administered SA MAC
28  * byte 12 = 0x81 & byte 13 = 0x00:
29  *      In case of VLAN filter first two bytes defines ether type (0x8100)
30  *      and remaining two bytes are placeholder for programming a given VLAN ID
31  *      In case of Ether type filter it is treated as header without VLAN tag
32  *      and byte 12 and 13 is used to program a given Ether type instead
33  */
34 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
35                                                         0x2, 0, 0, 0, 0, 0,
36                                                         0x81, 0, 0, 0};
37
38 struct ice_dummy_pkt_offsets {
39         enum ice_protocol_type type;
40         u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
41 };
42
43 static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = {
44         { ICE_MAC_OFOS,         0 },
45         { ICE_ETYPE_OL,         12 },
46         { ICE_IPV4_OFOS,        14 },
47         { ICE_NVGRE,            34 },
48         { ICE_MAC_IL,           42 },
49         { ICE_IPV4_IL,          56 },
50         { ICE_TCP_IL,           76 },
51         { ICE_PROTOCOL_LAST,    0 },
52 };
53
54 static const u8 dummy_gre_tcp_packet[] = {
55         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
56         0x00, 0x00, 0x00, 0x00,
57         0x00, 0x00, 0x00, 0x00,
58
59         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
60
61         0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
62         0x00, 0x00, 0x00, 0x00,
63         0x00, 0x2F, 0x00, 0x00,
64         0x00, 0x00, 0x00, 0x00,
65         0x00, 0x00, 0x00, 0x00,
66
67         0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
68         0x00, 0x00, 0x00, 0x00,
69
70         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
71         0x00, 0x00, 0x00, 0x00,
72         0x00, 0x00, 0x00, 0x00,
73         0x08, 0x00,
74
75         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
76         0x00, 0x00, 0x00, 0x00,
77         0x00, 0x06, 0x00, 0x00,
78         0x00, 0x00, 0x00, 0x00,
79         0x00, 0x00, 0x00, 0x00,
80
81         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */
82         0x00, 0x00, 0x00, 0x00,
83         0x00, 0x00, 0x00, 0x00,
84         0x50, 0x02, 0x20, 0x00,
85         0x00, 0x00, 0x00, 0x00
86 };
87
88 static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = {
89         { ICE_MAC_OFOS,         0 },
90         { ICE_ETYPE_OL,         12 },
91         { ICE_IPV4_OFOS,        14 },
92         { ICE_NVGRE,            34 },
93         { ICE_MAC_IL,           42 },
94         { ICE_IPV4_IL,          56 },
95         { ICE_UDP_ILOS,         76 },
96         { ICE_PROTOCOL_LAST,    0 },
97 };
98
99 static const u8 dummy_gre_udp_packet[] = {
100         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
101         0x00, 0x00, 0x00, 0x00,
102         0x00, 0x00, 0x00, 0x00,
103
104         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
105
106         0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
107         0x00, 0x00, 0x00, 0x00,
108         0x00, 0x2F, 0x00, 0x00,
109         0x00, 0x00, 0x00, 0x00,
110         0x00, 0x00, 0x00, 0x00,
111
112         0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
113         0x00, 0x00, 0x00, 0x00,
114
115         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
116         0x00, 0x00, 0x00, 0x00,
117         0x00, 0x00, 0x00, 0x00,
118         0x08, 0x00,
119
120         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
121         0x00, 0x00, 0x00, 0x00,
122         0x00, 0x11, 0x00, 0x00,
123         0x00, 0x00, 0x00, 0x00,
124         0x00, 0x00, 0x00, 0x00,
125
126         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */
127         0x00, 0x08, 0x00, 0x00,
128 };
129
130 static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
131         { ICE_MAC_OFOS,         0 },
132         { ICE_ETYPE_OL,         12 },
133         { ICE_IPV4_OFOS,        14 },
134         { ICE_UDP_OF,           34 },
135         { ICE_VXLAN,            42 },
136         { ICE_GENEVE,           42 },
137         { ICE_VXLAN_GPE,        42 },
138         { ICE_MAC_IL,           50 },
139         { ICE_IPV4_IL,          64 },
140         { ICE_TCP_IL,           84 },
141         { ICE_PROTOCOL_LAST,    0 },
142 };
143
144 static const u8 dummy_udp_tun_tcp_packet[] = {
145         0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
146         0x00, 0x00, 0x00, 0x00,
147         0x00, 0x00, 0x00, 0x00,
148
149         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
150
151         0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
152         0x00, 0x01, 0x00, 0x00,
153         0x40, 0x11, 0x00, 0x00,
154         0x00, 0x00, 0x00, 0x00,
155         0x00, 0x00, 0x00, 0x00,
156
157         0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
158         0x00, 0x46, 0x00, 0x00,
159
160         0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
161         0x00, 0x00, 0x00, 0x00,
162
163         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
164         0x00, 0x00, 0x00, 0x00,
165         0x00, 0x00, 0x00, 0x00,
166         0x08, 0x00,
167
168         0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
169         0x00, 0x01, 0x00, 0x00,
170         0x40, 0x06, 0x00, 0x00,
171         0x00, 0x00, 0x00, 0x00,
172         0x00, 0x00, 0x00, 0x00,
173
174         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
175         0x00, 0x00, 0x00, 0x00,
176         0x00, 0x00, 0x00, 0x00,
177         0x50, 0x02, 0x20, 0x00,
178         0x00, 0x00, 0x00, 0x00
179 };
180
181 static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
182         { ICE_MAC_OFOS,         0 },
183         { ICE_ETYPE_OL,         12 },
184         { ICE_IPV4_OFOS,        14 },
185         { ICE_UDP_OF,           34 },
186         { ICE_VXLAN,            42 },
187         { ICE_GENEVE,           42 },
188         { ICE_VXLAN_GPE,        42 },
189         { ICE_MAC_IL,           50 },
190         { ICE_IPV4_IL,          64 },
191         { ICE_UDP_ILOS,         84 },
192         { ICE_PROTOCOL_LAST,    0 },
193 };
194
195 static const u8 dummy_udp_tun_udp_packet[] = {
196         0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
197         0x00, 0x00, 0x00, 0x00,
198         0x00, 0x00, 0x00, 0x00,
199
200         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
201
202         0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
203         0x00, 0x01, 0x00, 0x00,
204         0x00, 0x11, 0x00, 0x00,
205         0x00, 0x00, 0x00, 0x00,
206         0x00, 0x00, 0x00, 0x00,
207
208         0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
209         0x00, 0x3a, 0x00, 0x00,
210
211         0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
212         0x00, 0x00, 0x00, 0x00,
213
214         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
215         0x00, 0x00, 0x00, 0x00,
216         0x00, 0x00, 0x00, 0x00,
217         0x08, 0x00,
218
219         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
220         0x00, 0x01, 0x00, 0x00,
221         0x00, 0x11, 0x00, 0x00,
222         0x00, 0x00, 0x00, 0x00,
223         0x00, 0x00, 0x00, 0x00,
224
225         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
226         0x00, 0x08, 0x00, 0x00,
227 };
228
229 /* offset info for MAC + IPv4 + UDP dummy packet */
230 static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
231         { ICE_MAC_OFOS,         0 },
232         { ICE_ETYPE_OL,         12 },
233         { ICE_IPV4_OFOS,        14 },
234         { ICE_UDP_ILOS,         34 },
235         { ICE_PROTOCOL_LAST,    0 },
236 };
237
238 /* Dummy packet for MAC + IPv4 + UDP */
239 static const u8 dummy_udp_packet[] = {
240         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
241         0x00, 0x00, 0x00, 0x00,
242         0x00, 0x00, 0x00, 0x00,
243
244         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
245
246         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
247         0x00, 0x01, 0x00, 0x00,
248         0x00, 0x11, 0x00, 0x00,
249         0x00, 0x00, 0x00, 0x00,
250         0x00, 0x00, 0x00, 0x00,
251
252         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
253         0x00, 0x08, 0x00, 0x00,
254
255         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
256 };
257
258 /* offset info for MAC + VLAN + IPv4 + UDP dummy packet */
259 static const struct ice_dummy_pkt_offsets dummy_vlan_udp_packet_offsets[] = {
260         { ICE_MAC_OFOS,         0 },
261         { ICE_ETYPE_OL,         12 },
262         { ICE_VLAN_OFOS,        14 },
263         { ICE_IPV4_OFOS,        18 },
264         { ICE_UDP_ILOS,         38 },
265         { ICE_PROTOCOL_LAST,    0 },
266 };
267
268 /* C-tag (801.1Q), IPv4:UDP dummy packet */
269 static const u8 dummy_vlan_udp_packet[] = {
270         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
271         0x00, 0x00, 0x00, 0x00,
272         0x00, 0x00, 0x00, 0x00,
273
274         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
275
276         0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 14 */
277
278         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 18 */
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 38 */
285         0x00, 0x08, 0x00, 0x00,
286
287         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
288 };
289
290 /* offset info for MAC + IPv4 + TCP dummy packet */
291 static const struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = {
292         { ICE_MAC_OFOS,         0 },
293         { ICE_ETYPE_OL,         12 },
294         { ICE_IPV4_OFOS,        14 },
295         { ICE_TCP_IL,           34 },
296         { ICE_PROTOCOL_LAST,    0 },
297 };
298
299 /* Dummy packet for MAC + IPv4 + TCP */
300 static const u8 dummy_tcp_packet[] = {
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, 0x28, /* ICE_IPV4_OFOS 14 */
308         0x00, 0x01, 0x00, 0x00,
309         0x00, 0x06, 0x00, 0x00,
310         0x00, 0x00, 0x00, 0x00,
311         0x00, 0x00, 0x00, 0x00,
312
313         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
314         0x00, 0x00, 0x00, 0x00,
315         0x00, 0x00, 0x00, 0x00,
316         0x50, 0x00, 0x00, 0x00,
317         0x00, 0x00, 0x00, 0x00,
318
319         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
320 };
321
322 /* offset info for MAC + VLAN (C-tag, 802.1Q) + IPv4 + TCP dummy packet */
323 static const struct ice_dummy_pkt_offsets dummy_vlan_tcp_packet_offsets[] = {
324         { ICE_MAC_OFOS,         0 },
325         { ICE_ETYPE_OL,         12 },
326         { ICE_VLAN_OFOS,        14 },
327         { ICE_IPV4_OFOS,        18 },
328         { ICE_TCP_IL,           38 },
329         { ICE_PROTOCOL_LAST,    0 },
330 };
331
332 /* C-tag (801.1Q), IPv4:TCP dummy packet */
333 static const u8 dummy_vlan_tcp_packet[] = {
334         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
335         0x00, 0x00, 0x00, 0x00,
336         0x00, 0x00, 0x00, 0x00,
337
338         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
339
340         0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 14 */
341
342         0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 18 */
343         0x00, 0x01, 0x00, 0x00,
344         0x00, 0x06, 0x00, 0x00,
345         0x00, 0x00, 0x00, 0x00,
346         0x00, 0x00, 0x00, 0x00,
347
348         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 38 */
349         0x00, 0x00, 0x00, 0x00,
350         0x00, 0x00, 0x00, 0x00,
351         0x50, 0x00, 0x00, 0x00,
352         0x00, 0x00, 0x00, 0x00,
353
354         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
355 };
356
357 static const struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = {
358         { ICE_MAC_OFOS,         0 },
359         { ICE_ETYPE_OL,         12 },
360         { ICE_IPV6_OFOS,        14 },
361         { ICE_TCP_IL,           54 },
362         { ICE_PROTOCOL_LAST,    0 },
363 };
364
365 static const u8 dummy_tcp_ipv6_packet[] = {
366         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
367         0x00, 0x00, 0x00, 0x00,
368         0x00, 0x00, 0x00, 0x00,
369
370         0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
371
372         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
373         0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
374         0x00, 0x00, 0x00, 0x00,
375         0x00, 0x00, 0x00, 0x00,
376         0x00, 0x00, 0x00, 0x00,
377         0x00, 0x00, 0x00, 0x00,
378         0x00, 0x00, 0x00, 0x00,
379         0x00, 0x00, 0x00, 0x00,
380         0x00, 0x00, 0x00, 0x00,
381         0x00, 0x00, 0x00, 0x00,
382
383         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
384         0x00, 0x00, 0x00, 0x00,
385         0x00, 0x00, 0x00, 0x00,
386         0x50, 0x00, 0x00, 0x00,
387         0x00, 0x00, 0x00, 0x00,
388
389         0x00, 0x00, /* 2 bytes for 4 byte alignment */
390 };
391
392 /* C-tag (802.1Q): IPv6 + TCP */
393 static const struct ice_dummy_pkt_offsets
394 dummy_vlan_tcp_ipv6_packet_offsets[] = {
395         { ICE_MAC_OFOS,         0 },
396         { ICE_ETYPE_OL,         12 },
397         { ICE_VLAN_OFOS,        14 },
398         { ICE_IPV6_OFOS,        18 },
399         { ICE_TCP_IL,           58 },
400         { ICE_PROTOCOL_LAST,    0 },
401 };
402
403 /* C-tag (802.1Q), IPv6 + TCP dummy packet */
404 static const u8 dummy_vlan_tcp_ipv6_packet[] = {
405         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
406         0x00, 0x00, 0x00, 0x00,
407         0x00, 0x00, 0x00, 0x00,
408
409         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
410
411         0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 14 */
412
413         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
414         0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
415         0x00, 0x00, 0x00, 0x00,
416         0x00, 0x00, 0x00, 0x00,
417         0x00, 0x00, 0x00, 0x00,
418         0x00, 0x00, 0x00, 0x00,
419         0x00, 0x00, 0x00, 0x00,
420         0x00, 0x00, 0x00, 0x00,
421         0x00, 0x00, 0x00, 0x00,
422         0x00, 0x00, 0x00, 0x00,
423
424         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 58 */
425         0x00, 0x00, 0x00, 0x00,
426         0x00, 0x00, 0x00, 0x00,
427         0x50, 0x00, 0x00, 0x00,
428         0x00, 0x00, 0x00, 0x00,
429
430         0x00, 0x00, /* 2 bytes for 4 byte alignment */
431 };
432
433 /* IPv6 + UDP */
434 static const struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = {
435         { ICE_MAC_OFOS,         0 },
436         { ICE_ETYPE_OL,         12 },
437         { ICE_IPV6_OFOS,        14 },
438         { ICE_UDP_ILOS,         54 },
439         { ICE_PROTOCOL_LAST,    0 },
440 };
441
442 /* IPv6 + UDP dummy packet */
443 static const u8 dummy_udp_ipv6_packet[] = {
444         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
445         0x00, 0x00, 0x00, 0x00,
446         0x00, 0x00, 0x00, 0x00,
447
448         0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
449
450         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
451         0x00, 0x10, 0x11, 0x00, /* Next header UDP */
452         0x00, 0x00, 0x00, 0x00,
453         0x00, 0x00, 0x00, 0x00,
454         0x00, 0x00, 0x00, 0x00,
455         0x00, 0x00, 0x00, 0x00,
456         0x00, 0x00, 0x00, 0x00,
457         0x00, 0x00, 0x00, 0x00,
458         0x00, 0x00, 0x00, 0x00,
459         0x00, 0x00, 0x00, 0x00,
460
461         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
462         0x00, 0x10, 0x00, 0x00,
463
464         0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
465         0x00, 0x00, 0x00, 0x00,
466
467         0x00, 0x00, /* 2 bytes for 4 byte alignment */
468 };
469
470 /* C-tag (802.1Q): IPv6 + UDP */
471 static const struct ice_dummy_pkt_offsets
472 dummy_vlan_udp_ipv6_packet_offsets[] = {
473         { ICE_MAC_OFOS,         0 },
474         { ICE_ETYPE_OL,         12 },
475         { ICE_VLAN_OFOS,        14 },
476         { ICE_IPV6_OFOS,        18 },
477         { ICE_UDP_ILOS,         58 },
478         { ICE_PROTOCOL_LAST,    0 },
479 };
480
481 /* C-tag (802.1Q), IPv6 + UDP dummy packet */
482 static const u8 dummy_vlan_udp_ipv6_packet[] = {
483         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
484         0x00, 0x00, 0x00, 0x00,
485         0x00, 0x00, 0x00, 0x00,
486
487         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
488
489         0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 14 */
490
491         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
492         0x00, 0x08, 0x11, 0x00, /* Next header UDP */
493         0x00, 0x00, 0x00, 0x00,
494         0x00, 0x00, 0x00, 0x00,
495         0x00, 0x00, 0x00, 0x00,
496         0x00, 0x00, 0x00, 0x00,
497         0x00, 0x00, 0x00, 0x00,
498         0x00, 0x00, 0x00, 0x00,
499         0x00, 0x00, 0x00, 0x00,
500         0x00, 0x00, 0x00, 0x00,
501
502         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 58 */
503         0x00, 0x08, 0x00, 0x00,
504
505         0x00, 0x00, /* 2 bytes for 4 byte alignment */
506 };
507
508 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
509 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = {
510         { ICE_MAC_OFOS,         0 },
511         { ICE_IPV4_OFOS,        14 },
512         { ICE_UDP_OF,           34 },
513         { ICE_GTP,              42 },
514         { ICE_IPV4_IL,          62 },
515         { ICE_TCP_IL,           82 },
516         { ICE_PROTOCOL_LAST,    0 },
517 };
518
519 static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = {
520         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
521         0x00, 0x00, 0x00, 0x00,
522         0x00, 0x00, 0x00, 0x00,
523         0x08, 0x00,
524
525         0x45, 0x00, 0x00, 0x58, /* IP 14 */
526         0x00, 0x00, 0x00, 0x00,
527         0x00, 0x11, 0x00, 0x00,
528         0x00, 0x00, 0x00, 0x00,
529         0x00, 0x00, 0x00, 0x00,
530
531         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
532         0x00, 0x44, 0x00, 0x00,
533
534         0x34, 0xff, 0x00, 0x34, /* GTP-U Header 42 */
535         0x00, 0x00, 0x00, 0x00,
536         0x00, 0x00, 0x00, 0x85,
537
538         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
539         0x00, 0x00, 0x00, 0x00,
540
541         0x45, 0x00, 0x00, 0x28, /* IP 62 */
542         0x00, 0x00, 0x00, 0x00,
543         0x00, 0x06, 0x00, 0x00,
544         0x00, 0x00, 0x00, 0x00,
545         0x00, 0x00, 0x00, 0x00,
546
547         0x00, 0x00, 0x00, 0x00, /* TCP 82 */
548         0x00, 0x00, 0x00, 0x00,
549         0x00, 0x00, 0x00, 0x00,
550         0x50, 0x00, 0x00, 0x00,
551         0x00, 0x00, 0x00, 0x00,
552
553         0x00, 0x00, /* 2 bytes for 4 byte alignment */
554 };
555
556 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
557 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = {
558         { ICE_MAC_OFOS,         0 },
559         { ICE_IPV4_OFOS,        14 },
560         { ICE_UDP_OF,           34 },
561         { ICE_GTP,              42 },
562         { ICE_IPV4_IL,          62 },
563         { ICE_UDP_ILOS,         82 },
564         { ICE_PROTOCOL_LAST,    0 },
565 };
566
567 static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = {
568         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
569         0x00, 0x00, 0x00, 0x00,
570         0x00, 0x00, 0x00, 0x00,
571         0x08, 0x00,
572
573         0x45, 0x00, 0x00, 0x4c, /* IP 14 */
574         0x00, 0x00, 0x00, 0x00,
575         0x00, 0x11, 0x00, 0x00,
576         0x00, 0x00, 0x00, 0x00,
577         0x00, 0x00, 0x00, 0x00,
578
579         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
580         0x00, 0x38, 0x00, 0x00,
581
582         0x34, 0xff, 0x00, 0x28, /* GTP-U Header 42 */
583         0x00, 0x00, 0x00, 0x00,
584         0x00, 0x00, 0x00, 0x85,
585
586         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
587         0x00, 0x00, 0x00, 0x00,
588
589         0x45, 0x00, 0x00, 0x1c, /* IP 62 */
590         0x00, 0x00, 0x00, 0x00,
591         0x00, 0x11, 0x00, 0x00,
592         0x00, 0x00, 0x00, 0x00,
593         0x00, 0x00, 0x00, 0x00,
594
595         0x00, 0x00, 0x00, 0x00, /* UDP 82 */
596         0x00, 0x08, 0x00, 0x00,
597
598         0x00, 0x00, /* 2 bytes for 4 byte alignment */
599 };
600
601 /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
602 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = {
603         { ICE_MAC_OFOS,         0 },
604         { ICE_IPV4_OFOS,        14 },
605         { ICE_UDP_OF,           34 },
606         { ICE_GTP,              42 },
607         { ICE_IPV6_IL,          62 },
608         { ICE_TCP_IL,           102 },
609         { ICE_PROTOCOL_LAST,    0 },
610 };
611
612 static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = {
613         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
614         0x00, 0x00, 0x00, 0x00,
615         0x00, 0x00, 0x00, 0x00,
616         0x08, 0x00,
617
618         0x45, 0x00, 0x00, 0x6c, /* IP 14 */
619         0x00, 0x00, 0x00, 0x00,
620         0x00, 0x11, 0x00, 0x00,
621         0x00, 0x00, 0x00, 0x00,
622         0x00, 0x00, 0x00, 0x00,
623
624         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
625         0x00, 0x58, 0x00, 0x00,
626
627         0x34, 0xff, 0x00, 0x48, /* GTP-U Header 42 */
628         0x00, 0x00, 0x00, 0x00,
629         0x00, 0x00, 0x00, 0x85,
630
631         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
632         0x00, 0x00, 0x00, 0x00,
633
634         0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
635         0x00, 0x14, 0x06, 0x00,
636         0x00, 0x00, 0x00, 0x00,
637         0x00, 0x00, 0x00, 0x00,
638         0x00, 0x00, 0x00, 0x00,
639         0x00, 0x00, 0x00, 0x00,
640         0x00, 0x00, 0x00, 0x00,
641         0x00, 0x00, 0x00, 0x00,
642         0x00, 0x00, 0x00, 0x00,
643         0x00, 0x00, 0x00, 0x00,
644
645         0x00, 0x00, 0x00, 0x00, /* TCP 102 */
646         0x00, 0x00, 0x00, 0x00,
647         0x00, 0x00, 0x00, 0x00,
648         0x50, 0x00, 0x00, 0x00,
649         0x00, 0x00, 0x00, 0x00,
650
651         0x00, 0x00, /* 2 bytes for 4 byte alignment */
652 };
653
654 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_udp_packet_offsets[] = {
655         { ICE_MAC_OFOS,         0 },
656         { ICE_IPV4_OFOS,        14 },
657         { ICE_UDP_OF,           34 },
658         { ICE_GTP,              42 },
659         { ICE_IPV6_IL,          62 },
660         { ICE_UDP_ILOS,         102 },
661         { ICE_PROTOCOL_LAST,    0 },
662 };
663
664 static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = {
665         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
666         0x00, 0x00, 0x00, 0x00,
667         0x00, 0x00, 0x00, 0x00,
668         0x08, 0x00,
669
670         0x45, 0x00, 0x00, 0x60, /* IP 14 */
671         0x00, 0x00, 0x00, 0x00,
672         0x00, 0x11, 0x00, 0x00,
673         0x00, 0x00, 0x00, 0x00,
674         0x00, 0x00, 0x00, 0x00,
675
676         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
677         0x00, 0x4c, 0x00, 0x00,
678
679         0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 42 */
680         0x00, 0x00, 0x00, 0x00,
681         0x00, 0x00, 0x00, 0x85,
682
683         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
684         0x00, 0x00, 0x00, 0x00,
685
686         0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
687         0x00, 0x08, 0x11, 0x00,
688         0x00, 0x00, 0x00, 0x00,
689         0x00, 0x00, 0x00, 0x00,
690         0x00, 0x00, 0x00, 0x00,
691         0x00, 0x00, 0x00, 0x00,
692         0x00, 0x00, 0x00, 0x00,
693         0x00, 0x00, 0x00, 0x00,
694         0x00, 0x00, 0x00, 0x00,
695         0x00, 0x00, 0x00, 0x00,
696
697         0x00, 0x00, 0x00, 0x00, /* UDP 102 */
698         0x00, 0x08, 0x00, 0x00,
699
700         0x00, 0x00, /* 2 bytes for 4 byte alignment */
701 };
702
703 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = {
704         { ICE_MAC_OFOS,         0 },
705         { ICE_IPV6_OFOS,        14 },
706         { ICE_UDP_OF,           54 },
707         { ICE_GTP,              62 },
708         { ICE_IPV4_IL,          82 },
709         { ICE_TCP_IL,           102 },
710         { ICE_PROTOCOL_LAST,    0 },
711 };
712
713 static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = {
714         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
715         0x00, 0x00, 0x00, 0x00,
716         0x00, 0x00, 0x00, 0x00,
717         0x86, 0xdd,
718
719         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
720         0x00, 0x44, 0x11, 0x00,
721         0x00, 0x00, 0x00, 0x00,
722         0x00, 0x00, 0x00, 0x00,
723         0x00, 0x00, 0x00, 0x00,
724         0x00, 0x00, 0x00, 0x00,
725         0x00, 0x00, 0x00, 0x00,
726         0x00, 0x00, 0x00, 0x00,
727         0x00, 0x00, 0x00, 0x00,
728         0x00, 0x00, 0x00, 0x00,
729
730         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
731         0x00, 0x44, 0x00, 0x00,
732
733         0x34, 0xff, 0x00, 0x34, /* GTP-U Header 62 */
734         0x00, 0x00, 0x00, 0x00,
735         0x00, 0x00, 0x00, 0x85,
736
737         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
738         0x00, 0x00, 0x00, 0x00,
739
740         0x45, 0x00, 0x00, 0x28, /* IP 82 */
741         0x00, 0x00, 0x00, 0x00,
742         0x00, 0x06, 0x00, 0x00,
743         0x00, 0x00, 0x00, 0x00,
744         0x00, 0x00, 0x00, 0x00,
745
746         0x00, 0x00, 0x00, 0x00, /* TCP 102 */
747         0x00, 0x00, 0x00, 0x00,
748         0x00, 0x00, 0x00, 0x00,
749         0x50, 0x00, 0x00, 0x00,
750         0x00, 0x00, 0x00, 0x00,
751
752         0x00, 0x00, /* 2 bytes for 4 byte alignment */
753 };
754
755 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_udp_packet_offsets[] = {
756         { ICE_MAC_OFOS,         0 },
757         { ICE_IPV6_OFOS,        14 },
758         { ICE_UDP_OF,           54 },
759         { ICE_GTP,              62 },
760         { ICE_IPV4_IL,          82 },
761         { ICE_UDP_ILOS,         102 },
762         { ICE_PROTOCOL_LAST,    0 },
763 };
764
765 static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = {
766         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
767         0x00, 0x00, 0x00, 0x00,
768         0x00, 0x00, 0x00, 0x00,
769         0x86, 0xdd,
770
771         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
772         0x00, 0x38, 0x11, 0x00,
773         0x00, 0x00, 0x00, 0x00,
774         0x00, 0x00, 0x00, 0x00,
775         0x00, 0x00, 0x00, 0x00,
776         0x00, 0x00, 0x00, 0x00,
777         0x00, 0x00, 0x00, 0x00,
778         0x00, 0x00, 0x00, 0x00,
779         0x00, 0x00, 0x00, 0x00,
780         0x00, 0x00, 0x00, 0x00,
781
782         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
783         0x00, 0x38, 0x00, 0x00,
784
785         0x34, 0xff, 0x00, 0x28, /* GTP-U Header 62 */
786         0x00, 0x00, 0x00, 0x00,
787         0x00, 0x00, 0x00, 0x85,
788
789         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
790         0x00, 0x00, 0x00, 0x00,
791
792         0x45, 0x00, 0x00, 0x1c, /* IP 82 */
793         0x00, 0x00, 0x00, 0x00,
794         0x00, 0x11, 0x00, 0x00,
795         0x00, 0x00, 0x00, 0x00,
796         0x00, 0x00, 0x00, 0x00,
797
798         0x00, 0x00, 0x00, 0x00, /* UDP 102 */
799         0x00, 0x08, 0x00, 0x00,
800
801         0x00, 0x00, /* 2 bytes for 4 byte alignment */
802 };
803
804 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = {
805         { ICE_MAC_OFOS,         0 },
806         { ICE_IPV6_OFOS,        14 },
807         { ICE_UDP_OF,           54 },
808         { ICE_GTP,              62 },
809         { ICE_IPV6_IL,          82 },
810         { ICE_TCP_IL,           102 },
811         { ICE_PROTOCOL_LAST,    0 },
812 };
813
814 static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = {
815         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
816         0x00, 0x00, 0x00, 0x00,
817         0x00, 0x00, 0x00, 0x00,
818         0x86, 0xdd,
819
820         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
821         0x00, 0x58, 0x11, 0x00,
822         0x00, 0x00, 0x00, 0x00,
823         0x00, 0x00, 0x00, 0x00,
824         0x00, 0x00, 0x00, 0x00,
825         0x00, 0x00, 0x00, 0x00,
826         0x00, 0x00, 0x00, 0x00,
827         0x00, 0x00, 0x00, 0x00,
828         0x00, 0x00, 0x00, 0x00,
829         0x00, 0x00, 0x00, 0x00,
830
831         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
832         0x00, 0x58, 0x00, 0x00,
833
834         0x34, 0xff, 0x00, 0x48, /* GTP-U Header 62 */
835         0x00, 0x00, 0x00, 0x00,
836         0x00, 0x00, 0x00, 0x85,
837
838         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
839         0x00, 0x00, 0x00, 0x00,
840
841         0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
842         0x00, 0x14, 0x06, 0x00,
843         0x00, 0x00, 0x00, 0x00,
844         0x00, 0x00, 0x00, 0x00,
845         0x00, 0x00, 0x00, 0x00,
846         0x00, 0x00, 0x00, 0x00,
847         0x00, 0x00, 0x00, 0x00,
848         0x00, 0x00, 0x00, 0x00,
849         0x00, 0x00, 0x00, 0x00,
850         0x00, 0x00, 0x00, 0x00,
851
852         0x00, 0x00, 0x00, 0x00, /* TCP 122 */
853         0x00, 0x00, 0x00, 0x00,
854         0x00, 0x00, 0x00, 0x00,
855         0x50, 0x00, 0x00, 0x00,
856         0x00, 0x00, 0x00, 0x00,
857
858         0x00, 0x00, /* 2 bytes for 4 byte alignment */
859 };
860
861 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_udp_packet_offsets[] = {
862         { ICE_MAC_OFOS,         0 },
863         { ICE_IPV6_OFOS,        14 },
864         { ICE_UDP_OF,           54 },
865         { ICE_GTP,              62 },
866         { ICE_IPV6_IL,          82 },
867         { ICE_UDP_ILOS,         102 },
868         { ICE_PROTOCOL_LAST,    0 },
869 };
870
871 static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = {
872         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
873         0x00, 0x00, 0x00, 0x00,
874         0x00, 0x00, 0x00, 0x00,
875         0x86, 0xdd,
876
877         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
878         0x00, 0x4c, 0x11, 0x00,
879         0x00, 0x00, 0x00, 0x00,
880         0x00, 0x00, 0x00, 0x00,
881         0x00, 0x00, 0x00, 0x00,
882         0x00, 0x00, 0x00, 0x00,
883         0x00, 0x00, 0x00, 0x00,
884         0x00, 0x00, 0x00, 0x00,
885         0x00, 0x00, 0x00, 0x00,
886         0x00, 0x00, 0x00, 0x00,
887
888         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
889         0x00, 0x4c, 0x00, 0x00,
890
891         0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 62 */
892         0x00, 0x00, 0x00, 0x00,
893         0x00, 0x00, 0x00, 0x85,
894
895         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
896         0x00, 0x00, 0x00, 0x00,
897
898         0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
899         0x00, 0x08, 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, 0x00, 0x00, /* UDP 122 */
910         0x00, 0x08, 0x00, 0x00,
911
912         0x00, 0x00, /* 2 bytes for 4 byte alignment */
913 };
914
915 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_packet_offsets[] = {
916         { ICE_MAC_OFOS,         0 },
917         { ICE_IPV4_OFOS,        14 },
918         { ICE_UDP_OF,           34 },
919         { ICE_GTP,              42 },
920         { ICE_IPV4_IL,          62 },
921         { ICE_PROTOCOL_LAST,    0 },
922 };
923
924 static const u8 dummy_ipv4_gtpu_ipv4_packet[] = {
925         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
926         0x00, 0x00, 0x00, 0x00,
927         0x00, 0x00, 0x00, 0x00,
928         0x08, 0x00,
929
930         0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
931         0x00, 0x00, 0x40, 0x00,
932         0x40, 0x11, 0x00, 0x00,
933         0x00, 0x00, 0x00, 0x00,
934         0x00, 0x00, 0x00, 0x00,
935
936         0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
937         0x00, 0x00, 0x00, 0x00,
938
939         0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 42 */
940         0x00, 0x00, 0x00, 0x00,
941         0x00, 0x00, 0x00, 0x85,
942
943         0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
944         0x00, 0x00, 0x00, 0x00,
945
946         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
947         0x00, 0x00, 0x40, 0x00,
948         0x40, 0x00, 0x00, 0x00,
949         0x00, 0x00, 0x00, 0x00,
950         0x00, 0x00, 0x00, 0x00,
951         0x00, 0x00,
952 };
953
954 static const
955 struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_packet_offsets[] = {
956         { ICE_MAC_OFOS,         0 },
957         { ICE_IPV4_OFOS,        14 },
958         { ICE_UDP_OF,           34 },
959         { ICE_GTP,              42 },
960         { ICE_IPV6_IL,          62 },
961         { ICE_PROTOCOL_LAST,    0 },
962 };
963
964 static const u8 dummy_ipv4_gtpu_ipv6_packet[] = {
965         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
966         0x00, 0x00, 0x00, 0x00,
967         0x00, 0x00, 0x00, 0x00,
968         0x08, 0x00,
969
970         0x45, 0x00, 0x00, 0x58, /* ICE_IPV4_OFOS 14 */
971         0x00, 0x00, 0x40, 0x00,
972         0x40, 0x11, 0x00, 0x00,
973         0x00, 0x00, 0x00, 0x00,
974         0x00, 0x00, 0x00, 0x00,
975
976         0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
977         0x00, 0x00, 0x00, 0x00,
978
979         0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 42 */
980         0x00, 0x00, 0x00, 0x00,
981         0x00, 0x00, 0x00, 0x85,
982
983         0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
984         0x00, 0x00, 0x00, 0x00,
985
986         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 62 */
987         0x00, 0x00, 0x3b, 0x00,
988         0x00, 0x00, 0x00, 0x00,
989         0x00, 0x00, 0x00, 0x00,
990         0x00, 0x00, 0x00, 0x00,
991         0x00, 0x00, 0x00, 0x00,
992         0x00, 0x00, 0x00, 0x00,
993         0x00, 0x00, 0x00, 0x00,
994         0x00, 0x00, 0x00, 0x00,
995         0x00, 0x00, 0x00, 0x00,
996
997         0x00, 0x00,
998 };
999
1000 static const
1001 struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_packet_offsets[] = {
1002         { ICE_MAC_OFOS,         0 },
1003         { ICE_IPV6_OFOS,        14 },
1004         { ICE_UDP_OF,           54 },
1005         { ICE_GTP,              62 },
1006         { ICE_IPV4_IL,          82 },
1007         { ICE_PROTOCOL_LAST,    0 },
1008 };
1009
1010 static const u8 dummy_ipv6_gtpu_ipv4_packet[] = {
1011         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1012         0x00, 0x00, 0x00, 0x00,
1013         0x00, 0x00, 0x00, 0x00,
1014         0x86, 0xdd,
1015
1016         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1017         0x00, 0x58, 0x11, 0x00, /* Next header UDP*/
1018         0x00, 0x00, 0x00, 0x00,
1019         0x00, 0x00, 0x00, 0x00,
1020         0x00, 0x00, 0x00, 0x00,
1021         0x00, 0x00, 0x00, 0x00,
1022         0x00, 0x00, 0x00, 0x00,
1023         0x00, 0x00, 0x00, 0x00,
1024         0x00, 0x00, 0x00, 0x00,
1025         0x00, 0x00, 0x00, 0x00,
1026
1027         0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1028         0x00, 0x00, 0x00, 0x00,
1029
1030         0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 62 */
1031         0x00, 0x00, 0x00, 0x00,
1032         0x00, 0x00, 0x00, 0x85,
1033
1034         0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1035         0x00, 0x00, 0x00, 0x00,
1036
1037         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 82 */
1038         0x00, 0x00, 0x40, 0x00,
1039         0x40, 0x00, 0x00, 0x00,
1040         0x00, 0x00, 0x00, 0x00,
1041         0x00, 0x00, 0x00, 0x00,
1042
1043         0x00, 0x00,
1044 };
1045
1046 static const
1047 struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_packet_offsets[] = {
1048         { ICE_MAC_OFOS,         0 },
1049         { ICE_IPV6_OFOS,        14 },
1050         { ICE_UDP_OF,           54 },
1051         { ICE_GTP,              62 },
1052         { ICE_IPV6_IL,          82 },
1053         { ICE_PROTOCOL_LAST,    0 },
1054 };
1055
1056 static const u8 dummy_ipv6_gtpu_ipv6_packet[] = {
1057         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1058         0x00, 0x00, 0x00, 0x00,
1059         0x00, 0x00, 0x00, 0x00,
1060         0x86, 0xdd,
1061
1062         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1063         0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1064         0x00, 0x00, 0x00, 0x00,
1065         0x00, 0x00, 0x00, 0x00,
1066         0x00, 0x00, 0x00, 0x00,
1067         0x00, 0x00, 0x00, 0x00,
1068         0x00, 0x00, 0x00, 0x00,
1069         0x00, 0x00, 0x00, 0x00,
1070         0x00, 0x00, 0x00, 0x00,
1071         0x00, 0x00, 0x00, 0x00,
1072
1073         0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1074         0x00, 0x00, 0x00, 0x00,
1075
1076         0x34, 0xff, 0x00, 0x28,  /* ICE_GTP 62 */
1077         0x00, 0x00, 0x00, 0x00,
1078         0x00, 0x00, 0x00, 0x85,
1079
1080         0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1081         0x00, 0x00, 0x00, 0x00,
1082
1083         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFIL 82 */
1084         0x00, 0x00, 0x3b, 0x00,
1085         0x00, 0x00, 0x00, 0x00,
1086         0x00, 0x00, 0x00, 0x00,
1087         0x00, 0x00, 0x00, 0x00,
1088         0x00, 0x00, 0x00, 0x00,
1089         0x00, 0x00, 0x00, 0x00,
1090         0x00, 0x00, 0x00, 0x00,
1091         0x00, 0x00, 0x00, 0x00,
1092         0x00, 0x00, 0x00, 0x00,
1093
1094         0x00, 0x00,
1095 };
1096
1097 static const struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = {
1098         { ICE_MAC_OFOS,         0 },
1099         { ICE_IPV4_OFOS,        14 },
1100         { ICE_UDP_OF,           34 },
1101         { ICE_GTP,              42 },
1102         { ICE_PROTOCOL_LAST,    0 },
1103 };
1104
1105 static const u8 dummy_udp_gtp_packet[] = {
1106         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1107         0x00, 0x00, 0x00, 0x00,
1108         0x00, 0x00, 0x00, 0x00,
1109         0x08, 0x00,
1110
1111         0x45, 0x00, 0x00, 0x30, /* ICE_IPV4_OFOS 14 */
1112         0x00, 0x00, 0x00, 0x00,
1113         0x00, 0x11, 0x00, 0x00,
1114         0x00, 0x00, 0x00, 0x00,
1115         0x00, 0x00, 0x00, 0x00,
1116
1117         0x00, 0x00, 0x08, 0x68, /* ICE_UDP_OF 34 */
1118         0x00, 0x1c, 0x00, 0x00,
1119
1120         0x34, 0xff, 0x00, 0x0c, /* ICE_GTP 42 */
1121         0x00, 0x00, 0x00, 0x00,
1122         0x00, 0x00, 0x00, 0x85,
1123
1124         0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1125         0x00, 0x00, 0x00, 0x00,
1126 };
1127
1128 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtp_no_pay_packet_offsets[] = {
1129         { ICE_MAC_OFOS,         0 },
1130         { ICE_IPV4_OFOS,        14 },
1131         { ICE_UDP_OF,           34 },
1132         { ICE_GTP_NO_PAY,       42 },
1133         { ICE_PROTOCOL_LAST,    0 },
1134 };
1135
1136 static const
1137 struct ice_dummy_pkt_offsets dummy_ipv6_gtp_no_pay_packet_offsets[] = {
1138         { ICE_MAC_OFOS,         0 },
1139         { ICE_IPV6_OFOS,        14 },
1140         { ICE_UDP_OF,           54 },
1141         { ICE_GTP_NO_PAY,       62 },
1142         { ICE_PROTOCOL_LAST,    0 },
1143 };
1144
1145 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_offsets[] = {
1146         { ICE_MAC_OFOS,         0 },
1147         { ICE_ETYPE_OL,         12 },
1148         { ICE_VLAN_OFOS,        14},
1149         { ICE_PPPOE,            18 },
1150         { ICE_PROTOCOL_LAST,    0 },
1151 };
1152
1153 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv4_offsets[] = {
1154         { ICE_MAC_OFOS,         0 },
1155         { ICE_ETYPE_OL,         12 },
1156         { ICE_VLAN_OFOS,        14},
1157         { ICE_PPPOE,            18 },
1158         { ICE_IPV4_OFOS,        26 },
1159         { ICE_PROTOCOL_LAST,    0 },
1160 };
1161
1162 static const u8 dummy_pppoe_ipv4_packet[] = {
1163         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1164         0x00, 0x00, 0x00, 0x00,
1165         0x00, 0x00, 0x00, 0x00,
1166
1167         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
1168
1169         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1170
1171         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1172         0x00, 0x16,
1173
1174         0x00, 0x21,             /* PPP Link Layer 24 */
1175
1176         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 26 */
1177         0x00, 0x00, 0x00, 0x00,
1178         0x00, 0x00, 0x00, 0x00,
1179         0x00, 0x00, 0x00, 0x00,
1180         0x00, 0x00, 0x00, 0x00,
1181
1182         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1183 };
1184
1185 static const
1186 struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_tcp_packet_offsets[] = {
1187         { ICE_MAC_OFOS,         0 },
1188         { ICE_ETYPE_OL,         12 },
1189         { ICE_VLAN_OFOS,        14},
1190         { ICE_PPPOE,            18 },
1191         { ICE_IPV4_OFOS,        26 },
1192         { ICE_TCP_IL,           46 },
1193         { ICE_PROTOCOL_LAST,    0 },
1194 };
1195
1196 static const u8 dummy_pppoe_ipv4_tcp_packet[] = {
1197         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1198         0x00, 0x00, 0x00, 0x00,
1199         0x00, 0x00, 0x00, 0x00,
1200
1201         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
1202
1203         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1204
1205         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1206         0x00, 0x16,
1207
1208         0x00, 0x21,             /* PPP Link Layer 24 */
1209
1210         0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 26 */
1211         0x00, 0x01, 0x00, 0x00,
1212         0x00, 0x06, 0x00, 0x00,
1213         0x00, 0x00, 0x00, 0x00,
1214         0x00, 0x00, 0x00, 0x00,
1215
1216         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 46 */
1217         0x00, 0x00, 0x00, 0x00,
1218         0x00, 0x00, 0x00, 0x00,
1219         0x50, 0x00, 0x00, 0x00,
1220         0x00, 0x00, 0x00, 0x00,
1221
1222         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1223 };
1224
1225 static const
1226 struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_udp_packet_offsets[] = {
1227         { ICE_MAC_OFOS,         0 },
1228         { ICE_ETYPE_OL,         12 },
1229         { ICE_VLAN_OFOS,        14},
1230         { ICE_PPPOE,            18 },
1231         { ICE_IPV4_OFOS,        26 },
1232         { ICE_UDP_ILOS,         46 },
1233         { ICE_PROTOCOL_LAST,    0 },
1234 };
1235
1236 static const u8 dummy_pppoe_ipv4_udp_packet[] = {
1237         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1238         0x00, 0x00, 0x00, 0x00,
1239         0x00, 0x00, 0x00, 0x00,
1240
1241         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
1242
1243         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1244
1245         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1246         0x00, 0x16,
1247
1248         0x00, 0x21,             /* PPP Link Layer 24 */
1249
1250         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 26 */
1251         0x00, 0x01, 0x00, 0x00,
1252         0x00, 0x11, 0x00, 0x00,
1253         0x00, 0x00, 0x00, 0x00,
1254         0x00, 0x00, 0x00, 0x00,
1255
1256         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 46 */
1257         0x00, 0x08, 0x00, 0x00,
1258
1259         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1260 };
1261
1262 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_offsets[] = {
1263         { ICE_MAC_OFOS,         0 },
1264         { ICE_ETYPE_OL,         12 },
1265         { ICE_VLAN_OFOS,        14},
1266         { ICE_PPPOE,            18 },
1267         { ICE_IPV6_OFOS,        26 },
1268         { ICE_PROTOCOL_LAST,    0 },
1269 };
1270
1271 static const u8 dummy_pppoe_ipv6_packet[] = {
1272         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1273         0x00, 0x00, 0x00, 0x00,
1274         0x00, 0x00, 0x00, 0x00,
1275
1276         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
1277
1278         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1279
1280         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1281         0x00, 0x2a,
1282
1283         0x00, 0x57,             /* PPP Link Layer 24 */
1284
1285         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1286         0x00, 0x00, 0x3b, 0x00,
1287         0x00, 0x00, 0x00, 0x00,
1288         0x00, 0x00, 0x00, 0x00,
1289         0x00, 0x00, 0x00, 0x00,
1290         0x00, 0x00, 0x00, 0x00,
1291         0x00, 0x00, 0x00, 0x00,
1292         0x00, 0x00, 0x00, 0x00,
1293         0x00, 0x00, 0x00, 0x00,
1294         0x00, 0x00, 0x00, 0x00,
1295
1296         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1297 };
1298
1299 static const
1300 struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_tcp_offsets[] = {
1301         { ICE_MAC_OFOS,         0 },
1302         { ICE_ETYPE_OL,         12 },
1303         { ICE_VLAN_OFOS,        14},
1304         { ICE_PPPOE,            18 },
1305         { ICE_IPV6_OFOS,        26 },
1306         { ICE_TCP_IL,           66 },
1307         { ICE_PROTOCOL_LAST,    0 },
1308 };
1309
1310 static const u8 dummy_pppoe_ipv6_tcp_packet[] = {
1311         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1312         0x00, 0x00, 0x00, 0x00,
1313         0x00, 0x00, 0x00, 0x00,
1314
1315         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
1316
1317         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1318
1319         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1320         0x00, 0x2a,
1321
1322         0x00, 0x57,             /* PPP Link Layer 24 */
1323
1324         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1325         0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
1326         0x00, 0x00, 0x00, 0x00,
1327         0x00, 0x00, 0x00, 0x00,
1328         0x00, 0x00, 0x00, 0x00,
1329         0x00, 0x00, 0x00, 0x00,
1330         0x00, 0x00, 0x00, 0x00,
1331         0x00, 0x00, 0x00, 0x00,
1332         0x00, 0x00, 0x00, 0x00,
1333         0x00, 0x00, 0x00, 0x00,
1334
1335         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 66 */
1336         0x00, 0x00, 0x00, 0x00,
1337         0x00, 0x00, 0x00, 0x00,
1338         0x50, 0x00, 0x00, 0x00,
1339         0x00, 0x00, 0x00, 0x00,
1340
1341         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1342 };
1343
1344 static const
1345 struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_udp_offsets[] = {
1346         { ICE_MAC_OFOS,         0 },
1347         { ICE_ETYPE_OL,         12 },
1348         { ICE_VLAN_OFOS,        14},
1349         { ICE_PPPOE,            18 },
1350         { ICE_IPV6_OFOS,        26 },
1351         { ICE_UDP_ILOS,         66 },
1352         { ICE_PROTOCOL_LAST,    0 },
1353 };
1354
1355 static const u8 dummy_pppoe_ipv6_udp_packet[] = {
1356         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1357         0x00, 0x00, 0x00, 0x00,
1358         0x00, 0x00, 0x00, 0x00,
1359
1360         0x81, 0x00,             /* ICE_ETYPE_OL 12 */
1361
1362         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */
1363
1364         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1365         0x00, 0x2a,
1366
1367         0x00, 0x57,             /* PPP Link Layer 24 */
1368
1369         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1370         0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
1371         0x00, 0x00, 0x00, 0x00,
1372         0x00, 0x00, 0x00, 0x00,
1373         0x00, 0x00, 0x00, 0x00,
1374         0x00, 0x00, 0x00, 0x00,
1375         0x00, 0x00, 0x00, 0x00,
1376         0x00, 0x00, 0x00, 0x00,
1377         0x00, 0x00, 0x00, 0x00,
1378         0x00, 0x00, 0x00, 0x00,
1379
1380         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 66 */
1381         0x00, 0x08, 0x00, 0x00,
1382
1383         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1384 };
1385
1386 static const struct ice_dummy_pkt_offsets dummy_ipv4_esp_packet_offsets[] = {
1387         { ICE_MAC_OFOS,         0 },
1388         { ICE_IPV4_OFOS,        14 },
1389         { ICE_ESP,                      34 },
1390         { ICE_PROTOCOL_LAST,    0 },
1391 };
1392
1393 static const u8 dummy_ipv4_esp_pkt[] = {
1394         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1395         0x00, 0x00, 0x00, 0x00,
1396         0x00, 0x00, 0x00, 0x00,
1397         0x08, 0x00,
1398
1399         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 14 */
1400         0x00, 0x00, 0x40, 0x00,
1401         0x40, 0x32, 0x00, 0x00,
1402         0x00, 0x00, 0x00, 0x00,
1403         0x00, 0x00, 0x00, 0x00,
1404
1405         0x00, 0x00, 0x00, 0x00, /* ICE_ESP 34 */
1406         0x00, 0x00, 0x00, 0x00,
1407         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1408 };
1409
1410 static const struct ice_dummy_pkt_offsets dummy_ipv6_esp_packet_offsets[] = {
1411         { ICE_MAC_OFOS,         0 },
1412         { ICE_IPV6_OFOS,        14 },
1413         { ICE_ESP,                      54 },
1414         { ICE_PROTOCOL_LAST,    0 },
1415 };
1416
1417 static const u8 dummy_ipv6_esp_pkt[] = {
1418         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1419         0x00, 0x00, 0x00, 0x00,
1420         0x00, 0x00, 0x00, 0x00,
1421         0x86, 0xDD,
1422
1423         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1424         0x00, 0x08, 0x32, 0x00, /* Next header ESP */
1425         0x00, 0x00, 0x00, 0x00,
1426         0x00, 0x00, 0x00, 0x00,
1427         0x00, 0x00, 0x00, 0x00,
1428         0x00, 0x00, 0x00, 0x00,
1429         0x00, 0x00, 0x00, 0x00,
1430         0x00, 0x00, 0x00, 0x00,
1431         0x00, 0x00, 0x00, 0x00,
1432         0x00, 0x00, 0x00, 0x00,
1433
1434         0x00, 0x00, 0x00, 0x00, /* ICE_ESP 54 */
1435         0x00, 0x00, 0x00, 0x00,
1436         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1437 };
1438
1439 static const struct ice_dummy_pkt_offsets dummy_ipv4_ah_packet_offsets[] = {
1440         { ICE_MAC_OFOS,         0 },
1441         { ICE_IPV4_OFOS,        14 },
1442         { ICE_AH,                       34 },
1443         { ICE_PROTOCOL_LAST,    0 },
1444 };
1445
1446 static const u8 dummy_ipv4_ah_pkt[] = {
1447         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1448         0x00, 0x00, 0x00, 0x00,
1449         0x00, 0x00, 0x00, 0x00,
1450         0x08, 0x00,
1451
1452         0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1453         0x00, 0x00, 0x40, 0x00,
1454         0x40, 0x33, 0x00, 0x00,
1455         0x00, 0x00, 0x00, 0x00,
1456         0x00, 0x00, 0x00, 0x00,
1457
1458         0x00, 0x00, 0x00, 0x00, /* ICE_AH 34 */
1459         0x00, 0x00, 0x00, 0x00,
1460         0x00, 0x00, 0x00, 0x00,
1461         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1462 };
1463
1464 static const struct ice_dummy_pkt_offsets dummy_ipv6_ah_packet_offsets[] = {
1465         { ICE_MAC_OFOS,         0 },
1466         { ICE_IPV6_OFOS,        14 },
1467         { ICE_AH,                       54 },
1468         { ICE_PROTOCOL_LAST,    0 },
1469 };
1470
1471 static const u8 dummy_ipv6_ah_pkt[] = {
1472         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1473         0x00, 0x00, 0x00, 0x00,
1474         0x00, 0x00, 0x00, 0x00,
1475         0x86, 0xDD,
1476
1477         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1478         0x00, 0x0c, 0x33, 0x00, /* Next header AH */
1479         0x00, 0x00, 0x00, 0x00,
1480         0x00, 0x00, 0x00, 0x00,
1481         0x00, 0x00, 0x00, 0x00,
1482         0x00, 0x00, 0x00, 0x00,
1483         0x00, 0x00, 0x00, 0x00,
1484         0x00, 0x00, 0x00, 0x00,
1485         0x00, 0x00, 0x00, 0x00,
1486         0x00, 0x00, 0x00, 0x00,
1487
1488         0x00, 0x00, 0x00, 0x00, /* ICE_AH 54 */
1489         0x00, 0x00, 0x00, 0x00,
1490         0x00, 0x00, 0x00, 0x00,
1491         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1492 };
1493
1494 static const struct ice_dummy_pkt_offsets dummy_ipv4_nat_packet_offsets[] = {
1495         { ICE_MAC_OFOS,         0 },
1496         { ICE_IPV4_OFOS,        14 },
1497         { ICE_UDP_ILOS,         34 },
1498         { ICE_NAT_T,            42 },
1499         { ICE_PROTOCOL_LAST,    0 },
1500 };
1501
1502 static const u8 dummy_ipv4_nat_pkt[] = {
1503         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1504         0x00, 0x00, 0x00, 0x00,
1505         0x00, 0x00, 0x00, 0x00,
1506         0x08, 0x00,
1507
1508         0x45, 0x00, 0x00, 0x24, /* ICE_IPV4_IL 14 */
1509         0x00, 0x00, 0x40, 0x00,
1510         0x40, 0x11, 0x00, 0x00,
1511         0x00, 0x00, 0x00, 0x00,
1512         0x00, 0x00, 0x00, 0x00,
1513
1514         0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 34 */
1515         0x00, 0x00, 0x00, 0x00,
1516
1517         0x00, 0x00, 0x00, 0x00,
1518         0x00, 0x00, 0x00, 0x00,
1519         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1520 };
1521
1522 static const struct ice_dummy_pkt_offsets dummy_ipv6_nat_packet_offsets[] = {
1523         { ICE_MAC_OFOS,         0 },
1524         { ICE_IPV6_OFOS,        14 },
1525         { ICE_UDP_ILOS,         54 },
1526         { ICE_NAT_T,            62 },
1527         { ICE_PROTOCOL_LAST,    0 },
1528 };
1529
1530 static const u8 dummy_ipv6_nat_pkt[] = {
1531         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1532         0x00, 0x00, 0x00, 0x00,
1533         0x00, 0x00, 0x00, 0x00,
1534         0x86, 0xDD,
1535
1536         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1537         0x00, 0x10, 0x11, 0x00, /* Next header NAT_T */
1538         0x00, 0x00, 0x00, 0x00,
1539         0x00, 0x00, 0x00, 0x00,
1540         0x00, 0x00, 0x00, 0x00,
1541         0x00, 0x00, 0x00, 0x00,
1542         0x00, 0x00, 0x00, 0x00,
1543         0x00, 0x00, 0x00, 0x00,
1544         0x00, 0x00, 0x00, 0x00,
1545         0x00, 0x00, 0x00, 0x00,
1546
1547         0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 54 */
1548         0x00, 0x00, 0x00, 0x00,
1549
1550         0x00, 0x00, 0x00, 0x00,
1551         0x00, 0x00, 0x00, 0x00,
1552         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1553
1554 };
1555
1556 static const struct ice_dummy_pkt_offsets dummy_ipv4_l2tpv3_packet_offsets[] = {
1557         { ICE_MAC_OFOS,         0 },
1558         { ICE_IPV4_OFOS,        14 },
1559         { ICE_L2TPV3,           34 },
1560         { ICE_PROTOCOL_LAST,    0 },
1561 };
1562
1563 static const u8 dummy_ipv4_l2tpv3_pkt[] = {
1564         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1565         0x00, 0x00, 0x00, 0x00,
1566         0x00, 0x00, 0x00, 0x00,
1567         0x08, 0x00,
1568
1569         0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1570         0x00, 0x00, 0x40, 0x00,
1571         0x40, 0x73, 0x00, 0x00,
1572         0x00, 0x00, 0x00, 0x00,
1573         0x00, 0x00, 0x00, 0x00,
1574
1575         0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
1576         0x00, 0x00, 0x00, 0x00,
1577         0x00, 0x00, 0x00, 0x00,
1578         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1579 };
1580
1581 static const struct ice_dummy_pkt_offsets dummy_ipv6_l2tpv3_packet_offsets[] = {
1582         { ICE_MAC_OFOS,         0 },
1583         { ICE_IPV6_OFOS,        14 },
1584         { ICE_L2TPV3,           54 },
1585         { ICE_PROTOCOL_LAST,    0 },
1586 };
1587
1588 static const u8 dummy_ipv6_l2tpv3_pkt[] = {
1589         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1590         0x00, 0x00, 0x00, 0x00,
1591         0x00, 0x00, 0x00, 0x00,
1592         0x86, 0xDD,
1593
1594         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
1595         0x00, 0x0c, 0x73, 0x40,
1596         0x00, 0x00, 0x00, 0x00,
1597         0x00, 0x00, 0x00, 0x00,
1598         0x00, 0x00, 0x00, 0x00,
1599         0x00, 0x00, 0x00, 0x00,
1600         0x00, 0x00, 0x00, 0x00,
1601         0x00, 0x00, 0x00, 0x00,
1602         0x00, 0x00, 0x00, 0x00,
1603         0x00, 0x00, 0x00, 0x00,
1604
1605         0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
1606         0x00, 0x00, 0x00, 0x00,
1607         0x00, 0x00, 0x00, 0x00,
1608         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1609 };
1610
1611 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv4_packet_offsets[] = {
1612         { ICE_MAC_OFOS,         0 },
1613         { ICE_ETYPE_OL,         12 },
1614         { ICE_VLAN_EX,          14 },
1615         { ICE_VLAN_IN,          18 },
1616         { ICE_IPV4_OFOS,        22 },
1617         { ICE_PROTOCOL_LAST,    0 },
1618 };
1619
1620 static const u8 dummy_qinq_ipv4_pkt[] = {
1621         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1622         0x00, 0x00, 0x00, 0x00,
1623         0x00, 0x00, 0x00, 0x00,
1624
1625         0x91, 0x00,             /* ICE_ETYPE_OL 12 */
1626
1627         0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1628         0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_IN 18 */
1629
1630         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
1631         0x00, 0x01, 0x00, 0x00,
1632         0x00, 0x11, 0x00, 0x00,
1633         0x00, 0x00, 0x00, 0x00,
1634         0x00, 0x00, 0x00, 0x00,
1635
1636         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
1637         0x00, 0x08, 0x00, 0x00,
1638
1639         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
1640 };
1641
1642 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv6_packet_offsets[] = {
1643         { ICE_MAC_OFOS,         0 },
1644         { ICE_ETYPE_OL,         12 },
1645         { ICE_VLAN_EX,          14 },
1646         { ICE_VLAN_IN,          18 },
1647         { ICE_IPV6_OFOS,        22 },
1648         { ICE_PROTOCOL_LAST,    0 },
1649 };
1650
1651 static const u8 dummy_qinq_ipv6_pkt[] = {
1652         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1653         0x00, 0x00, 0x00, 0x00,
1654         0x00, 0x00, 0x00, 0x00,
1655
1656         0x91, 0x00,             /* ICE_ETYPE_OL 12 */
1657
1658         0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1659         0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_IN 18 */
1660
1661         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1662         0x00, 0x10, 0x11, 0x00, /* Next header UDP */
1663         0x00, 0x00, 0x00, 0x00,
1664         0x00, 0x00, 0x00, 0x00,
1665         0x00, 0x00, 0x00, 0x00,
1666         0x00, 0x00, 0x00, 0x00,
1667         0x00, 0x00, 0x00, 0x00,
1668         0x00, 0x00, 0x00, 0x00,
1669         0x00, 0x00, 0x00, 0x00,
1670         0x00, 0x00, 0x00, 0x00,
1671
1672         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
1673         0x00, 0x10, 0x00, 0x00,
1674
1675         0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
1676         0x00, 0x00, 0x00, 0x00,
1677
1678         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
1679 };
1680
1681 static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = {
1682         { ICE_MAC_OFOS,         0 },
1683         { ICE_ETYPE_OL,         12 },
1684         { ICE_VLAN_EX,          14 },
1685         { ICE_VLAN_IN,          18 },
1686         { ICE_PPPOE,            22 },
1687         { ICE_PROTOCOL_LAST,    0 },
1688 };
1689
1690 static const
1691 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_ipv4_packet_offsets[] = {
1692         { ICE_MAC_OFOS,         0 },
1693         { ICE_ETYPE_OL,         12 },
1694         { ICE_VLAN_EX,          14 },
1695         { ICE_VLAN_IN,          18 },
1696         { ICE_PPPOE,            22 },
1697         { ICE_IPV4_OFOS,        30 },
1698         { ICE_PROTOCOL_LAST,    0 },
1699 };
1700
1701 static const u8 dummy_qinq_pppoe_ipv4_pkt[] = {
1702         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1703         0x00, 0x00, 0x00, 0x00,
1704         0x00, 0x00, 0x00, 0x00,
1705
1706         0x91, 0x00,             /* ICE_ETYPE_OL 12 */
1707
1708         0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1709         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_IN 18 */
1710
1711         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
1712         0x00, 0x16,
1713
1714         0x00, 0x21,             /* PPP Link Layer 28 */
1715
1716         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_OFOS 30 */
1717         0x00, 0x00, 0x00, 0x00,
1718         0x00, 0x00, 0x00, 0x00,
1719         0x00, 0x00, 0x00, 0x00,
1720         0x00, 0x00, 0x00, 0x00,
1721
1722         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
1723 };
1724
1725 static const
1726 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_ipv6_offsets[] = {
1727         { ICE_MAC_OFOS,         0 },
1728         { ICE_ETYPE_OL,         12 },
1729         { ICE_VLAN_EX,          14},
1730         { ICE_VLAN_IN,          18 },
1731         { ICE_PPPOE,            22 },
1732         { ICE_IPV6_OFOS,        30 },
1733         { ICE_PROTOCOL_LAST,    0 },
1734 };
1735
1736 static const u8 dummy_qinq_pppoe_ipv6_packet[] = {
1737         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1738         0x00, 0x00, 0x00, 0x00,
1739         0x00, 0x00, 0x00, 0x00,
1740
1741         0x91, 0x00,             /* ICE_ETYPE_OL 12 */
1742
1743         0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */
1744         0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_IN 18 */
1745
1746         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
1747         0x00, 0x2a,
1748
1749         0x00, 0x57,             /* PPP Link Layer 28*/
1750
1751         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 30 */
1752         0x00, 0x00, 0x3b, 0x00,
1753         0x00, 0x00, 0x00, 0x00,
1754         0x00, 0x00, 0x00, 0x00,
1755         0x00, 0x00, 0x00, 0x00,
1756         0x00, 0x00, 0x00, 0x00,
1757         0x00, 0x00, 0x00, 0x00,
1758         0x00, 0x00, 0x00, 0x00,
1759         0x00, 0x00, 0x00, 0x00,
1760         0x00, 0x00, 0x00, 0x00,
1761
1762         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1763 };
1764
1765 /* this is a recipe to profile association bitmap */
1766 static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES],
1767                           ICE_MAX_NUM_PROFILES);
1768
1769 /* this is a profile to recipe association bitmap */
1770 static ice_declare_bitmap(profile_to_recipe[ICE_MAX_NUM_PROFILES],
1771                           ICE_MAX_NUM_RECIPES);
1772
1773 static void ice_get_recp_to_prof_map(struct ice_hw *hw);
1774
1775 /**
1776  * ice_collect_result_idx - copy result index values
1777  * @buf: buffer that contains the result index
1778  * @recp: the recipe struct to copy data into
1779  */
1780 static void ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
1781                                    struct ice_sw_recipe *recp)
1782 {
1783         if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
1784                 ice_set_bit(buf->content.result_indx &
1785                             ~ICE_AQ_RECIPE_RESULT_EN, recp->res_idxs);
1786 }
1787
1788 /**
1789  * ice_get_tun_type_for_recipe - get tunnel type for the recipe
1790  * @rid: recipe ID that we are populating
1791  */
1792 static enum ice_sw_tunnel_type ice_get_tun_type_for_recipe(u8 rid, bool vlan)
1793 {
1794         u8 vxlan_profile[12] = {10, 11, 12, 16, 17, 18, 22, 23, 24, 25, 26, 27};
1795         u8 gre_profile[12] = {13, 14, 15, 19, 20, 21, 28, 29, 30, 31, 32, 33};
1796         u8 pppoe_profile[7] = {34, 35, 36, 37, 38, 39, 40};
1797         u8 non_tun_profile[6] = {4, 5, 6, 7, 8, 9};
1798         enum ice_sw_tunnel_type tun_type;
1799         u16 i, j, profile_num = 0;
1800         bool non_tun_valid = false;
1801         bool pppoe_valid = false;
1802         bool vxlan_valid = false;
1803         bool gre_valid = false;
1804         bool gtp_valid = false;
1805         bool flag_valid = false;
1806
1807         for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) {
1808                 if (!ice_is_bit_set(recipe_to_profile[rid], j))
1809                         continue;
1810                 else
1811                         profile_num++;
1812
1813                 for (i = 0; i < 12; i++) {
1814                         if (gre_profile[i] == j)
1815                                 gre_valid = true;
1816                 }
1817
1818                 for (i = 0; i < 12; i++) {
1819                         if (vxlan_profile[i] == j)
1820                                 vxlan_valid = true;
1821                 }
1822
1823                 for (i = 0; i < 7; i++) {
1824                         if (pppoe_profile[i] == j)
1825                                 pppoe_valid = true;
1826                 }
1827
1828                 for (i = 0; i < 6; i++) {
1829                         if (non_tun_profile[i] == j)
1830                                 non_tun_valid = true;
1831                 }
1832
1833                 if (j >= ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER &&
1834                     j <= ICE_PROFID_IPV6_GTPU_IPV6_TCP)
1835                         gtp_valid = true;
1836
1837                 if ((j >= ICE_PROFID_IPV4_ESP &&
1838                      j <= ICE_PROFID_IPV6_PFCP_SESSION) ||
1839                     (j >= ICE_PROFID_IPV4_GTPC_TEID &&
1840                      j <= ICE_PROFID_IPV6_GTPU_TEID))
1841                         flag_valid = true;
1842         }
1843
1844         if (!non_tun_valid && vxlan_valid)
1845                 tun_type = ICE_SW_TUN_VXLAN;
1846         else if (!non_tun_valid && gre_valid)
1847                 tun_type = ICE_SW_TUN_NVGRE;
1848         else if (!non_tun_valid && pppoe_valid)
1849                 tun_type = ICE_SW_TUN_PPPOE;
1850         else if (!non_tun_valid && gtp_valid)
1851                 tun_type = ICE_SW_TUN_GTP;
1852         else if (non_tun_valid &&
1853                  (vxlan_valid || gre_valid || gtp_valid || pppoe_valid))
1854                 tun_type = ICE_SW_TUN_AND_NON_TUN;
1855         else if (non_tun_valid && !vxlan_valid && !gre_valid && !gtp_valid &&
1856                  !pppoe_valid)
1857                 tun_type = ICE_NON_TUN;
1858         else
1859                 tun_type = ICE_NON_TUN;
1860
1861         if (profile_num > 1 && tun_type == ICE_SW_TUN_PPPOE) {
1862                 i = ice_is_bit_set(recipe_to_profile[rid],
1863                                    ICE_PROFID_PPPOE_IPV4_OTHER);
1864                 j = ice_is_bit_set(recipe_to_profile[rid],
1865                                    ICE_PROFID_PPPOE_IPV6_OTHER);
1866                 if (i && !j)
1867                         tun_type = ICE_SW_TUN_PPPOE_IPV4;
1868                 else if (!i && j)
1869                         tun_type = ICE_SW_TUN_PPPOE_IPV6;
1870         }
1871
1872         if (tun_type == ICE_SW_TUN_GTP) {
1873                 if (ice_is_bit_set(recipe_to_profile[rid],
1874                                    ICE_PROFID_IPV4_GTPU_IPV4_OTHER))
1875                         tun_type = ICE_SW_TUN_IPV4_GTPU_IPV4;
1876                 else if (ice_is_bit_set(recipe_to_profile[rid],
1877                                         ICE_PROFID_IPV4_GTPU_IPV6_OTHER))
1878                         tun_type = ICE_SW_TUN_IPV4_GTPU_IPV6;
1879                 else if (ice_is_bit_set(recipe_to_profile[rid],
1880                                         ICE_PROFID_IPV6_GTPU_IPV4_OTHER))
1881                         tun_type = ICE_SW_TUN_IPV6_GTPU_IPV4;
1882                 else if (ice_is_bit_set(recipe_to_profile[rid],
1883                                         ICE_PROFID_IPV6_GTPU_IPV6_OTHER))
1884                         tun_type = ICE_SW_TUN_IPV6_GTPU_IPV6;
1885         }
1886
1887         if (profile_num == 1 && (flag_valid || non_tun_valid || pppoe_valid)) {
1888                 for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) {
1889                         if (ice_is_bit_set(recipe_to_profile[rid], j)) {
1890                                 switch (j) {
1891                                 case ICE_PROFID_IPV4_TCP:
1892                                         tun_type = ICE_SW_IPV4_TCP;
1893                                         break;
1894                                 case ICE_PROFID_IPV4_UDP:
1895                                         tun_type = ICE_SW_IPV4_UDP;
1896                                         break;
1897                                 case ICE_PROFID_IPV6_TCP:
1898                                         tun_type = ICE_SW_IPV6_TCP;
1899                                         break;
1900                                 case ICE_PROFID_IPV6_UDP:
1901                                         tun_type = ICE_SW_IPV6_UDP;
1902                                         break;
1903                                 case ICE_PROFID_PPPOE_PAY:
1904                                         tun_type = ICE_SW_TUN_PPPOE_PAY;
1905                                         break;
1906                                 case ICE_PROFID_PPPOE_IPV4_TCP:
1907                                         tun_type = ICE_SW_TUN_PPPOE_IPV4_TCP;
1908                                         break;
1909                                 case ICE_PROFID_PPPOE_IPV4_UDP:
1910                                         tun_type = ICE_SW_TUN_PPPOE_IPV4_UDP;
1911                                         break;
1912                                 case ICE_PROFID_PPPOE_IPV4_OTHER:
1913                                         tun_type = ICE_SW_TUN_PPPOE_IPV4;
1914                                         break;
1915                                 case ICE_PROFID_PPPOE_IPV6_TCP:
1916                                         tun_type = ICE_SW_TUN_PPPOE_IPV6_TCP;
1917                                         break;
1918                                 case ICE_PROFID_PPPOE_IPV6_UDP:
1919                                         tun_type = ICE_SW_TUN_PPPOE_IPV6_UDP;
1920                                         break;
1921                                 case ICE_PROFID_PPPOE_IPV6_OTHER:
1922                                         tun_type = ICE_SW_TUN_PPPOE_IPV6;
1923                                         break;
1924                                 case ICE_PROFID_IPV4_ESP:
1925                                         tun_type = ICE_SW_TUN_IPV4_ESP;
1926                                         break;
1927                                 case ICE_PROFID_IPV6_ESP:
1928                                         tun_type = ICE_SW_TUN_IPV6_ESP;
1929                                         break;
1930                                 case ICE_PROFID_IPV4_AH:
1931                                         tun_type = ICE_SW_TUN_IPV4_AH;
1932                                         break;
1933                                 case ICE_PROFID_IPV6_AH:
1934                                         tun_type = ICE_SW_TUN_IPV6_AH;
1935                                         break;
1936                                 case ICE_PROFID_IPV4_NAT_T:
1937                                         tun_type = ICE_SW_TUN_IPV4_NAT_T;
1938                                         break;
1939                                 case ICE_PROFID_IPV6_NAT_T:
1940                                         tun_type = ICE_SW_TUN_IPV6_NAT_T;
1941                                         break;
1942                                 case ICE_PROFID_IPV4_PFCP_NODE:
1943                                         tun_type =
1944                                         ICE_SW_TUN_PROFID_IPV4_PFCP_NODE;
1945                                         break;
1946                                 case ICE_PROFID_IPV6_PFCP_NODE:
1947                                         tun_type =
1948                                         ICE_SW_TUN_PROFID_IPV6_PFCP_NODE;
1949                                         break;
1950                                 case ICE_PROFID_IPV4_PFCP_SESSION:
1951                                         tun_type =
1952                                         ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION;
1953                                         break;
1954                                 case ICE_PROFID_IPV6_PFCP_SESSION:
1955                                         tun_type =
1956                                         ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION;
1957                                         break;
1958                                 case ICE_PROFID_MAC_IPV4_L2TPV3:
1959                                         tun_type = ICE_SW_TUN_IPV4_L2TPV3;
1960                                         break;
1961                                 case ICE_PROFID_MAC_IPV6_L2TPV3:
1962                                         tun_type = ICE_SW_TUN_IPV6_L2TPV3;
1963                                         break;
1964                                 case ICE_PROFID_IPV4_GTPU_TEID:
1965                                         tun_type = ICE_SW_TUN_IPV4_GTPU_NO_PAY;
1966                                         break;
1967                                 case ICE_PROFID_IPV6_GTPU_TEID:
1968                                         tun_type = ICE_SW_TUN_IPV6_GTPU_NO_PAY;
1969                                         break;
1970                                 default:
1971                                         break;
1972                                 }
1973
1974                                 return tun_type;
1975                         }
1976                 }
1977         }
1978
1979         if (vlan && tun_type == ICE_SW_TUN_PPPOE)
1980                 tun_type = ICE_SW_TUN_PPPOE_QINQ;
1981         else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV6)
1982                 tun_type = ICE_SW_TUN_PPPOE_IPV6_QINQ;
1983         else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV4)
1984                 tun_type = ICE_SW_TUN_PPPOE_IPV4_QINQ;
1985         else if (vlan && tun_type == ICE_SW_TUN_PPPOE_PAY)
1986                 tun_type = ICE_SW_TUN_PPPOE_PAY_QINQ;
1987         else if (vlan && tun_type == ICE_SW_TUN_AND_NON_TUN)
1988                 tun_type = ICE_SW_TUN_AND_NON_TUN_QINQ;
1989         else if (vlan && tun_type == ICE_NON_TUN)
1990                 tun_type = ICE_NON_TUN_QINQ;
1991
1992         return tun_type;
1993 }
1994
1995 /**
1996  * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
1997  * @hw: pointer to hardware structure
1998  * @recps: struct that we need to populate
1999  * @rid: recipe ID that we are populating
2000  * @refresh_required: true if we should get recipe to profile mapping from FW
2001  *
2002  * This function is used to populate all the necessary entries into our
2003  * bookkeeping so that we have a current list of all the recipes that are
2004  * programmed in the firmware.
2005  */
2006 static enum ice_status
2007 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2008                     bool *refresh_required)
2009 {
2010         ice_declare_bitmap(result_bm, ICE_MAX_FV_WORDS);
2011         struct ice_aqc_recipe_data_elem *tmp;
2012         u16 num_recps = ICE_MAX_NUM_RECIPES;
2013         struct ice_prot_lkup_ext *lkup_exts;
2014         enum ice_status status;
2015         u8 fv_word_idx = 0;
2016         bool vlan = false;
2017         u16 sub_recps;
2018
2019         ice_zero_bitmap(result_bm, ICE_MAX_FV_WORDS);
2020
2021         /* we need a buffer big enough to accommodate all the recipes */
2022         tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
2023                 ICE_MAX_NUM_RECIPES, sizeof(*tmp));
2024         if (!tmp)
2025                 return ICE_ERR_NO_MEMORY;
2026
2027         tmp[0].recipe_indx = rid;
2028         status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2029         /* non-zero status meaning recipe doesn't exist */
2030         if (status)
2031                 goto err_unroll;
2032
2033         /* Get recipe to profile map so that we can get the fv from lkups that
2034          * we read for a recipe from FW. Since we want to minimize the number of
2035          * times we make this FW call, just make one call and cache the copy
2036          * until a new recipe is added. This operation is only required the
2037          * first time to get the changes from FW. Then to search existing
2038          * entries we don't need to update the cache again until another recipe
2039          * gets added.
2040          */
2041         if (*refresh_required) {
2042                 ice_get_recp_to_prof_map(hw);
2043                 *refresh_required = false;
2044         }
2045
2046         /* Start populating all the entries for recps[rid] based on lkups from
2047          * firmware. Note that we are only creating the root recipe in our
2048          * database.
2049          */
2050         lkup_exts = &recps[rid].lkup_exts;
2051
2052         for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2053                 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2054                 struct ice_recp_grp_entry *rg_entry;
2055                 u8 i, prof, idx, prot = 0;
2056                 bool is_root;
2057                 u16 off = 0;
2058
2059                 rg_entry = (struct ice_recp_grp_entry *)
2060                         ice_malloc(hw, sizeof(*rg_entry));
2061                 if (!rg_entry) {
2062                         status = ICE_ERR_NO_MEMORY;
2063                         goto err_unroll;
2064                 }
2065
2066                 idx = root_bufs.recipe_indx;
2067                 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2068
2069                 /* Mark all result indices in this chain */
2070                 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2071                         ice_set_bit(root_bufs.content.result_indx &
2072                                     ~ICE_AQ_RECIPE_RESULT_EN, result_bm);
2073
2074                 /* get the first profile that is associated with rid */
2075                 prof = ice_find_first_bit(recipe_to_profile[idx],
2076                                           ICE_MAX_NUM_PROFILES);
2077                 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2078                         u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2079
2080                         rg_entry->fv_idx[i] = lkup_indx;
2081                         rg_entry->fv_mask[i] =
2082                                 LE16_TO_CPU(root_bufs.content.mask[i + 1]);
2083
2084                         /* If the recipe is a chained recipe then all its
2085                          * child recipe's result will have a result index.
2086                          * To fill fv_words we should not use those result
2087                          * index, we only need the protocol ids and offsets.
2088                          * We will skip all the fv_idx which stores result
2089                          * index in them. We also need to skip any fv_idx which
2090                          * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2091                          * valid offset value.
2092                          */
2093                         if (ice_is_bit_set(hw->switch_info->prof_res_bm[prof],
2094                                            rg_entry->fv_idx[i]) ||
2095                             rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2096                             rg_entry->fv_idx[i] == 0)
2097                                 continue;
2098
2099                         ice_find_prot_off(hw, ICE_BLK_SW, prof,
2100                                           rg_entry->fv_idx[i], &prot, &off);
2101                         lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2102                         lkup_exts->fv_words[fv_word_idx].off = off;
2103                         lkup_exts->field_mask[fv_word_idx] =
2104                                 rg_entry->fv_mask[i];
2105                         if (prot == ICE_META_DATA_ID_HW &&
2106                             off == ICE_TUN_FLAG_MDID_OFF)
2107                                 vlan = true;
2108                         fv_word_idx++;
2109                 }
2110                 /* populate rg_list with the data from the child entry of this
2111                  * recipe
2112                  */
2113                 LIST_ADD(&rg_entry->l_entry, &recps[rid].rg_list);
2114
2115                 /* Propagate some data to the recipe database */
2116                 recps[idx].is_root = !!is_root;
2117                 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2118                 ice_zero_bitmap(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2119                 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2120                         recps[idx].chain_idx = root_bufs.content.result_indx &
2121                                 ~ICE_AQ_RECIPE_RESULT_EN;
2122                         ice_set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2123                 } else {
2124                         recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2125                 }
2126
2127                 if (!is_root)
2128                         continue;
2129
2130                 /* Only do the following for root recipes entries */
2131                 ice_memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2132                            sizeof(recps[idx].r_bitmap), ICE_NONDMA_TO_NONDMA);
2133                 recps[idx].root_rid = root_bufs.content.rid &
2134                         ~ICE_AQ_RECIPE_ID_IS_ROOT;
2135                 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2136         }
2137
2138         /* Complete initialization of the root recipe entry */
2139         lkup_exts->n_val_words = fv_word_idx;
2140         recps[rid].big_recp = (num_recps > 1);
2141         recps[rid].n_grp_count = (u8)num_recps;
2142         recps[rid].tun_type = ice_get_tun_type_for_recipe(rid, vlan);
2143         recps[rid].root_buf = (struct ice_aqc_recipe_data_elem *)
2144                 ice_memdup(hw, tmp, recps[rid].n_grp_count *
2145                            sizeof(*recps[rid].root_buf), ICE_NONDMA_TO_NONDMA);
2146         if (!recps[rid].root_buf)
2147                 goto err_unroll;
2148
2149         /* Copy result indexes */
2150         ice_cp_bitmap(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2151         recps[rid].recp_created = true;
2152
2153 err_unroll:
2154         ice_free(hw, tmp);
2155         return status;
2156 }
2157
2158 /**
2159  * ice_get_recp_to_prof_map - updates recipe to profile mapping
2160  * @hw: pointer to hardware structure
2161  *
2162  * This function is used to populate recipe_to_profile matrix where index to
2163  * this array is the recipe ID and the element is the mapping of which profiles
2164  * is this recipe mapped to.
2165  */
2166 static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2167 {
2168         ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2169         u16 i;
2170
2171         for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2172                 u16 j;
2173
2174                 ice_zero_bitmap(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2175                 ice_zero_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2176                 if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
2177                         continue;
2178                 ice_cp_bitmap(profile_to_recipe[i], r_bitmap,
2179                               ICE_MAX_NUM_RECIPES);
2180                 ice_for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2181                         ice_set_bit(i, recipe_to_profile[j]);
2182         }
2183 }
2184
2185 /**
2186  * ice_init_def_sw_recp - initialize the recipe book keeping tables
2187  * @hw: pointer to the HW struct
2188  * @recp_list: pointer to sw recipe list
2189  *
2190  * Allocate memory for the entire recipe table and initialize the structures/
2191  * entries corresponding to basic recipes.
2192  */
2193 enum ice_status
2194 ice_init_def_sw_recp(struct ice_hw *hw, struct ice_sw_recipe **recp_list)
2195 {
2196         struct ice_sw_recipe *recps;
2197         u8 i;
2198
2199         recps = (struct ice_sw_recipe *)
2200                 ice_calloc(hw, ICE_MAX_NUM_RECIPES, sizeof(*recps));
2201         if (!recps)
2202                 return ICE_ERR_NO_MEMORY;
2203
2204         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
2205                 recps[i].root_rid = i;
2206                 INIT_LIST_HEAD(&recps[i].filt_rules);
2207                 INIT_LIST_HEAD(&recps[i].filt_replay_rules);
2208                 INIT_LIST_HEAD(&recps[i].rg_list);
2209                 ice_init_lock(&recps[i].filt_rule_lock);
2210         }
2211
2212         *recp_list = recps;
2213
2214         return ICE_SUCCESS;
2215 }
2216
2217 /**
2218  * ice_aq_get_sw_cfg - get switch configuration
2219  * @hw: pointer to the hardware structure
2220  * @buf: pointer to the result buffer
2221  * @buf_size: length of the buffer available for response
2222  * @req_desc: pointer to requested descriptor
2223  * @num_elems: pointer to number of elements
2224  * @cd: pointer to command details structure or NULL
2225  *
2226  * Get switch configuration (0x0200) to be placed in buf.
2227  * This admin command returns information such as initial VSI/port number
2228  * and switch ID it belongs to.
2229  *
2230  * NOTE: *req_desc is both an input/output parameter.
2231  * The caller of this function first calls this function with *request_desc set
2232  * to 0. If the response from f/w has *req_desc set to 0, all the switch
2233  * configuration information has been returned; if non-zero (meaning not all
2234  * the information was returned), the caller should call this function again
2235  * with *req_desc set to the previous value returned by f/w to get the
2236  * next block of switch configuration information.
2237  *
2238  * *num_elems is output only parameter. This reflects the number of elements
2239  * in response buffer. The caller of this function to use *num_elems while
2240  * parsing the response buffer.
2241  */
2242 static enum ice_status
2243 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
2244                   u16 buf_size, u16 *req_desc, u16 *num_elems,
2245                   struct ice_sq_cd *cd)
2246 {
2247         struct ice_aqc_get_sw_cfg *cmd;
2248         struct ice_aq_desc desc;
2249         enum ice_status status;
2250
2251         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
2252         cmd = &desc.params.get_sw_conf;
2253         cmd->element = CPU_TO_LE16(*req_desc);
2254
2255         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
2256         if (!status) {
2257                 *req_desc = LE16_TO_CPU(cmd->element);
2258                 *num_elems = LE16_TO_CPU(cmd->num_elems);
2259         }
2260
2261         return status;
2262 }
2263
2264 /**
2265  * ice_alloc_rss_global_lut - allocate a RSS global LUT
2266  * @hw: pointer to the HW struct
2267  * @shared_res: true to allocate as a shared resource and false to allocate as a dedicated resource
2268  * @global_lut_id: output parameter for the RSS global LUT's ID
2269  */
2270 enum ice_status ice_alloc_rss_global_lut(struct ice_hw *hw, bool shared_res, u16 *global_lut_id)
2271 {
2272         struct ice_aqc_alloc_free_res_elem *sw_buf;
2273         enum ice_status status;
2274         u16 buf_len;
2275
2276         buf_len = ice_struct_size(sw_buf, elem, 1);
2277         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2278         if (!sw_buf)
2279                 return ICE_ERR_NO_MEMORY;
2280
2281         sw_buf->num_elems = CPU_TO_LE16(1);
2282         sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH |
2283                                        (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2284                                        ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2285
2286         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, ice_aqc_opc_alloc_res, NULL);
2287         if (status) {
2288                 ice_debug(hw, ICE_DBG_RES, "Failed to allocate %s RSS global LUT, status %d\n",
2289                           shared_res ? "shared" : "dedicated", status);
2290                 goto ice_alloc_global_lut_exit;
2291         }
2292
2293         *global_lut_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
2294
2295 ice_alloc_global_lut_exit:
2296         ice_free(hw, sw_buf);
2297         return status;
2298 }
2299
2300 /**
2301  * ice_free_rss_global_lut - free a RSS global LUT
2302  * @hw: pointer to the HW struct
2303  * @global_lut_id: ID of the RSS global LUT to free
2304  */
2305 enum ice_status ice_free_rss_global_lut(struct ice_hw *hw, u16 global_lut_id)
2306 {
2307         struct ice_aqc_alloc_free_res_elem *sw_buf;
2308         u16 buf_len, num_elems = 1;
2309         enum ice_status status;
2310
2311         buf_len = ice_struct_size(sw_buf, elem, num_elems);
2312         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2313         if (!sw_buf)
2314                 return ICE_ERR_NO_MEMORY;
2315
2316         sw_buf->num_elems = CPU_TO_LE16(num_elems);
2317         sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH);
2318         sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(global_lut_id);
2319
2320         status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len, ice_aqc_opc_free_res, NULL);
2321         if (status)
2322                 ice_debug(hw, ICE_DBG_RES, "Failed to free RSS global LUT %d, status %d\n",
2323                           global_lut_id, status);
2324
2325         ice_free(hw, sw_buf);
2326         return status;
2327 }
2328
2329 /**
2330  * ice_alloc_sw - allocate resources specific to switch
2331  * @hw: pointer to the HW struct
2332  * @ena_stats: true to turn on VEB stats
2333  * @shared_res: true for shared resource, false for dedicated resource
2334  * @sw_id: switch ID returned
2335  * @counter_id: VEB counter ID returned
2336  *
2337  * allocates switch resources (SWID and VEB counter) (0x0208)
2338  */
2339 enum ice_status
2340 ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id,
2341              u16 *counter_id)
2342 {
2343         struct ice_aqc_alloc_free_res_elem *sw_buf;
2344         struct ice_aqc_res_elem *sw_ele;
2345         enum ice_status status;
2346         u16 buf_len;
2347
2348         buf_len = ice_struct_size(sw_buf, elem, 1);
2349         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2350         if (!sw_buf)
2351                 return ICE_ERR_NO_MEMORY;
2352
2353         /* Prepare buffer for switch ID.
2354          * The number of resource entries in buffer is passed as 1 since only a
2355          * single switch/VEB instance is allocated, and hence a single sw_id
2356          * is requested.
2357          */
2358         sw_buf->num_elems = CPU_TO_LE16(1);
2359         sw_buf->res_type =
2360                 CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID |
2361                             (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2362                             ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2363
2364         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2365                                        ice_aqc_opc_alloc_res, NULL);
2366
2367         if (status)
2368                 goto ice_alloc_sw_exit;
2369
2370         sw_ele = &sw_buf->elem[0];
2371         *sw_id = LE16_TO_CPU(sw_ele->e.sw_resp);
2372
2373         if (ena_stats) {
2374                 /* Prepare buffer for VEB Counter */
2375                 enum ice_adminq_opc opc = ice_aqc_opc_alloc_res;
2376                 struct ice_aqc_alloc_free_res_elem *counter_buf;
2377                 struct ice_aqc_res_elem *counter_ele;
2378
2379                 counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2380                                 ice_malloc(hw, buf_len);
2381                 if (!counter_buf) {
2382                         status = ICE_ERR_NO_MEMORY;
2383                         goto ice_alloc_sw_exit;
2384                 }
2385
2386                 /* The number of resource entries in buffer is passed as 1 since
2387                  * only a single switch/VEB instance is allocated, and hence a
2388                  * single VEB counter is requested.
2389                  */
2390                 counter_buf->num_elems = CPU_TO_LE16(1);
2391                 counter_buf->res_type =
2392                         CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER |
2393                                     ICE_AQC_RES_TYPE_FLAG_DEDICATED);
2394                 status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2395                                                opc, NULL);
2396
2397                 if (status) {
2398                         ice_free(hw, counter_buf);
2399                         goto ice_alloc_sw_exit;
2400                 }
2401                 counter_ele = &counter_buf->elem[0];
2402                 *counter_id = LE16_TO_CPU(counter_ele->e.sw_resp);
2403                 ice_free(hw, counter_buf);
2404         }
2405
2406 ice_alloc_sw_exit:
2407         ice_free(hw, sw_buf);
2408         return status;
2409 }
2410
2411 /**
2412  * ice_free_sw - free resources specific to switch
2413  * @hw: pointer to the HW struct
2414  * @sw_id: switch ID returned
2415  * @counter_id: VEB counter ID returned
2416  *
2417  * free switch resources (SWID and VEB counter) (0x0209)
2418  *
2419  * NOTE: This function frees multiple resources. It continues
2420  * releasing other resources even after it encounters error.
2421  * The error code returned is the last error it encountered.
2422  */
2423 enum ice_status ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id)
2424 {
2425         struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf;
2426         enum ice_status status, ret_status;
2427         u16 buf_len;
2428
2429         buf_len = ice_struct_size(sw_buf, elem, 1);
2430         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2431         if (!sw_buf)
2432                 return ICE_ERR_NO_MEMORY;
2433
2434         /* Prepare buffer to free for switch ID res.
2435          * The number of resource entries in buffer is passed as 1 since only a
2436          * single switch/VEB instance is freed, and hence a single sw_id
2437          * is released.
2438          */
2439         sw_buf->num_elems = CPU_TO_LE16(1);
2440         sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID);
2441         sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id);
2442
2443         ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2444                                            ice_aqc_opc_free_res, NULL);
2445
2446         if (ret_status)
2447                 ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
2448
2449         /* Prepare buffer to free for VEB Counter resource */
2450         counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2451                         ice_malloc(hw, buf_len);
2452         if (!counter_buf) {
2453                 ice_free(hw, sw_buf);
2454                 return ICE_ERR_NO_MEMORY;
2455         }
2456
2457         /* The number of resource entries in buffer is passed as 1 since only a
2458          * single switch/VEB instance is freed, and hence a single VEB counter
2459          * is released
2460          */
2461         counter_buf->num_elems = CPU_TO_LE16(1);
2462         counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER);
2463         counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
2464
2465         status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2466                                        ice_aqc_opc_free_res, NULL);
2467         if (status) {
2468                 ice_debug(hw, ICE_DBG_SW, "VEB counter resource could not be freed\n");
2469                 ret_status = status;
2470         }
2471
2472         ice_free(hw, counter_buf);
2473         ice_free(hw, sw_buf);
2474         return ret_status;
2475 }
2476
2477 /**
2478  * ice_aq_add_vsi
2479  * @hw: pointer to the HW struct
2480  * @vsi_ctx: pointer to a VSI context struct
2481  * @cd: pointer to command details structure or NULL
2482  *
2483  * Add a VSI context to the hardware (0x0210)
2484  */
2485 enum ice_status
2486 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2487                struct ice_sq_cd *cd)
2488 {
2489         struct ice_aqc_add_update_free_vsi_resp *res;
2490         struct ice_aqc_add_get_update_free_vsi *cmd;
2491         struct ice_aq_desc desc;
2492         enum ice_status status;
2493
2494         cmd = &desc.params.vsi_cmd;
2495         res = &desc.params.add_update_free_vsi_res;
2496
2497         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
2498
2499         if (!vsi_ctx->alloc_from_pool)
2500                 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num |
2501                                            ICE_AQ_VSI_IS_VALID);
2502
2503         cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
2504
2505         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2506
2507         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2508                                  sizeof(vsi_ctx->info), cd);
2509
2510         if (!status) {
2511                 vsi_ctx->vsi_num = LE16_TO_CPU(res->vsi_num) & ICE_AQ_VSI_NUM_M;
2512                 vsi_ctx->vsis_allocd = LE16_TO_CPU(res->vsi_used);
2513                 vsi_ctx->vsis_unallocated = LE16_TO_CPU(res->vsi_free);
2514         }
2515
2516         return status;
2517 }
2518
2519 /**
2520  * ice_aq_free_vsi
2521  * @hw: pointer to the HW struct
2522  * @vsi_ctx: pointer to a VSI context struct
2523  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
2524  * @cd: pointer to command details structure or NULL
2525  *
2526  * Free VSI context info from hardware (0x0213)
2527  */
2528 enum ice_status
2529 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2530                 bool keep_vsi_alloc, struct ice_sq_cd *cd)
2531 {
2532         struct ice_aqc_add_update_free_vsi_resp *resp;
2533         struct ice_aqc_add_get_update_free_vsi *cmd;
2534         struct ice_aq_desc desc;
2535         enum ice_status status;
2536
2537         cmd = &desc.params.vsi_cmd;
2538         resp = &desc.params.add_update_free_vsi_res;
2539
2540         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
2541
2542         cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
2543         if (keep_vsi_alloc)
2544                 cmd->cmd_flags = CPU_TO_LE16(ICE_AQ_VSI_KEEP_ALLOC);
2545
2546         status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2547         if (!status) {
2548                 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
2549                 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2550         }
2551
2552         return status;
2553 }
2554
2555 /**
2556  * ice_aq_update_vsi
2557  * @hw: pointer to the HW struct
2558  * @vsi_ctx: pointer to a VSI context struct
2559  * @cd: pointer to command details structure or NULL
2560  *
2561  * Update VSI context in the hardware (0x0211)
2562  */
2563 enum ice_status
2564 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2565                   struct ice_sq_cd *cd)
2566 {
2567         struct ice_aqc_add_update_free_vsi_resp *resp;
2568         struct ice_aqc_add_get_update_free_vsi *cmd;
2569         struct ice_aq_desc desc;
2570         enum ice_status status;
2571
2572         cmd = &desc.params.vsi_cmd;
2573         resp = &desc.params.add_update_free_vsi_res;
2574
2575         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
2576
2577         cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
2578
2579         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2580
2581         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2582                                  sizeof(vsi_ctx->info), cd);
2583
2584         if (!status) {
2585                 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
2586                 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2587         }
2588
2589         return status;
2590 }
2591
2592 /**
2593  * ice_is_vsi_valid - check whether the VSI is valid or not
2594  * @hw: pointer to the HW struct
2595  * @vsi_handle: VSI handle
2596  *
2597  * check whether the VSI is valid or not
2598  */
2599 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
2600 {
2601         return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
2602 }
2603
2604 /**
2605  * ice_get_hw_vsi_num - return the HW VSI number
2606  * @hw: pointer to the HW struct
2607  * @vsi_handle: VSI handle
2608  *
2609  * return the HW VSI number
2610  * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
2611  */
2612 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
2613 {
2614         return hw->vsi_ctx[vsi_handle]->vsi_num;
2615 }
2616
2617 /**
2618  * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
2619  * @hw: pointer to the HW struct
2620  * @vsi_handle: VSI handle
2621  *
2622  * return the VSI context entry for a given VSI handle
2623  */
2624 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
2625 {
2626         return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
2627 }
2628
2629 /**
2630  * ice_save_vsi_ctx - save the VSI context for a given VSI handle
2631  * @hw: pointer to the HW struct
2632  * @vsi_handle: VSI handle
2633  * @vsi: VSI context pointer
2634  *
2635  * save the VSI context entry for a given VSI handle
2636  */
2637 static void
2638 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
2639 {
2640         hw->vsi_ctx[vsi_handle] = vsi;
2641 }
2642
2643 /**
2644  * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
2645  * @hw: pointer to the HW struct
2646  * @vsi_handle: VSI handle
2647  */
2648 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
2649 {
2650         struct ice_vsi_ctx *vsi;
2651         u8 i;
2652
2653         vsi = ice_get_vsi_ctx(hw, vsi_handle);
2654         if (!vsi)
2655                 return;
2656         ice_for_each_traffic_class(i) {
2657                 if (vsi->lan_q_ctx[i]) {
2658                         ice_free(hw, vsi->lan_q_ctx[i]);
2659                         vsi->lan_q_ctx[i] = NULL;
2660                 }
2661         }
2662 }
2663
2664 /**
2665  * ice_clear_vsi_ctx - clear the VSI context entry
2666  * @hw: pointer to the HW struct
2667  * @vsi_handle: VSI handle
2668  *
2669  * clear the VSI context entry
2670  */
2671 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
2672 {
2673         struct ice_vsi_ctx *vsi;
2674
2675         vsi = ice_get_vsi_ctx(hw, vsi_handle);
2676         if (vsi) {
2677                 ice_clear_vsi_q_ctx(hw, vsi_handle);
2678                 ice_free(hw, vsi);
2679                 hw->vsi_ctx[vsi_handle] = NULL;
2680         }
2681 }
2682
2683 /**
2684  * ice_clear_all_vsi_ctx - clear all the VSI context entries
2685  * @hw: pointer to the HW struct
2686  */
2687 void ice_clear_all_vsi_ctx(struct ice_hw *hw)
2688 {
2689         u16 i;
2690
2691         for (i = 0; i < ICE_MAX_VSI; i++)
2692                 ice_clear_vsi_ctx(hw, i);
2693 }
2694
2695 /**
2696  * ice_add_vsi - add VSI context to the hardware and VSI handle list
2697  * @hw: pointer to the HW struct
2698  * @vsi_handle: unique VSI handle provided by drivers
2699  * @vsi_ctx: pointer to a VSI context struct
2700  * @cd: pointer to command details structure or NULL
2701  *
2702  * Add a VSI context to the hardware also add it into the VSI handle list.
2703  * If this function gets called after reset for existing VSIs then update
2704  * with the new HW VSI number in the corresponding VSI handle list entry.
2705  */
2706 enum ice_status
2707 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
2708             struct ice_sq_cd *cd)
2709 {
2710         struct ice_vsi_ctx *tmp_vsi_ctx;
2711         enum ice_status status;
2712
2713         if (vsi_handle >= ICE_MAX_VSI)
2714                 return ICE_ERR_PARAM;
2715         status = ice_aq_add_vsi(hw, vsi_ctx, cd);
2716         if (status)
2717                 return status;
2718         tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
2719         if (!tmp_vsi_ctx) {
2720                 /* Create a new VSI context */
2721                 tmp_vsi_ctx = (struct ice_vsi_ctx *)
2722                         ice_malloc(hw, sizeof(*tmp_vsi_ctx));
2723                 if (!tmp_vsi_ctx) {
2724                         ice_aq_free_vsi(hw, vsi_ctx, false, cd);
2725                         return ICE_ERR_NO_MEMORY;
2726                 }
2727                 *tmp_vsi_ctx = *vsi_ctx;
2728
2729                 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
2730         } else {
2731                 /* update with new HW VSI num */
2732                 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
2733         }
2734
2735         return ICE_SUCCESS;
2736 }
2737
2738 /**
2739  * ice_free_vsi- free VSI context from hardware and VSI handle list
2740  * @hw: pointer to the HW struct
2741  * @vsi_handle: unique VSI handle
2742  * @vsi_ctx: pointer to a VSI context struct
2743  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
2744  * @cd: pointer to command details structure or NULL
2745  *
2746  * Free VSI context info from hardware as well as from VSI handle list
2747  */
2748 enum ice_status
2749 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
2750              bool keep_vsi_alloc, struct ice_sq_cd *cd)
2751 {
2752         enum ice_status status;
2753
2754         if (!ice_is_vsi_valid(hw, vsi_handle))
2755                 return ICE_ERR_PARAM;
2756         vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
2757         status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
2758         if (!status)
2759                 ice_clear_vsi_ctx(hw, vsi_handle);
2760         return status;
2761 }
2762
2763 /**
2764  * ice_update_vsi
2765  * @hw: pointer to the HW struct
2766  * @vsi_handle: unique VSI handle
2767  * @vsi_ctx: pointer to a VSI context struct
2768  * @cd: pointer to command details structure or NULL
2769  *
2770  * Update VSI context in the hardware
2771  */
2772 enum ice_status
2773 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
2774                struct ice_sq_cd *cd)
2775 {
2776         if (!ice_is_vsi_valid(hw, vsi_handle))
2777                 return ICE_ERR_PARAM;
2778         vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
2779         return ice_aq_update_vsi(hw, vsi_ctx, cd);
2780 }
2781
2782 /**
2783  * ice_aq_get_vsi_params
2784  * @hw: pointer to the HW struct
2785  * @vsi_ctx: pointer to a VSI context struct
2786  * @cd: pointer to command details structure or NULL
2787  *
2788  * Get VSI context info from hardware (0x0212)
2789  */
2790 enum ice_status
2791 ice_aq_get_vsi_params(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2792                       struct ice_sq_cd *cd)
2793 {
2794         struct ice_aqc_add_get_update_free_vsi *cmd;
2795         struct ice_aqc_get_vsi_resp *resp;
2796         struct ice_aq_desc desc;
2797         enum ice_status status;
2798
2799         cmd = &desc.params.vsi_cmd;
2800         resp = &desc.params.get_vsi_resp;
2801
2802         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_vsi_params);
2803
2804         cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
2805
2806         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2807                                  sizeof(vsi_ctx->info), cd);
2808         if (!status) {
2809                 vsi_ctx->vsi_num = LE16_TO_CPU(resp->vsi_num) &
2810                                         ICE_AQ_VSI_NUM_M;
2811                 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
2812                 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
2813         }
2814
2815         return status;
2816 }
2817
2818 /**
2819  * ice_aq_add_update_mir_rule - add/update a mirror rule
2820  * @hw: pointer to the HW struct
2821  * @rule_type: Rule Type
2822  * @dest_vsi: VSI number to which packets will be mirrored
2823  * @count: length of the list
2824  * @mr_buf: buffer for list of mirrored VSI numbers
2825  * @cd: pointer to command details structure or NULL
2826  * @rule_id: Rule ID
2827  *
2828  * Add/Update Mirror Rule (0x260).
2829  */
2830 enum ice_status
2831 ice_aq_add_update_mir_rule(struct ice_hw *hw, u16 rule_type, u16 dest_vsi,
2832                            u16 count, struct ice_mir_rule_buf *mr_buf,
2833                            struct ice_sq_cd *cd, u16 *rule_id)
2834 {
2835         struct ice_aqc_add_update_mir_rule *cmd;
2836         struct ice_aq_desc desc;
2837         enum ice_status status;
2838         __le16 *mr_list = NULL;
2839         u16 buf_size = 0;
2840
2841         switch (rule_type) {
2842         case ICE_AQC_RULE_TYPE_VPORT_INGRESS:
2843         case ICE_AQC_RULE_TYPE_VPORT_EGRESS:
2844                 /* Make sure count and mr_buf are set for these rule_types */
2845                 if (!(count && mr_buf))
2846                         return ICE_ERR_PARAM;
2847
2848                 buf_size = count * sizeof(__le16);
2849                 mr_list = (_FORCE_ __le16 *)ice_malloc(hw, buf_size);
2850                 if (!mr_list)
2851                         return ICE_ERR_NO_MEMORY;
2852                 break;
2853         case ICE_AQC_RULE_TYPE_PPORT_INGRESS:
2854         case ICE_AQC_RULE_TYPE_PPORT_EGRESS:
2855                 /* Make sure count and mr_buf are not set for these
2856                  * rule_types
2857                  */
2858                 if (count || mr_buf)
2859                         return ICE_ERR_PARAM;
2860                 break;
2861         default:
2862                 ice_debug(hw, ICE_DBG_SW, "Error due to unsupported rule_type %u\n", rule_type);
2863                 return ICE_ERR_OUT_OF_RANGE;
2864         }
2865
2866         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_update_mir_rule);
2867
2868         /* Pre-process 'mr_buf' items for add/update of virtual port
2869          * ingress/egress mirroring (but not physical port ingress/egress
2870          * mirroring)
2871          */
2872         if (mr_buf) {
2873                 int i;
2874
2875                 for (i = 0; i < count; i++) {
2876                         u16 id;
2877
2878                         id = mr_buf[i].vsi_idx & ICE_AQC_RULE_MIRRORED_VSI_M;
2879
2880                         /* Validate specified VSI number, make sure it is less
2881                          * than ICE_MAX_VSI, if not return with error.
2882                          */
2883                         if (id >= ICE_MAX_VSI) {
2884                                 ice_debug(hw, ICE_DBG_SW, "Error VSI index (%u) out-of-range\n",
2885                                           id);
2886                                 ice_free(hw, mr_list);
2887                                 return ICE_ERR_OUT_OF_RANGE;
2888                         }
2889
2890                         /* add VSI to mirror rule */
2891                         if (mr_buf[i].add)
2892                                 mr_list[i] =
2893                                         CPU_TO_LE16(id | ICE_AQC_RULE_ACT_M);
2894                         else /* remove VSI from mirror rule */
2895                                 mr_list[i] = CPU_TO_LE16(id);
2896                 }
2897         }
2898
2899         cmd = &desc.params.add_update_rule;
2900         if ((*rule_id) != ICE_INVAL_MIRROR_RULE_ID)
2901                 cmd->rule_id = CPU_TO_LE16(((*rule_id) & ICE_AQC_RULE_ID_M) |
2902                                            ICE_AQC_RULE_ID_VALID_M);
2903         cmd->rule_type = CPU_TO_LE16(rule_type & ICE_AQC_RULE_TYPE_M);
2904         cmd->num_entries = CPU_TO_LE16(count);
2905         cmd->dest = CPU_TO_LE16(dest_vsi);
2906
2907         status = ice_aq_send_cmd(hw, &desc, mr_list, buf_size, cd);
2908         if (!status)
2909                 *rule_id = LE16_TO_CPU(cmd->rule_id) & ICE_AQC_RULE_ID_M;
2910
2911         ice_free(hw, mr_list);
2912
2913         return status;
2914 }
2915
2916 /**
2917  * ice_aq_delete_mir_rule - delete a mirror rule
2918  * @hw: pointer to the HW struct
2919  * @rule_id: Mirror rule ID (to be deleted)
2920  * @keep_allocd: if set, the VSI stays part of the PF allocated res,
2921  *               otherwise it is returned to the shared pool
2922  * @cd: pointer to command details structure or NULL
2923  *
2924  * Delete Mirror Rule (0x261).
2925  */
2926 enum ice_status
2927 ice_aq_delete_mir_rule(struct ice_hw *hw, u16 rule_id, bool keep_allocd,
2928                        struct ice_sq_cd *cd)
2929 {
2930         struct ice_aqc_delete_mir_rule *cmd;
2931         struct ice_aq_desc desc;
2932
2933         /* rule_id should be in the range 0...63 */
2934         if (rule_id >= ICE_MAX_NUM_MIRROR_RULES)
2935                 return ICE_ERR_OUT_OF_RANGE;
2936
2937         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_del_mir_rule);
2938
2939         cmd = &desc.params.del_rule;
2940         rule_id |= ICE_AQC_RULE_ID_VALID_M;
2941         cmd->rule_id = CPU_TO_LE16(rule_id);
2942
2943         if (keep_allocd)
2944                 cmd->flags = CPU_TO_LE16(ICE_AQC_FLAG_KEEP_ALLOCD_M);
2945
2946         return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2947 }
2948
2949 /**
2950  * ice_aq_alloc_free_vsi_list
2951  * @hw: pointer to the HW struct
2952  * @vsi_list_id: VSI list ID returned or used for lookup
2953  * @lkup_type: switch rule filter lookup type
2954  * @opc: switch rules population command type - pass in the command opcode
2955  *
2956  * allocates or free a VSI list resource
2957  */
2958 static enum ice_status
2959 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
2960                            enum ice_sw_lkup_type lkup_type,
2961                            enum ice_adminq_opc opc)
2962 {
2963         struct ice_aqc_alloc_free_res_elem *sw_buf;
2964         struct ice_aqc_res_elem *vsi_ele;
2965         enum ice_status status;
2966         u16 buf_len;
2967
2968         buf_len = ice_struct_size(sw_buf, elem, 1);
2969         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2970         if (!sw_buf)
2971                 return ICE_ERR_NO_MEMORY;
2972         sw_buf->num_elems = CPU_TO_LE16(1);
2973
2974         if (lkup_type == ICE_SW_LKUP_MAC ||
2975             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
2976             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2977             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2978             lkup_type == ICE_SW_LKUP_PROMISC ||
2979             lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2980             lkup_type == ICE_SW_LKUP_LAST) {
2981                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
2982         } else if (lkup_type == ICE_SW_LKUP_VLAN) {
2983                 sw_buf->res_type =
2984                         CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
2985         } else {
2986                 status = ICE_ERR_PARAM;
2987                 goto ice_aq_alloc_free_vsi_list_exit;
2988         }
2989
2990         if (opc == ice_aqc_opc_free_res)
2991                 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(*vsi_list_id);
2992
2993         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
2994         if (status)
2995                 goto ice_aq_alloc_free_vsi_list_exit;
2996
2997         if (opc == ice_aqc_opc_alloc_res) {
2998                 vsi_ele = &sw_buf->elem[0];
2999                 *vsi_list_id = LE16_TO_CPU(vsi_ele->e.sw_resp);
3000         }
3001
3002 ice_aq_alloc_free_vsi_list_exit:
3003         ice_free(hw, sw_buf);
3004         return status;
3005 }
3006
3007 /**
3008  * ice_aq_set_storm_ctrl - Sets storm control configuration
3009  * @hw: pointer to the HW struct
3010  * @bcast_thresh: represents the upper threshold for broadcast storm control
3011  * @mcast_thresh: represents the upper threshold for multicast storm control
3012  * @ctl_bitmask: storm control knobs
3013  *
3014  * Sets the storm control configuration (0x0280)
3015  */
3016 enum ice_status
3017 ice_aq_set_storm_ctrl(struct ice_hw *hw, u32 bcast_thresh, u32 mcast_thresh,
3018                       u32 ctl_bitmask)
3019 {
3020         struct ice_aqc_storm_cfg *cmd;
3021         struct ice_aq_desc desc;
3022
3023         cmd = &desc.params.storm_conf;
3024
3025         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_storm_cfg);
3026
3027         cmd->bcast_thresh_size = CPU_TO_LE32(bcast_thresh & ICE_AQ_THRESHOLD_M);
3028         cmd->mcast_thresh_size = CPU_TO_LE32(mcast_thresh & ICE_AQ_THRESHOLD_M);
3029         cmd->storm_ctrl_ctrl = CPU_TO_LE32(ctl_bitmask);
3030
3031         return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3032 }
3033
3034 /**
3035  * ice_aq_get_storm_ctrl - gets storm control configuration
3036  * @hw: pointer to the HW struct
3037  * @bcast_thresh: represents the upper threshold for broadcast storm control
3038  * @mcast_thresh: represents the upper threshold for multicast storm control
3039  * @ctl_bitmask: storm control knobs
3040  *
3041  * Gets the storm control configuration (0x0281)
3042  */
3043 enum ice_status
3044 ice_aq_get_storm_ctrl(struct ice_hw *hw, u32 *bcast_thresh, u32 *mcast_thresh,
3045                       u32 *ctl_bitmask)
3046 {
3047         enum ice_status status;
3048         struct ice_aq_desc desc;
3049
3050         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_storm_cfg);
3051
3052         status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3053         if (!status) {
3054                 struct ice_aqc_storm_cfg *resp = &desc.params.storm_conf;
3055
3056                 if (bcast_thresh)
3057                         *bcast_thresh = LE32_TO_CPU(resp->bcast_thresh_size) &
3058                                 ICE_AQ_THRESHOLD_M;
3059                 if (mcast_thresh)
3060                         *mcast_thresh = LE32_TO_CPU(resp->mcast_thresh_size) &
3061                                 ICE_AQ_THRESHOLD_M;
3062                 if (ctl_bitmask)
3063                         *ctl_bitmask = LE32_TO_CPU(resp->storm_ctrl_ctrl);
3064         }
3065
3066         return status;
3067 }
3068
3069 /**
3070  * ice_aq_sw_rules - add/update/remove switch rules
3071  * @hw: pointer to the HW struct
3072  * @rule_list: pointer to switch rule population list
3073  * @rule_list_sz: total size of the rule list in bytes
3074  * @num_rules: number of switch rules in the rule_list
3075  * @opc: switch rules population command type - pass in the command opcode
3076  * @cd: pointer to command details structure or NULL
3077  *
3078  * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
3079  */
3080 static enum ice_status
3081 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
3082                 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
3083 {
3084         struct ice_aq_desc desc;
3085         enum ice_status status;
3086
3087         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3088
3089         if (opc != ice_aqc_opc_add_sw_rules &&
3090             opc != ice_aqc_opc_update_sw_rules &&
3091             opc != ice_aqc_opc_remove_sw_rules)
3092                 return ICE_ERR_PARAM;
3093
3094         ice_fill_dflt_direct_cmd_desc(&desc, opc);
3095
3096         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3097         desc.params.sw_rules.num_rules_fltr_entry_index =
3098                 CPU_TO_LE16(num_rules);
3099         status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
3100         if (opc != ice_aqc_opc_add_sw_rules &&
3101             hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
3102                 status = ICE_ERR_DOES_NOT_EXIST;
3103
3104         return status;
3105 }
3106
3107 /**
3108  * ice_aq_add_recipe - add switch recipe
3109  * @hw: pointer to the HW struct
3110  * @s_recipe_list: pointer to switch rule population list
3111  * @num_recipes: number of switch recipes in the list
3112  * @cd: pointer to command details structure or NULL
3113  *
3114  * Add(0x0290)
3115  */
3116 enum ice_status
3117 ice_aq_add_recipe(struct ice_hw *hw,
3118                   struct ice_aqc_recipe_data_elem *s_recipe_list,
3119                   u16 num_recipes, struct ice_sq_cd *cd)
3120 {
3121         struct ice_aqc_add_get_recipe *cmd;
3122         struct ice_aq_desc desc;
3123         u16 buf_size;
3124
3125         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3126         cmd = &desc.params.add_get_recipe;
3127         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
3128
3129         cmd->num_sub_recipes = CPU_TO_LE16(num_recipes);
3130         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3131
3132         buf_size = num_recipes * sizeof(*s_recipe_list);
3133
3134         return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3135 }
3136
3137 /**
3138  * ice_aq_get_recipe - get switch recipe
3139  * @hw: pointer to the HW struct
3140  * @s_recipe_list: pointer to switch rule population list
3141  * @num_recipes: pointer to the number of recipes (input and output)
3142  * @recipe_root: root recipe number of recipe(s) to retrieve
3143  * @cd: pointer to command details structure or NULL
3144  *
3145  * Get(0x0292)
3146  *
3147  * On input, *num_recipes should equal the number of entries in s_recipe_list.
3148  * On output, *num_recipes will equal the number of entries returned in
3149  * s_recipe_list.
3150  *
3151  * The caller must supply enough space in s_recipe_list to hold all possible
3152  * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
3153  */
3154 enum ice_status
3155 ice_aq_get_recipe(struct ice_hw *hw,
3156                   struct ice_aqc_recipe_data_elem *s_recipe_list,
3157                   u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
3158 {
3159         struct ice_aqc_add_get_recipe *cmd;
3160         struct ice_aq_desc desc;
3161         enum ice_status status;
3162         u16 buf_size;
3163
3164         if (*num_recipes != ICE_MAX_NUM_RECIPES)
3165                 return ICE_ERR_PARAM;
3166
3167         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3168         cmd = &desc.params.add_get_recipe;
3169         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
3170
3171         cmd->return_index = CPU_TO_LE16(recipe_root);
3172         cmd->num_sub_recipes = 0;
3173
3174         buf_size = *num_recipes * sizeof(*s_recipe_list);
3175
3176         status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3177         *num_recipes = LE16_TO_CPU(cmd->num_sub_recipes);
3178
3179         return status;
3180 }
3181
3182 /**
3183  * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
3184  * @hw: pointer to the HW struct
3185  * @params: parameters used to update the default recipe
3186  *
3187  * This function only supports updating default recipes and it only supports
3188  * updating a single recipe based on the lkup_idx at a time.
3189  *
3190  * This is done as a read-modify-write operation. First, get the current recipe
3191  * contents based on the recipe's ID. Then modify the field vector index and
3192  * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
3193  * the pre-existing recipe with the modifications.
3194  */
3195 enum ice_status
3196 ice_update_recipe_lkup_idx(struct ice_hw *hw,
3197                            struct ice_update_recipe_lkup_idx_params *params)
3198 {
3199         struct ice_aqc_recipe_data_elem *rcp_list;
3200         u16 num_recps = ICE_MAX_NUM_RECIPES;
3201         enum ice_status status;
3202
3203         rcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));
3204         if (!rcp_list)
3205                 return ICE_ERR_NO_MEMORY;
3206
3207         /* read current recipe list from firmware */
3208         rcp_list->recipe_indx = params->rid;
3209         status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
3210         if (status) {
3211                 ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
3212                           params->rid, status);
3213                 goto error_out;
3214         }
3215
3216         /* only modify existing recipe's lkup_idx and mask if valid, while
3217          * leaving all other fields the same, then update the recipe firmware
3218          */
3219         rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
3220         if (params->mask_valid)
3221                 rcp_list->content.mask[params->lkup_idx] =
3222                         CPU_TO_LE16(params->mask);
3223
3224         if (params->ignore_valid)
3225                 rcp_list->content.lkup_indx[params->lkup_idx] |=
3226                         ICE_AQ_RECIPE_LKUP_IGNORE;
3227
3228         status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
3229         if (status)
3230                 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",
3231                           params->rid, params->lkup_idx, params->fv_idx,
3232                           params->mask, params->mask_valid ? "true" : "false",
3233                           status);
3234
3235 error_out:
3236         ice_free(hw, rcp_list);
3237         return status;
3238 }
3239
3240 /**
3241  * ice_aq_map_recipe_to_profile - Map recipe to packet profile
3242  * @hw: pointer to the HW struct
3243  * @profile_id: package profile ID to associate the recipe with
3244  * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3245  * @cd: pointer to command details structure or NULL
3246  * Recipe to profile association (0x0291)
3247  */
3248 enum ice_status
3249 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3250                              struct ice_sq_cd *cd)
3251 {
3252         struct ice_aqc_recipe_to_profile *cmd;
3253         struct ice_aq_desc desc;
3254
3255         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3256         cmd = &desc.params.recipe_to_profile;
3257         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
3258         cmd->profile_id = CPU_TO_LE16(profile_id);
3259         /* Set the recipe ID bit in the bitmask to let the device know which
3260          * profile we are associating the recipe to
3261          */
3262         ice_memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc),
3263                    ICE_NONDMA_TO_NONDMA);
3264
3265         return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3266 }
3267
3268 /**
3269  * ice_aq_get_recipe_to_profile - Map recipe to packet profile
3270  * @hw: pointer to the HW struct
3271  * @profile_id: package profile ID to associate the recipe with
3272  * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3273  * @cd: pointer to command details structure or NULL
3274  * Associate profile ID with given recipe (0x0293)
3275  */
3276 enum ice_status
3277 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3278                              struct ice_sq_cd *cd)
3279 {
3280         struct ice_aqc_recipe_to_profile *cmd;
3281         struct ice_aq_desc desc;
3282         enum ice_status status;
3283
3284         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3285         cmd = &desc.params.recipe_to_profile;
3286         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
3287         cmd->profile_id = CPU_TO_LE16(profile_id);
3288
3289         status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3290         if (!status)
3291                 ice_memcpy(r_bitmap, cmd->recipe_assoc,
3292                            sizeof(cmd->recipe_assoc), ICE_NONDMA_TO_NONDMA);
3293
3294         return status;
3295 }
3296
3297 /**
3298  * ice_alloc_recipe - add recipe resource
3299  * @hw: pointer to the hardware structure
3300  * @rid: recipe ID returned as response to AQ call
3301  */
3302 enum ice_status ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
3303 {
3304         struct ice_aqc_alloc_free_res_elem *sw_buf;
3305         enum ice_status status;
3306         u16 buf_len;
3307
3308         buf_len = ice_struct_size(sw_buf, elem, 1);
3309         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3310         if (!sw_buf)
3311                 return ICE_ERR_NO_MEMORY;
3312
3313         sw_buf->num_elems = CPU_TO_LE16(1);
3314         sw_buf->res_type = CPU_TO_LE16((ICE_AQC_RES_TYPE_RECIPE <<
3315                                         ICE_AQC_RES_TYPE_S) |
3316                                         ICE_AQC_RES_TYPE_FLAG_SHARED);
3317         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
3318                                        ice_aqc_opc_alloc_res, NULL);
3319         if (!status)
3320                 *rid = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
3321         ice_free(hw, sw_buf);
3322
3323         return status;
3324 }
3325
3326 /* ice_init_port_info - Initialize port_info with switch configuration data
3327  * @pi: pointer to port_info
3328  * @vsi_port_num: VSI number or port number
3329  * @type: Type of switch element (port or VSI)
3330  * @swid: switch ID of the switch the element is attached to
3331  * @pf_vf_num: PF or VF number
3332  * @is_vf: true if the element is a VF, false otherwise
3333  */
3334 static void
3335 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
3336                    u16 swid, u16 pf_vf_num, bool is_vf)
3337 {
3338         switch (type) {
3339         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3340                 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
3341                 pi->sw_id = swid;
3342                 pi->pf_vf_num = pf_vf_num;
3343                 pi->is_vf = is_vf;
3344                 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
3345                 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
3346                 break;
3347         default:
3348                 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
3349                 break;
3350         }
3351 }
3352
3353 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
3354  * @hw: pointer to the hardware structure
3355  */
3356 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
3357 {
3358         struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
3359         enum ice_status status;
3360         u8 num_total_ports;
3361         u16 req_desc = 0;
3362         u16 num_elems;
3363         u8 j = 0;
3364         u16 i;
3365
3366         num_total_ports = 1;
3367
3368         rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *)
3369                 ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN);
3370
3371         if (!rbuf)
3372                 return ICE_ERR_NO_MEMORY;
3373
3374         /* Multiple calls to ice_aq_get_sw_cfg may be required
3375          * to get all the switch configuration information. The need
3376          * for additional calls is indicated by ice_aq_get_sw_cfg
3377          * writing a non-zero value in req_desc
3378          */
3379         do {
3380                 struct ice_aqc_get_sw_cfg_resp_elem *ele;
3381
3382                 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
3383                                            &req_desc, &num_elems, NULL);
3384
3385                 if (status)
3386                         break;
3387
3388                 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
3389                         u16 pf_vf_num, swid, vsi_port_num;
3390                         bool is_vf = false;
3391                         u8 res_type;
3392
3393                         vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) &
3394                                 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
3395
3396                         pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) &
3397                                 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
3398
3399                         swid = LE16_TO_CPU(ele->swid);
3400
3401                         if (LE16_TO_CPU(ele->pf_vf_num) &
3402                             ICE_AQC_GET_SW_CONF_RESP_IS_VF)
3403                                 is_vf = true;
3404
3405                         res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >>
3406                                         ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
3407
3408                         switch (res_type) {
3409                         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3410                         case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT:
3411                                 if (j == num_total_ports) {
3412                                         ice_debug(hw, ICE_DBG_SW, "more ports than expected\n");
3413                                         status = ICE_ERR_CFG;
3414                                         goto out;
3415                                 }
3416                                 ice_init_port_info(hw->port_info,
3417                                                    vsi_port_num, res_type, swid,
3418                                                    pf_vf_num, is_vf);
3419                                 j++;
3420                                 break;
3421                         default:
3422                                 break;
3423                         }
3424                 }
3425         } while (req_desc && !status);
3426
3427 out:
3428         ice_free(hw, rbuf);
3429         return status;
3430 }
3431
3432 /**
3433  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
3434  * @hw: pointer to the hardware structure
3435  * @fi: filter info structure to fill/update
3436  *
3437  * This helper function populates the lb_en and lan_en elements of the provided
3438  * ice_fltr_info struct using the switch's type and characteristics of the
3439  * switch rule being configured.
3440  */
3441 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
3442 {
3443         if ((fi->flag & ICE_FLTR_RX) &&
3444             (fi->fltr_act == ICE_FWD_TO_VSI ||
3445              fi->fltr_act == ICE_FWD_TO_VSI_LIST) &&
3446             fi->lkup_type == ICE_SW_LKUP_LAST)
3447                 fi->lan_en = true;
3448         fi->lb_en = false;
3449         fi->lan_en = false;
3450         if ((fi->flag & ICE_FLTR_TX) &&
3451             (fi->fltr_act == ICE_FWD_TO_VSI ||
3452              fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
3453              fi->fltr_act == ICE_FWD_TO_Q ||
3454              fi->fltr_act == ICE_FWD_TO_QGRP)) {
3455                 /* Setting LB for prune actions will result in replicated
3456                  * packets to the internal switch that will be dropped.
3457                  */
3458                 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
3459                         fi->lb_en = true;
3460
3461                 /* Set lan_en to TRUE if
3462                  * 1. The switch is a VEB AND
3463                  * 2
3464                  * 2.1 The lookup is a directional lookup like ethertype,
3465                  * promiscuous, ethertype-MAC, promiscuous-VLAN
3466                  * and default-port OR
3467                  * 2.2 The lookup is VLAN, OR
3468                  * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
3469                  * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
3470                  *
3471                  * OR
3472                  *
3473                  * The switch is a VEPA.
3474                  *
3475                  * In all other cases, the LAN enable has to be set to false.
3476                  */
3477                 if (hw->evb_veb) {
3478                         if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3479                             fi->lkup_type == ICE_SW_LKUP_PROMISC ||
3480                             fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3481                             fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3482                             fi->lkup_type == ICE_SW_LKUP_DFLT ||
3483                             fi->lkup_type == ICE_SW_LKUP_VLAN ||
3484                             (fi->lkup_type == ICE_SW_LKUP_MAC &&
3485                              !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) ||
3486                             (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
3487                              !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)))
3488                                 fi->lan_en = true;
3489                 } else {
3490                         fi->lan_en = true;
3491                 }
3492         }
3493 }
3494
3495 /**
3496  * ice_fill_sw_rule - Helper function to fill switch rule structure
3497  * @hw: pointer to the hardware structure
3498  * @f_info: entry containing packet forwarding information
3499  * @s_rule: switch rule structure to be filled in based on mac_entry
3500  * @opc: switch rules population command type - pass in the command opcode
3501  */
3502 static void
3503 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
3504                  struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
3505 {
3506         u16 vlan_id = ICE_MAX_VLAN_ID + 1;
3507         u16 vlan_tpid = ICE_ETH_P_8021Q;
3508         void *daddr = NULL;
3509         u16 eth_hdr_sz;
3510         u8 *eth_hdr;
3511         u32 act = 0;
3512         __be16 *off;
3513         u8 q_rgn;
3514
3515         if (opc == ice_aqc_opc_remove_sw_rules) {
3516                 s_rule->pdata.lkup_tx_rx.act = 0;
3517                 s_rule->pdata.lkup_tx_rx.index =
3518                         CPU_TO_LE16(f_info->fltr_rule_id);
3519                 s_rule->pdata.lkup_tx_rx.hdr_len = 0;
3520                 return;
3521         }
3522
3523         eth_hdr_sz = sizeof(dummy_eth_header);
3524         eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
3525
3526         /* initialize the ether header with a dummy header */
3527         ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA);
3528         ice_fill_sw_info(hw, f_info);
3529
3530         switch (f_info->fltr_act) {
3531         case ICE_FWD_TO_VSI:
3532                 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
3533                         ICE_SINGLE_ACT_VSI_ID_M;
3534                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
3535                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
3536                                 ICE_SINGLE_ACT_VALID_BIT;
3537                 break;
3538         case ICE_FWD_TO_VSI_LIST:
3539                 act |= ICE_SINGLE_ACT_VSI_LIST;
3540                 act |= (f_info->fwd_id.vsi_list_id <<
3541                         ICE_SINGLE_ACT_VSI_LIST_ID_S) &
3542                         ICE_SINGLE_ACT_VSI_LIST_ID_M;
3543                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
3544                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
3545                                 ICE_SINGLE_ACT_VALID_BIT;
3546                 break;
3547         case ICE_FWD_TO_Q:
3548                 act |= ICE_SINGLE_ACT_TO_Q;
3549                 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
3550                         ICE_SINGLE_ACT_Q_INDEX_M;
3551                 break;
3552         case ICE_DROP_PACKET:
3553                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
3554                         ICE_SINGLE_ACT_VALID_BIT;
3555                 break;
3556         case ICE_FWD_TO_QGRP:
3557                 q_rgn = f_info->qgrp_size > 0 ?
3558                         (u8)ice_ilog2(f_info->qgrp_size) : 0;
3559                 act |= ICE_SINGLE_ACT_TO_Q;
3560                 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
3561                         ICE_SINGLE_ACT_Q_INDEX_M;
3562                 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
3563                         ICE_SINGLE_ACT_Q_REGION_M;
3564                 break;
3565         default:
3566                 return;
3567         }
3568
3569         if (f_info->lb_en)
3570                 act |= ICE_SINGLE_ACT_LB_ENABLE;
3571         if (f_info->lan_en)
3572                 act |= ICE_SINGLE_ACT_LAN_ENABLE;
3573
3574         switch (f_info->lkup_type) {
3575         case ICE_SW_LKUP_MAC:
3576                 daddr = f_info->l_data.mac.mac_addr;
3577                 break;
3578         case ICE_SW_LKUP_VLAN:
3579                 vlan_id = f_info->l_data.vlan.vlan_id;
3580                 if (f_info->l_data.vlan.tpid_valid)
3581                         vlan_tpid = f_info->l_data.vlan.tpid;
3582                 if (f_info->fltr_act == ICE_FWD_TO_VSI ||
3583                     f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3584                         act |= ICE_SINGLE_ACT_PRUNE;
3585                         act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
3586                 }
3587                 break;
3588         case ICE_SW_LKUP_ETHERTYPE_MAC:
3589                 daddr = f_info->l_data.ethertype_mac.mac_addr;
3590                 /* fall-through */
3591         case ICE_SW_LKUP_ETHERTYPE:
3592                 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
3593                 *off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype);
3594                 break;
3595         case ICE_SW_LKUP_MAC_VLAN:
3596                 daddr = f_info->l_data.mac_vlan.mac_addr;
3597                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
3598                 break;
3599         case ICE_SW_LKUP_PROMISC_VLAN:
3600                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
3601                 /* fall-through */
3602         case ICE_SW_LKUP_PROMISC:
3603                 daddr = f_info->l_data.mac_vlan.mac_addr;
3604                 break;
3605         default:
3606                 break;
3607         }
3608
3609         s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
3610                 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) :
3611                 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
3612
3613         /* Recipe set depending on lookup type */
3614         s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(f_info->lkup_type);
3615         s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(f_info->src);
3616         s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
3617
3618         if (daddr)
3619                 ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN,
3620                            ICE_NONDMA_TO_NONDMA);
3621
3622         if (!(vlan_id > ICE_MAX_VLAN_ID)) {
3623                 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
3624                 *off = CPU_TO_BE16(vlan_id);
3625                 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
3626                 *off = CPU_TO_BE16(vlan_tpid);
3627         }
3628
3629         /* Create the switch rule with the final dummy Ethernet header */
3630         if (opc != ice_aqc_opc_update_sw_rules)
3631                 s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(eth_hdr_sz);
3632 }
3633
3634 /**
3635  * ice_add_marker_act
3636  * @hw: pointer to the hardware structure
3637  * @m_ent: the management entry for which sw marker needs to be added
3638  * @sw_marker: sw marker to tag the Rx descriptor with
3639  * @l_id: large action resource ID
3640  *
3641  * Create a large action to hold software marker and update the switch rule
3642  * entry pointed by m_ent with newly created large action
3643  */
3644 static enum ice_status
3645 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
3646                    u16 sw_marker, u16 l_id)
3647 {
3648         struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
3649         /* For software marker we need 3 large actions
3650          * 1. FWD action: FWD TO VSI or VSI LIST
3651          * 2. GENERIC VALUE action to hold the profile ID
3652          * 3. GENERIC VALUE action to hold the software marker ID
3653          */
3654         const u16 num_lg_acts = 3;
3655         enum ice_status status;
3656         u16 lg_act_size;
3657         u16 rules_size;
3658         u32 act;
3659         u16 id;
3660
3661         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
3662                 return ICE_ERR_PARAM;
3663
3664         /* Create two back-to-back switch rules and submit them to the HW using
3665          * one memory buffer:
3666          *    1. Large Action
3667          *    2. Look up Tx Rx
3668          */
3669         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
3670         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
3671         lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
3672         if (!lg_act)
3673                 return ICE_ERR_NO_MEMORY;
3674
3675         rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
3676
3677         /* Fill in the first switch rule i.e. large action */
3678         lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
3679         lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
3680         lg_act->pdata.lg_act.size = CPU_TO_LE16(num_lg_acts);
3681
3682         /* First action VSI forwarding or VSI list forwarding depending on how
3683          * many VSIs
3684          */
3685         id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
3686                 m_ent->fltr_info.fwd_id.hw_vsi_id;
3687
3688         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
3689         act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
3690         if (m_ent->vsi_count > 1)
3691                 act |= ICE_LG_ACT_VSI_LIST;
3692         lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
3693
3694         /* Second action descriptor type */
3695         act = ICE_LG_ACT_GENERIC;
3696
3697         act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
3698         lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
3699
3700         act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
3701                ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
3702
3703         /* Third action Marker value */
3704         act |= ICE_LG_ACT_GENERIC;
3705         act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
3706                 ICE_LG_ACT_GENERIC_VALUE_M;
3707
3708         lg_act->pdata.lg_act.act[2] = CPU_TO_LE32(act);
3709
3710         /* call the fill switch rule to fill the lookup Tx Rx structure */
3711         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
3712                          ice_aqc_opc_update_sw_rules);
3713
3714         /* Update the action to point to the large action ID */
3715         rx_tx->pdata.lkup_tx_rx.act =
3716                 CPU_TO_LE32(ICE_SINGLE_ACT_PTR |
3717                             ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
3718                              ICE_SINGLE_ACT_PTR_VAL_M));
3719
3720         /* Use the filter rule ID of the previously created rule with single
3721          * act. Once the update happens, hardware will treat this as large
3722          * action
3723          */
3724         rx_tx->pdata.lkup_tx_rx.index =
3725                 CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id);
3726
3727         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
3728                                  ice_aqc_opc_update_sw_rules, NULL);
3729         if (!status) {
3730                 m_ent->lg_act_idx = l_id;
3731                 m_ent->sw_marker_id = sw_marker;
3732         }
3733
3734         ice_free(hw, lg_act);
3735         return status;
3736 }
3737
3738 /**
3739  * ice_add_counter_act - add/update filter rule with counter action
3740  * @hw: pointer to the hardware structure
3741  * @m_ent: the management entry for which counter needs to be added
3742  * @counter_id: VLAN counter ID returned as part of allocate resource
3743  * @l_id: large action resource ID
3744  */
3745 static enum ice_status
3746 ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
3747                     u16 counter_id, u16 l_id)
3748 {
3749         struct ice_aqc_sw_rules_elem *lg_act;
3750         struct ice_aqc_sw_rules_elem *rx_tx;
3751         enum ice_status status;
3752         /* 2 actions will be added while adding a large action counter */
3753         const int num_acts = 2;
3754         u16 lg_act_size;
3755         u16 rules_size;
3756         u16 f_rule_id;
3757         u32 act;
3758         u16 id;
3759
3760         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
3761                 return ICE_ERR_PARAM;
3762
3763         /* Create two back-to-back switch rules and submit them to the HW using
3764          * one memory buffer:
3765          * 1. Large Action
3766          * 2. Look up Tx Rx
3767          */
3768         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_acts);
3769         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
3770         lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
3771         if (!lg_act)
3772                 return ICE_ERR_NO_MEMORY;
3773
3774         rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
3775
3776         /* Fill in the first switch rule i.e. large action */
3777         lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
3778         lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
3779         lg_act->pdata.lg_act.size = CPU_TO_LE16(num_acts);
3780
3781         /* First action VSI forwarding or VSI list forwarding depending on how
3782          * many VSIs
3783          */
3784         id = (m_ent->vsi_count > 1) ?  m_ent->fltr_info.fwd_id.vsi_list_id :
3785                 m_ent->fltr_info.fwd_id.hw_vsi_id;
3786
3787         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
3788         act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
3789                 ICE_LG_ACT_VSI_LIST_ID_M;
3790         if (m_ent->vsi_count > 1)
3791                 act |= ICE_LG_ACT_VSI_LIST;
3792         lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
3793
3794         /* Second action counter ID */
3795         act = ICE_LG_ACT_STAT_COUNT;
3796         act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) &
3797                 ICE_LG_ACT_STAT_COUNT_M;
3798         lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
3799
3800         /* call the fill switch rule to fill the lookup Tx Rx structure */
3801         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
3802                          ice_aqc_opc_update_sw_rules);
3803
3804         act = ICE_SINGLE_ACT_PTR;
3805         act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M;
3806         rx_tx->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
3807
3808         /* Use the filter rule ID of the previously created rule with single
3809          * act. Once the update happens, hardware will treat this as large
3810          * action
3811          */
3812         f_rule_id = m_ent->fltr_info.fltr_rule_id;
3813         rx_tx->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_rule_id);
3814
3815         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
3816                                  ice_aqc_opc_update_sw_rules, NULL);
3817         if (!status) {
3818                 m_ent->lg_act_idx = l_id;
3819                 m_ent->counter_index = counter_id;
3820         }
3821
3822         ice_free(hw, lg_act);
3823         return status;
3824 }
3825
3826 /**
3827  * ice_create_vsi_list_map
3828  * @hw: pointer to the hardware structure
3829  * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
3830  * @num_vsi: number of VSI handles in the array
3831  * @vsi_list_id: VSI list ID generated as part of allocate resource
3832  *
3833  * Helper function to create a new entry of VSI list ID to VSI mapping
3834  * using the given VSI list ID
3835  */
3836 static struct ice_vsi_list_map_info *
3837 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3838                         u16 vsi_list_id)
3839 {
3840         struct ice_switch_info *sw = hw->switch_info;
3841         struct ice_vsi_list_map_info *v_map;
3842         int i;
3843
3844         v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map));
3845         if (!v_map)
3846                 return NULL;
3847
3848         v_map->vsi_list_id = vsi_list_id;
3849         v_map->ref_cnt = 1;
3850         for (i = 0; i < num_vsi; i++)
3851                 ice_set_bit(vsi_handle_arr[i], v_map->vsi_map);
3852
3853         LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head);
3854         return v_map;
3855 }
3856
3857 /**
3858  * ice_update_vsi_list_rule
3859  * @hw: pointer to the hardware structure
3860  * @vsi_handle_arr: array of VSI handles to form a VSI list
3861  * @num_vsi: number of VSI handles in the array
3862  * @vsi_list_id: VSI list ID generated as part of allocate resource
3863  * @remove: Boolean value to indicate if this is a remove action
3864  * @opc: switch rules population command type - pass in the command opcode
3865  * @lkup_type: lookup type of the filter
3866  *
3867  * Call AQ command to add a new switch rule or update existing switch rule
3868  * using the given VSI list ID
3869  */
3870 static enum ice_status
3871 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3872                          u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
3873                          enum ice_sw_lkup_type lkup_type)
3874 {
3875         struct ice_aqc_sw_rules_elem *s_rule;
3876         enum ice_status status;
3877         u16 s_rule_size;
3878         u16 rule_type;
3879         int i;
3880
3881         if (!num_vsi)
3882                 return ICE_ERR_PARAM;
3883
3884         if (lkup_type == ICE_SW_LKUP_MAC ||
3885             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
3886             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3887             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3888             lkup_type == ICE_SW_LKUP_PROMISC ||
3889             lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3890             lkup_type == ICE_SW_LKUP_LAST)
3891                 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
3892                         ICE_AQC_SW_RULES_T_VSI_LIST_SET;
3893         else if (lkup_type == ICE_SW_LKUP_VLAN)
3894                 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
3895                         ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
3896         else
3897                 return ICE_ERR_PARAM;
3898
3899         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
3900         s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
3901         if (!s_rule)
3902                 return ICE_ERR_NO_MEMORY;
3903         for (i = 0; i < num_vsi; i++) {
3904                 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
3905                         status = ICE_ERR_PARAM;
3906                         goto exit;
3907                 }
3908                 /* AQ call requires hw_vsi_id(s) */
3909                 s_rule->pdata.vsi_list.vsi[i] =
3910                         CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
3911         }
3912
3913         s_rule->type = CPU_TO_LE16(rule_type);
3914         s_rule->pdata.vsi_list.number_vsi = CPU_TO_LE16(num_vsi);
3915         s_rule->pdata.vsi_list.index = CPU_TO_LE16(vsi_list_id);
3916
3917         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
3918
3919 exit:
3920         ice_free(hw, s_rule);
3921         return status;
3922 }
3923
3924 /**
3925  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
3926  * @hw: pointer to the HW struct
3927  * @vsi_handle_arr: array of VSI handles to form a VSI list
3928  * @num_vsi: number of VSI handles in the array
3929  * @vsi_list_id: stores the ID of the VSI list to be created
3930  * @lkup_type: switch rule filter's lookup type
3931  */
3932 static enum ice_status
3933 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3934                          u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
3935 {
3936         enum ice_status status;
3937
3938         status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
3939                                             ice_aqc_opc_alloc_res);
3940         if (status)
3941                 return status;
3942
3943         /* Update the newly created VSI list to include the specified VSIs */
3944         return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
3945                                         *vsi_list_id, false,
3946                                         ice_aqc_opc_add_sw_rules, lkup_type);
3947 }
3948
3949 /**
3950  * ice_create_pkt_fwd_rule
3951  * @hw: pointer to the hardware structure
3952  * @recp_list: corresponding filter management list
3953  * @f_entry: entry containing packet forwarding information
3954  *
3955  * Create switch rule with given filter information and add an entry
3956  * to the corresponding filter management list to track this switch rule
3957  * and VSI mapping
3958  */
3959 static enum ice_status
3960 ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
3961                         struct ice_fltr_list_entry *f_entry)
3962 {
3963         struct ice_fltr_mgmt_list_entry *fm_entry;
3964         struct ice_aqc_sw_rules_elem *s_rule;
3965         enum ice_status status;
3966
3967         s_rule = (struct ice_aqc_sw_rules_elem *)
3968                 ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
3969         if (!s_rule)
3970                 return ICE_ERR_NO_MEMORY;
3971         fm_entry = (struct ice_fltr_mgmt_list_entry *)
3972                    ice_malloc(hw, sizeof(*fm_entry));
3973         if (!fm_entry) {
3974                 status = ICE_ERR_NO_MEMORY;
3975                 goto ice_create_pkt_fwd_rule_exit;
3976         }
3977
3978         fm_entry->fltr_info = f_entry->fltr_info;
3979
3980         /* Initialize all the fields for the management entry */
3981         fm_entry->vsi_count = 1;
3982         fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
3983         fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
3984         fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
3985
3986         ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
3987                          ice_aqc_opc_add_sw_rules);
3988
3989         status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
3990                                  ice_aqc_opc_add_sw_rules, NULL);
3991         if (status) {
3992                 ice_free(hw, fm_entry);
3993                 goto ice_create_pkt_fwd_rule_exit;
3994         }
3995
3996         f_entry->fltr_info.fltr_rule_id =
3997                 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
3998         fm_entry->fltr_info.fltr_rule_id =
3999                 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
4000
4001         /* The book keeping entries will get removed when base driver
4002          * calls remove filter AQ command
4003          */
4004         LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules);
4005
4006 ice_create_pkt_fwd_rule_exit:
4007         ice_free(hw, s_rule);
4008         return status;
4009 }
4010
4011 /**
4012  * ice_update_pkt_fwd_rule
4013  * @hw: pointer to the hardware structure
4014  * @f_info: filter information for switch rule
4015  *
4016  * Call AQ command to update a previously created switch rule with a
4017  * VSI list ID
4018  */
4019 static enum ice_status
4020 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
4021 {
4022         struct ice_aqc_sw_rules_elem *s_rule;
4023         enum ice_status status;
4024
4025         s_rule = (struct ice_aqc_sw_rules_elem *)
4026                 ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
4027         if (!s_rule)
4028                 return ICE_ERR_NO_MEMORY;
4029
4030         ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
4031
4032         s_rule->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_info->fltr_rule_id);
4033
4034         /* Update switch rule with new rule set to forward VSI list */
4035         status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
4036                                  ice_aqc_opc_update_sw_rules, NULL);
4037
4038         ice_free(hw, s_rule);
4039         return status;
4040 }
4041
4042 /**
4043  * ice_update_sw_rule_bridge_mode
4044  * @hw: pointer to the HW struct
4045  *
4046  * Updates unicast switch filter rules based on VEB/VEPA mode
4047  */
4048 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
4049 {
4050         struct ice_switch_info *sw = hw->switch_info;
4051         struct ice_fltr_mgmt_list_entry *fm_entry;
4052         enum ice_status status = ICE_SUCCESS;
4053         struct LIST_HEAD_TYPE *rule_head;
4054         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4055
4056         rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
4057         rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4058
4059         ice_acquire_lock(rule_lock);
4060         LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry,
4061                             list_entry) {
4062                 struct ice_fltr_info *fi = &fm_entry->fltr_info;
4063                 u8 *addr = fi->l_data.mac.mac_addr;
4064
4065                 /* Update unicast Tx rules to reflect the selected
4066                  * VEB/VEPA mode
4067                  */
4068                 if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) &&
4069                     (fi->fltr_act == ICE_FWD_TO_VSI ||
4070                      fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
4071                      fi->fltr_act == ICE_FWD_TO_Q ||
4072                      fi->fltr_act == ICE_FWD_TO_QGRP)) {
4073                         status = ice_update_pkt_fwd_rule(hw, fi);
4074                         if (status)
4075                                 break;
4076                 }
4077         }
4078
4079         ice_release_lock(rule_lock);
4080
4081         return status;
4082 }
4083
4084 /**
4085  * ice_add_update_vsi_list
4086  * @hw: pointer to the hardware structure
4087  * @m_entry: pointer to current filter management list entry
4088  * @cur_fltr: filter information from the book keeping entry
4089  * @new_fltr: filter information with the new VSI to be added
4090  *
4091  * Call AQ command to add or update previously created VSI list with new VSI.
4092  *
4093  * Helper function to do book keeping associated with adding filter information
4094  * The algorithm to do the book keeping is described below :
4095  * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
4096  *      if only one VSI has been added till now
4097  *              Allocate a new VSI list and add two VSIs
4098  *              to this list using switch rule command
4099  *              Update the previously created switch rule with the
4100  *              newly created VSI list ID
4101  *      if a VSI list was previously created
4102  *              Add the new VSI to the previously created VSI list set
4103  *              using the update switch rule command
4104  */
4105 static enum ice_status
4106 ice_add_update_vsi_list(struct ice_hw *hw,
4107                         struct ice_fltr_mgmt_list_entry *m_entry,
4108                         struct ice_fltr_info *cur_fltr,
4109                         struct ice_fltr_info *new_fltr)
4110 {
4111         enum ice_status status = ICE_SUCCESS;
4112         u16 vsi_list_id = 0;
4113
4114         if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
4115              cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
4116                 return ICE_ERR_NOT_IMPL;
4117
4118         if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
4119              new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
4120             (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
4121              cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
4122                 return ICE_ERR_NOT_IMPL;
4123
4124         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
4125                 /* Only one entry existed in the mapping and it was not already
4126                  * a part of a VSI list. So, create a VSI list with the old and
4127                  * new VSIs.
4128                  */
4129                 struct ice_fltr_info tmp_fltr;
4130                 u16 vsi_handle_arr[2];
4131
4132                 /* A rule already exists with the new VSI being added */
4133                 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
4134                         return ICE_ERR_ALREADY_EXISTS;
4135
4136                 vsi_handle_arr[0] = cur_fltr->vsi_handle;
4137                 vsi_handle_arr[1] = new_fltr->vsi_handle;
4138                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4139                                                   &vsi_list_id,
4140                                                   new_fltr->lkup_type);
4141                 if (status)
4142                         return status;
4143
4144                 tmp_fltr = *new_fltr;
4145                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
4146                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4147                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4148                 /* Update the previous switch rule of "MAC forward to VSI" to
4149                  * "MAC fwd to VSI list"
4150                  */
4151                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4152                 if (status)
4153                         return status;
4154
4155                 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
4156                 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4157                 m_entry->vsi_list_info =
4158                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4159                                                 vsi_list_id);
4160
4161                 if (!m_entry->vsi_list_info)
4162                         return ICE_ERR_NO_MEMORY;
4163
4164                 /* If this entry was large action then the large action needs
4165                  * to be updated to point to FWD to VSI list
4166                  */
4167                 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
4168                         status =
4169                             ice_add_marker_act(hw, m_entry,
4170                                                m_entry->sw_marker_id,
4171                                                m_entry->lg_act_idx);
4172         } else {
4173                 u16 vsi_handle = new_fltr->vsi_handle;
4174                 enum ice_adminq_opc opcode;
4175
4176                 if (!m_entry->vsi_list_info)
4177                         return ICE_ERR_CFG;
4178
4179                 /* A rule already exists with the new VSI being added */
4180                 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
4181                         return ICE_SUCCESS;
4182
4183                 /* Update the previously created VSI list set with
4184                  * the new VSI ID passed in
4185                  */
4186                 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
4187                 opcode = ice_aqc_opc_update_sw_rules;
4188
4189                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
4190                                                   vsi_list_id, false, opcode,
4191                                                   new_fltr->lkup_type);
4192                 /* update VSI list mapping info with new VSI ID */
4193                 if (!status)
4194                         ice_set_bit(vsi_handle,
4195                                     m_entry->vsi_list_info->vsi_map);
4196         }
4197         if (!status)
4198                 m_entry->vsi_count++;
4199         return status;
4200 }
4201
4202 /**
4203  * ice_find_rule_entry - Search a rule entry
4204  * @list_head: head of rule list
4205  * @f_info: rule information
4206  *
4207  * Helper function to search for a given rule entry
4208  * Returns pointer to entry storing the rule if found
4209  */
4210 static struct ice_fltr_mgmt_list_entry *
4211 ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head,
4212                     struct ice_fltr_info *f_info)
4213 {
4214         struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
4215
4216         LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
4217                             list_entry) {
4218                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
4219                             sizeof(f_info->l_data)) &&
4220                     f_info->flag == list_itr->fltr_info.flag) {
4221                         ret = list_itr;
4222                         break;
4223                 }
4224         }
4225         return ret;
4226 }
4227
4228 /**
4229  * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
4230  * @recp_list: VSI lists needs to be searched
4231  * @vsi_handle: VSI handle to be found in VSI list
4232  * @vsi_list_id: VSI list ID found containing vsi_handle
4233  *
4234  * Helper function to search a VSI list with single entry containing given VSI
4235  * handle element. This can be extended further to search VSI list with more
4236  * than 1 vsi_count. Returns pointer to VSI list entry if found.
4237  */
4238 static struct ice_vsi_list_map_info *
4239 ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle,
4240                         u16 *vsi_list_id)
4241 {
4242         struct ice_vsi_list_map_info *map_info = NULL;
4243         struct LIST_HEAD_TYPE *list_head;
4244
4245         list_head = &recp_list->filt_rules;
4246         if (recp_list->adv_rule) {
4247                 struct ice_adv_fltr_mgmt_list_entry *list_itr;
4248
4249                 LIST_FOR_EACH_ENTRY(list_itr, list_head,
4250                                     ice_adv_fltr_mgmt_list_entry,
4251                                     list_entry) {
4252                         if (list_itr->vsi_list_info) {
4253                                 map_info = list_itr->vsi_list_info;
4254                                 if (ice_is_bit_set(map_info->vsi_map,
4255                                                    vsi_handle)) {
4256                                         *vsi_list_id = map_info->vsi_list_id;
4257                                         return map_info;
4258                                 }
4259                         }
4260                 }
4261         } else {
4262                 struct ice_fltr_mgmt_list_entry *list_itr;
4263
4264                 LIST_FOR_EACH_ENTRY(list_itr, list_head,
4265                                     ice_fltr_mgmt_list_entry,
4266                                     list_entry) {
4267                         if (list_itr->vsi_count == 1 &&
4268                             list_itr->vsi_list_info) {
4269                                 map_info = list_itr->vsi_list_info;
4270                                 if (ice_is_bit_set(map_info->vsi_map,
4271                                                    vsi_handle)) {
4272                                         *vsi_list_id = map_info->vsi_list_id;
4273                                         return map_info;
4274                                 }
4275                         }
4276                 }
4277         }
4278         return NULL;
4279 }
4280
4281 /**
4282  * ice_add_rule_internal - add rule for a given lookup type
4283  * @hw: pointer to the hardware structure
4284  * @recp_list: recipe list for which rule has to be added
4285  * @lport: logic port number on which function add rule
4286  * @f_entry: structure containing MAC forwarding information
4287  *
4288  * Adds or updates the rule lists for a given recipe
4289  */
4290 static enum ice_status
4291 ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4292                       u8 lport, struct ice_fltr_list_entry *f_entry)
4293 {
4294         struct ice_fltr_info *new_fltr, *cur_fltr;
4295         struct ice_fltr_mgmt_list_entry *m_entry;
4296         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4297         enum ice_status status = ICE_SUCCESS;
4298
4299         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4300                 return ICE_ERR_PARAM;
4301
4302         /* Load the hw_vsi_id only if the fwd action is fwd to VSI */
4303         if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI)
4304                 f_entry->fltr_info.fwd_id.hw_vsi_id =
4305                         ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4306
4307         rule_lock = &recp_list->filt_rule_lock;
4308
4309         ice_acquire_lock(rule_lock);
4310         new_fltr = &f_entry->fltr_info;
4311         if (new_fltr->flag & ICE_FLTR_RX)
4312                 new_fltr->src = lport;
4313         else if (new_fltr->flag & ICE_FLTR_TX)
4314                 new_fltr->src =
4315                         ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4316
4317         m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4318         if (!m_entry) {
4319                 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4320                 goto exit_add_rule_internal;
4321         }
4322
4323         cur_fltr = &m_entry->fltr_info;
4324         status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
4325
4326 exit_add_rule_internal:
4327         ice_release_lock(rule_lock);
4328         return status;
4329 }
4330
4331 /**
4332  * ice_remove_vsi_list_rule
4333  * @hw: pointer to the hardware structure
4334  * @vsi_list_id: VSI list ID generated as part of allocate resource
4335  * @lkup_type: switch rule filter lookup type
4336  *
4337  * The VSI list should be emptied before this function is called to remove the
4338  * VSI list.
4339  */
4340 static enum ice_status
4341 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
4342                          enum ice_sw_lkup_type lkup_type)
4343 {
4344         /* Free the vsi_list resource that we allocated. It is assumed that the
4345          * list is empty at this point.
4346          */
4347         return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
4348                                             ice_aqc_opc_free_res);
4349 }
4350
4351 /**
4352  * ice_rem_update_vsi_list
4353  * @hw: pointer to the hardware structure
4354  * @vsi_handle: VSI handle of the VSI to remove
4355  * @fm_list: filter management entry for which the VSI list management needs to
4356  *           be done
4357  */
4358 static enum ice_status
4359 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
4360                         struct ice_fltr_mgmt_list_entry *fm_list)
4361 {
4362         enum ice_sw_lkup_type lkup_type;
4363         enum ice_status status = ICE_SUCCESS;
4364         u16 vsi_list_id;
4365
4366         if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
4367             fm_list->vsi_count == 0)
4368                 return ICE_ERR_PARAM;
4369
4370         /* A rule with the VSI being removed does not exist */
4371         if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
4372                 return ICE_ERR_DOES_NOT_EXIST;
4373
4374         lkup_type = fm_list->fltr_info.lkup_type;
4375         vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
4376         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
4377                                           ice_aqc_opc_update_sw_rules,
4378                                           lkup_type);
4379         if (status)
4380                 return status;
4381
4382         fm_list->vsi_count--;
4383         ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
4384
4385         if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
4386                 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
4387                 struct ice_vsi_list_map_info *vsi_list_info =
4388                         fm_list->vsi_list_info;
4389                 u16 rem_vsi_handle;
4390
4391                 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
4392                                                     ICE_MAX_VSI);
4393                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
4394                         return ICE_ERR_OUT_OF_RANGE;
4395
4396                 /* Make sure VSI list is empty before removing it below */
4397                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
4398                                                   vsi_list_id, true,
4399                                                   ice_aqc_opc_update_sw_rules,
4400                                                   lkup_type);
4401                 if (status)
4402                         return status;
4403
4404                 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
4405                 tmp_fltr_info.fwd_id.hw_vsi_id =
4406                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
4407                 tmp_fltr_info.vsi_handle = rem_vsi_handle;
4408                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
4409                 if (status) {
4410                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
4411                                   tmp_fltr_info.fwd_id.hw_vsi_id, status);
4412                         return status;
4413                 }
4414
4415                 fm_list->fltr_info = tmp_fltr_info;
4416         }
4417
4418         if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
4419             (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
4420                 struct ice_vsi_list_map_info *vsi_list_info =
4421                         fm_list->vsi_list_info;
4422
4423                 /* Remove the VSI list since it is no longer used */
4424                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
4425                 if (status) {
4426                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
4427                                   vsi_list_id, status);
4428                         return status;
4429                 }
4430
4431                 LIST_DEL(&vsi_list_info->list_entry);
4432                 ice_free(hw, vsi_list_info);
4433                 fm_list->vsi_list_info = NULL;
4434         }
4435
4436         return status;
4437 }
4438
4439 /**
4440  * ice_remove_rule_internal - Remove a filter rule of a given type
4441  *
4442  * @hw: pointer to the hardware structure
4443  * @recp_list: recipe list for which the rule needs to removed
4444  * @f_entry: rule entry containing filter information
4445  */
4446 static enum ice_status
4447 ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4448                          struct ice_fltr_list_entry *f_entry)
4449 {
4450         struct ice_fltr_mgmt_list_entry *list_elem;
4451         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4452         enum ice_status status = ICE_SUCCESS;
4453         bool remove_rule = false;
4454         u16 vsi_handle;
4455
4456         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4457                 return ICE_ERR_PARAM;
4458         f_entry->fltr_info.fwd_id.hw_vsi_id =
4459                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4460
4461         rule_lock = &recp_list->filt_rule_lock;
4462         ice_acquire_lock(rule_lock);
4463         list_elem = ice_find_rule_entry(&recp_list->filt_rules,
4464                                         &f_entry->fltr_info);
4465         if (!list_elem) {
4466                 status = ICE_ERR_DOES_NOT_EXIST;
4467                 goto exit;
4468         }
4469
4470         if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
4471                 remove_rule = true;
4472         } else if (!list_elem->vsi_list_info) {
4473                 status = ICE_ERR_DOES_NOT_EXIST;
4474                 goto exit;
4475         } else if (list_elem->vsi_list_info->ref_cnt > 1) {
4476                 /* a ref_cnt > 1 indicates that the vsi_list is being
4477                  * shared by multiple rules. Decrement the ref_cnt and
4478                  * remove this rule, but do not modify the list, as it
4479                  * is in-use by other rules.
4480                  */
4481                 list_elem->vsi_list_info->ref_cnt--;
4482                 remove_rule = true;
4483         } else {
4484                 /* a ref_cnt of 1 indicates the vsi_list is only used
4485                  * by one rule. However, the original removal request is only
4486                  * for a single VSI. Update the vsi_list first, and only
4487                  * remove the rule if there are no further VSIs in this list.
4488                  */
4489                 vsi_handle = f_entry->fltr_info.vsi_handle;
4490                 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
4491                 if (status)
4492                         goto exit;
4493                 /* if VSI count goes to zero after updating the VSI list */
4494                 if (list_elem->vsi_count == 0)
4495                         remove_rule = true;
4496         }
4497
4498         if (remove_rule) {
4499                 /* Remove the lookup rule */
4500                 struct ice_aqc_sw_rules_elem *s_rule;
4501
4502                 s_rule = (struct ice_aqc_sw_rules_elem *)
4503                         ice_malloc(hw, ICE_SW_RULE_RX_TX_NO_HDR_SIZE);
4504                 if (!s_rule) {
4505                         status = ICE_ERR_NO_MEMORY;
4506                         goto exit;
4507                 }
4508
4509                 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
4510                                  ice_aqc_opc_remove_sw_rules);
4511
4512                 status = ice_aq_sw_rules(hw, s_rule,
4513                                          ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
4514                                          ice_aqc_opc_remove_sw_rules, NULL);
4515
4516                 /* Remove a book keeping from the list */
4517                 ice_free(hw, s_rule);
4518
4519                 if (status)
4520                         goto exit;
4521
4522                 LIST_DEL(&list_elem->list_entry);
4523                 ice_free(hw, list_elem);
4524         }
4525 exit:
4526         ice_release_lock(rule_lock);
4527         return status;
4528 }
4529
4530 /**
4531  * ice_aq_get_res_alloc - get allocated resources
4532  * @hw: pointer to the HW struct
4533  * @num_entries: pointer to u16 to store the number of resource entries returned
4534  * @buf: pointer to buffer
4535  * @buf_size: size of buf
4536  * @cd: pointer to command details structure or NULL
4537  *
4538  * The caller-supplied buffer must be large enough to store the resource
4539  * information for all resource types. Each resource type is an
4540  * ice_aqc_get_res_resp_elem structure.
4541  */
4542 enum ice_status
4543 ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries,
4544                      struct ice_aqc_get_res_resp_elem *buf, u16 buf_size,
4545                      struct ice_sq_cd *cd)
4546 {
4547         struct ice_aqc_get_res_alloc *resp;
4548         enum ice_status status;
4549         struct ice_aq_desc desc;
4550
4551         if (!buf)
4552                 return ICE_ERR_BAD_PTR;
4553
4554         if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN)
4555                 return ICE_ERR_INVAL_SIZE;
4556
4557         resp = &desc.params.get_res;
4558
4559         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc);
4560         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4561
4562         if (!status && num_entries)
4563                 *num_entries = LE16_TO_CPU(resp->resp_elem_num);
4564
4565         return status;
4566 }
4567
4568 /**
4569  * ice_aq_get_res_descs - get allocated resource descriptors
4570  * @hw: pointer to the hardware structure
4571  * @num_entries: number of resource entries in buffer
4572  * @buf: structure to hold response data buffer
4573  * @buf_size: size of buffer
4574  * @res_type: resource type
4575  * @res_shared: is resource shared
4576  * @desc_id: input - first desc ID to start; output - next desc ID
4577  * @cd: pointer to command details structure or NULL
4578  */
4579 enum ice_status
4580 ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries,
4581                      struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type,
4582                      bool res_shared, u16 *desc_id, struct ice_sq_cd *cd)
4583 {
4584         struct ice_aqc_get_allocd_res_desc *cmd;
4585         struct ice_aq_desc desc;
4586         enum ice_status status;
4587
4588         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
4589
4590         cmd = &desc.params.get_res_desc;
4591
4592         if (!buf)
4593                 return ICE_ERR_PARAM;
4594
4595         if (buf_size != (num_entries * sizeof(*buf)))
4596                 return ICE_ERR_PARAM;
4597
4598         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc);
4599
4600         cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) &
4601                                          ICE_AQC_RES_TYPE_M) | (res_shared ?
4602                                         ICE_AQC_RES_TYPE_FLAG_SHARED : 0));
4603         cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id);
4604
4605         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4606         if (!status)
4607                 *desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc);
4608
4609         return status;
4610 }
4611
4612 /**
4613  * ice_add_mac_rule - Add a MAC address based filter rule
4614  * @hw: pointer to the hardware structure
4615  * @m_list: list of MAC addresses and forwarding information
4616  * @sw: pointer to switch info struct for which function add rule
4617  * @lport: logic port number on which function add rule
4618  *
4619  * IMPORTANT: When the ucast_shared flag is set to false and m_list has
4620  * multiple unicast addresses, the function assumes that all the
4621  * addresses are unique in a given add_mac call. It doesn't
4622  * check for duplicates in this case, removing duplicates from a given
4623  * list should be taken care of in the caller of this function.
4624  */
4625 static enum ice_status
4626 ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
4627                  struct ice_switch_info *sw, u8 lport)
4628 {
4629         struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC];
4630         struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
4631         struct ice_fltr_list_entry *m_list_itr;
4632         struct LIST_HEAD_TYPE *rule_head;
4633         u16 total_elem_left, s_rule_size;
4634         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4635         enum ice_status status = ICE_SUCCESS;
4636         u16 num_unicast = 0;
4637         u8 elem_sent;
4638
4639         s_rule = NULL;
4640         rule_lock = &recp_list->filt_rule_lock;
4641         rule_head = &recp_list->filt_rules;
4642
4643         LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4644                             list_entry) {
4645                 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
4646                 u16 vsi_handle;
4647                 u16 hw_vsi_id;
4648
4649                 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
4650                 vsi_handle = m_list_itr->fltr_info.vsi_handle;
4651                 if (!ice_is_vsi_valid(hw, vsi_handle))
4652                         return ICE_ERR_PARAM;
4653                 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4654                 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
4655                 /* update the src in case it is VSI num */
4656                 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
4657                         return ICE_ERR_PARAM;
4658                 m_list_itr->fltr_info.src = hw_vsi_id;
4659                 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
4660                     IS_ZERO_ETHER_ADDR(add))
4661                         return ICE_ERR_PARAM;
4662                 if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) {
4663                         /* Don't overwrite the unicast address */
4664                         ice_acquire_lock(rule_lock);
4665                         if (ice_find_rule_entry(rule_head,
4666                                                 &m_list_itr->fltr_info)) {
4667                                 ice_release_lock(rule_lock);
4668                                 return ICE_ERR_ALREADY_EXISTS;
4669                         }
4670                         ice_release_lock(rule_lock);
4671                         num_unicast++;
4672                 } else if (IS_MULTICAST_ETHER_ADDR(add) ||
4673                            (IS_UNICAST_ETHER_ADDR(add) && hw->ucast_shared)) {
4674                         m_list_itr->status =
4675                                 ice_add_rule_internal(hw, recp_list, lport,
4676                                                       m_list_itr);
4677                         if (m_list_itr->status)
4678                                 return m_list_itr->status;
4679                 }
4680         }
4681
4682         ice_acquire_lock(rule_lock);
4683         /* Exit if no suitable entries were found for adding bulk switch rule */
4684         if (!num_unicast) {
4685                 status = ICE_SUCCESS;
4686                 goto ice_add_mac_exit;
4687         }
4688
4689         /* Allocate switch rule buffer for the bulk update for unicast */
4690         s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
4691         s_rule = (struct ice_aqc_sw_rules_elem *)
4692                 ice_calloc(hw, num_unicast, s_rule_size);
4693         if (!s_rule) {
4694                 status = ICE_ERR_NO_MEMORY;
4695                 goto ice_add_mac_exit;
4696         }
4697
4698         r_iter = s_rule;
4699         LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4700                             list_entry) {
4701                 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
4702                 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
4703
4704                 if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
4705                         ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
4706                                          ice_aqc_opc_add_sw_rules);
4707                         r_iter = (struct ice_aqc_sw_rules_elem *)
4708                                 ((u8 *)r_iter + s_rule_size);
4709                 }
4710         }
4711
4712         /* Call AQ bulk switch rule update for all unicast addresses */
4713         r_iter = s_rule;
4714         /* Call AQ switch rule in AQ_MAX chunk */
4715         for (total_elem_left = num_unicast; total_elem_left > 0;
4716              total_elem_left -= elem_sent) {
4717                 struct ice_aqc_sw_rules_elem *entry = r_iter;
4718
4719                 elem_sent = MIN_T(u8, total_elem_left,
4720                                   (ICE_AQ_MAX_BUF_LEN / s_rule_size));
4721                 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
4722                                          elem_sent, ice_aqc_opc_add_sw_rules,
4723                                          NULL);
4724                 if (status)
4725                         goto ice_add_mac_exit;
4726                 r_iter = (struct ice_aqc_sw_rules_elem *)
4727                         ((u8 *)r_iter + (elem_sent * s_rule_size));
4728         }
4729
4730         /* Fill up rule ID based on the value returned from FW */
4731         r_iter = s_rule;
4732         LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4733                             list_entry) {
4734                 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
4735                 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
4736                 struct ice_fltr_mgmt_list_entry *fm_entry;
4737
4738                 if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
4739                         f_info->fltr_rule_id =
4740                                 LE16_TO_CPU(r_iter->pdata.lkup_tx_rx.index);
4741                         f_info->fltr_act = ICE_FWD_TO_VSI;
4742                         /* Create an entry to track this MAC address */
4743                         fm_entry = (struct ice_fltr_mgmt_list_entry *)
4744                                 ice_malloc(hw, sizeof(*fm_entry));
4745                         if (!fm_entry) {
4746                                 status = ICE_ERR_NO_MEMORY;
4747                                 goto ice_add_mac_exit;
4748                         }
4749                         fm_entry->fltr_info = *f_info;
4750                         fm_entry->vsi_count = 1;
4751                         /* The book keeping entries will get removed when
4752                          * base driver calls remove filter AQ command
4753                          */
4754
4755                         LIST_ADD(&fm_entry->list_entry, rule_head);
4756                         r_iter = (struct ice_aqc_sw_rules_elem *)
4757                                 ((u8 *)r_iter + s_rule_size);
4758                 }
4759         }
4760
4761 ice_add_mac_exit:
4762         ice_release_lock(rule_lock);
4763         if (s_rule)
4764                 ice_free(hw, s_rule);
4765         return status;
4766 }
4767
4768 /**
4769  * ice_add_mac - Add a MAC address based filter rule
4770  * @hw: pointer to the hardware structure
4771  * @m_list: list of MAC addresses and forwarding information
4772  *
4773  * Function add MAC rule for logical port from HW struct
4774  */
4775 enum ice_status ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
4776 {
4777         if (!m_list || !hw)
4778                 return ICE_ERR_PARAM;
4779
4780         return ice_add_mac_rule(hw, m_list, hw->switch_info,
4781                                 hw->port_info->lport);
4782 }
4783
4784 /**
4785  * ice_add_vlan_internal - Add one VLAN based filter rule
4786  * @hw: pointer to the hardware structure
4787  * @recp_list: recipe list for which rule has to be added
4788  * @f_entry: filter entry containing one VLAN information
4789  */
4790 static enum ice_status
4791 ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4792                       struct ice_fltr_list_entry *f_entry)
4793 {
4794         struct ice_fltr_mgmt_list_entry *v_list_itr;
4795         struct ice_fltr_info *new_fltr, *cur_fltr;
4796         enum ice_sw_lkup_type lkup_type;
4797         u16 vsi_list_id = 0, vsi_handle;
4798         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4799         enum ice_status status = ICE_SUCCESS;
4800
4801         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4802                 return ICE_ERR_PARAM;
4803
4804         f_entry->fltr_info.fwd_id.hw_vsi_id =
4805                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4806         new_fltr = &f_entry->fltr_info;
4807
4808         /* VLAN ID should only be 12 bits */
4809         if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
4810                 return ICE_ERR_PARAM;
4811
4812         if (new_fltr->src_id != ICE_SRC_ID_VSI)
4813                 return ICE_ERR_PARAM;
4814
4815         new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
4816         lkup_type = new_fltr->lkup_type;
4817         vsi_handle = new_fltr->vsi_handle;
4818         rule_lock = &recp_list->filt_rule_lock;
4819         ice_acquire_lock(rule_lock);
4820         v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4821         if (!v_list_itr) {
4822                 struct ice_vsi_list_map_info *map_info = NULL;
4823
4824                 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
4825                         /* All VLAN pruning rules use a VSI list. Check if
4826                          * there is already a VSI list containing VSI that we
4827                          * want to add. If found, use the same vsi_list_id for
4828                          * this new VLAN rule or else create a new list.
4829                          */
4830                         map_info = ice_find_vsi_list_entry(recp_list,
4831                                                            vsi_handle,
4832                                                            &vsi_list_id);
4833                         if (!map_info) {
4834                                 status = ice_create_vsi_list_rule(hw,
4835                                                                   &vsi_handle,
4836                                                                   1,
4837                                                                   &vsi_list_id,
4838                                                                   lkup_type);
4839                                 if (status)
4840                                         goto exit;
4841                         }
4842                         /* Convert the action to forwarding to a VSI list. */
4843                         new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4844                         new_fltr->fwd_id.vsi_list_id = vsi_list_id;
4845                 }
4846
4847                 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4848                 if (!status) {
4849                         v_list_itr = ice_find_rule_entry(&recp_list->filt_rules,
4850                                                          new_fltr);
4851                         if (!v_list_itr) {
4852                                 status = ICE_ERR_DOES_NOT_EXIST;
4853                                 goto exit;
4854                         }
4855                         /* reuse VSI list for new rule and increment ref_cnt */
4856                         if (map_info) {
4857                                 v_list_itr->vsi_list_info = map_info;
4858                                 map_info->ref_cnt++;
4859                         } else {
4860                                 v_list_itr->vsi_list_info =
4861                                         ice_create_vsi_list_map(hw, &vsi_handle,
4862                                                                 1, vsi_list_id);
4863                         }
4864                 }
4865         } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
4866                 /* Update existing VSI list to add new VSI ID only if it used
4867                  * by one VLAN rule.
4868                  */
4869                 cur_fltr = &v_list_itr->fltr_info;
4870                 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
4871                                                  new_fltr);
4872         } else {
4873                 /* If VLAN rule exists and VSI list being used by this rule is
4874                  * referenced by more than 1 VLAN rule. Then create a new VSI
4875                  * list appending previous VSI with new VSI and update existing
4876                  * VLAN rule to point to new VSI list ID
4877                  */
4878                 struct ice_fltr_info tmp_fltr;
4879                 u16 vsi_handle_arr[2];
4880                 u16 cur_handle;
4881
4882                 /* Current implementation only supports reusing VSI list with
4883                  * one VSI count. We should never hit below condition
4884                  */
4885                 if (v_list_itr->vsi_count > 1 &&
4886                     v_list_itr->vsi_list_info->ref_cnt > 1) {
4887                         ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
4888                         status = ICE_ERR_CFG;
4889                         goto exit;
4890                 }
4891
4892                 cur_handle =
4893                         ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map,
4894                                            ICE_MAX_VSI);
4895
4896                 /* A rule already exists with the new VSI being added */
4897                 if (cur_handle == vsi_handle) {
4898                         status = ICE_ERR_ALREADY_EXISTS;
4899                         goto exit;
4900                 }
4901
4902                 vsi_handle_arr[0] = cur_handle;
4903                 vsi_handle_arr[1] = vsi_handle;
4904                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4905                                                   &vsi_list_id, lkup_type);
4906                 if (status)
4907                         goto exit;
4908
4909                 tmp_fltr = v_list_itr->fltr_info;
4910                 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
4911                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4912                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4913                 /* Update the previous switch rule to a new VSI list which
4914                  * includes current VSI that is requested
4915                  */
4916                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4917                 if (status)
4918                         goto exit;
4919
4920                 /* before overriding VSI list map info. decrement ref_cnt of
4921                  * previous VSI list
4922                  */
4923                 v_list_itr->vsi_list_info->ref_cnt--;
4924
4925                 /* now update to newly created list */
4926                 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
4927                 v_list_itr->vsi_list_info =
4928                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4929                                                 vsi_list_id);
4930                 v_list_itr->vsi_count++;
4931         }
4932
4933 exit:
4934         ice_release_lock(rule_lock);
4935         return status;
4936 }
4937
4938 /**
4939  * ice_add_vlan_rule - Add VLAN based filter rule
4940  * @hw: pointer to the hardware structure
4941  * @v_list: list of VLAN entries and forwarding information
4942  * @sw: pointer to switch info struct for which function add rule
4943  */
4944 static enum ice_status
4945 ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
4946                   struct ice_switch_info *sw)
4947 {
4948         struct ice_fltr_list_entry *v_list_itr;
4949         struct ice_sw_recipe *recp_list;
4950
4951         recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN];
4952         LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry,
4953                             list_entry) {
4954                 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
4955                         return ICE_ERR_PARAM;
4956                 v_list_itr->fltr_info.flag = ICE_FLTR_TX;
4957                 v_list_itr->status = ice_add_vlan_internal(hw, recp_list,
4958                                                            v_list_itr);
4959                 if (v_list_itr->status)
4960                         return v_list_itr->status;
4961         }
4962         return ICE_SUCCESS;
4963 }
4964
4965 /**
4966  * ice_add_vlan - Add a VLAN based filter rule
4967  * @hw: pointer to the hardware structure
4968  * @v_list: list of VLAN and forwarding information
4969  *
4970  * Function add VLAN rule for logical port from HW struct
4971  */
4972 enum ice_status ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
4973 {
4974         if (!v_list || !hw)
4975                 return ICE_ERR_PARAM;
4976
4977         return ice_add_vlan_rule(hw, v_list, hw->switch_info);
4978 }
4979
4980 /**
4981  * ice_add_mac_vlan_rule - Add MAC and VLAN pair based filter rule
4982  * @hw: pointer to the hardware structure
4983  * @mv_list: list of MAC and VLAN filters
4984  * @sw: pointer to switch info struct for which function add rule
4985  * @lport: logic port number on which function add rule
4986  *
4987  * If the VSI on which the MAC-VLAN pair has to be added has Rx and Tx VLAN
4988  * pruning bits enabled, then it is the responsibility of the caller to make
4989  * sure to add a VLAN only filter on the same VSI. Packets belonging to that
4990  * VLAN won't be received on that VSI otherwise.
4991  */
4992 static enum ice_status
4993 ice_add_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list,
4994                       struct ice_switch_info *sw, u8 lport)
4995 {
4996         struct ice_fltr_list_entry *mv_list_itr;
4997         struct ice_sw_recipe *recp_list;
4998
4999         if (!mv_list || !hw)
5000                 return ICE_ERR_PARAM;
5001
5002         recp_list = &sw->recp_list[ICE_SW_LKUP_MAC_VLAN];
5003         LIST_FOR_EACH_ENTRY(mv_list_itr, mv_list, ice_fltr_list_entry,
5004                             list_entry) {
5005                 enum ice_sw_lkup_type l_type =
5006                         mv_list_itr->fltr_info.lkup_type;
5007
5008                 if (l_type != ICE_SW_LKUP_MAC_VLAN)
5009                         return ICE_ERR_PARAM;
5010                 mv_list_itr->fltr_info.flag = ICE_FLTR_TX;
5011                 mv_list_itr->status =
5012                         ice_add_rule_internal(hw, recp_list, lport,
5013                                               mv_list_itr);
5014                 if (mv_list_itr->status)
5015                         return mv_list_itr->status;
5016         }
5017         return ICE_SUCCESS;
5018 }
5019
5020 /**
5021  * ice_add_mac_vlan - Add a MAC VLAN address based filter rule
5022  * @hw: pointer to the hardware structure
5023  * @mv_list: list of MAC VLAN addresses and forwarding information
5024  *
5025  * Function add MAC VLAN rule for logical port from HW struct
5026  */
5027 enum ice_status
5028 ice_add_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5029 {
5030         if (!mv_list || !hw)
5031                 return ICE_ERR_PARAM;
5032
5033         return ice_add_mac_vlan_rule(hw, mv_list, hw->switch_info,
5034                                      hw->port_info->lport);
5035 }
5036
5037 /**
5038  * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule
5039  * @hw: pointer to the hardware structure
5040  * @em_list: list of ether type MAC filter, MAC is optional
5041  * @sw: pointer to switch info struct for which function add rule
5042  * @lport: logic port number on which function add rule
5043  *
5044  * This function requires the caller to populate the entries in
5045  * the filter list with the necessary fields (including flags to
5046  * indicate Tx or Rx rules).
5047  */
5048 static enum ice_status
5049 ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5050                      struct ice_switch_info *sw, u8 lport)
5051 {
5052         struct ice_fltr_list_entry *em_list_itr;
5053
5054         LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry,
5055                             list_entry) {
5056                 struct ice_sw_recipe *recp_list;
5057                 enum ice_sw_lkup_type l_type;
5058
5059                 l_type = em_list_itr->fltr_info.lkup_type;
5060                 recp_list = &sw->recp_list[l_type];
5061
5062                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5063                     l_type != ICE_SW_LKUP_ETHERTYPE)
5064                         return ICE_ERR_PARAM;
5065
5066                 em_list_itr->status = ice_add_rule_internal(hw, recp_list,
5067                                                             lport,
5068                                                             em_list_itr);
5069                 if (em_list_itr->status)
5070                         return em_list_itr->status;
5071         }
5072         return ICE_SUCCESS;
5073 }
5074
5075 /**
5076  * ice_add_eth_mac - Add a ethertype based filter rule
5077  * @hw: pointer to the hardware structure
5078  * @em_list: list of ethertype and forwarding information
5079  *
5080  * Function add ethertype rule for logical port from HW struct
5081  */
5082 enum ice_status
5083 ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5084 {
5085         if (!em_list || !hw)
5086                 return ICE_ERR_PARAM;
5087
5088         return ice_add_eth_mac_rule(hw, em_list, hw->switch_info,
5089                                     hw->port_info->lport);
5090 }
5091
5092 /**
5093  * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule
5094  * @hw: pointer to the hardware structure
5095  * @em_list: list of ethertype or ethertype MAC entries
5096  * @sw: pointer to switch info struct for which function add rule
5097  */
5098 static enum ice_status
5099 ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5100                         struct ice_switch_info *sw)
5101 {
5102         struct ice_fltr_list_entry *em_list_itr, *tmp;
5103
5104         LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry,
5105                                  list_entry) {
5106                 struct ice_sw_recipe *recp_list;
5107                 enum ice_sw_lkup_type l_type;
5108
5109                 l_type = em_list_itr->fltr_info.lkup_type;
5110
5111                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5112                     l_type != ICE_SW_LKUP_ETHERTYPE)
5113                         return ICE_ERR_PARAM;
5114
5115                 recp_list = &sw->recp_list[l_type];
5116                 em_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5117                                                                em_list_itr);
5118                 if (em_list_itr->status)
5119                         return em_list_itr->status;
5120         }
5121         return ICE_SUCCESS;
5122 }
5123
5124 /**
5125  * ice_remove_eth_mac - remove a ethertype based filter rule
5126  * @hw: pointer to the hardware structure
5127  * @em_list: list of ethertype and forwarding information
5128  *
5129  */
5130 enum ice_status
5131 ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5132 {
5133         if (!em_list || !hw)
5134                 return ICE_ERR_PARAM;
5135
5136         return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info);
5137 }
5138
5139 /**
5140  * ice_rem_sw_rule_info
5141  * @hw: pointer to the hardware structure
5142  * @rule_head: pointer to the switch list structure that we want to delete
5143  */
5144 static void
5145 ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5146 {
5147         if (!LIST_EMPTY(rule_head)) {
5148                 struct ice_fltr_mgmt_list_entry *entry;
5149                 struct ice_fltr_mgmt_list_entry *tmp;
5150
5151                 LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head,
5152                                          ice_fltr_mgmt_list_entry, list_entry) {
5153                         LIST_DEL(&entry->list_entry);
5154                         ice_free(hw, entry);
5155                 }
5156         }
5157 }
5158
5159 /**
5160  * ice_rem_adv_rule_info
5161  * @hw: pointer to the hardware structure
5162  * @rule_head: pointer to the switch list structure that we want to delete
5163  */
5164 static void
5165 ice_rem_adv_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5166 {
5167         struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
5168         struct ice_adv_fltr_mgmt_list_entry *lst_itr;
5169
5170         if (LIST_EMPTY(rule_head))
5171                 return;
5172
5173         LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry, rule_head,
5174                                  ice_adv_fltr_mgmt_list_entry, list_entry) {
5175                 LIST_DEL(&lst_itr->list_entry);
5176                 ice_free(hw, lst_itr->lkups);
5177                 ice_free(hw, lst_itr);
5178         }
5179 }
5180
5181 /**
5182  * ice_rem_all_sw_rules_info
5183  * @hw: pointer to the hardware structure
5184  */
5185 void ice_rem_all_sw_rules_info(struct ice_hw *hw)
5186 {
5187         struct ice_switch_info *sw = hw->switch_info;
5188         u8 i;
5189
5190         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
5191                 struct LIST_HEAD_TYPE *rule_head;
5192
5193                 rule_head = &sw->recp_list[i].filt_rules;
5194                 if (!sw->recp_list[i].adv_rule)
5195                         ice_rem_sw_rule_info(hw, rule_head);
5196                 else
5197                         ice_rem_adv_rule_info(hw, rule_head);
5198                 if (sw->recp_list[i].adv_rule &&
5199                     LIST_EMPTY(&sw->recp_list[i].filt_rules))
5200                         sw->recp_list[i].adv_rule = false;
5201         }
5202 }
5203
5204 /**
5205  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
5206  * @pi: pointer to the port_info structure
5207  * @vsi_handle: VSI handle to set as default
5208  * @set: true to add the above mentioned switch rule, false to remove it
5209  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
5210  *
5211  * add filter rule to set/unset given VSI as default VSI for the switch
5212  * (represented by swid)
5213  */
5214 enum ice_status
5215 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
5216                  u8 direction)
5217 {
5218         struct ice_aqc_sw_rules_elem *s_rule;
5219         struct ice_fltr_info f_info;
5220         struct ice_hw *hw = pi->hw;
5221         enum ice_adminq_opc opcode;
5222         enum ice_status status;
5223         u16 s_rule_size;
5224         u16 hw_vsi_id;
5225
5226         if (!ice_is_vsi_valid(hw, vsi_handle))
5227                 return ICE_ERR_PARAM;
5228         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5229
5230         s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
5231                 ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
5232
5233         s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
5234         if (!s_rule)
5235                 return ICE_ERR_NO_MEMORY;
5236
5237         ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM);
5238
5239         f_info.lkup_type = ICE_SW_LKUP_DFLT;
5240         f_info.flag = direction;
5241         f_info.fltr_act = ICE_FWD_TO_VSI;
5242         f_info.fwd_id.hw_vsi_id = hw_vsi_id;
5243
5244         if (f_info.flag & ICE_FLTR_RX) {
5245                 f_info.src = pi->lport;
5246                 f_info.src_id = ICE_SRC_ID_LPORT;
5247                 if (!set)
5248                         f_info.fltr_rule_id =
5249                                 pi->dflt_rx_vsi_rule_id;
5250         } else if (f_info.flag & ICE_FLTR_TX) {
5251                 f_info.src_id = ICE_SRC_ID_VSI;
5252                 f_info.src = hw_vsi_id;
5253                 if (!set)
5254                         f_info.fltr_rule_id =
5255                                 pi->dflt_tx_vsi_rule_id;
5256         }
5257
5258         if (set)
5259                 opcode = ice_aqc_opc_add_sw_rules;
5260         else
5261                 opcode = ice_aqc_opc_remove_sw_rules;
5262
5263         ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
5264
5265         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
5266         if (status || !(f_info.flag & ICE_FLTR_TX_RX))
5267                 goto out;
5268         if (set) {
5269                 u16 index = LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
5270
5271                 if (f_info.flag & ICE_FLTR_TX) {
5272                         pi->dflt_tx_vsi_num = hw_vsi_id;
5273                         pi->dflt_tx_vsi_rule_id = index;
5274                 } else if (f_info.flag & ICE_FLTR_RX) {
5275                         pi->dflt_rx_vsi_num = hw_vsi_id;
5276                         pi->dflt_rx_vsi_rule_id = index;
5277                 }
5278         } else {
5279                 if (f_info.flag & ICE_FLTR_TX) {
5280                         pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
5281                         pi->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
5282                 } else if (f_info.flag & ICE_FLTR_RX) {
5283                         pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
5284                         pi->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
5285                 }
5286         }
5287
5288 out:
5289         ice_free(hw, s_rule);
5290         return status;
5291 }
5292
5293 /**
5294  * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
5295  * @list_head: head of rule list
5296  * @f_info: rule information
5297  *
5298  * Helper function to search for a unicast rule entry - this is to be used
5299  * to remove unicast MAC filter that is not shared with other VSIs on the
5300  * PF switch.
5301  *
5302  * Returns pointer to entry storing the rule if found
5303  */
5304 static struct ice_fltr_mgmt_list_entry *
5305 ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head,
5306                           struct ice_fltr_info *f_info)
5307 {
5308         struct ice_fltr_mgmt_list_entry *list_itr;
5309
5310         LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
5311                             list_entry) {
5312                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
5313                             sizeof(f_info->l_data)) &&
5314                     f_info->fwd_id.hw_vsi_id ==
5315                     list_itr->fltr_info.fwd_id.hw_vsi_id &&
5316                     f_info->flag == list_itr->fltr_info.flag)
5317                         return list_itr;
5318         }
5319         return NULL;
5320 }
5321
5322 /**
5323  * ice_remove_mac_rule - remove a MAC based filter rule
5324  * @hw: pointer to the hardware structure
5325  * @m_list: list of MAC addresses and forwarding information
5326  * @recp_list: list from which function remove MAC address
5327  *
5328  * This function removes either a MAC filter rule or a specific VSI from a
5329  * VSI list for a multicast MAC address.
5330  *
5331  * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
5332  * ice_add_mac. Caller should be aware that this call will only work if all
5333  * the entries passed into m_list were added previously. It will not attempt to
5334  * do a partial remove of entries that were found.
5335  */
5336 static enum ice_status
5337 ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5338                     struct ice_sw_recipe *recp_list)
5339 {
5340         struct ice_fltr_list_entry *list_itr, *tmp;
5341         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5342
5343         if (!m_list)
5344                 return ICE_ERR_PARAM;
5345
5346         rule_lock = &recp_list->filt_rule_lock;
5347         LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry,
5348                                  list_entry) {
5349                 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
5350                 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
5351                 u16 vsi_handle;
5352
5353                 if (l_type != ICE_SW_LKUP_MAC)
5354                         return ICE_ERR_PARAM;
5355
5356                 vsi_handle = list_itr->fltr_info.vsi_handle;
5357                 if (!ice_is_vsi_valid(hw, vsi_handle))
5358                         return ICE_ERR_PARAM;
5359
5360                 list_itr->fltr_info.fwd_id.hw_vsi_id =
5361                                         ice_get_hw_vsi_num(hw, vsi_handle);
5362                 if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) {
5363                         /* Don't remove the unicast address that belongs to
5364                          * another VSI on the switch, since it is not being
5365                          * shared...
5366                          */
5367                         ice_acquire_lock(rule_lock);
5368                         if (!ice_find_ucast_rule_entry(&recp_list->filt_rules,
5369                                                        &list_itr->fltr_info)) {
5370                                 ice_release_lock(rule_lock);
5371                                 return ICE_ERR_DOES_NOT_EXIST;
5372                         }
5373                         ice_release_lock(rule_lock);
5374                 }
5375                 list_itr->status = ice_remove_rule_internal(hw, recp_list,
5376                                                             list_itr);
5377                 if (list_itr->status)
5378                         return list_itr->status;
5379         }
5380         return ICE_SUCCESS;
5381 }
5382
5383 /**
5384  * ice_remove_mac - remove a MAC address based filter rule
5385  * @hw: pointer to the hardware structure
5386  * @m_list: list of MAC addresses and forwarding information
5387  *
5388  */
5389 enum ice_status ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5390 {
5391         struct ice_sw_recipe *recp_list;
5392
5393         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
5394         return ice_remove_mac_rule(hw, m_list, recp_list);
5395 }
5396
5397 /**
5398  * ice_remove_vlan_rule - Remove VLAN based filter rule
5399  * @hw: pointer to the hardware structure
5400  * @v_list: list of VLAN entries and forwarding information
5401  * @recp_list: list from which function remove VLAN
5402  */
5403 static enum ice_status
5404 ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5405                      struct ice_sw_recipe *recp_list)
5406 {
5407         struct ice_fltr_list_entry *v_list_itr, *tmp;
5408
5409         LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5410                                  list_entry) {
5411                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5412
5413                 if (l_type != ICE_SW_LKUP_VLAN)
5414                         return ICE_ERR_PARAM;
5415                 v_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5416                                                               v_list_itr);
5417                 if (v_list_itr->status)
5418                         return v_list_itr->status;
5419         }
5420         return ICE_SUCCESS;
5421 }
5422
5423 /**
5424  * ice_remove_vlan - remove a VLAN address based filter rule
5425  * @hw: pointer to the hardware structure
5426  * @v_list: list of VLAN and forwarding information
5427  *
5428  */
5429 enum ice_status
5430 ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5431 {
5432         struct ice_sw_recipe *recp_list;
5433
5434         if (!v_list || !hw)
5435                 return ICE_ERR_PARAM;
5436
5437         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN];
5438         return ice_remove_vlan_rule(hw, v_list, recp_list);
5439 }
5440
5441 /**
5442  * ice_remove_mac_vlan_rule - Remove MAC VLAN based filter rule
5443  * @hw: pointer to the hardware structure
5444  * @v_list: list of MAC VLAN entries and forwarding information
5445  * @recp_list: list from which function remove MAC VLAN
5446  */
5447 static enum ice_status
5448 ice_remove_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5449                          struct ice_sw_recipe *recp_list)
5450 {
5451         struct ice_fltr_list_entry *v_list_itr, *tmp;
5452
5453         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
5454         LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5455                                  list_entry) {
5456                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5457
5458                 if (l_type != ICE_SW_LKUP_MAC_VLAN)
5459                         return ICE_ERR_PARAM;
5460                 v_list_itr->status =
5461                         ice_remove_rule_internal(hw, recp_list,
5462                                                  v_list_itr);
5463                 if (v_list_itr->status)
5464                         return v_list_itr->status;
5465         }
5466         return ICE_SUCCESS;
5467 }
5468
5469 /**
5470  * ice_remove_mac_vlan - remove a MAC VLAN address based filter rule
5471  * @hw: pointer to the hardware structure
5472  * @mv_list: list of MAC VLAN and forwarding information
5473  */
5474 enum ice_status
5475 ice_remove_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5476 {
5477         struct ice_sw_recipe *recp_list;
5478
5479         if (!mv_list || !hw)
5480                 return ICE_ERR_PARAM;
5481
5482         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
5483         return ice_remove_mac_vlan_rule(hw, mv_list, recp_list);
5484 }
5485
5486 /**
5487  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
5488  * @fm_entry: filter entry to inspect
5489  * @vsi_handle: VSI handle to compare with filter info
5490  */
5491 static bool
5492 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
5493 {
5494         return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
5495                  fm_entry->fltr_info.vsi_handle == vsi_handle) ||
5496                 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
5497                  fm_entry->vsi_list_info &&
5498                  (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map,
5499                                  vsi_handle))));
5500 }
5501
5502 /**
5503  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
5504  * @hw: pointer to the hardware structure
5505  * @vsi_handle: VSI handle to remove filters from
5506  * @vsi_list_head: pointer to the list to add entry to
5507  * @fi: pointer to fltr_info of filter entry to copy & add
5508  *
5509  * Helper function, used when creating a list of filters to remove from
5510  * a specific VSI. The entry added to vsi_list_head is a COPY of the
5511  * original filter entry, with the exception of fltr_info.fltr_act and
5512  * fltr_info.fwd_id fields. These are set such that later logic can
5513  * extract which VSI to remove the fltr from, and pass on that information.
5514  */
5515 static enum ice_status
5516 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
5517                                struct LIST_HEAD_TYPE *vsi_list_head,
5518                                struct ice_fltr_info *fi)
5519 {
5520         struct ice_fltr_list_entry *tmp;
5521
5522         /* this memory is freed up in the caller function
5523          * once filters for this VSI are removed
5524          */
5525         tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp));
5526         if (!tmp)
5527                 return ICE_ERR_NO_MEMORY;
5528
5529         tmp->fltr_info = *fi;
5530
5531         /* Overwrite these fields to indicate which VSI to remove filter from,
5532          * so find and remove logic can extract the information from the
5533          * list entries. Note that original entries will still have proper
5534          * values.
5535          */
5536         tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
5537         tmp->fltr_info.vsi_handle = vsi_handle;
5538         tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5539
5540         LIST_ADD(&tmp->list_entry, vsi_list_head);
5541
5542         return ICE_SUCCESS;
5543 }
5544
5545 /**
5546  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
5547  * @hw: pointer to the hardware structure
5548  * @vsi_handle: VSI handle to remove filters from
5549  * @lkup_list_head: pointer to the list that has certain lookup type filters
5550  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
5551  *
5552  * Locates all filters in lkup_list_head that are used by the given VSI,
5553  * and adds COPIES of those entries to vsi_list_head (intended to be used
5554  * to remove the listed filters).
5555  * Note that this means all entries in vsi_list_head must be explicitly
5556  * deallocated by the caller when done with list.
5557  */
5558 static enum ice_status
5559 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
5560                          struct LIST_HEAD_TYPE *lkup_list_head,
5561                          struct LIST_HEAD_TYPE *vsi_list_head)
5562 {
5563         struct ice_fltr_mgmt_list_entry *fm_entry;
5564         enum ice_status status = ICE_SUCCESS;
5565
5566         /* check to make sure VSI ID is valid and within boundary */
5567         if (!ice_is_vsi_valid(hw, vsi_handle))
5568                 return ICE_ERR_PARAM;
5569
5570         LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head,
5571                             ice_fltr_mgmt_list_entry, list_entry) {
5572                 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
5573                         continue;
5574
5575                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
5576                                                         vsi_list_head,
5577                                                         &fm_entry->fltr_info);
5578                 if (status)
5579                         return status;
5580         }
5581         return status;
5582 }
5583
5584 /**
5585  * ice_determine_promisc_mask
5586  * @fi: filter info to parse
5587  *
5588  * Helper function to determine which ICE_PROMISC_ mask corresponds
5589  * to given filter into.
5590  */
5591 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
5592 {
5593         u16 vid = fi->l_data.mac_vlan.vlan_id;
5594         u8 *macaddr = fi->l_data.mac.mac_addr;
5595         bool is_tx_fltr = false;
5596         u8 promisc_mask = 0;
5597
5598         if (fi->flag == ICE_FLTR_TX)
5599                 is_tx_fltr = true;
5600
5601         if (IS_BROADCAST_ETHER_ADDR(macaddr))
5602                 promisc_mask |= is_tx_fltr ?
5603                         ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
5604         else if (IS_MULTICAST_ETHER_ADDR(macaddr))
5605                 promisc_mask |= is_tx_fltr ?
5606                         ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
5607         else if (IS_UNICAST_ETHER_ADDR(macaddr))
5608                 promisc_mask |= is_tx_fltr ?
5609                         ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
5610         if (vid)
5611                 promisc_mask |= is_tx_fltr ?
5612                         ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
5613
5614         return promisc_mask;
5615 }
5616
5617 /**
5618  * _ice_get_vsi_promisc - get promiscuous mode of given VSI
5619  * @hw: pointer to the hardware structure
5620  * @vsi_handle: VSI handle to retrieve info from
5621  * @promisc_mask: pointer to mask to be filled in
5622  * @vid: VLAN ID of promisc VLAN VSI
5623  * @sw: pointer to switch info struct for which function add rule
5624  */
5625 static enum ice_status
5626 _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5627                      u16 *vid, struct ice_switch_info *sw)
5628 {
5629         struct ice_fltr_mgmt_list_entry *itr;
5630         struct LIST_HEAD_TYPE *rule_head;
5631         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
5632
5633         if (!ice_is_vsi_valid(hw, vsi_handle))
5634                 return ICE_ERR_PARAM;
5635
5636         *vid = 0;
5637         *promisc_mask = 0;
5638         rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rules;
5639         rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rule_lock;
5640
5641         ice_acquire_lock(rule_lock);
5642         LIST_FOR_EACH_ENTRY(itr, rule_head,
5643                             ice_fltr_mgmt_list_entry, list_entry) {
5644                 /* Continue if this filter doesn't apply to this VSI or the
5645                  * VSI ID is not in the VSI map for this filter
5646                  */
5647                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
5648                         continue;
5649
5650                 *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
5651         }
5652         ice_release_lock(rule_lock);
5653
5654         return ICE_SUCCESS;
5655 }
5656
5657 /**
5658  * ice_get_vsi_promisc - get promiscuous mode of given VSI
5659  * @hw: pointer to the hardware structure
5660  * @vsi_handle: VSI handle to retrieve info from
5661  * @promisc_mask: pointer to mask to be filled in
5662  * @vid: VLAN ID of promisc VLAN VSI
5663  */
5664 enum ice_status
5665 ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5666                     u16 *vid)
5667 {
5668         return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
5669                                     vid, hw->switch_info);
5670 }
5671
5672 /**
5673  * _ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
5674  * @hw: pointer to the hardware structure
5675  * @vsi_handle: VSI handle to retrieve info from
5676  * @promisc_mask: pointer to mask to be filled in
5677  * @vid: VLAN ID of promisc VLAN VSI
5678  * @sw: pointer to switch info struct for which function add rule
5679  */
5680 static enum ice_status
5681 _ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5682                           u16 *vid, struct ice_switch_info *sw)
5683 {
5684         struct ice_fltr_mgmt_list_entry *itr;
5685         struct LIST_HEAD_TYPE *rule_head;
5686         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
5687
5688         if (!ice_is_vsi_valid(hw, vsi_handle))
5689                 return ICE_ERR_PARAM;
5690
5691         *vid = 0;
5692         *promisc_mask = 0;
5693         rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rules;
5694         rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rule_lock;
5695
5696         ice_acquire_lock(rule_lock);
5697         LIST_FOR_EACH_ENTRY(itr, rule_head, ice_fltr_mgmt_list_entry,
5698                             list_entry) {
5699                 /* Continue if this filter doesn't apply to this VSI or the
5700                  * VSI ID is not in the VSI map for this filter
5701                  */
5702                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
5703                         continue;
5704
5705                 *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
5706         }
5707         ice_release_lock(rule_lock);
5708
5709         return ICE_SUCCESS;
5710 }
5711
5712 /**
5713  * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
5714  * @hw: pointer to the hardware structure
5715  * @vsi_handle: VSI handle to retrieve info from
5716  * @promisc_mask: pointer to mask to be filled in
5717  * @vid: VLAN ID of promisc VLAN VSI
5718  */
5719 enum ice_status
5720 ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5721                          u16 *vid)
5722 {
5723         return _ice_get_vsi_vlan_promisc(hw, vsi_handle, promisc_mask,
5724                                          vid, hw->switch_info);
5725 }
5726
5727 /**
5728  * ice_remove_promisc - Remove promisc based filter rules
5729  * @hw: pointer to the hardware structure
5730  * @recp_id: recipe ID for which the rule needs to removed
5731  * @v_list: list of promisc entries
5732  */
5733 static enum ice_status
5734 ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
5735                    struct LIST_HEAD_TYPE *v_list)
5736 {
5737         struct ice_fltr_list_entry *v_list_itr, *tmp;
5738         struct ice_sw_recipe *recp_list;
5739
5740         recp_list = &hw->switch_info->recp_list[recp_id];
5741         LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5742                                  list_entry) {
5743                 v_list_itr->status =
5744                         ice_remove_rule_internal(hw, recp_list, v_list_itr);
5745                 if (v_list_itr->status)
5746                         return v_list_itr->status;
5747         }
5748         return ICE_SUCCESS;
5749 }
5750
5751 /**
5752  * _ice_clear_vsi_promisc - clear specified promiscuous mode(s)
5753  * @hw: pointer to the hardware structure
5754  * @vsi_handle: VSI handle to clear mode
5755  * @promisc_mask: mask of promiscuous config bits to clear
5756  * @vid: VLAN ID to clear VLAN promiscuous
5757  * @sw: pointer to switch info struct for which function add rule
5758  */
5759 static enum ice_status
5760 _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5761                        u16 vid, struct ice_switch_info *sw)
5762 {
5763         struct ice_fltr_list_entry *fm_entry, *tmp;
5764         struct LIST_HEAD_TYPE remove_list_head;
5765         struct ice_fltr_mgmt_list_entry *itr;
5766         struct LIST_HEAD_TYPE *rule_head;
5767         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
5768         enum ice_status status = ICE_SUCCESS;
5769         u8 recipe_id;
5770
5771         if (!ice_is_vsi_valid(hw, vsi_handle))
5772                 return ICE_ERR_PARAM;
5773
5774         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
5775                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
5776         else
5777                 recipe_id = ICE_SW_LKUP_PROMISC;
5778
5779         rule_head = &sw->recp_list[recipe_id].filt_rules;
5780         rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
5781
5782         INIT_LIST_HEAD(&remove_list_head);
5783
5784         ice_acquire_lock(rule_lock);
5785         LIST_FOR_EACH_ENTRY(itr, rule_head,
5786                             ice_fltr_mgmt_list_entry, list_entry) {
5787                 struct ice_fltr_info *fltr_info;
5788                 u8 fltr_promisc_mask = 0;
5789
5790                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
5791                         continue;
5792                 fltr_info = &itr->fltr_info;
5793
5794                 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
5795                     vid != fltr_info->l_data.mac_vlan.vlan_id)
5796                         continue;
5797
5798                 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
5799
5800                 /* Skip if filter is not completely specified by given mask */
5801                 if (fltr_promisc_mask & ~promisc_mask)
5802                         continue;
5803
5804                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
5805                                                         &remove_list_head,
5806                                                         fltr_info);
5807                 if (status) {
5808                         ice_release_lock(rule_lock);
5809                         goto free_fltr_list;
5810                 }
5811         }
5812         ice_release_lock(rule_lock);
5813
5814         status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
5815
5816 free_fltr_list:
5817         LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
5818                                  ice_fltr_list_entry, list_entry) {
5819                 LIST_DEL(&fm_entry->list_entry);
5820                 ice_free(hw, fm_entry);
5821         }
5822
5823         return status;
5824 }
5825
5826 /**
5827  * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
5828  * @hw: pointer to the hardware structure
5829  * @vsi_handle: VSI handle to clear mode
5830  * @promisc_mask: mask of promiscuous config bits to clear
5831  * @vid: VLAN ID to clear VLAN promiscuous
5832  */
5833 enum ice_status
5834 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
5835                       u8 promisc_mask, u16 vid)
5836 {
5837         return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask,
5838                                       vid, hw->switch_info);
5839 }
5840
5841 /**
5842  * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
5843  * @hw: pointer to the hardware structure
5844  * @vsi_handle: VSI handle to configure
5845  * @promisc_mask: mask of promiscuous config bits
5846  * @vid: VLAN ID to set VLAN promiscuous
5847  * @lport: logical port number to configure promisc mode
5848  * @sw: pointer to switch info struct for which function add rule
5849  */
5850 static enum ice_status
5851 _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5852                      u16 vid, u8 lport, struct ice_switch_info *sw)
5853 {
5854         enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
5855         struct ice_fltr_list_entry f_list_entry;
5856         struct ice_fltr_info new_fltr;
5857         enum ice_status status = ICE_SUCCESS;
5858         bool is_tx_fltr;
5859         u16 hw_vsi_id;
5860         int pkt_type;
5861         u8 recipe_id;
5862
5863         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
5864
5865         if (!ice_is_vsi_valid(hw, vsi_handle))
5866                 return ICE_ERR_PARAM;
5867         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5868
5869         ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM);
5870
5871         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
5872                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
5873                 new_fltr.l_data.mac_vlan.vlan_id = vid;
5874                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
5875         } else {
5876                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
5877                 recipe_id = ICE_SW_LKUP_PROMISC;
5878         }
5879
5880         /* Separate filters must be set for each direction/packet type
5881          * combination, so we will loop over the mask value, store the
5882          * individual type, and clear it out in the input mask as it
5883          * is found.
5884          */
5885         while (promisc_mask) {
5886                 struct ice_sw_recipe *recp_list;
5887                 u8 *mac_addr;
5888
5889                 pkt_type = 0;
5890                 is_tx_fltr = false;
5891
5892                 if (promisc_mask & ICE_PROMISC_UCAST_RX) {
5893                         promisc_mask &= ~ICE_PROMISC_UCAST_RX;
5894                         pkt_type = UCAST_FLTR;
5895                 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
5896                         promisc_mask &= ~ICE_PROMISC_UCAST_TX;
5897                         pkt_type = UCAST_FLTR;
5898                         is_tx_fltr = true;
5899                 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
5900                         promisc_mask &= ~ICE_PROMISC_MCAST_RX;
5901                         pkt_type = MCAST_FLTR;
5902                 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
5903                         promisc_mask &= ~ICE_PROMISC_MCAST_TX;
5904                         pkt_type = MCAST_FLTR;
5905                         is_tx_fltr = true;
5906                 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
5907                         promisc_mask &= ~ICE_PROMISC_BCAST_RX;
5908                         pkt_type = BCAST_FLTR;
5909                 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
5910                         promisc_mask &= ~ICE_PROMISC_BCAST_TX;
5911                         pkt_type = BCAST_FLTR;
5912                         is_tx_fltr = true;
5913                 }
5914
5915                 /* Check for VLAN promiscuous flag */
5916                 if (promisc_mask & ICE_PROMISC_VLAN_RX) {
5917                         promisc_mask &= ~ICE_PROMISC_VLAN_RX;
5918                 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
5919                         promisc_mask &= ~ICE_PROMISC_VLAN_TX;
5920                         is_tx_fltr = true;
5921                 }
5922
5923                 /* Set filter DA based on packet type */
5924                 mac_addr = new_fltr.l_data.mac.mac_addr;
5925                 if (pkt_type == BCAST_FLTR) {
5926                         ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM);
5927                 } else if (pkt_type == MCAST_FLTR ||
5928                            pkt_type == UCAST_FLTR) {
5929                         /* Use the dummy ether header DA */
5930                         ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN,
5931                                    ICE_NONDMA_TO_NONDMA);
5932                         if (pkt_type == MCAST_FLTR)
5933                                 mac_addr[0] |= 0x1;     /* Set multicast bit */
5934                 }
5935
5936                 /* Need to reset this to zero for all iterations */
5937                 new_fltr.flag = 0;
5938                 if (is_tx_fltr) {
5939                         new_fltr.flag |= ICE_FLTR_TX;
5940                         new_fltr.src = hw_vsi_id;
5941                 } else {
5942                         new_fltr.flag |= ICE_FLTR_RX;
5943                         new_fltr.src = lport;
5944                 }
5945
5946                 new_fltr.fltr_act = ICE_FWD_TO_VSI;
5947                 new_fltr.vsi_handle = vsi_handle;
5948                 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
5949                 f_list_entry.fltr_info = new_fltr;
5950                 recp_list = &sw->recp_list[recipe_id];
5951
5952                 status = ice_add_rule_internal(hw, recp_list, lport,
5953                                                &f_list_entry);
5954                 if (status != ICE_SUCCESS)
5955                         goto set_promisc_exit;
5956         }
5957
5958 set_promisc_exit:
5959         return status;
5960 }
5961
5962 /**
5963  * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
5964  * @hw: pointer to the hardware structure
5965  * @vsi_handle: VSI handle to configure
5966  * @promisc_mask: mask of promiscuous config bits
5967  * @vid: VLAN ID to set VLAN promiscuous
5968  */
5969 enum ice_status
5970 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5971                     u16 vid)
5972 {
5973         return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid,
5974                                     hw->port_info->lport,
5975                                     hw->switch_info);
5976 }
5977
5978 /**
5979  * _ice_set_vlan_vsi_promisc
5980  * @hw: pointer to the hardware structure
5981  * @vsi_handle: VSI handle to configure
5982  * @promisc_mask: mask of promiscuous config bits
5983  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
5984  * @lport: logical port number to configure promisc mode
5985  * @sw: pointer to switch info struct for which function add rule
5986  *
5987  * Configure VSI with all associated VLANs to given promiscuous mode(s)
5988  */
5989 static enum ice_status
5990 _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5991                           bool rm_vlan_promisc, u8 lport,
5992                           struct ice_switch_info *sw)
5993 {
5994         struct ice_fltr_list_entry *list_itr, *tmp;
5995         struct LIST_HEAD_TYPE vsi_list_head;
5996         struct LIST_HEAD_TYPE *vlan_head;
5997         struct ice_lock *vlan_lock; /* Lock to protect filter rule list */
5998         enum ice_status status;
5999         u16 vlan_id;
6000
6001         INIT_LIST_HEAD(&vsi_list_head);
6002         vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
6003         vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
6004         ice_acquire_lock(vlan_lock);
6005         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
6006                                           &vsi_list_head);
6007         ice_release_lock(vlan_lock);
6008         if (status)
6009                 goto free_fltr_list;
6010
6011         LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry,
6012                             list_entry) {
6013                 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
6014                 if (rm_vlan_promisc)
6015                         status =  _ice_clear_vsi_promisc(hw, vsi_handle,
6016                                                          promisc_mask,
6017                                                          vlan_id, sw);
6018                 else
6019                         status =  _ice_set_vsi_promisc(hw, vsi_handle,
6020                                                        promisc_mask, vlan_id,
6021                                                        lport, sw);
6022                 if (status)
6023                         break;
6024         }
6025
6026 free_fltr_list:
6027         LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head,
6028                                  ice_fltr_list_entry, list_entry) {
6029                 LIST_DEL(&list_itr->list_entry);
6030                 ice_free(hw, list_itr);
6031         }
6032         return status;
6033 }
6034
6035 /**
6036  * ice_set_vlan_vsi_promisc
6037  * @hw: pointer to the hardware structure
6038  * @vsi_handle: VSI handle to configure
6039  * @promisc_mask: mask of promiscuous config bits
6040  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6041  *
6042  * Configure VSI with all associated VLANs to given promiscuous mode(s)
6043  */
6044 enum ice_status
6045 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6046                          bool rm_vlan_promisc)
6047 {
6048         return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask,
6049                                          rm_vlan_promisc, hw->port_info->lport,
6050                                          hw->switch_info);
6051 }
6052
6053 /**
6054  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
6055  * @hw: pointer to the hardware structure
6056  * @vsi_handle: VSI handle to remove filters from
6057  * @recp_list: recipe list from which function remove fltr
6058  * @lkup: switch rule filter lookup type
6059  */
6060 static void
6061 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
6062                          struct ice_sw_recipe *recp_list,
6063                          enum ice_sw_lkup_type lkup)
6064 {
6065         struct ice_fltr_list_entry *fm_entry;
6066         struct LIST_HEAD_TYPE remove_list_head;
6067         struct LIST_HEAD_TYPE *rule_head;
6068         struct ice_fltr_list_entry *tmp;
6069         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
6070         enum ice_status status;
6071
6072         INIT_LIST_HEAD(&remove_list_head);
6073         rule_lock = &recp_list[lkup].filt_rule_lock;
6074         rule_head = &recp_list[lkup].filt_rules;
6075         ice_acquire_lock(rule_lock);
6076         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
6077                                           &remove_list_head);
6078         ice_release_lock(rule_lock);
6079         if (status)
6080                 goto free_fltr_list;
6081
6082         switch (lkup) {
6083         case ICE_SW_LKUP_MAC:
6084                 ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]);
6085                 break;
6086         case ICE_SW_LKUP_VLAN:
6087                 ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]);
6088                 break;
6089         case ICE_SW_LKUP_PROMISC:
6090         case ICE_SW_LKUP_PROMISC_VLAN:
6091                 ice_remove_promisc(hw, lkup, &remove_list_head);
6092                 break;
6093         case ICE_SW_LKUP_MAC_VLAN:
6094                 ice_remove_mac_vlan(hw, &remove_list_head);
6095                 break;
6096         case ICE_SW_LKUP_ETHERTYPE:
6097         case ICE_SW_LKUP_ETHERTYPE_MAC:
6098                 ice_remove_eth_mac(hw, &remove_list_head);
6099                 break;
6100         case ICE_SW_LKUP_DFLT:
6101                 ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n");
6102                 break;
6103         case ICE_SW_LKUP_LAST:
6104                 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n");
6105                 break;
6106         }
6107
6108 free_fltr_list:
6109         LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
6110                                  ice_fltr_list_entry, list_entry) {
6111                 LIST_DEL(&fm_entry->list_entry);
6112                 ice_free(hw, fm_entry);
6113         }
6114 }
6115
6116 /**
6117  * ice_remove_vsi_fltr_rule - Remove all filters for a VSI
6118  * @hw: pointer to the hardware structure
6119  * @vsi_handle: VSI handle to remove filters from
6120  * @sw: pointer to switch info struct
6121  */
6122 static void
6123 ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle,
6124                          struct ice_switch_info *sw)
6125 {
6126         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6127
6128         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6129                                  sw->recp_list, ICE_SW_LKUP_MAC);
6130         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6131                                  sw->recp_list, ICE_SW_LKUP_MAC_VLAN);
6132         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6133                                  sw->recp_list, ICE_SW_LKUP_PROMISC);
6134         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6135                                  sw->recp_list, ICE_SW_LKUP_VLAN);
6136         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6137                                  sw->recp_list, ICE_SW_LKUP_DFLT);
6138         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6139                                  sw->recp_list, ICE_SW_LKUP_ETHERTYPE);
6140         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6141                                  sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC);
6142         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6143                                  sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN);
6144 }
6145
6146 /**
6147  * ice_remove_vsi_fltr - Remove all filters for a VSI
6148  * @hw: pointer to the hardware structure
6149  * @vsi_handle: VSI handle to remove filters from
6150  */
6151 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
6152 {
6153         ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info);
6154 }
6155
6156 /**
6157  * ice_alloc_res_cntr - allocating resource counter
6158  * @hw: pointer to the hardware structure
6159  * @type: type of resource
6160  * @alloc_shared: if set it is shared else dedicated
6161  * @num_items: number of entries requested for FD resource type
6162  * @counter_id: counter index returned by AQ call
6163  */
6164 enum ice_status
6165 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6166                    u16 *counter_id)
6167 {
6168         struct ice_aqc_alloc_free_res_elem *buf;
6169         enum ice_status status;
6170         u16 buf_len;
6171
6172         /* Allocate resource */
6173         buf_len = ice_struct_size(buf, elem, 1);
6174         buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6175         if (!buf)
6176                 return ICE_ERR_NO_MEMORY;
6177
6178         buf->num_elems = CPU_TO_LE16(num_items);
6179         buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6180                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
6181
6182         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6183                                        ice_aqc_opc_alloc_res, NULL);
6184         if (status)
6185                 goto exit;
6186
6187         *counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp);
6188
6189 exit:
6190         ice_free(hw, buf);
6191         return status;
6192 }
6193
6194 /**
6195  * ice_free_res_cntr - free resource counter
6196  * @hw: pointer to the hardware structure
6197  * @type: type of resource
6198  * @alloc_shared: if set it is shared else dedicated
6199  * @num_items: number of entries to be freed for FD resource type
6200  * @counter_id: counter ID resource which needs to be freed
6201  */
6202 enum ice_status
6203 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6204                   u16 counter_id)
6205 {
6206         struct ice_aqc_alloc_free_res_elem *buf;
6207         enum ice_status status;
6208         u16 buf_len;
6209
6210         /* Free resource */
6211         buf_len = ice_struct_size(buf, elem, 1);
6212         buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6213         if (!buf)
6214                 return ICE_ERR_NO_MEMORY;
6215
6216         buf->num_elems = CPU_TO_LE16(num_items);
6217         buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6218                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
6219         buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
6220
6221         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6222                                        ice_aqc_opc_free_res, NULL);
6223         if (status)
6224                 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
6225
6226         ice_free(hw, buf);
6227         return status;
6228 }
6229
6230 /**
6231  * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type
6232  * @hw: pointer to the hardware structure
6233  * @counter_id: returns counter index
6234  */
6235 enum ice_status ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id)
6236 {
6237         return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6238                                   ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6239                                   counter_id);
6240 }
6241
6242 /**
6243  * ice_free_vlan_res_counter - Free counter resource for VLAN type
6244  * @hw: pointer to the hardware structure
6245  * @counter_id: counter index to be freed
6246  */
6247 enum ice_status ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id)
6248 {
6249         return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6250                                  ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6251                                  counter_id);
6252 }
6253
6254 /**
6255  * ice_alloc_res_lg_act - add large action resource
6256  * @hw: pointer to the hardware structure
6257  * @l_id: large action ID to fill it in
6258  * @num_acts: number of actions to hold with a large action entry
6259  */
6260 static enum ice_status
6261 ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts)
6262 {
6263         struct ice_aqc_alloc_free_res_elem *sw_buf;
6264         enum ice_status status;
6265         u16 buf_len;
6266
6267         if (num_acts > ICE_MAX_LG_ACT || num_acts == 0)
6268                 return ICE_ERR_PARAM;
6269
6270         /* Allocate resource for large action */
6271         buf_len = ice_struct_size(sw_buf, elem, 1);
6272         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6273         if (!sw_buf)
6274                 return ICE_ERR_NO_MEMORY;
6275
6276         sw_buf->num_elems = CPU_TO_LE16(1);
6277
6278         /* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1.
6279          * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3.
6280          * If num_acts is greater than 2, then use
6281          * ICE_AQC_RES_TYPE_WIDE_TABLE_4.
6282          * The num_acts cannot exceed 4. This was ensured at the
6283          * beginning of the function.
6284          */
6285         if (num_acts == 1)
6286                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_1);
6287         else if (num_acts == 2)
6288                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_2);
6289         else
6290                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_4);
6291
6292         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
6293                                        ice_aqc_opc_alloc_res, NULL);
6294         if (!status)
6295                 *l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
6296
6297         ice_free(hw, sw_buf);
6298         return status;
6299 }
6300
6301 /**
6302  * ice_add_mac_with_sw_marker - add filter with sw marker
6303  * @hw: pointer to the hardware structure
6304  * @f_info: filter info structure containing the MAC filter information
6305  * @sw_marker: sw marker to tag the Rx descriptor with
6306  */
6307 enum ice_status
6308 ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info,
6309                            u16 sw_marker)
6310 {
6311         struct ice_fltr_mgmt_list_entry *m_entry;
6312         struct ice_fltr_list_entry fl_info;
6313         struct ice_sw_recipe *recp_list;
6314         struct LIST_HEAD_TYPE l_head;
6315         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
6316         enum ice_status ret;
6317         bool entry_exists;
6318         u16 lg_act_id;
6319
6320         if (f_info->fltr_act != ICE_FWD_TO_VSI)
6321                 return ICE_ERR_PARAM;
6322
6323         if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6324                 return ICE_ERR_PARAM;
6325
6326         if (sw_marker == ICE_INVAL_SW_MARKER_ID)
6327                 return ICE_ERR_PARAM;
6328
6329         if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6330                 return ICE_ERR_PARAM;
6331         f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6332
6333         /* Add filter if it doesn't exist so then the adding of large
6334          * action always results in update
6335          */
6336
6337         INIT_LIST_HEAD(&l_head);
6338         fl_info.fltr_info = *f_info;
6339         LIST_ADD(&fl_info.list_entry, &l_head);
6340
6341         entry_exists = false;
6342         ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6343                                hw->port_info->lport);
6344         if (ret == ICE_ERR_ALREADY_EXISTS)
6345                 entry_exists = true;
6346         else if (ret)
6347                 return ret;
6348
6349         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6350         rule_lock = &recp_list->filt_rule_lock;
6351         ice_acquire_lock(rule_lock);
6352         /* Get the book keeping entry for the filter */
6353         m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6354         if (!m_entry)
6355                 goto exit_error;
6356
6357         /* If counter action was enabled for this rule then don't enable
6358          * sw marker large action
6359          */
6360         if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6361                 ret = ICE_ERR_PARAM;
6362                 goto exit_error;
6363         }
6364
6365         /* if same marker was added before */
6366         if (m_entry->sw_marker_id == sw_marker) {
6367                 ret = ICE_ERR_ALREADY_EXISTS;
6368                 goto exit_error;
6369         }
6370
6371         /* Allocate a hardware table entry to hold large act. Three actions
6372          * for marker based large action
6373          */
6374         ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3);
6375         if (ret)
6376                 goto exit_error;
6377
6378         if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6379                 goto exit_error;
6380
6381         /* Update the switch rule to add the marker action */
6382         ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id);
6383         if (!ret) {
6384                 ice_release_lock(rule_lock);
6385                 return ret;
6386         }
6387
6388 exit_error:
6389         ice_release_lock(rule_lock);
6390         /* only remove entry if it did not exist previously */
6391         if (!entry_exists)
6392                 ret = ice_remove_mac(hw, &l_head);
6393
6394         return ret;
6395 }
6396
6397 /**
6398  * ice_add_mac_with_counter - add filter with counter enabled
6399  * @hw: pointer to the hardware structure
6400  * @f_info: pointer to filter info structure containing the MAC filter
6401  *          information
6402  */
6403 enum ice_status
6404 ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info)
6405 {
6406         struct ice_fltr_mgmt_list_entry *m_entry;
6407         struct ice_fltr_list_entry fl_info;
6408         struct ice_sw_recipe *recp_list;
6409         struct LIST_HEAD_TYPE l_head;
6410         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
6411         enum ice_status ret;
6412         bool entry_exist;
6413         u16 counter_id;
6414         u16 lg_act_id;
6415
6416         if (f_info->fltr_act != ICE_FWD_TO_VSI)
6417                 return ICE_ERR_PARAM;
6418
6419         if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6420                 return ICE_ERR_PARAM;
6421
6422         if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6423                 return ICE_ERR_PARAM;
6424         f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6425         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6426
6427         entry_exist = false;
6428
6429         rule_lock = &recp_list->filt_rule_lock;
6430
6431         /* Add filter if it doesn't exist so then the adding of large
6432          * action always results in update
6433          */
6434         INIT_LIST_HEAD(&l_head);
6435
6436         fl_info.fltr_info = *f_info;
6437         LIST_ADD(&fl_info.list_entry, &l_head);
6438
6439         ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6440                                hw->port_info->lport);
6441         if (ret == ICE_ERR_ALREADY_EXISTS)
6442                 entry_exist = true;
6443         else if (ret)
6444                 return ret;
6445
6446         ice_acquire_lock(rule_lock);
6447         m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6448         if (!m_entry) {
6449                 ret = ICE_ERR_BAD_PTR;
6450                 goto exit_error;
6451         }
6452
6453         /* Don't enable counter for a filter for which sw marker was enabled */
6454         if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) {
6455                 ret = ICE_ERR_PARAM;
6456                 goto exit_error;
6457         }
6458
6459         /* If a counter was already enabled then don't need to add again */
6460         if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6461                 ret = ICE_ERR_ALREADY_EXISTS;
6462                 goto exit_error;
6463         }
6464
6465         /* Allocate a hardware table entry to VLAN counter */
6466         ret = ice_alloc_vlan_res_counter(hw, &counter_id);
6467         if (ret)
6468                 goto exit_error;
6469
6470         /* Allocate a hardware table entry to hold large act. Two actions for
6471          * counter based large action
6472          */
6473         ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2);
6474         if (ret)
6475                 goto exit_error;
6476
6477         if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6478                 goto exit_error;
6479
6480         /* Update the switch rule to add the counter action */
6481         ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id);
6482         if (!ret) {
6483                 ice_release_lock(rule_lock);
6484                 return ret;
6485         }
6486
6487 exit_error:
6488         ice_release_lock(rule_lock);
6489         /* only remove entry if it did not exist previously */
6490         if (!entry_exist)
6491                 ret = ice_remove_mac(hw, &l_head);
6492
6493         return ret;
6494 }
6495
6496 /* This is mapping table entry that maps every word within a given protocol
6497  * structure to the real byte offset as per the specification of that
6498  * protocol header.
6499  * for example dst address is 3 words in ethertype header and corresponding
6500  * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
6501  * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
6502  * matching entry describing its field. This needs to be updated if new
6503  * structure is added to that union.
6504  */
6505 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
6506         { ICE_MAC_OFOS,         { 0, 2, 4, 6, 8, 10, 12 } },
6507         { ICE_MAC_IL,           { 0, 2, 4, 6, 8, 10, 12 } },
6508         { ICE_ETYPE_OL,         { 0 } },
6509         { ICE_VLAN_OFOS,        { 0, 2 } },
6510         { ICE_IPV4_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6511         { ICE_IPV4_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6512         { ICE_IPV6_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6513                                  26, 28, 30, 32, 34, 36, 38 } },
6514         { ICE_IPV6_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6515                                  26, 28, 30, 32, 34, 36, 38 } },
6516         { ICE_TCP_IL,           { 0, 2 } },
6517         { ICE_UDP_OF,           { 0, 2 } },
6518         { ICE_UDP_ILOS,         { 0, 2 } },
6519         { ICE_SCTP_IL,          { 0, 2 } },
6520         { ICE_VXLAN,            { 8, 10, 12, 14 } },
6521         { ICE_GENEVE,           { 8, 10, 12, 14 } },
6522         { ICE_VXLAN_GPE,        { 8, 10, 12, 14 } },
6523         { ICE_NVGRE,            { 0, 2, 4, 6 } },
6524         { ICE_GTP,              { 8, 10, 12, 14, 16, 18, 20 } },
6525         { ICE_PPPOE,            { 0, 2, 4, 6 } },
6526         { ICE_PFCP,             { 8, 10, 12, 14, 16, 18, 20, 22 } },
6527         { ICE_L2TPV3,           { 0, 2, 4, 6, 8, 10 } },
6528         { ICE_ESP,              { 0, 2, 4, 6 } },
6529         { ICE_AH,               { 0, 2, 4, 6, 8, 10 } },
6530         { ICE_NAT_T,            { 8, 10, 12, 14 } },
6531         { ICE_GTP_NO_PAY,       { 8, 10, 12, 14 } },
6532         { ICE_VLAN_EX,          { 0, 2 } },
6533         { ICE_VLAN_IN,          { 0, 2 } },
6534 };
6535
6536 /* The following table describes preferred grouping of recipes.
6537  * If a recipe that needs to be programmed is a superset or matches one of the
6538  * following combinations, then the recipe needs to be chained as per the
6539  * following policy.
6540  */
6541
6542 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
6543         { ICE_MAC_OFOS,         ICE_MAC_OFOS_HW },
6544         { ICE_MAC_IL,           ICE_MAC_IL_HW },
6545         { ICE_ETYPE_OL,         ICE_ETYPE_OL_HW },
6546         { ICE_VLAN_OFOS,        ICE_VLAN_OL_HW },
6547         { ICE_IPV4_OFOS,        ICE_IPV4_OFOS_HW },
6548         { ICE_IPV4_IL,          ICE_IPV4_IL_HW },
6549         { ICE_IPV6_OFOS,        ICE_IPV6_OFOS_HW },
6550         { ICE_IPV6_IL,          ICE_IPV6_IL_HW },
6551         { ICE_TCP_IL,           ICE_TCP_IL_HW },
6552         { ICE_UDP_OF,           ICE_UDP_OF_HW },
6553         { ICE_UDP_ILOS,         ICE_UDP_ILOS_HW },
6554         { ICE_SCTP_IL,          ICE_SCTP_IL_HW },
6555         { ICE_VXLAN,            ICE_UDP_OF_HW },
6556         { ICE_GENEVE,           ICE_UDP_OF_HW },
6557         { ICE_VXLAN_GPE,        ICE_UDP_OF_HW },
6558         { ICE_NVGRE,            ICE_GRE_OF_HW },
6559         { ICE_GTP,              ICE_UDP_OF_HW },
6560         { ICE_PPPOE,            ICE_PPPOE_HW },
6561         { ICE_PFCP,             ICE_UDP_ILOS_HW },
6562         { ICE_L2TPV3,           ICE_L2TPV3_HW },
6563         { ICE_ESP,              ICE_ESP_HW },
6564         { ICE_AH,               ICE_AH_HW },
6565         { ICE_NAT_T,            ICE_UDP_ILOS_HW },
6566         { ICE_GTP_NO_PAY,       ICE_UDP_ILOS_HW },
6567         { ICE_VLAN_EX,          ICE_VLAN_OF_HW },
6568         { ICE_VLAN_IN,          ICE_VLAN_OL_HW },
6569 };
6570
6571 /**
6572  * ice_find_recp - find a recipe
6573  * @hw: pointer to the hardware structure
6574  * @lkup_exts: extension sequence to match
6575  *
6576  * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
6577  */
6578 static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
6579                          enum ice_sw_tunnel_type tun_type, u32 priority)
6580 {
6581         bool refresh_required = true;
6582         struct ice_sw_recipe *recp;
6583         u8 i;
6584
6585         /* Walk through existing recipes to find a match */
6586         recp = hw->switch_info->recp_list;
6587         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6588                 /* If recipe was not created for this ID, in SW bookkeeping,
6589                  * check if FW has an entry for this recipe. If the FW has an
6590                  * entry update it in our SW bookkeeping and continue with the
6591                  * matching.
6592                  */
6593                 if (!recp[i].recp_created)
6594                         if (ice_get_recp_frm_fw(hw,
6595                                                 hw->switch_info->recp_list, i,
6596                                                 &refresh_required))
6597                                 continue;
6598
6599                 /* Skip inverse action recipes */
6600                 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
6601                     ICE_AQ_RECIPE_ACT_INV_ACT)
6602                         continue;
6603
6604                 /* if number of words we are looking for match */
6605                 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
6606                         struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
6607                         struct ice_fv_word *be = lkup_exts->fv_words;
6608                         u16 *cr = recp[i].lkup_exts.field_mask;
6609                         u16 *de = lkup_exts->field_mask;
6610                         bool found = true;
6611                         u8 pe, qr;
6612
6613                         /* ar, cr, and qr are related to the recipe words, while
6614                          * be, de, and pe are related to the lookup words
6615                          */
6616                         for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
6617                                 for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
6618                                      qr++) {
6619                                         if (ar[qr].off == be[pe].off &&
6620                                             ar[qr].prot_id == be[pe].prot_id &&
6621                                             cr[qr] == de[pe])
6622                                                 /* Found the "pe"th word in the
6623                                                  * given recipe
6624                                                  */
6625                                                 break;
6626                                 }
6627                                 /* After walking through all the words in the
6628                                  * "i"th recipe if "p"th word was not found then
6629                                  * this recipe is not what we are looking for.
6630                                  * So break out from this loop and try the next
6631                                  * recipe
6632                                  */
6633                                 if (qr >= recp[i].lkup_exts.n_val_words) {
6634                                         found = false;
6635                                         break;
6636                                 }
6637                         }
6638                         /* If for "i"th recipe the found was never set to false
6639                          * then it means we found our match
6640                          */
6641                         if (tun_type == recp[i].tun_type && found &&
6642                             priority == recp[i].priority)
6643                                 return i; /* Return the recipe ID */
6644                 }
6645         }
6646         return ICE_MAX_NUM_RECIPES;
6647 }
6648
6649 /**
6650  * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
6651  *
6652  * As protocol id for outer vlan is different in dvm and svm, if dvm is
6653  * supported protocol array record for outer vlan has to be modified to
6654  * reflect the value proper for DVM.
6655  */
6656 void ice_change_proto_id_to_dvm(void)
6657 {
6658         u8 i;
6659
6660         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
6661                 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
6662                     ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
6663                         ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
6664 }
6665
6666 /**
6667  * ice_prot_type_to_id - get protocol ID from protocol type
6668  * @type: protocol type
6669  * @id: pointer to variable that will receive the ID
6670  *
6671  * Returns true if found, false otherwise
6672  */
6673 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
6674 {
6675         u8 i;
6676
6677         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
6678                 if (ice_prot_id_tbl[i].type == type) {
6679                         *id = ice_prot_id_tbl[i].protocol_id;
6680                         return true;
6681                 }
6682         return false;
6683 }
6684
6685 /**
6686  * ice_fill_valid_words - count valid words
6687  * @rule: advanced rule with lookup information
6688  * @lkup_exts: byte offset extractions of the words that are valid
6689  *
6690  * calculate valid words in a lookup rule using mask value
6691  */
6692 static u8
6693 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
6694                      struct ice_prot_lkup_ext *lkup_exts)
6695 {
6696         u8 j, word, prot_id, ret_val;
6697
6698         if (!ice_prot_type_to_id(rule->type, &prot_id))
6699                 return 0;
6700
6701         word = lkup_exts->n_val_words;
6702
6703         for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
6704                 if (((u16 *)&rule->m_u)[j] &&
6705                     (size_t)rule->type < ARRAY_SIZE(ice_prot_ext)) {
6706                         /* No more space to accommodate */
6707                         if (word >= ICE_MAX_CHAIN_WORDS)
6708                                 return 0;
6709                         lkup_exts->fv_words[word].off =
6710                                 ice_prot_ext[rule->type].offs[j];
6711                         lkup_exts->fv_words[word].prot_id =
6712                                 ice_prot_id_tbl[rule->type].protocol_id;
6713                         lkup_exts->field_mask[word] =
6714                                 BE16_TO_CPU(((_FORCE_ __be16 *)&rule->m_u)[j]);
6715                         word++;
6716                 }
6717
6718         ret_val = word - lkup_exts->n_val_words;
6719         lkup_exts->n_val_words = word;
6720
6721         return ret_val;
6722 }
6723
6724 /**
6725  * ice_create_first_fit_recp_def - Create a recipe grouping
6726  * @hw: pointer to the hardware structure
6727  * @lkup_exts: an array of protocol header extractions
6728  * @rg_list: pointer to a list that stores new recipe groups
6729  * @recp_cnt: pointer to a variable that stores returned number of recipe groups
6730  *
6731  * Using first fit algorithm, take all the words that are still not done
6732  * and start grouping them in 4-word groups. Each group makes up one
6733  * recipe.
6734  */
6735 static enum ice_status
6736 ice_create_first_fit_recp_def(struct ice_hw *hw,
6737                               struct ice_prot_lkup_ext *lkup_exts,
6738                               struct LIST_HEAD_TYPE *rg_list,
6739                               u8 *recp_cnt)
6740 {
6741         struct ice_pref_recipe_group *grp = NULL;
6742         u8 j;
6743
6744         *recp_cnt = 0;
6745
6746         if (!lkup_exts->n_val_words) {
6747                 struct ice_recp_grp_entry *entry;
6748
6749                 entry = (struct ice_recp_grp_entry *)
6750                         ice_malloc(hw, sizeof(*entry));
6751                 if (!entry)
6752                         return ICE_ERR_NO_MEMORY;
6753                 LIST_ADD(&entry->l_entry, rg_list);
6754                 grp = &entry->r_group;
6755                 (*recp_cnt)++;
6756                 grp->n_val_pairs = 0;
6757         }
6758
6759         /* Walk through every word in the rule to check if it is not done. If so
6760          * then this word needs to be part of a new recipe.
6761          */
6762         for (j = 0; j < lkup_exts->n_val_words; j++)
6763                 if (!ice_is_bit_set(lkup_exts->done, j)) {
6764                         if (!grp ||
6765                             grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
6766                                 struct ice_recp_grp_entry *entry;
6767
6768                                 entry = (struct ice_recp_grp_entry *)
6769                                         ice_malloc(hw, sizeof(*entry));
6770                                 if (!entry)
6771                                         return ICE_ERR_NO_MEMORY;
6772                                 LIST_ADD(&entry->l_entry, rg_list);
6773                                 grp = &entry->r_group;
6774                                 (*recp_cnt)++;
6775                         }
6776
6777                         grp->pairs[grp->n_val_pairs].prot_id =
6778                                 lkup_exts->fv_words[j].prot_id;
6779                         grp->pairs[grp->n_val_pairs].off =
6780                                 lkup_exts->fv_words[j].off;
6781                         grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
6782                         grp->n_val_pairs++;
6783                 }
6784
6785         return ICE_SUCCESS;
6786 }
6787
6788 /**
6789  * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
6790  * @hw: pointer to the hardware structure
6791  * @fv_list: field vector with the extraction sequence information
6792  * @rg_list: recipe groupings with protocol-offset pairs
6793  *
6794  * Helper function to fill in the field vector indices for protocol-offset
6795  * pairs. These indexes are then ultimately programmed into a recipe.
6796  */
6797 static enum ice_status
6798 ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,
6799                        struct LIST_HEAD_TYPE *rg_list)
6800 {
6801         struct ice_sw_fv_list_entry *fv;
6802         struct ice_recp_grp_entry *rg;
6803         struct ice_fv_word *fv_ext;
6804
6805         if (LIST_EMPTY(fv_list))
6806                 return ICE_SUCCESS;
6807
6808         fv = LIST_FIRST_ENTRY(fv_list, struct ice_sw_fv_list_entry, list_entry);
6809         fv_ext = fv->fv_ptr->ew;
6810
6811         LIST_FOR_EACH_ENTRY(rg, rg_list, ice_recp_grp_entry, l_entry) {
6812                 u8 i;
6813
6814                 for (i = 0; i < rg->r_group.n_val_pairs; i++) {
6815                         struct ice_fv_word *pr;
6816                         bool found = false;
6817                         u16 mask;
6818                         u8 j;
6819
6820                         pr = &rg->r_group.pairs[i];
6821                         mask = rg->r_group.mask[i];
6822
6823                         for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
6824                                 if (fv_ext[j].prot_id == pr->prot_id &&
6825                                     fv_ext[j].off == pr->off) {
6826                                         found = true;
6827
6828                                         /* Store index of field vector */
6829                                         rg->fv_idx[i] = j;
6830                                         rg->fv_mask[i] = mask;
6831                                         break;
6832                                 }
6833
6834                         /* Protocol/offset could not be found, caller gave an
6835                          * invalid pair
6836                          */
6837                         if (!found)
6838                                 return ICE_ERR_PARAM;
6839                 }
6840         }
6841
6842         return ICE_SUCCESS;
6843 }
6844
6845 /**
6846  * ice_find_free_recp_res_idx - find free result indexes for recipe
6847  * @hw: pointer to hardware structure
6848  * @profiles: bitmap of profiles that will be associated with the new recipe
6849  * @free_idx: pointer to variable to receive the free index bitmap
6850  *
6851  * The algorithm used here is:
6852  *      1. When creating a new recipe, create a set P which contains all
6853  *         Profiles that will be associated with our new recipe
6854  *
6855  *      2. For each Profile p in set P:
6856  *          a. Add all recipes associated with Profile p into set R
6857  *          b. Optional : PossibleIndexes &= profile[p].possibleIndexes
6858  *              [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
6859  *              i. Or just assume they all have the same possible indexes:
6860  *                      44, 45, 46, 47
6861  *                      i.e., PossibleIndexes = 0x0000F00000000000
6862  *
6863  *      3. For each Recipe r in set R:
6864  *          a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
6865  *          b. FreeIndexes = UsedIndexes ^ PossibleIndexes
6866  *
6867  *      FreeIndexes will contain the bits indicating the indexes free for use,
6868  *      then the code needs to update the recipe[r].used_result_idx_bits to
6869  *      indicate which indexes were selected for use by this recipe.
6870  */
6871 static u16
6872 ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles,
6873                            ice_bitmap_t *free_idx)
6874 {
6875         ice_declare_bitmap(possible_idx, ICE_MAX_FV_WORDS);
6876         ice_declare_bitmap(recipes, ICE_MAX_NUM_RECIPES);
6877         ice_declare_bitmap(used_idx, ICE_MAX_FV_WORDS);
6878         u16 bit;
6879
6880         ice_zero_bitmap(possible_idx, ICE_MAX_FV_WORDS);
6881         ice_zero_bitmap(recipes, ICE_MAX_NUM_RECIPES);
6882         ice_zero_bitmap(used_idx, ICE_MAX_FV_WORDS);
6883         ice_zero_bitmap(free_idx, ICE_MAX_FV_WORDS);
6884
6885         ice_bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);
6886
6887         /* For each profile we are going to associate the recipe with, add the
6888          * recipes that are associated with that profile. This will give us
6889          * the set of recipes that our recipe may collide with. Also, determine
6890          * what possible result indexes are usable given this set of profiles.
6891          */
6892         ice_for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
6893                 ice_or_bitmap(recipes, recipes, profile_to_recipe[bit],
6894                               ICE_MAX_NUM_RECIPES);
6895                 ice_and_bitmap(possible_idx, possible_idx,
6896                                hw->switch_info->prof_res_bm[bit],
6897                                ICE_MAX_FV_WORDS);
6898         }
6899
6900         /* For each recipe that our new recipe may collide with, determine
6901          * which indexes have been used.
6902          */
6903         ice_for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
6904                 ice_or_bitmap(used_idx, used_idx,
6905                               hw->switch_info->recp_list[bit].res_idxs,
6906                               ICE_MAX_FV_WORDS);
6907
6908         ice_xor_bitmap(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
6909
6910         /* return number of free indexes */
6911         return (u16)ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS);
6912 }
6913
6914 /**
6915  * ice_add_sw_recipe - function to call AQ calls to create switch recipe
6916  * @hw: pointer to hardware structure
6917  * @rm: recipe management list entry
6918  * @profiles: bitmap of profiles that will be associated.
6919  */
6920 static enum ice_status
6921 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
6922                   ice_bitmap_t *profiles)
6923 {
6924         ice_declare_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
6925         struct ice_aqc_recipe_data_elem *tmp;
6926         struct ice_aqc_recipe_data_elem *buf;
6927         struct ice_recp_grp_entry *entry;
6928         enum ice_status status;
6929         u16 free_res_idx;
6930         u16 recipe_count;
6931         u8 chain_idx;
6932         u8 recps = 0;
6933
6934         /* When more than one recipe are required, another recipe is needed to
6935          * chain them together. Matching a tunnel metadata ID takes up one of
6936          * the match fields in the chaining recipe reducing the number of
6937          * chained recipes by one.
6938          */
6939          /* check number of free result indices */
6940         ice_zero_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
6941         free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
6942
6943         ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
6944                   free_res_idx, rm->n_grp_count);
6945
6946         if (rm->n_grp_count > 1) {
6947                 if (rm->n_grp_count > free_res_idx)
6948                         return ICE_ERR_MAX_LIMIT;
6949
6950                 rm->n_grp_count++;
6951         }
6952
6953         if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
6954                 return ICE_ERR_MAX_LIMIT;
6955
6956         tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
6957                                                             ICE_MAX_NUM_RECIPES,
6958                                                             sizeof(*tmp));
6959         if (!tmp)
6960                 return ICE_ERR_NO_MEMORY;
6961
6962         buf = (struct ice_aqc_recipe_data_elem *)
6963                 ice_calloc(hw, rm->n_grp_count, sizeof(*buf));
6964         if (!buf) {
6965                 status = ICE_ERR_NO_MEMORY;
6966                 goto err_mem;
6967         }
6968
6969         ice_zero_bitmap(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
6970         recipe_count = ICE_MAX_NUM_RECIPES;
6971         status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
6972                                    NULL);
6973         if (status || recipe_count == 0)
6974                 goto err_unroll;
6975
6976         /* Allocate the recipe resources, and configure them according to the
6977          * match fields from protocol headers and extracted field vectors.
6978          */
6979         chain_idx = ice_find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
6980         LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
6981                 u8 i;
6982
6983                 status = ice_alloc_recipe(hw, &entry->rid);
6984                 if (status)
6985                         goto err_unroll;
6986
6987                 /* Clear the result index of the located recipe, as this will be
6988                  * updated, if needed, later in the recipe creation process.
6989                  */
6990                 tmp[0].content.result_indx = 0;
6991
6992                 buf[recps] = tmp[0];
6993                 buf[recps].recipe_indx = (u8)entry->rid;
6994                 /* if the recipe is a non-root recipe RID should be programmed
6995                  * as 0 for the rules to be applied correctly.
6996                  */
6997                 buf[recps].content.rid = 0;
6998                 ice_memset(&buf[recps].content.lkup_indx, 0,
6999                            sizeof(buf[recps].content.lkup_indx),
7000                            ICE_NONDMA_MEM);
7001
7002                 /* All recipes use look-up index 0 to match switch ID. */
7003                 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7004                 buf[recps].content.mask[0] =
7005                         CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7006                 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
7007                  * to be 0
7008                  */
7009                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7010                         buf[recps].content.lkup_indx[i] = 0x80;
7011                         buf[recps].content.mask[i] = 0;
7012                 }
7013
7014                 for (i = 0; i < entry->r_group.n_val_pairs; i++) {
7015                         buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
7016                         buf[recps].content.mask[i + 1] =
7017                                 CPU_TO_LE16(entry->fv_mask[i]);
7018                 }
7019
7020                 if (rm->n_grp_count > 1) {
7021                         /* Checks to see if there really is a valid result index
7022                          * that can be used.
7023                          */
7024                         if (chain_idx >= ICE_MAX_FV_WORDS) {
7025                                 ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
7026                                 status = ICE_ERR_MAX_LIMIT;
7027                                 goto err_unroll;
7028                         }
7029
7030                         entry->chain_idx = chain_idx;
7031                         buf[recps].content.result_indx =
7032                                 ICE_AQ_RECIPE_RESULT_EN |
7033                                 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
7034                                  ICE_AQ_RECIPE_RESULT_DATA_M);
7035                         ice_clear_bit(chain_idx, result_idx_bm);
7036                         chain_idx = ice_find_first_bit(result_idx_bm,
7037                                                        ICE_MAX_FV_WORDS);
7038                 }
7039
7040                 /* fill recipe dependencies */
7041                 ice_zero_bitmap((ice_bitmap_t *)buf[recps].recipe_bitmap,
7042                                 ICE_MAX_NUM_RECIPES);
7043                 ice_set_bit(buf[recps].recipe_indx,
7044                             (ice_bitmap_t *)buf[recps].recipe_bitmap);
7045                 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7046                 recps++;
7047         }
7048
7049         if (rm->n_grp_count == 1) {
7050                 rm->root_rid = buf[0].recipe_indx;
7051                 ice_set_bit(buf[0].recipe_indx, rm->r_bitmap);
7052                 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
7053                 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
7054                         ice_memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
7055                                    sizeof(buf[0].recipe_bitmap),
7056                                    ICE_NONDMA_TO_NONDMA);
7057                 } else {
7058                         status = ICE_ERR_BAD_PTR;
7059                         goto err_unroll;
7060                 }
7061                 /* Applicable only for ROOT_RECIPE, set the fwd_priority for
7062                  * the recipe which is getting created if specified
7063                  * by user. Usually any advanced switch filter, which results
7064                  * into new extraction sequence, ended up creating a new recipe
7065                  * of type ROOT and usually recipes are associated with profiles
7066                  * Switch rule referreing newly created recipe, needs to have
7067                  * either/or 'fwd' or 'join' priority, otherwise switch rule
7068                  * evaluation will not happen correctly. In other words, if
7069                  * switch rule to be evaluated on priority basis, then recipe
7070                  * needs to have priority, otherwise it will be evaluated last.
7071                  */
7072                 buf[0].content.act_ctrl_fwd_priority = rm->priority;
7073         } else {
7074                 struct ice_recp_grp_entry *last_chain_entry;
7075                 u16 rid, i;
7076
7077                 /* Allocate the last recipe that will chain the outcomes of the
7078                  * other recipes together
7079                  */
7080                 status = ice_alloc_recipe(hw, &rid);
7081                 if (status)
7082                         goto err_unroll;
7083
7084                 buf[recps].recipe_indx = (u8)rid;
7085                 buf[recps].content.rid = (u8)rid;
7086                 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
7087                 /* the new entry created should also be part of rg_list to
7088                  * make sure we have complete recipe
7089                  */
7090                 last_chain_entry = (struct ice_recp_grp_entry *)ice_malloc(hw,
7091                         sizeof(*last_chain_entry));
7092                 if (!last_chain_entry) {
7093                         status = ICE_ERR_NO_MEMORY;
7094                         goto err_unroll;
7095                 }
7096                 last_chain_entry->rid = rid;
7097                 ice_memset(&buf[recps].content.lkup_indx, 0,
7098                            sizeof(buf[recps].content.lkup_indx),
7099                            ICE_NONDMA_MEM);
7100                 /* All recipes use look-up index 0 to match switch ID. */
7101                 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7102                 buf[recps].content.mask[0] =
7103                         CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7104                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7105                         buf[recps].content.lkup_indx[i] =
7106                                 ICE_AQ_RECIPE_LKUP_IGNORE;
7107                         buf[recps].content.mask[i] = 0;
7108                 }
7109
7110                 i = 1;
7111                 /* update r_bitmap with the recp that is used for chaining */
7112                 ice_set_bit(rid, rm->r_bitmap);
7113                 /* this is the recipe that chains all the other recipes so it
7114                  * should not have a chaining ID to indicate the same
7115                  */
7116                 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
7117                 LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry,
7118                                     l_entry) {
7119                         last_chain_entry->fv_idx[i] = entry->chain_idx;
7120                         buf[recps].content.lkup_indx[i] = entry->chain_idx;
7121                         buf[recps].content.mask[i++] = CPU_TO_LE16(0xFFFF);
7122                         ice_set_bit(entry->rid, rm->r_bitmap);
7123                 }
7124                 LIST_ADD(&last_chain_entry->l_entry, &rm->rg_list);
7125                 if (sizeof(buf[recps].recipe_bitmap) >=
7126                     sizeof(rm->r_bitmap)) {
7127                         ice_memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
7128                                    sizeof(buf[recps].recipe_bitmap),
7129                                    ICE_NONDMA_TO_NONDMA);
7130                 } else {
7131                         status = ICE_ERR_BAD_PTR;
7132                         goto err_unroll;
7133                 }
7134                 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7135
7136                 recps++;
7137                 rm->root_rid = (u8)rid;
7138         }
7139         status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7140         if (status)
7141                 goto err_unroll;
7142
7143         status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
7144         ice_release_change_lock(hw);
7145         if (status)
7146                 goto err_unroll;
7147
7148         /* Every recipe that just got created add it to the recipe
7149          * book keeping list
7150          */
7151         LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7152                 struct ice_switch_info *sw = hw->switch_info;
7153                 bool is_root, idx_found = false;
7154                 struct ice_sw_recipe *recp;
7155                 u16 idx, buf_idx = 0;
7156
7157                 /* find buffer index for copying some data */
7158                 for (idx = 0; idx < rm->n_grp_count; idx++)
7159                         if (buf[idx].recipe_indx == entry->rid) {
7160                                 buf_idx = idx;
7161                                 idx_found = true;
7162                         }
7163
7164                 if (!idx_found) {
7165                         status = ICE_ERR_OUT_OF_RANGE;
7166                         goto err_unroll;
7167                 }
7168
7169                 recp = &sw->recp_list[entry->rid];
7170                 is_root = (rm->root_rid == entry->rid);
7171                 recp->is_root = is_root;
7172
7173                 recp->root_rid = entry->rid;
7174                 recp->big_recp = (is_root && rm->n_grp_count > 1);
7175
7176                 ice_memcpy(&recp->ext_words, entry->r_group.pairs,
7177                            entry->r_group.n_val_pairs *
7178                            sizeof(struct ice_fv_word),
7179                            ICE_NONDMA_TO_NONDMA);
7180
7181                 ice_memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
7182                            sizeof(recp->r_bitmap), ICE_NONDMA_TO_NONDMA);
7183
7184                 /* Copy non-result fv index values and masks to recipe. This
7185                  * call will also update the result recipe bitmask.
7186                  */
7187                 ice_collect_result_idx(&buf[buf_idx], recp);
7188
7189                 /* for non-root recipes, also copy to the root, this allows
7190                  * easier matching of a complete chained recipe
7191                  */
7192                 if (!is_root)
7193                         ice_collect_result_idx(&buf[buf_idx],
7194                                                &sw->recp_list[rm->root_rid]);
7195
7196                 recp->n_ext_words = entry->r_group.n_val_pairs;
7197                 recp->chain_idx = entry->chain_idx;
7198                 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
7199                 recp->n_grp_count = rm->n_grp_count;
7200                 recp->tun_type = rm->tun_type;
7201                 recp->recp_created = true;
7202         }
7203         rm->root_buf = buf;
7204         ice_free(hw, tmp);
7205         return status;
7206
7207 err_unroll:
7208 err_mem:
7209         ice_free(hw, tmp);
7210         ice_free(hw, buf);
7211         return status;
7212 }
7213
7214 /**
7215  * ice_create_recipe_group - creates recipe group
7216  * @hw: pointer to hardware structure
7217  * @rm: recipe management list entry
7218  * @lkup_exts: lookup elements
7219  */
7220 static enum ice_status
7221 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
7222                         struct ice_prot_lkup_ext *lkup_exts)
7223 {
7224         enum ice_status status;
7225         u8 recp_count = 0;
7226
7227         rm->n_grp_count = 0;
7228
7229         /* Create recipes for words that are marked not done by packing them
7230          * as best fit.
7231          */
7232         status = ice_create_first_fit_recp_def(hw, lkup_exts,
7233                                                &rm->rg_list, &recp_count);
7234         if (!status) {
7235                 rm->n_grp_count += recp_count;
7236                 rm->n_ext_words = lkup_exts->n_val_words;
7237                 ice_memcpy(&rm->ext_words, lkup_exts->fv_words,
7238                            sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA);
7239                 ice_memcpy(rm->word_masks, lkup_exts->field_mask,
7240                            sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA);
7241         }
7242
7243         return status;
7244 }
7245
7246 /**
7247  * ice_get_fv - get field vectors/extraction sequences for spec. lookup types
7248  * @hw: pointer to hardware structure
7249  * @lkups: lookup elements or match criteria for the advanced recipe, one
7250  *         structure per protocol header
7251  * @lkups_cnt: number of protocols
7252  * @bm: bitmap of field vectors to consider
7253  * @fv_list: pointer to a list that holds the returned field vectors
7254  */
7255 static enum ice_status
7256 ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
7257            ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)
7258 {
7259         enum ice_status status;
7260         u8 *prot_ids;
7261         u16 i;
7262
7263         if (!lkups_cnt)
7264                 return ICE_SUCCESS;
7265
7266         prot_ids = (u8 *)ice_calloc(hw, lkups_cnt, sizeof(*prot_ids));
7267         if (!prot_ids)
7268                 return ICE_ERR_NO_MEMORY;
7269
7270         for (i = 0; i < lkups_cnt; i++)
7271                 if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {
7272                         status = ICE_ERR_CFG;
7273                         goto free_mem;
7274                 }
7275
7276         /* Find field vectors that include all specified protocol types */
7277         status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);
7278
7279 free_mem:
7280         ice_free(hw, prot_ids);
7281         return status;
7282 }
7283
7284 /**
7285  * ice_tun_type_match_word - determine if tun type needs a match mask
7286  * @tun_type: tunnel type
7287  * @mask: mask to be used for the tunnel
7288  */
7289 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
7290 {
7291         switch (tun_type) {
7292         case ICE_SW_TUN_VXLAN_GPE:
7293         case ICE_SW_TUN_GENEVE:
7294         case ICE_SW_TUN_VXLAN:
7295         case ICE_SW_TUN_NVGRE:
7296         case ICE_SW_TUN_UDP:
7297         case ICE_ALL_TUNNELS:
7298         case ICE_SW_TUN_AND_NON_TUN_QINQ:
7299         case ICE_NON_TUN_QINQ:
7300         case ICE_SW_TUN_PPPOE_QINQ:
7301         case ICE_SW_TUN_PPPOE_PAY_QINQ:
7302         case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7303         case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7304                 *mask = ICE_TUN_FLAG_MASK;
7305                 return true;
7306
7307         case ICE_SW_TUN_GENEVE_VLAN:
7308         case ICE_SW_TUN_VXLAN_VLAN:
7309                 *mask = ICE_TUN_FLAG_MASK & ~ICE_TUN_FLAG_VLAN_MASK;
7310                 return true;
7311
7312         default:
7313                 *mask = 0;
7314                 return false;
7315         }
7316 }
7317
7318 /**
7319  * ice_add_special_words - Add words that are not protocols, such as metadata
7320  * @rinfo: other information regarding the rule e.g. priority and action info
7321  * @lkup_exts: lookup word structure
7322  */
7323 static enum ice_status
7324 ice_add_special_words(struct ice_adv_rule_info *rinfo,
7325                       struct ice_prot_lkup_ext *lkup_exts)
7326 {
7327         u16 mask;
7328
7329         /* If this is a tunneled packet, then add recipe index to match the
7330          * tunnel bit in the packet metadata flags.
7331          */
7332         if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
7333                 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7334                         u8 word = lkup_exts->n_val_words++;
7335
7336                         lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7337                         lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
7338                         lkup_exts->field_mask[word] = mask;
7339                 } else {
7340                         return ICE_ERR_MAX_LIMIT;
7341                 }
7342         }
7343
7344         return ICE_SUCCESS;
7345 }
7346
7347 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
7348  * @hw: pointer to hardware structure
7349  * @rinfo: other information regarding the rule e.g. priority and action info
7350  * @bm: pointer to memory for returning the bitmap of field vectors
7351  */
7352 static void
7353 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
7354                          ice_bitmap_t *bm)
7355 {
7356         enum ice_prof_type prof_type;
7357
7358         ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
7359
7360         switch (rinfo->tun_type) {
7361         case ICE_NON_TUN:
7362         case ICE_NON_TUN_QINQ:
7363                 prof_type = ICE_PROF_NON_TUN;
7364                 break;
7365         case ICE_ALL_TUNNELS:
7366                 prof_type = ICE_PROF_TUN_ALL;
7367                 break;
7368         case ICE_SW_TUN_VXLAN_GPE:
7369         case ICE_SW_TUN_GENEVE:
7370         case ICE_SW_TUN_GENEVE_VLAN:
7371         case ICE_SW_TUN_VXLAN:
7372         case ICE_SW_TUN_VXLAN_VLAN:
7373         case ICE_SW_TUN_UDP:
7374         case ICE_SW_TUN_GTP:
7375                 prof_type = ICE_PROF_TUN_UDP;
7376                 break;
7377         case ICE_SW_TUN_NVGRE:
7378                 prof_type = ICE_PROF_TUN_GRE;
7379                 break;
7380         case ICE_SW_TUN_PPPOE:
7381         case ICE_SW_TUN_PPPOE_QINQ:
7382                 prof_type = ICE_PROF_TUN_PPPOE;
7383                 break;
7384         case ICE_SW_TUN_PPPOE_PAY:
7385         case ICE_SW_TUN_PPPOE_PAY_QINQ:
7386                 ice_set_bit(ICE_PROFID_PPPOE_PAY, bm);
7387                 return;
7388         case ICE_SW_TUN_PPPOE_IPV4:
7389         case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7390                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_OTHER, bm);
7391                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7392                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7393                 return;
7394         case ICE_SW_TUN_PPPOE_IPV4_TCP:
7395                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7396                 return;
7397         case ICE_SW_TUN_PPPOE_IPV4_UDP:
7398                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7399                 return;
7400         case ICE_SW_TUN_PPPOE_IPV6:
7401         case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7402                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_OTHER, bm);
7403                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7404                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7405                 return;
7406         case ICE_SW_TUN_PPPOE_IPV6_TCP:
7407                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7408                 return;
7409         case ICE_SW_TUN_PPPOE_IPV6_UDP:
7410                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7411                 return;
7412         case ICE_SW_TUN_PROFID_IPV6_ESP:
7413         case ICE_SW_TUN_IPV6_ESP:
7414                 ice_set_bit(ICE_PROFID_IPV6_ESP, bm);
7415                 return;
7416         case ICE_SW_TUN_PROFID_IPV6_AH:
7417         case ICE_SW_TUN_IPV6_AH:
7418                 ice_set_bit(ICE_PROFID_IPV6_AH, bm);
7419                 return;
7420         case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7421         case ICE_SW_TUN_IPV6_L2TPV3:
7422                 ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm);
7423                 return;
7424         case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7425         case ICE_SW_TUN_IPV6_NAT_T:
7426                 ice_set_bit(ICE_PROFID_IPV6_NAT_T, bm);
7427                 return;
7428         case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7429                 ice_set_bit(ICE_PROFID_IPV4_PFCP_NODE, bm);
7430                 return;
7431         case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7432                 ice_set_bit(ICE_PROFID_IPV4_PFCP_SESSION, bm);
7433                 return;
7434         case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7435                 ice_set_bit(ICE_PROFID_IPV6_PFCP_NODE, bm);
7436                 return;
7437         case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7438                 ice_set_bit(ICE_PROFID_IPV6_PFCP_SESSION, bm);
7439                 return;
7440         case ICE_SW_TUN_IPV4_NAT_T:
7441                 ice_set_bit(ICE_PROFID_IPV4_NAT_T, bm);
7442                 return;
7443         case ICE_SW_TUN_IPV4_L2TPV3:
7444                 ice_set_bit(ICE_PROFID_MAC_IPV4_L2TPV3, bm);
7445                 return;
7446         case ICE_SW_TUN_IPV4_ESP:
7447                 ice_set_bit(ICE_PROFID_IPV4_ESP, bm);
7448                 return;
7449         case ICE_SW_TUN_IPV4_AH:
7450                 ice_set_bit(ICE_PROFID_IPV4_AH, bm);
7451                 return;
7452         case ICE_SW_IPV4_TCP:
7453                 ice_set_bit(ICE_PROFID_IPV4_TCP, bm);
7454                 return;
7455         case ICE_SW_IPV4_UDP:
7456                 ice_set_bit(ICE_PROFID_IPV4_UDP, bm);
7457                 return;
7458         case ICE_SW_IPV6_TCP:
7459                 ice_set_bit(ICE_PROFID_IPV6_TCP, bm);
7460                 return;
7461         case ICE_SW_IPV6_UDP:
7462                 ice_set_bit(ICE_PROFID_IPV6_UDP, bm);
7463                 return;
7464         case ICE_SW_TUN_IPV4_GTPU_IPV4:
7465                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, bm);
7466                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_OTHER, bm);
7467                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
7468                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
7469                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
7470                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
7471                 return;
7472         case ICE_SW_TUN_IPV6_GTPU_IPV4:
7473                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, bm);
7474                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_OTHER, bm);
7475                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
7476                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
7477                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
7478                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
7479                 return;
7480         case ICE_SW_TUN_IPV4_GTPU_IPV6:
7481                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, bm);
7482                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_OTHER, bm);
7483                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
7484                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
7485                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
7486                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
7487                 return;
7488         case ICE_SW_TUN_IPV6_GTPU_IPV6:
7489                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, bm);
7490                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_OTHER, bm);
7491                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
7492                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
7493                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
7494                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
7495                 return;
7496         case ICE_SW_TUN_AND_NON_TUN:
7497         case ICE_SW_TUN_AND_NON_TUN_QINQ:
7498         default:
7499                 prof_type = ICE_PROF_ALL;
7500                 break;
7501         }
7502
7503         ice_get_sw_fv_bitmap(hw, prof_type, bm);
7504 }
7505
7506 /**
7507  * ice_is_prof_rule - determine if rule type is a profile rule
7508  * @type: the rule type
7509  *
7510  * if the rule type is a profile rule, that means that there no field value
7511  * match required, in this case just a profile hit is required.
7512  */
7513 bool ice_is_prof_rule(enum ice_sw_tunnel_type type)
7514 {
7515         switch (type) {
7516         case ICE_SW_TUN_PROFID_IPV6_ESP:
7517         case ICE_SW_TUN_PROFID_IPV6_AH:
7518         case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7519         case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7520         case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7521         case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7522         case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7523         case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7524                 return true;
7525         default:
7526                 break;
7527         }
7528
7529         return false;
7530 }
7531
7532 /**
7533  * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
7534  * @hw: pointer to hardware structure
7535  * @lkups: lookup elements or match criteria for the advanced recipe, one
7536  *  structure per protocol header
7537  * @lkups_cnt: number of protocols
7538  * @rinfo: other information regarding the rule e.g. priority and action info
7539  * @rid: return the recipe ID of the recipe created
7540  */
7541 static enum ice_status
7542 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
7543                    u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
7544 {
7545         ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES);
7546         ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES);
7547         struct ice_prot_lkup_ext *lkup_exts;
7548         struct ice_recp_grp_entry *r_entry;
7549         struct ice_sw_fv_list_entry *fvit;
7550         struct ice_recp_grp_entry *r_tmp;
7551         struct ice_sw_fv_list_entry *tmp;
7552         enum ice_status status = ICE_SUCCESS;
7553         struct ice_sw_recipe *rm;
7554         u8 i;
7555
7556         if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt)
7557                 return ICE_ERR_PARAM;
7558
7559         lkup_exts = (struct ice_prot_lkup_ext *)
7560                 ice_malloc(hw, sizeof(*lkup_exts));
7561         if (!lkup_exts)
7562                 return ICE_ERR_NO_MEMORY;
7563
7564         /* Determine the number of words to be matched and if it exceeds a
7565          * recipe's restrictions
7566          */
7567         for (i = 0; i < lkups_cnt; i++) {
7568                 u16 count;
7569
7570                 if (lkups[i].type >= ICE_PROTOCOL_LAST) {
7571                         status = ICE_ERR_CFG;
7572                         goto err_free_lkup_exts;
7573                 }
7574
7575                 count = ice_fill_valid_words(&lkups[i], lkup_exts);
7576                 if (!count) {
7577                         status = ICE_ERR_CFG;
7578                         goto err_free_lkup_exts;
7579                 }
7580         }
7581
7582         rm = (struct ice_sw_recipe *)ice_malloc(hw, sizeof(*rm));
7583         if (!rm) {
7584                 status = ICE_ERR_NO_MEMORY;
7585                 goto err_free_lkup_exts;
7586         }
7587
7588         /* Get field vectors that contain fields extracted from all the protocol
7589          * headers being programmed.
7590          */
7591         INIT_LIST_HEAD(&rm->fv_list);
7592         INIT_LIST_HEAD(&rm->rg_list);
7593
7594         /* Get bitmap of field vectors (profiles) that are compatible with the
7595          * rule request; only these will be searched in the subsequent call to
7596          * ice_get_fv.
7597          */
7598         ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
7599
7600         status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);
7601         if (status)
7602                 goto err_unroll;
7603
7604         /* Create any special protocol/offset pairs, such as looking at tunnel
7605          * bits by extracting metadata
7606          */
7607         status = ice_add_special_words(rinfo, lkup_exts);
7608         if (status)
7609                 goto err_free_lkup_exts;
7610
7611         /* Group match words into recipes using preferred recipe grouping
7612          * criteria.
7613          */
7614         status = ice_create_recipe_group(hw, rm, lkup_exts);
7615         if (status)
7616                 goto err_unroll;
7617
7618         /* set the recipe priority if specified */
7619         rm->priority = (u8)rinfo->priority;
7620
7621         /* Find offsets from the field vector. Pick the first one for all the
7622          * recipes.
7623          */
7624         status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
7625         if (status)
7626                 goto err_unroll;
7627
7628         /* An empty FV list means to use all the profiles returned in the
7629          * profile bitmap
7630          */
7631         if (LIST_EMPTY(&rm->fv_list)) {
7632                 u16 j;
7633
7634                 ice_for_each_set_bit(j, fv_bitmap, ICE_MAX_NUM_PROFILES) {
7635                         struct ice_sw_fv_list_entry *fvl;
7636
7637                         fvl = (struct ice_sw_fv_list_entry *)
7638                                 ice_malloc(hw, sizeof(*fvl));
7639                         if (!fvl)
7640                                 goto err_unroll;
7641                         fvl->fv_ptr = NULL;
7642                         fvl->profile_id = j;
7643                         LIST_ADD(&fvl->list_entry, &rm->fv_list);
7644                 }
7645         }
7646
7647         /* get bitmap of all profiles the recipe will be associated with */
7648         ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES);
7649         LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
7650                             list_entry) {
7651                 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
7652                 ice_set_bit((u16)fvit->profile_id, profiles);
7653         }
7654
7655         /* Look for a recipe which matches our requested fv / mask list */
7656         *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type, rinfo->priority);
7657         if (*rid < ICE_MAX_NUM_RECIPES)
7658                 /* Success if found a recipe that match the existing criteria */
7659                 goto err_unroll;
7660
7661         rm->tun_type = rinfo->tun_type;
7662         /* Recipe we need does not exist, add a recipe */
7663         status = ice_add_sw_recipe(hw, rm, profiles);
7664         if (status)
7665                 goto err_unroll;
7666
7667         /* Associate all the recipes created with all the profiles in the
7668          * common field vector.
7669          */
7670         LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
7671                             list_entry) {
7672                 ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
7673                 u16 j;
7674
7675                 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
7676                                                       (u8 *)r_bitmap, NULL);
7677                 if (status)
7678                         goto err_unroll;
7679
7680                 ice_or_bitmap(r_bitmap, r_bitmap, rm->r_bitmap,
7681                               ICE_MAX_NUM_RECIPES);
7682                 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7683                 if (status)
7684                         goto err_unroll;
7685
7686                 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
7687                                                       (u8 *)r_bitmap,
7688                                                       NULL);
7689                 ice_release_change_lock(hw);
7690
7691                 if (status)
7692                         goto err_unroll;
7693
7694                 /* Update profile to recipe bitmap array */
7695                 ice_cp_bitmap(profile_to_recipe[fvit->profile_id], r_bitmap,
7696                               ICE_MAX_NUM_RECIPES);
7697
7698                 /* Update recipe to profile bitmap array */
7699                 ice_for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
7700                         ice_set_bit((u16)fvit->profile_id,
7701                                     recipe_to_profile[j]);
7702         }
7703
7704         *rid = rm->root_rid;
7705         ice_memcpy(&hw->switch_info->recp_list[*rid].lkup_exts,
7706                    lkup_exts, sizeof(*lkup_exts), ICE_NONDMA_TO_NONDMA);
7707 err_unroll:
7708         LIST_FOR_EACH_ENTRY_SAFE(r_entry, r_tmp, &rm->rg_list,
7709                                  ice_recp_grp_entry, l_entry) {
7710                 LIST_DEL(&r_entry->l_entry);
7711                 ice_free(hw, r_entry);
7712         }
7713
7714         LIST_FOR_EACH_ENTRY_SAFE(fvit, tmp, &rm->fv_list, ice_sw_fv_list_entry,
7715                                  list_entry) {
7716                 LIST_DEL(&fvit->list_entry);
7717                 ice_free(hw, fvit);
7718         }
7719
7720         if (rm->root_buf)
7721                 ice_free(hw, rm->root_buf);
7722
7723         ice_free(hw, rm);
7724
7725 err_free_lkup_exts:
7726         ice_free(hw, lkup_exts);
7727
7728         return status;
7729 }
7730
7731 /**
7732  * ice_find_dummy_packet - find dummy packet by tunnel type
7733  *
7734  * @lkups: lookup elements or match criteria for the advanced recipe, one
7735  *         structure per protocol header
7736  * @lkups_cnt: number of protocols
7737  * @tun_type: tunnel type from the match criteria
7738  * @pkt: dummy packet to fill according to filter match criteria
7739  * @pkt_len: packet length of dummy packet
7740  * @offsets: pointer to receive the pointer to the offsets for the packet
7741  */
7742 static void
7743 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
7744                       enum ice_sw_tunnel_type tun_type, const u8 **pkt,
7745                       u16 *pkt_len,
7746                       const struct ice_dummy_pkt_offsets **offsets)
7747 {
7748         bool tcp = false, udp = false, ipv6 = false, vlan = false;
7749         bool gre = false;
7750         u16 i;
7751
7752         for (i = 0; i < lkups_cnt; i++) {
7753                 if (lkups[i].type == ICE_UDP_ILOS)
7754                         udp = true;
7755                 else if (lkups[i].type == ICE_TCP_IL)
7756                         tcp = true;
7757                 else if (lkups[i].type == ICE_IPV6_OFOS)
7758                         ipv6 = true;
7759                 else if (lkups[i].type == ICE_VLAN_OFOS)
7760                         vlan = true;
7761                 else if (lkups[i].type == ICE_IPV4_OFOS &&
7762                          lkups[i].h_u.ipv4_hdr.protocol ==
7763                                 ICE_IPV4_NVGRE_PROTO_ID &&
7764                          lkups[i].m_u.ipv4_hdr.protocol ==
7765                                 0xFF)
7766                         gre = true;
7767                 else if (lkups[i].type == ICE_PPPOE &&
7768                          lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
7769                                 CPU_TO_BE16(ICE_PPP_IPV6_PROTO_ID) &&
7770                          lkups[i].m_u.pppoe_hdr.ppp_prot_id ==
7771                                 0xFFFF)
7772                         ipv6 = true;
7773                 else if (lkups[i].type == ICE_ETYPE_OL &&
7774                          lkups[i].h_u.ethertype.ethtype_id ==
7775                                 CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
7776                          lkups[i].m_u.ethertype.ethtype_id ==
7777                                         0xFFFF)
7778                         ipv6 = true;
7779                 else if (lkups[i].type == ICE_IPV4_IL &&
7780                          lkups[i].h_u.ipv4_hdr.protocol ==
7781                                 ICE_TCP_PROTO_ID &&
7782                          lkups[i].m_u.ipv4_hdr.protocol ==
7783                                 0xFF)
7784                         tcp = true;
7785         }
7786
7787         if ((tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
7788              tun_type == ICE_NON_TUN_QINQ) && ipv6) {
7789                 *pkt = dummy_qinq_ipv6_pkt;
7790                 *pkt_len = sizeof(dummy_qinq_ipv6_pkt);
7791                 *offsets = dummy_qinq_ipv6_packet_offsets;
7792                 return;
7793         } else if (tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
7794                            tun_type == ICE_NON_TUN_QINQ) {
7795                 *pkt = dummy_qinq_ipv4_pkt;
7796                 *pkt_len = sizeof(dummy_qinq_ipv4_pkt);
7797                 *offsets = dummy_qinq_ipv4_packet_offsets;
7798                 return;
7799         }
7800
7801         if (tun_type == ICE_SW_TUN_PPPOE_IPV6_QINQ) {
7802                 *pkt = dummy_qinq_pppoe_ipv6_packet;
7803                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
7804                 *offsets = dummy_qinq_pppoe_packet_ipv6_offsets;
7805                 return;
7806         } else if (tun_type == ICE_SW_TUN_PPPOE_IPV4_QINQ) {
7807                 *pkt = dummy_qinq_pppoe_ipv4_pkt;
7808                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
7809                 *offsets = dummy_qinq_pppoe_ipv4_packet_offsets;
7810                 return;
7811         } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ && ipv6) {
7812                 *pkt = dummy_qinq_pppoe_ipv6_packet;
7813                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
7814                 *offsets = dummy_qinq_pppoe_packet_offsets;
7815                 return;
7816         } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ ||
7817                         tun_type == ICE_SW_TUN_PPPOE_PAY_QINQ) {
7818                 *pkt = dummy_qinq_pppoe_ipv4_pkt;
7819                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
7820                 *offsets = dummy_qinq_pppoe_packet_offsets;
7821                 return;
7822         }
7823
7824         if (tun_type == ICE_SW_TUN_IPV4_GTPU_NO_PAY) {
7825                 *pkt = dummy_ipv4_gtpu_ipv4_packet;
7826                 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
7827                 *offsets = dummy_ipv4_gtp_no_pay_packet_offsets;
7828                 return;
7829         } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_NO_PAY) {
7830                 *pkt = dummy_ipv6_gtpu_ipv6_packet;
7831                 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
7832                 *offsets = dummy_ipv6_gtp_no_pay_packet_offsets;
7833                 return;
7834         }
7835
7836         if (tun_type == ICE_SW_TUN_IPV4_ESP) {
7837                 *pkt = dummy_ipv4_esp_pkt;
7838                 *pkt_len = sizeof(dummy_ipv4_esp_pkt);
7839                 *offsets = dummy_ipv4_esp_packet_offsets;
7840                 return;
7841         }
7842
7843         if (tun_type == ICE_SW_TUN_IPV6_ESP) {
7844                 *pkt = dummy_ipv6_esp_pkt;
7845                 *pkt_len = sizeof(dummy_ipv6_esp_pkt);
7846                 *offsets = dummy_ipv6_esp_packet_offsets;
7847                 return;
7848         }
7849
7850         if (tun_type == ICE_SW_TUN_IPV4_AH) {
7851                 *pkt = dummy_ipv4_ah_pkt;
7852                 *pkt_len = sizeof(dummy_ipv4_ah_pkt);
7853                 *offsets = dummy_ipv4_ah_packet_offsets;
7854                 return;
7855         }
7856
7857         if (tun_type == ICE_SW_TUN_IPV6_AH) {
7858                 *pkt = dummy_ipv6_ah_pkt;
7859                 *pkt_len = sizeof(dummy_ipv6_ah_pkt);
7860                 *offsets = dummy_ipv6_ah_packet_offsets;
7861                 return;
7862         }
7863
7864         if (tun_type == ICE_SW_TUN_IPV4_NAT_T) {
7865                 *pkt = dummy_ipv4_nat_pkt;
7866                 *pkt_len = sizeof(dummy_ipv4_nat_pkt);
7867                 *offsets = dummy_ipv4_nat_packet_offsets;
7868                 return;
7869         }
7870
7871         if (tun_type == ICE_SW_TUN_IPV6_NAT_T) {
7872                 *pkt = dummy_ipv6_nat_pkt;
7873                 *pkt_len = sizeof(dummy_ipv6_nat_pkt);
7874                 *offsets = dummy_ipv6_nat_packet_offsets;
7875                 return;
7876         }
7877
7878         if (tun_type == ICE_SW_TUN_IPV4_L2TPV3) {
7879                 *pkt = dummy_ipv4_l2tpv3_pkt;
7880                 *pkt_len = sizeof(dummy_ipv4_l2tpv3_pkt);
7881                 *offsets = dummy_ipv4_l2tpv3_packet_offsets;
7882                 return;
7883         }
7884
7885         if (tun_type == ICE_SW_TUN_IPV6_L2TPV3) {
7886                 *pkt = dummy_ipv6_l2tpv3_pkt;
7887                 *pkt_len = sizeof(dummy_ipv6_l2tpv3_pkt);
7888                 *offsets = dummy_ipv6_l2tpv3_packet_offsets;
7889                 return;
7890         }
7891
7892         if (tun_type == ICE_SW_TUN_GTP) {
7893                 *pkt = dummy_udp_gtp_packet;
7894                 *pkt_len = sizeof(dummy_udp_gtp_packet);
7895                 *offsets = dummy_udp_gtp_packet_offsets;
7896                 return;
7897         }
7898
7899         if (tun_type == ICE_SW_TUN_PPPOE && ipv6) {
7900                 *pkt = dummy_pppoe_ipv6_packet;
7901                 *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
7902                 *offsets = dummy_pppoe_packet_offsets;
7903                 return;
7904         } else if (tun_type == ICE_SW_TUN_PPPOE ||
7905                 tun_type == ICE_SW_TUN_PPPOE_PAY) {
7906                 *pkt = dummy_pppoe_ipv4_packet;
7907                 *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
7908                 *offsets = dummy_pppoe_packet_offsets;
7909                 return;
7910         }
7911
7912         if (tun_type == ICE_SW_TUN_PPPOE_IPV4) {
7913                 *pkt = dummy_pppoe_ipv4_packet;
7914                 *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
7915                 *offsets = dummy_pppoe_packet_ipv4_offsets;
7916                 return;
7917         }
7918
7919         if (tun_type == ICE_SW_TUN_PPPOE_IPV4_TCP) {
7920                 *pkt = dummy_pppoe_ipv4_tcp_packet;
7921                 *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
7922                 *offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
7923                 return;
7924         }
7925
7926         if (tun_type == ICE_SW_TUN_PPPOE_IPV4_UDP) {
7927                 *pkt = dummy_pppoe_ipv4_udp_packet;
7928                 *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
7929                 *offsets = dummy_pppoe_ipv4_udp_packet_offsets;
7930                 return;
7931         }
7932
7933         if (tun_type == ICE_SW_TUN_PPPOE_IPV6) {
7934                 *pkt = dummy_pppoe_ipv6_packet;
7935                 *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
7936                 *offsets = dummy_pppoe_packet_ipv6_offsets;
7937                 return;
7938         }
7939
7940         if (tun_type == ICE_SW_TUN_PPPOE_IPV6_TCP) {
7941                 *pkt = dummy_pppoe_ipv6_tcp_packet;
7942                 *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
7943                 *offsets = dummy_pppoe_packet_ipv6_tcp_offsets;
7944                 return;
7945         }
7946
7947         if (tun_type == ICE_SW_TUN_PPPOE_IPV6_UDP) {
7948                 *pkt = dummy_pppoe_ipv6_udp_packet;
7949                 *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
7950                 *offsets = dummy_pppoe_packet_ipv6_udp_offsets;
7951                 return;
7952         }
7953
7954         if (tun_type == ICE_SW_IPV4_TCP) {
7955                 *pkt = dummy_tcp_packet;
7956                 *pkt_len = sizeof(dummy_tcp_packet);
7957                 *offsets = dummy_tcp_packet_offsets;
7958                 return;
7959         }
7960
7961         if (tun_type == ICE_SW_IPV4_UDP) {
7962                 *pkt = dummy_udp_packet;
7963                 *pkt_len = sizeof(dummy_udp_packet);
7964                 *offsets = dummy_udp_packet_offsets;
7965                 return;
7966         }
7967
7968         if (tun_type == ICE_SW_IPV6_TCP) {
7969                 *pkt = dummy_tcp_ipv6_packet;
7970                 *pkt_len = sizeof(dummy_tcp_ipv6_packet);
7971                 *offsets = dummy_tcp_ipv6_packet_offsets;
7972                 return;
7973         }
7974
7975         if (tun_type == ICE_SW_IPV6_UDP) {
7976                 *pkt = dummy_udp_ipv6_packet;
7977                 *pkt_len = sizeof(dummy_udp_ipv6_packet);
7978                 *offsets = dummy_udp_ipv6_packet_offsets;
7979                 return;
7980         }
7981
7982         /* Support GTP tunnel + L3 */
7983         if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4) {
7984                 *pkt = dummy_ipv4_gtpu_ipv4_packet;
7985                 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
7986                 *offsets = dummy_ipv4_gtpu_ipv4_packet_offsets;
7987                 return;
7988         }
7989         if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6) {
7990                 *pkt = dummy_ipv4_gtpu_ipv6_packet;
7991                 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_packet);
7992                 *offsets = dummy_ipv4_gtpu_ipv6_packet_offsets;
7993                 return;
7994         }
7995         if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4) {
7996                 *pkt = dummy_ipv6_gtpu_ipv4_packet;
7997                 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_packet);
7998                 *offsets = dummy_ipv6_gtpu_ipv4_packet_offsets;
7999                 return;
8000         }
8001         if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6) {
8002                 *pkt = dummy_ipv6_gtpu_ipv6_packet;
8003                 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
8004                 *offsets = dummy_ipv6_gtpu_ipv6_packet_offsets;
8005                 return;
8006         }
8007
8008         if (tun_type == ICE_ALL_TUNNELS) {
8009                 *pkt = dummy_gre_udp_packet;
8010                 *pkt_len = sizeof(dummy_gre_udp_packet);
8011                 *offsets = dummy_gre_udp_packet_offsets;
8012                 return;
8013         }
8014
8015         if (tun_type == ICE_SW_TUN_NVGRE || gre) {
8016                 if (tcp) {
8017                         *pkt = dummy_gre_tcp_packet;
8018                         *pkt_len = sizeof(dummy_gre_tcp_packet);
8019                         *offsets = dummy_gre_tcp_packet_offsets;
8020                         return;
8021                 }
8022
8023                 *pkt = dummy_gre_udp_packet;
8024                 *pkt_len = sizeof(dummy_gre_udp_packet);
8025                 *offsets = dummy_gre_udp_packet_offsets;
8026                 return;
8027         }
8028
8029         if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE ||
8030             tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP ||
8031             tun_type == ICE_SW_TUN_GENEVE_VLAN ||
8032             tun_type == ICE_SW_TUN_VXLAN_VLAN) {
8033                 if (tcp) {
8034                         *pkt = dummy_udp_tun_tcp_packet;
8035                         *pkt_len = sizeof(dummy_udp_tun_tcp_packet);
8036                         *offsets = dummy_udp_tun_tcp_packet_offsets;
8037                         return;
8038                 }
8039
8040                 *pkt = dummy_udp_tun_udp_packet;
8041                 *pkt_len = sizeof(dummy_udp_tun_udp_packet);
8042                 *offsets = dummy_udp_tun_udp_packet_offsets;
8043                 return;
8044         }
8045
8046         if (udp && !ipv6) {
8047                 if (vlan) {
8048                         *pkt = dummy_vlan_udp_packet;
8049                         *pkt_len = sizeof(dummy_vlan_udp_packet);
8050                         *offsets = dummy_vlan_udp_packet_offsets;
8051                         return;
8052                 }
8053                 *pkt = dummy_udp_packet;
8054                 *pkt_len = sizeof(dummy_udp_packet);
8055                 *offsets = dummy_udp_packet_offsets;
8056                 return;
8057         } else if (udp && ipv6) {
8058                 if (vlan) {
8059                         *pkt = dummy_vlan_udp_ipv6_packet;
8060                         *pkt_len = sizeof(dummy_vlan_udp_ipv6_packet);
8061                         *offsets = dummy_vlan_udp_ipv6_packet_offsets;
8062                         return;
8063                 }
8064                 *pkt = dummy_udp_ipv6_packet;
8065                 *pkt_len = sizeof(dummy_udp_ipv6_packet);
8066                 *offsets = dummy_udp_ipv6_packet_offsets;
8067                 return;
8068         } else if ((tcp && ipv6) || ipv6) {
8069                 if (vlan) {
8070                         *pkt = dummy_vlan_tcp_ipv6_packet;
8071                         *pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet);
8072                         *offsets = dummy_vlan_tcp_ipv6_packet_offsets;
8073                         return;
8074                 }
8075                 *pkt = dummy_tcp_ipv6_packet;
8076                 *pkt_len = sizeof(dummy_tcp_ipv6_packet);
8077                 *offsets = dummy_tcp_ipv6_packet_offsets;
8078                 return;
8079         }
8080
8081         if (vlan) {
8082                 *pkt = dummy_vlan_tcp_packet;
8083                 *pkt_len = sizeof(dummy_vlan_tcp_packet);
8084                 *offsets = dummy_vlan_tcp_packet_offsets;
8085         } else {
8086                 *pkt = dummy_tcp_packet;
8087                 *pkt_len = sizeof(dummy_tcp_packet);
8088                 *offsets = dummy_tcp_packet_offsets;
8089         }
8090 }
8091
8092 /**
8093  * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
8094  *
8095  * @lkups: lookup elements or match criteria for the advanced recipe, one
8096  *         structure per protocol header
8097  * @lkups_cnt: number of protocols
8098  * @s_rule: stores rule information from the match criteria
8099  * @dummy_pkt: dummy packet to fill according to filter match criteria
8100  * @pkt_len: packet length of dummy packet
8101  * @offsets: offset info for the dummy packet
8102  */
8103 static enum ice_status
8104 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8105                           struct ice_aqc_sw_rules_elem *s_rule,
8106                           const u8 *dummy_pkt, u16 pkt_len,
8107                           const struct ice_dummy_pkt_offsets *offsets)
8108 {
8109         u8 *pkt;
8110         u16 i;
8111
8112         /* Start with a packet with a pre-defined/dummy content. Then, fill
8113          * in the header values to be looked up or matched.
8114          */
8115         pkt = s_rule->pdata.lkup_tx_rx.hdr;
8116
8117         ice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA);
8118
8119         for (i = 0; i < lkups_cnt; i++) {
8120                 enum ice_protocol_type type;
8121                 u16 offset = 0, len = 0, j;
8122                 bool found = false;
8123
8124                 /* find the start of this layer; it should be found since this
8125                  * was already checked when search for the dummy packet
8126                  */
8127                 type = lkups[i].type;
8128                 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
8129                         if (type == offsets[j].type) {
8130                                 offset = offsets[j].offset;
8131                                 found = true;
8132                                 break;
8133                         }
8134                 }
8135                 /* this should never happen in a correct calling sequence */
8136                 if (!found)
8137                         return ICE_ERR_PARAM;
8138
8139                 switch (lkups[i].type) {
8140                 case ICE_MAC_OFOS:
8141                 case ICE_MAC_IL:
8142                         len = sizeof(struct ice_ether_hdr);
8143                         break;
8144                 case ICE_ETYPE_OL:
8145                         len = sizeof(struct ice_ethtype_hdr);
8146                         break;
8147                 case ICE_VLAN_OFOS:
8148                 case ICE_VLAN_EX:
8149                 case ICE_VLAN_IN:
8150                         len = sizeof(struct ice_vlan_hdr);
8151                         break;
8152                 case ICE_IPV4_OFOS:
8153                 case ICE_IPV4_IL:
8154                         len = sizeof(struct ice_ipv4_hdr);
8155                         break;
8156                 case ICE_IPV6_OFOS:
8157                 case ICE_IPV6_IL:
8158                         len = sizeof(struct ice_ipv6_hdr);
8159                         break;
8160                 case ICE_TCP_IL:
8161                 case ICE_UDP_OF:
8162                 case ICE_UDP_ILOS:
8163                         len = sizeof(struct ice_l4_hdr);
8164                         break;
8165                 case ICE_SCTP_IL:
8166                         len = sizeof(struct ice_sctp_hdr);
8167                         break;
8168                 case ICE_NVGRE:
8169                         len = sizeof(struct ice_nvgre);
8170                         break;
8171                 case ICE_VXLAN:
8172                 case ICE_GENEVE:
8173                 case ICE_VXLAN_GPE:
8174                         len = sizeof(struct ice_udp_tnl_hdr);
8175                         break;
8176
8177                 case ICE_GTP:
8178                 case ICE_GTP_NO_PAY:
8179                         len = sizeof(struct ice_udp_gtp_hdr);
8180                         break;
8181                 case ICE_PPPOE:
8182                         len = sizeof(struct ice_pppoe_hdr);
8183                         break;
8184                 case ICE_ESP:
8185                         len = sizeof(struct ice_esp_hdr);
8186                         break;
8187                 case ICE_NAT_T:
8188                         len = sizeof(struct ice_nat_t_hdr);
8189                         break;
8190                 case ICE_AH:
8191                         len = sizeof(struct ice_ah_hdr);
8192                         break;
8193                 case ICE_L2TPV3:
8194                         len = sizeof(struct ice_l2tpv3_sess_hdr);
8195                         break;
8196                 default:
8197                         return ICE_ERR_PARAM;
8198                 }
8199
8200                 /* the length should be a word multiple */
8201                 if (len % ICE_BYTES_PER_WORD)
8202                         return ICE_ERR_CFG;
8203
8204                 /* We have the offset to the header start, the length, the
8205                  * caller's header values and mask. Use this information to
8206                  * copy the data into the dummy packet appropriately based on
8207                  * the mask. Note that we need to only write the bits as
8208                  * indicated by the mask to make sure we don't improperly write
8209                  * over any significant packet data.
8210                  */
8211                 for (j = 0; j < len / sizeof(u16); j++)
8212                         if (((u16 *)&lkups[i].m_u)[j])
8213                                 ((u16 *)(pkt + offset))[j] =
8214                                         (((u16 *)(pkt + offset))[j] &
8215                                          ~((u16 *)&lkups[i].m_u)[j]) |
8216                                         (((u16 *)&lkups[i].h_u)[j] &
8217                                          ((u16 *)&lkups[i].m_u)[j]);
8218         }
8219
8220         s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(pkt_len);
8221
8222         return ICE_SUCCESS;
8223 }
8224
8225 /**
8226  * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
8227  * @hw: pointer to the hardware structure
8228  * @tun_type: tunnel type
8229  * @pkt: dummy packet to fill in
8230  * @offsets: offset info for the dummy packet
8231  */
8232 static enum ice_status
8233 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
8234                         u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
8235 {
8236         u16 open_port, i;
8237
8238         switch (tun_type) {
8239         case ICE_SW_TUN_AND_NON_TUN:
8240         case ICE_SW_TUN_VXLAN_GPE:
8241         case ICE_SW_TUN_VXLAN:
8242         case ICE_SW_TUN_VXLAN_VLAN:
8243         case ICE_SW_TUN_UDP:
8244                 if (!ice_get_open_tunnel_port(hw, TNL_VXLAN, &open_port))
8245                         return ICE_ERR_CFG;
8246                 break;
8247
8248         case ICE_SW_TUN_GENEVE:
8249         case ICE_SW_TUN_GENEVE_VLAN:
8250                 if (!ice_get_open_tunnel_port(hw, TNL_GENEVE, &open_port))
8251                         return ICE_ERR_CFG;
8252                 break;
8253
8254         default:
8255                 /* Nothing needs to be done for this tunnel type */
8256                 return ICE_SUCCESS;
8257         }
8258
8259         /* Find the outer UDP protocol header and insert the port number */
8260         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
8261                 if (offsets[i].type == ICE_UDP_OF) {
8262                         struct ice_l4_hdr *hdr;
8263                         u16 offset;
8264
8265                         offset = offsets[i].offset;
8266                         hdr = (struct ice_l4_hdr *)&pkt[offset];
8267                         hdr->dst_port = CPU_TO_BE16(open_port);
8268
8269                         return ICE_SUCCESS;
8270                 }
8271         }
8272
8273         return ICE_ERR_CFG;
8274 }
8275
8276 /**
8277  * ice_find_adv_rule_entry - Search a rule entry
8278  * @hw: pointer to the hardware structure
8279  * @lkups: lookup elements or match criteria for the advanced recipe, one
8280  *         structure per protocol header
8281  * @lkups_cnt: number of protocols
8282  * @recp_id: recipe ID for which we are finding the rule
8283  * @rinfo: other information regarding the rule e.g. priority and action info
8284  *
8285  * Helper function to search for a given advance rule entry
8286  * Returns pointer to entry storing the rule if found
8287  */
8288 static struct ice_adv_fltr_mgmt_list_entry *
8289 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8290                         u16 lkups_cnt, u16 recp_id,
8291                         struct ice_adv_rule_info *rinfo)
8292 {
8293         struct ice_adv_fltr_mgmt_list_entry *list_itr;
8294         struct ice_switch_info *sw = hw->switch_info;
8295         int i;
8296
8297         LIST_FOR_EACH_ENTRY(list_itr, &sw->recp_list[recp_id].filt_rules,
8298                             ice_adv_fltr_mgmt_list_entry, list_entry) {
8299                 bool lkups_matched = true;
8300
8301                 if (lkups_cnt != list_itr->lkups_cnt)
8302                         continue;
8303                 for (i = 0; i < list_itr->lkups_cnt; i++)
8304                         if (memcmp(&list_itr->lkups[i], &lkups[i],
8305                                    sizeof(*lkups))) {
8306                                 lkups_matched = false;
8307                                 break;
8308                         }
8309                 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
8310                     rinfo->tun_type == list_itr->rule_info.tun_type &&
8311                     lkups_matched)
8312                         return list_itr;
8313         }
8314         return NULL;
8315 }
8316
8317 /**
8318  * ice_adv_add_update_vsi_list
8319  * @hw: pointer to the hardware structure
8320  * @m_entry: pointer to current adv filter management list entry
8321  * @cur_fltr: filter information from the book keeping entry
8322  * @new_fltr: filter information with the new VSI to be added
8323  *
8324  * Call AQ command to add or update previously created VSI list with new VSI.
8325  *
8326  * Helper function to do book keeping associated with adding filter information
8327  * The algorithm to do the booking keeping is described below :
8328  * When a VSI needs to subscribe to a given advanced filter
8329  *      if only one VSI has been added till now
8330  *              Allocate a new VSI list and add two VSIs
8331  *              to this list using switch rule command
8332  *              Update the previously created switch rule with the
8333  *              newly created VSI list ID
8334  *      if a VSI list was previously created
8335  *              Add the new VSI to the previously created VSI list set
8336  *              using the update switch rule command
8337  */
8338 static enum ice_status
8339 ice_adv_add_update_vsi_list(struct ice_hw *hw,
8340                             struct ice_adv_fltr_mgmt_list_entry *m_entry,
8341                             struct ice_adv_rule_info *cur_fltr,
8342                             struct ice_adv_rule_info *new_fltr)
8343 {
8344         enum ice_status status;
8345         u16 vsi_list_id = 0;
8346
8347         if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
8348             cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
8349             cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
8350                 return ICE_ERR_NOT_IMPL;
8351
8352         if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
8353              new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
8354             (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
8355              cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
8356                 return ICE_ERR_NOT_IMPL;
8357
8358         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
8359                  /* Only one entry existed in the mapping and it was not already
8360                   * a part of a VSI list. So, create a VSI list with the old and
8361                   * new VSIs.
8362                   */
8363                 struct ice_fltr_info tmp_fltr;
8364                 u16 vsi_handle_arr[2];
8365
8366                 /* A rule already exists with the new VSI being added */
8367                 if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
8368                     new_fltr->sw_act.fwd_id.hw_vsi_id)
8369                         return ICE_ERR_ALREADY_EXISTS;
8370
8371                 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
8372                 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
8373                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
8374                                                   &vsi_list_id,
8375                                                   ICE_SW_LKUP_LAST);
8376                 if (status)
8377                         return status;
8378
8379                 ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
8380                 tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
8381                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
8382                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
8383                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
8384                 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
8385
8386                 /* Update the previous switch rule of "forward to VSI" to
8387                  * "fwd to VSI list"
8388                  */
8389                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
8390                 if (status)
8391                         return status;
8392
8393                 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
8394                 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
8395                 m_entry->vsi_list_info =
8396                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
8397                                                 vsi_list_id);
8398         } else {
8399                 u16 vsi_handle = new_fltr->sw_act.vsi_handle;
8400
8401                 if (!m_entry->vsi_list_info)
8402                         return ICE_ERR_CFG;
8403
8404                 /* A rule already exists with the new VSI being added */
8405                 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
8406                         return ICE_SUCCESS;
8407
8408                 /* Update the previously created VSI list set with
8409                  * the new VSI ID passed in
8410                  */
8411                 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
8412
8413                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
8414                                                   vsi_list_id, false,
8415                                                   ice_aqc_opc_update_sw_rules,
8416                                                   ICE_SW_LKUP_LAST);
8417                 /* update VSI list mapping info with new VSI ID */
8418                 if (!status)
8419                         ice_set_bit(vsi_handle,
8420                                     m_entry->vsi_list_info->vsi_map);
8421         }
8422         if (!status)
8423                 m_entry->vsi_count++;
8424         return status;
8425 }
8426
8427 /**
8428  * ice_add_adv_rule - helper function to create an advanced switch rule
8429  * @hw: pointer to the hardware structure
8430  * @lkups: information on the words that needs to be looked up. All words
8431  * together makes one recipe
8432  * @lkups_cnt: num of entries in the lkups array
8433  * @rinfo: other information related to the rule that needs to be programmed
8434  * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
8435  *               ignored is case of error.
8436  *
8437  * This function can program only 1 rule at a time. The lkups is used to
8438  * describe the all the words that forms the "lookup" portion of the recipe.
8439  * These words can span multiple protocols. Callers to this function need to
8440  * pass in a list of protocol headers with lookup information along and mask
8441  * that determines which words are valid from the given protocol header.
8442  * rinfo describes other information related to this rule such as forwarding
8443  * IDs, priority of this rule, etc.
8444  */
8445 enum ice_status
8446 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8447                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
8448                  struct ice_rule_query_data *added_entry)
8449 {
8450         struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
8451         u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;
8452         const struct ice_dummy_pkt_offsets *pkt_offsets;
8453         struct ice_aqc_sw_rules_elem *s_rule = NULL;
8454         struct LIST_HEAD_TYPE *rule_head;
8455         struct ice_switch_info *sw;
8456         enum ice_status status;
8457         const u8 *pkt = NULL;
8458         bool prof_rule;
8459         u16 word_cnt;
8460         u32 act = 0;
8461         u8 q_rgn;
8462
8463         /* Initialize profile to result index bitmap */
8464         if (!hw->switch_info->prof_res_bm_init) {
8465                 hw->switch_info->prof_res_bm_init = 1;
8466                 ice_init_prof_result_bm(hw);
8467         }
8468
8469         prof_rule = ice_is_prof_rule(rinfo->tun_type);
8470         if (!prof_rule && !lkups_cnt)
8471                 return ICE_ERR_PARAM;
8472
8473         /* get # of words we need to match */
8474         word_cnt = 0;
8475         for (i = 0; i < lkups_cnt; i++) {
8476                 u16 j, *ptr;
8477
8478                 ptr = (u16 *)&lkups[i].m_u;
8479                 for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)
8480                         if (ptr[j] != 0)
8481                                 word_cnt++;
8482         }
8483
8484         if (prof_rule) {
8485                 if (word_cnt > ICE_MAX_CHAIN_WORDS)
8486                         return ICE_ERR_PARAM;
8487         } else {
8488                 if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS)
8489                         return ICE_ERR_PARAM;
8490         }
8491
8492         /* make sure that we can locate a dummy packet */
8493         ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
8494                               &pkt_offsets);
8495         if (!pkt) {
8496                 status = ICE_ERR_PARAM;
8497                 goto err_ice_add_adv_rule;
8498         }
8499
8500         if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
8501               rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
8502               rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
8503               rinfo->sw_act.fltr_act == ICE_DROP_PACKET))
8504                 return ICE_ERR_CFG;
8505
8506         vsi_handle = rinfo->sw_act.vsi_handle;
8507         if (!ice_is_vsi_valid(hw, vsi_handle))
8508                 return ICE_ERR_PARAM;
8509
8510         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
8511                 rinfo->sw_act.fwd_id.hw_vsi_id =
8512                         ice_get_hw_vsi_num(hw, vsi_handle);
8513         if (rinfo->sw_act.flag & ICE_FLTR_TX)
8514                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
8515
8516         status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
8517         if (status)
8518                 return status;
8519         m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
8520         if (m_entry) {
8521                 /* we have to add VSI to VSI_LIST and increment vsi_count.
8522                  * Also Update VSI list so that we can change forwarding rule
8523                  * if the rule already exists, we will check if it exists with
8524                  * same vsi_id, if not then add it to the VSI list if it already
8525                  * exists if not then create a VSI list and add the existing VSI
8526                  * ID and the new VSI ID to the list
8527                  * We will add that VSI to the list
8528                  */
8529                 status = ice_adv_add_update_vsi_list(hw, m_entry,
8530                                                      &m_entry->rule_info,
8531                                                      rinfo);
8532                 if (added_entry) {
8533                         added_entry->rid = rid;
8534                         added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
8535                         added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
8536                 }
8537                 return status;
8538         }
8539         rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;
8540         s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rule_buf_sz);
8541         if (!s_rule)
8542                 return ICE_ERR_NO_MEMORY;
8543         act |= ICE_SINGLE_ACT_LAN_ENABLE;
8544         switch (rinfo->sw_act.fltr_act) {
8545         case ICE_FWD_TO_VSI:
8546                 act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
8547                         ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
8548                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
8549                 break;
8550         case ICE_FWD_TO_Q:
8551                 act |= ICE_SINGLE_ACT_TO_Q;
8552                 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
8553                        ICE_SINGLE_ACT_Q_INDEX_M;
8554                 break;
8555         case ICE_FWD_TO_QGRP:
8556                 q_rgn = rinfo->sw_act.qgrp_size > 0 ?
8557                         (u8)ice_ilog2(rinfo->sw_act.qgrp_size) : 0;
8558                 act |= ICE_SINGLE_ACT_TO_Q;
8559                 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
8560                        ICE_SINGLE_ACT_Q_INDEX_M;
8561                 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
8562                        ICE_SINGLE_ACT_Q_REGION_M;
8563                 break;
8564         case ICE_DROP_PACKET:
8565                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
8566                        ICE_SINGLE_ACT_VALID_BIT;
8567                 break;
8568         default:
8569                 status = ICE_ERR_CFG;
8570                 goto err_ice_add_adv_rule;
8571         }
8572
8573         /* set the rule LOOKUP type based on caller specified 'RX'
8574          * instead of hardcoding it to be either LOOKUP_TX/RX
8575          *
8576          * for 'RX' set the source to be the port number
8577          * for 'TX' set the source to be the source HW VSI number (determined
8578          * by caller)
8579          */
8580         if (rinfo->rx) {
8581                 s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX);
8582                 s_rule->pdata.lkup_tx_rx.src =
8583                         CPU_TO_LE16(hw->port_info->lport);
8584         } else {
8585                 s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
8586                 s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(rinfo->sw_act.src);
8587         }
8588
8589         s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(rid);
8590         s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
8591
8592         status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt,
8593                                            pkt_len, pkt_offsets);
8594         if (status)
8595                 goto err_ice_add_adv_rule;
8596
8597         if (rinfo->tun_type != ICE_NON_TUN &&
8598             rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
8599                 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
8600                                                  s_rule->pdata.lkup_tx_rx.hdr,
8601                                                  pkt_offsets);
8602                 if (status)
8603                         goto err_ice_add_adv_rule;
8604         }
8605
8606         status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
8607                                  rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
8608                                  NULL);
8609         if (status)
8610                 goto err_ice_add_adv_rule;
8611         adv_fltr = (struct ice_adv_fltr_mgmt_list_entry *)
8612                 ice_malloc(hw, sizeof(struct ice_adv_fltr_mgmt_list_entry));
8613         if (!adv_fltr) {
8614                 status = ICE_ERR_NO_MEMORY;
8615                 goto err_ice_add_adv_rule;
8616         }
8617
8618         adv_fltr->lkups = (struct ice_adv_lkup_elem *)
8619                 ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups),
8620                            ICE_NONDMA_TO_NONDMA);
8621         if (!adv_fltr->lkups && !prof_rule) {
8622                 status = ICE_ERR_NO_MEMORY;
8623                 goto err_ice_add_adv_rule;
8624         }
8625
8626         adv_fltr->lkups_cnt = lkups_cnt;
8627         adv_fltr->rule_info = *rinfo;
8628         adv_fltr->rule_info.fltr_rule_id =
8629                 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
8630         sw = hw->switch_info;
8631         sw->recp_list[rid].adv_rule = true;
8632         rule_head = &sw->recp_list[rid].filt_rules;
8633
8634         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
8635                 adv_fltr->vsi_count = 1;
8636
8637         /* Add rule entry to book keeping list */
8638         LIST_ADD(&adv_fltr->list_entry, rule_head);
8639         if (added_entry) {
8640                 added_entry->rid = rid;
8641                 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
8642                 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
8643         }
8644 err_ice_add_adv_rule:
8645         if (status && adv_fltr) {
8646                 ice_free(hw, adv_fltr->lkups);
8647                 ice_free(hw, adv_fltr);
8648         }
8649
8650         ice_free(hw, s_rule);
8651
8652         return status;
8653 }
8654
8655 /**
8656  * ice_adv_rem_update_vsi_list
8657  * @hw: pointer to the hardware structure
8658  * @vsi_handle: VSI handle of the VSI to remove
8659  * @fm_list: filter management entry for which the VSI list management needs to
8660  *           be done
8661  */
8662 static enum ice_status
8663 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
8664                             struct ice_adv_fltr_mgmt_list_entry *fm_list)
8665 {
8666         struct ice_vsi_list_map_info *vsi_list_info;
8667         enum ice_sw_lkup_type lkup_type;
8668         enum ice_status status;
8669         u16 vsi_list_id;
8670
8671         if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
8672             fm_list->vsi_count == 0)
8673                 return ICE_ERR_PARAM;
8674
8675         /* A rule with the VSI being removed does not exist */
8676         if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
8677                 return ICE_ERR_DOES_NOT_EXIST;
8678
8679         lkup_type = ICE_SW_LKUP_LAST;
8680         vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
8681         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
8682                                           ice_aqc_opc_update_sw_rules,
8683                                           lkup_type);
8684         if (status)
8685                 return status;
8686
8687         fm_list->vsi_count--;
8688         ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
8689         vsi_list_info = fm_list->vsi_list_info;
8690         if (fm_list->vsi_count == 1) {
8691                 struct ice_fltr_info tmp_fltr;
8692                 u16 rem_vsi_handle;
8693
8694                 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
8695                                                     ICE_MAX_VSI);
8696                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
8697                         return ICE_ERR_OUT_OF_RANGE;
8698
8699                 /* Make sure VSI list is empty before removing it below */
8700                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
8701                                                   vsi_list_id, true,
8702                                                   ice_aqc_opc_update_sw_rules,
8703                                                   lkup_type);
8704                 if (status)
8705                         return status;
8706
8707                 ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
8708                 tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
8709                 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
8710                 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
8711                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
8712                 tmp_fltr.fwd_id.hw_vsi_id =
8713                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
8714                 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
8715                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
8716                 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
8717
8718                 /* Update the previous switch rule of "MAC forward to VSI" to
8719                  * "MAC fwd to VSI list"
8720                  */
8721                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
8722                 if (status) {
8723                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
8724                                   tmp_fltr.fwd_id.hw_vsi_id, status);
8725                         return status;
8726                 }
8727                 fm_list->vsi_list_info->ref_cnt--;
8728
8729                 /* Remove the VSI list since it is no longer used */
8730                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
8731                 if (status) {
8732                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
8733                                   vsi_list_id, status);
8734                         return status;
8735                 }
8736
8737                 LIST_DEL(&vsi_list_info->list_entry);
8738                 ice_free(hw, vsi_list_info);
8739                 fm_list->vsi_list_info = NULL;
8740         }
8741
8742         return status;
8743 }
8744
8745 /**
8746  * ice_rem_adv_rule - removes existing advanced switch rule
8747  * @hw: pointer to the hardware structure
8748  * @lkups: information on the words that needs to be looked up. All words
8749  *         together makes one recipe
8750  * @lkups_cnt: num of entries in the lkups array
8751  * @rinfo: Its the pointer to the rule information for the rule
8752  *
8753  * This function can be used to remove 1 rule at a time. The lkups is
8754  * used to describe all the words that forms the "lookup" portion of the
8755  * rule. These words can span multiple protocols. Callers to this function
8756  * need to pass in a list of protocol headers with lookup information along
8757  * and mask that determines which words are valid from the given protocol
8758  * header. rinfo describes other information related to this rule such as
8759  * forwarding IDs, priority of this rule, etc.
8760  */
8761 enum ice_status
8762 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8763                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
8764 {
8765         struct ice_adv_fltr_mgmt_list_entry *list_elem;
8766         struct ice_prot_lkup_ext lkup_exts;
8767         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
8768         enum ice_status status = ICE_SUCCESS;
8769         bool remove_rule = false;
8770         u16 i, rid, vsi_handle;
8771
8772         ice_memset(&lkup_exts, 0, sizeof(lkup_exts), ICE_NONDMA_MEM);
8773         for (i = 0; i < lkups_cnt; i++) {
8774                 u16 count;
8775
8776                 if (lkups[i].type >= ICE_PROTOCOL_LAST)
8777                         return ICE_ERR_CFG;
8778
8779                 count = ice_fill_valid_words(&lkups[i], &lkup_exts);
8780                 if (!count)
8781                         return ICE_ERR_CFG;
8782         }
8783
8784         /* Create any special protocol/offset pairs, such as looking at tunnel
8785          * bits by extracting metadata
8786          */
8787         status = ice_add_special_words(rinfo, &lkup_exts);
8788         if (status)
8789                 return status;
8790
8791         rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type, rinfo->priority);
8792         /* If did not find a recipe that match the existing criteria */
8793         if (rid == ICE_MAX_NUM_RECIPES)
8794                 return ICE_ERR_PARAM;
8795
8796         rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
8797         list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
8798         /* the rule is already removed */
8799         if (!list_elem)
8800                 return ICE_SUCCESS;
8801         ice_acquire_lock(rule_lock);
8802         if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
8803                 remove_rule = true;
8804         } else if (list_elem->vsi_count > 1) {
8805                 remove_rule = false;
8806                 vsi_handle = rinfo->sw_act.vsi_handle;
8807                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
8808         } else {
8809                 vsi_handle = rinfo->sw_act.vsi_handle;
8810                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
8811                 if (status) {
8812                         ice_release_lock(rule_lock);
8813                         return status;
8814                 }
8815                 if (list_elem->vsi_count == 0)
8816                         remove_rule = true;
8817         }
8818         ice_release_lock(rule_lock);
8819         if (remove_rule) {
8820                 struct ice_aqc_sw_rules_elem *s_rule;
8821                 u16 rule_buf_sz;
8822
8823                 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
8824                 s_rule = (struct ice_aqc_sw_rules_elem *)
8825                         ice_malloc(hw, rule_buf_sz);
8826                 if (!s_rule)
8827                         return ICE_ERR_NO_MEMORY;
8828                 s_rule->pdata.lkup_tx_rx.act = 0;
8829                 s_rule->pdata.lkup_tx_rx.index =
8830                         CPU_TO_LE16(list_elem->rule_info.fltr_rule_id);
8831                 s_rule->pdata.lkup_tx_rx.hdr_len = 0;
8832                 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
8833                                          rule_buf_sz, 1,
8834                                          ice_aqc_opc_remove_sw_rules, NULL);
8835                 if (status == ICE_SUCCESS || status == ICE_ERR_DOES_NOT_EXIST) {
8836                         struct ice_switch_info *sw = hw->switch_info;
8837
8838                         ice_acquire_lock(rule_lock);
8839                         LIST_DEL(&list_elem->list_entry);
8840                         ice_free(hw, list_elem->lkups);
8841                         ice_free(hw, list_elem);
8842                         ice_release_lock(rule_lock);
8843                         if (LIST_EMPTY(&sw->recp_list[rid].filt_rules))
8844                                 sw->recp_list[rid].adv_rule = false;
8845                 }
8846                 ice_free(hw, s_rule);
8847         }
8848         return status;
8849 }
8850
8851 /**
8852  * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
8853  * @hw: pointer to the hardware structure
8854  * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
8855  *
8856  * This function is used to remove 1 rule at a time. The removal is based on
8857  * the remove_entry parameter. This function will remove rule for a given
8858  * vsi_handle with a given rule_id which is passed as parameter in remove_entry
8859  */
8860 enum ice_status
8861 ice_rem_adv_rule_by_id(struct ice_hw *hw,
8862                        struct ice_rule_query_data *remove_entry)
8863 {
8864         struct ice_adv_fltr_mgmt_list_entry *list_itr;
8865         struct LIST_HEAD_TYPE *list_head;
8866         struct ice_adv_rule_info rinfo;
8867         struct ice_switch_info *sw;
8868
8869         sw = hw->switch_info;
8870         if (!sw->recp_list[remove_entry->rid].recp_created)
8871                 return ICE_ERR_PARAM;
8872         list_head = &sw->recp_list[remove_entry->rid].filt_rules;
8873         LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_adv_fltr_mgmt_list_entry,
8874                             list_entry) {
8875                 if (list_itr->rule_info.fltr_rule_id ==
8876                     remove_entry->rule_id) {
8877                         rinfo = list_itr->rule_info;
8878                         rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
8879                         return ice_rem_adv_rule(hw, list_itr->lkups,
8880                                                 list_itr->lkups_cnt, &rinfo);
8881                 }
8882         }
8883         /* either list is empty or unable to find rule */
8884         return ICE_ERR_DOES_NOT_EXIST;
8885 }
8886
8887 /**
8888  * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a
8889  *                       given VSI handle
8890  * @hw: pointer to the hardware structure
8891  * @vsi_handle: VSI handle for which we are supposed to remove all the rules.
8892  *
8893  * This function is used to remove all the rules for a given VSI and as soon
8894  * as removing a rule fails, it will return immediately with the error code,
8895  * else it will return ICE_SUCCESS
8896  */
8897 enum ice_status ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
8898 {
8899         struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
8900         struct ice_vsi_list_map_info *map_info;
8901         struct LIST_HEAD_TYPE *list_head;
8902         struct ice_adv_rule_info rinfo;
8903         struct ice_switch_info *sw;
8904         enum ice_status status;
8905         u8 rid;
8906
8907         sw = hw->switch_info;
8908         for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
8909                 if (!sw->recp_list[rid].recp_created)
8910                         continue;
8911                 if (!sw->recp_list[rid].adv_rule)
8912                         continue;
8913
8914                 list_head = &sw->recp_list[rid].filt_rules;
8915                 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp_entry, list_head,
8916                                          ice_adv_fltr_mgmt_list_entry,
8917                                          list_entry) {
8918                         rinfo = list_itr->rule_info;
8919
8920                         if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
8921                                 map_info = list_itr->vsi_list_info;
8922                                 if (!map_info)
8923                                         continue;
8924
8925                                 if (!ice_is_bit_set(map_info->vsi_map,
8926                                                     vsi_handle))
8927                                         continue;
8928                         } else if (rinfo.sw_act.vsi_handle != vsi_handle) {
8929                                 continue;
8930                         }
8931
8932                         rinfo.sw_act.vsi_handle = vsi_handle;
8933                         status = ice_rem_adv_rule(hw, list_itr->lkups,
8934                                                   list_itr->lkups_cnt, &rinfo);
8935
8936                         if (status)
8937                                 return status;
8938                 }
8939         }
8940         return ICE_SUCCESS;
8941 }
8942
8943 /**
8944  * ice_replay_fltr - Replay all the filters stored by a specific list head
8945  * @hw: pointer to the hardware structure
8946  * @list_head: list for which filters needs to be replayed
8947  * @recp_id: Recipe ID for which rules need to be replayed
8948  */
8949 static enum ice_status
8950 ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head)
8951 {
8952         struct ice_fltr_mgmt_list_entry *itr;
8953         enum ice_status status = ICE_SUCCESS;
8954         struct ice_sw_recipe *recp_list;
8955         u8 lport = hw->port_info->lport;
8956         struct LIST_HEAD_TYPE l_head;
8957
8958         if (LIST_EMPTY(list_head))
8959                 return status;
8960
8961         recp_list = &hw->switch_info->recp_list[recp_id];
8962         /* Move entries from the given list_head to a temporary l_head so that
8963          * they can be replayed. Otherwise when trying to re-add the same
8964          * filter, the function will return already exists
8965          */
8966         LIST_REPLACE_INIT(list_head, &l_head);
8967
8968         /* Mark the given list_head empty by reinitializing it so filters
8969          * could be added again by *handler
8970          */
8971         LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry,
8972                             list_entry) {
8973                 struct ice_fltr_list_entry f_entry;
8974                 u16 vsi_handle;
8975
8976                 f_entry.fltr_info = itr->fltr_info;
8977                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
8978                         status = ice_add_rule_internal(hw, recp_list, lport,
8979                                                        &f_entry);
8980                         if (status != ICE_SUCCESS)
8981                                 goto end;
8982                         continue;
8983                 }
8984
8985                 /* Add a filter per VSI separately */
8986                 ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map,
8987                                      ICE_MAX_VSI) {
8988                         if (!ice_is_vsi_valid(hw, vsi_handle))
8989                                 break;
8990
8991                         ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
8992                         f_entry.fltr_info.vsi_handle = vsi_handle;
8993                         f_entry.fltr_info.fwd_id.hw_vsi_id =
8994                                 ice_get_hw_vsi_num(hw, vsi_handle);
8995                         f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
8996                         if (recp_id == ICE_SW_LKUP_VLAN)
8997                                 status = ice_add_vlan_internal(hw, recp_list,
8998                                                                &f_entry);
8999                         else
9000                                 status = ice_add_rule_internal(hw, recp_list,
9001                                                                lport,
9002                                                                &f_entry);
9003                         if (status != ICE_SUCCESS)
9004                                 goto end;
9005                 }
9006         }
9007 end:
9008         /* Clear the filter management list */
9009         ice_rem_sw_rule_info(hw, &l_head);
9010         return status;
9011 }
9012
9013 /**
9014  * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
9015  * @hw: pointer to the hardware structure
9016  *
9017  * NOTE: This function does not clean up partially added filters on error.
9018  * It is up to caller of the function to issue a reset or fail early.
9019  */
9020 enum ice_status ice_replay_all_fltr(struct ice_hw *hw)
9021 {
9022         struct ice_switch_info *sw = hw->switch_info;
9023         enum ice_status status = ICE_SUCCESS;
9024         u8 i;
9025
9026         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9027                 struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules;
9028
9029                 status = ice_replay_fltr(hw, i, head);
9030                 if (status != ICE_SUCCESS)
9031                         return status;
9032         }
9033         return status;
9034 }
9035
9036 /**
9037  * ice_replay_vsi_fltr - Replay filters for requested VSI
9038  * @hw: pointer to the hardware structure
9039  * @pi: pointer to port information structure
9040  * @sw: pointer to switch info struct for which function replays filters
9041  * @vsi_handle: driver VSI handle
9042  * @recp_id: Recipe ID for which rules need to be replayed
9043  * @list_head: list for which filters need to be replayed
9044  *
9045  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
9046  * It is required to pass valid VSI handle.
9047  */
9048 static enum ice_status
9049 ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9050                     struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id,
9051                     struct LIST_HEAD_TYPE *list_head)
9052 {
9053         struct ice_fltr_mgmt_list_entry *itr;
9054         enum ice_status status = ICE_SUCCESS;
9055         struct ice_sw_recipe *recp_list;
9056         u16 hw_vsi_id;
9057
9058         if (LIST_EMPTY(list_head))
9059                 return status;
9060         recp_list = &sw->recp_list[recp_id];
9061         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
9062
9063         LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry,
9064                             list_entry) {
9065                 struct ice_fltr_list_entry f_entry;
9066
9067                 f_entry.fltr_info = itr->fltr_info;
9068                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
9069                     itr->fltr_info.vsi_handle == vsi_handle) {
9070                         /* update the src in case it is VSI num */
9071                         if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
9072                                 f_entry.fltr_info.src = hw_vsi_id;
9073                         status = ice_add_rule_internal(hw, recp_list,
9074                                                        pi->lport,
9075                                                        &f_entry);
9076                         if (status != ICE_SUCCESS)
9077                                 goto end;
9078                         continue;
9079                 }
9080                 if (!itr->vsi_list_info ||
9081                     !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle))
9082                         continue;
9083                 /* Clearing it so that the logic can add it back */
9084                 ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
9085                 f_entry.fltr_info.vsi_handle = vsi_handle;
9086                 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
9087                 /* update the src in case it is VSI num */
9088                 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
9089                         f_entry.fltr_info.src = hw_vsi_id;
9090                 if (recp_id == ICE_SW_LKUP_VLAN)
9091                         status = ice_add_vlan_internal(hw, recp_list, &f_entry);
9092                 else
9093                         status = ice_add_rule_internal(hw, recp_list,
9094                                                        pi->lport,
9095                                                        &f_entry);
9096                 if (status != ICE_SUCCESS)
9097                         goto end;
9098         }
9099 end:
9100         return status;
9101 }
9102
9103 /**
9104  * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
9105  * @hw: pointer to the hardware structure
9106  * @vsi_handle: driver VSI handle
9107  * @list_head: list for which filters need to be replayed
9108  *
9109  * Replay the advanced rule for the given VSI.
9110  */
9111 static enum ice_status
9112 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
9113                         struct LIST_HEAD_TYPE *list_head)
9114 {
9115         struct ice_rule_query_data added_entry = { 0 };
9116         struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
9117         enum ice_status status = ICE_SUCCESS;
9118
9119         if (LIST_EMPTY(list_head))
9120                 return status;
9121         LIST_FOR_EACH_ENTRY(adv_fltr, list_head, ice_adv_fltr_mgmt_list_entry,
9122                             list_entry) {
9123                 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
9124                 u16 lk_cnt = adv_fltr->lkups_cnt;
9125
9126                 if (vsi_handle != rinfo->sw_act.vsi_handle)
9127                         continue;
9128                 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
9129                                           &added_entry);
9130                 if (status)
9131                         break;
9132         }
9133         return status;
9134 }
9135
9136 /**
9137  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
9138  * @hw: pointer to the hardware structure
9139  * @pi: pointer to port information structure
9140  * @vsi_handle: driver VSI handle
9141  *
9142  * Replays filters for requested VSI via vsi_handle.
9143  */
9144 enum ice_status
9145 ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9146                         u16 vsi_handle)
9147 {
9148         struct ice_switch_info *sw = hw->switch_info;
9149         enum ice_status status;
9150         u8 i;
9151
9152         /* Update the recipes that were created */
9153         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9154                 struct LIST_HEAD_TYPE *head;
9155
9156                 head = &sw->recp_list[i].filt_replay_rules;
9157                 if (!sw->recp_list[i].adv_rule)
9158                         status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i,
9159                                                      head);
9160                 else
9161                         status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
9162                 if (status != ICE_SUCCESS)
9163                         return status;
9164         }
9165
9166         return ICE_SUCCESS;
9167 }
9168
9169 /**
9170  * ice_rm_sw_replay_rule_info - helper function to delete filter replay rules
9171  * @hw: pointer to the HW struct
9172  * @sw: pointer to switch info struct for which function removes filters
9173  *
9174  * Deletes the filter replay rules for given switch
9175  */
9176 void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw)
9177 {
9178         u8 i;
9179
9180         if (!sw)
9181                 return;
9182
9183         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9184                 if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) {
9185                         struct LIST_HEAD_TYPE *l_head;
9186
9187                         l_head = &sw->recp_list[i].filt_replay_rules;
9188                         if (!sw->recp_list[i].adv_rule)
9189                                 ice_rem_sw_rule_info(hw, l_head);
9190                         else
9191                                 ice_rem_adv_rule_info(hw, l_head);
9192                 }
9193         }
9194 }
9195
9196 /**
9197  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
9198  * @hw: pointer to the HW struct
9199  *
9200  * Deletes the filter replay rules.
9201  */
9202 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
9203 {
9204         ice_rm_sw_replay_rule_info(hw, hw->switch_info);
9205 }