net/ice/base: cleanup filter list on error
[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_OFOS,        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_OFOS 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_OFOS,        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_OFOS 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_OFOS,        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_OFOS,        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_OFOS 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_IL 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_OFOS,        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_OFOS 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_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         /* cppcheck-suppress constArgument */
3178         *num_recipes = LE16_TO_CPU(cmd->num_sub_recipes);
3179
3180         return status;
3181 }
3182
3183 /**
3184  * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
3185  * @hw: pointer to the HW struct
3186  * @params: parameters used to update the default recipe
3187  *
3188  * This function only supports updating default recipes and it only supports
3189  * updating a single recipe based on the lkup_idx at a time.
3190  *
3191  * This is done as a read-modify-write operation. First, get the current recipe
3192  * contents based on the recipe's ID. Then modify the field vector index and
3193  * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
3194  * the pre-existing recipe with the modifications.
3195  */
3196 enum ice_status
3197 ice_update_recipe_lkup_idx(struct ice_hw *hw,
3198                            struct ice_update_recipe_lkup_idx_params *params)
3199 {
3200         struct ice_aqc_recipe_data_elem *rcp_list;
3201         u16 num_recps = ICE_MAX_NUM_RECIPES;
3202         enum ice_status status;
3203
3204         rcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));
3205         if (!rcp_list)
3206                 return ICE_ERR_NO_MEMORY;
3207
3208         /* read current recipe list from firmware */
3209         rcp_list->recipe_indx = params->rid;
3210         status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
3211         if (status) {
3212                 ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
3213                           params->rid, status);
3214                 goto error_out;
3215         }
3216
3217         /* only modify existing recipe's lkup_idx and mask if valid, while
3218          * leaving all other fields the same, then update the recipe firmware
3219          */
3220         rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
3221         if (params->mask_valid)
3222                 rcp_list->content.mask[params->lkup_idx] =
3223                         CPU_TO_LE16(params->mask);
3224
3225         if (params->ignore_valid)
3226                 rcp_list->content.lkup_indx[params->lkup_idx] |=
3227                         ICE_AQ_RECIPE_LKUP_IGNORE;
3228
3229         status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
3230         if (status)
3231                 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",
3232                           params->rid, params->lkup_idx, params->fv_idx,
3233                           params->mask, params->mask_valid ? "true" : "false",
3234                           status);
3235
3236 error_out:
3237         ice_free(hw, rcp_list);
3238         return status;
3239 }
3240
3241 /**
3242  * ice_aq_map_recipe_to_profile - Map recipe to packet profile
3243  * @hw: pointer to the HW struct
3244  * @profile_id: package profile ID to associate the recipe with
3245  * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3246  * @cd: pointer to command details structure or NULL
3247  * Recipe to profile association (0x0291)
3248  */
3249 enum ice_status
3250 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3251                              struct ice_sq_cd *cd)
3252 {
3253         struct ice_aqc_recipe_to_profile *cmd;
3254         struct ice_aq_desc desc;
3255
3256         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3257         cmd = &desc.params.recipe_to_profile;
3258         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
3259         cmd->profile_id = CPU_TO_LE16(profile_id);
3260         /* Set the recipe ID bit in the bitmask to let the device know which
3261          * profile we are associating the recipe to
3262          */
3263         ice_memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc),
3264                    ICE_NONDMA_TO_NONDMA);
3265
3266         return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3267 }
3268
3269 /**
3270  * ice_aq_get_recipe_to_profile - Map recipe to packet profile
3271  * @hw: pointer to the HW struct
3272  * @profile_id: package profile ID to associate the recipe with
3273  * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3274  * @cd: pointer to command details structure or NULL
3275  * Associate profile ID with given recipe (0x0293)
3276  */
3277 enum ice_status
3278 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3279                              struct ice_sq_cd *cd)
3280 {
3281         struct ice_aqc_recipe_to_profile *cmd;
3282         struct ice_aq_desc desc;
3283         enum ice_status status;
3284
3285         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3286         cmd = &desc.params.recipe_to_profile;
3287         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
3288         cmd->profile_id = CPU_TO_LE16(profile_id);
3289
3290         status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3291         if (!status)
3292                 ice_memcpy(r_bitmap, cmd->recipe_assoc,
3293                            sizeof(cmd->recipe_assoc), ICE_NONDMA_TO_NONDMA);
3294
3295         return status;
3296 }
3297
3298 /**
3299  * ice_alloc_recipe - add recipe resource
3300  * @hw: pointer to the hardware structure
3301  * @rid: recipe ID returned as response to AQ call
3302  */
3303 enum ice_status ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
3304 {
3305         struct ice_aqc_alloc_free_res_elem *sw_buf;
3306         enum ice_status status;
3307         u16 buf_len;
3308
3309         buf_len = ice_struct_size(sw_buf, elem, 1);
3310         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3311         if (!sw_buf)
3312                 return ICE_ERR_NO_MEMORY;
3313
3314         sw_buf->num_elems = CPU_TO_LE16(1);
3315         sw_buf->res_type = CPU_TO_LE16((ICE_AQC_RES_TYPE_RECIPE <<
3316                                         ICE_AQC_RES_TYPE_S) |
3317                                         ICE_AQC_RES_TYPE_FLAG_SHARED);
3318         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
3319                                        ice_aqc_opc_alloc_res, NULL);
3320         if (!status)
3321                 *rid = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
3322         ice_free(hw, sw_buf);
3323
3324         return status;
3325 }
3326
3327 /* ice_init_port_info - Initialize port_info with switch configuration data
3328  * @pi: pointer to port_info
3329  * @vsi_port_num: VSI number or port number
3330  * @type: Type of switch element (port or VSI)
3331  * @swid: switch ID of the switch the element is attached to
3332  * @pf_vf_num: PF or VF number
3333  * @is_vf: true if the element is a VF, false otherwise
3334  */
3335 static void
3336 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
3337                    u16 swid, u16 pf_vf_num, bool is_vf)
3338 {
3339         switch (type) {
3340         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3341                 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
3342                 pi->sw_id = swid;
3343                 pi->pf_vf_num = pf_vf_num;
3344                 pi->is_vf = is_vf;
3345                 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
3346                 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
3347                 break;
3348         default:
3349                 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
3350                 break;
3351         }
3352 }
3353
3354 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
3355  * @hw: pointer to the hardware structure
3356  */
3357 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
3358 {
3359         struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
3360         enum ice_status status;
3361         u8 num_total_ports;
3362         u16 req_desc = 0;
3363         u16 num_elems;
3364         u8 j = 0;
3365         u16 i;
3366
3367         num_total_ports = 1;
3368
3369         rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *)
3370                 ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN);
3371
3372         if (!rbuf)
3373                 return ICE_ERR_NO_MEMORY;
3374
3375         /* Multiple calls to ice_aq_get_sw_cfg may be required
3376          * to get all the switch configuration information. The need
3377          * for additional calls is indicated by ice_aq_get_sw_cfg
3378          * writing a non-zero value in req_desc
3379          */
3380         do {
3381                 struct ice_aqc_get_sw_cfg_resp_elem *ele;
3382
3383                 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
3384                                            &req_desc, &num_elems, NULL);
3385
3386                 if (status)
3387                         break;
3388
3389                 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
3390                         u16 pf_vf_num, swid, vsi_port_num;
3391                         bool is_vf = false;
3392                         u8 res_type;
3393
3394                         vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) &
3395                                 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
3396
3397                         pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) &
3398                                 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
3399
3400                         swid = LE16_TO_CPU(ele->swid);
3401
3402                         if (LE16_TO_CPU(ele->pf_vf_num) &
3403                             ICE_AQC_GET_SW_CONF_RESP_IS_VF)
3404                                 is_vf = true;
3405
3406                         res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >>
3407                                         ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
3408
3409                         switch (res_type) {
3410                         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3411                         case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT:
3412                                 if (j == num_total_ports) {
3413                                         ice_debug(hw, ICE_DBG_SW, "more ports than expected\n");
3414                                         status = ICE_ERR_CFG;
3415                                         goto out;
3416                                 }
3417                                 ice_init_port_info(hw->port_info,
3418                                                    vsi_port_num, res_type, swid,
3419                                                    pf_vf_num, is_vf);
3420                                 j++;
3421                                 break;
3422                         default:
3423                                 break;
3424                         }
3425                 }
3426         } while (req_desc && !status);
3427
3428 out:
3429         ice_free(hw, rbuf);
3430         return status;
3431 }
3432
3433 /**
3434  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
3435  * @hw: pointer to the hardware structure
3436  * @fi: filter info structure to fill/update
3437  *
3438  * This helper function populates the lb_en and lan_en elements of the provided
3439  * ice_fltr_info struct using the switch's type and characteristics of the
3440  * switch rule being configured.
3441  */
3442 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
3443 {
3444         if ((fi->flag & ICE_FLTR_RX) &&
3445             (fi->fltr_act == ICE_FWD_TO_VSI ||
3446              fi->fltr_act == ICE_FWD_TO_VSI_LIST) &&
3447             fi->lkup_type == ICE_SW_LKUP_LAST)
3448                 fi->lan_en = true;
3449         fi->lb_en = false;
3450         fi->lan_en = false;
3451         if ((fi->flag & ICE_FLTR_TX) &&
3452             (fi->fltr_act == ICE_FWD_TO_VSI ||
3453              fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
3454              fi->fltr_act == ICE_FWD_TO_Q ||
3455              fi->fltr_act == ICE_FWD_TO_QGRP)) {
3456                 /* Setting LB for prune actions will result in replicated
3457                  * packets to the internal switch that will be dropped.
3458                  */
3459                 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
3460                         fi->lb_en = true;
3461
3462                 /* Set lan_en to TRUE if
3463                  * 1. The switch is a VEB AND
3464                  * 2
3465                  * 2.1 The lookup is a directional lookup like ethertype,
3466                  * promiscuous, ethertype-MAC, promiscuous-VLAN
3467                  * and default-port OR
3468                  * 2.2 The lookup is VLAN, OR
3469                  * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
3470                  * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
3471                  *
3472                  * OR
3473                  *
3474                  * The switch is a VEPA.
3475                  *
3476                  * In all other cases, the LAN enable has to be set to false.
3477                  */
3478                 if (hw->evb_veb) {
3479                         if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3480                             fi->lkup_type == ICE_SW_LKUP_PROMISC ||
3481                             fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3482                             fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3483                             fi->lkup_type == ICE_SW_LKUP_DFLT ||
3484                             fi->lkup_type == ICE_SW_LKUP_VLAN ||
3485                             (fi->lkup_type == ICE_SW_LKUP_MAC &&
3486                              !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) ||
3487                             (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
3488                              !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)))
3489                                 fi->lan_en = true;
3490                 } else {
3491                         fi->lan_en = true;
3492                 }
3493         }
3494 }
3495
3496 /**
3497  * ice_fill_sw_rule - Helper function to fill switch rule structure
3498  * @hw: pointer to the hardware structure
3499  * @f_info: entry containing packet forwarding information
3500  * @s_rule: switch rule structure to be filled in based on mac_entry
3501  * @opc: switch rules population command type - pass in the command opcode
3502  */
3503 static void
3504 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
3505                  struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
3506 {
3507         u16 vlan_id = ICE_MAX_VLAN_ID + 1;
3508         u16 vlan_tpid = ICE_ETH_P_8021Q;
3509         void *daddr = NULL;
3510         u16 eth_hdr_sz;
3511         u8 *eth_hdr;
3512         u32 act = 0;
3513         __be16 *off;
3514         u8 q_rgn;
3515
3516         if (opc == ice_aqc_opc_remove_sw_rules) {
3517                 s_rule->pdata.lkup_tx_rx.act = 0;
3518                 s_rule->pdata.lkup_tx_rx.index =
3519                         CPU_TO_LE16(f_info->fltr_rule_id);
3520                 s_rule->pdata.lkup_tx_rx.hdr_len = 0;
3521                 return;
3522         }
3523
3524         eth_hdr_sz = sizeof(dummy_eth_header);
3525         eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
3526
3527         /* initialize the ether header with a dummy header */
3528         ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA);
3529         ice_fill_sw_info(hw, f_info);
3530
3531         switch (f_info->fltr_act) {
3532         case ICE_FWD_TO_VSI:
3533                 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
3534                         ICE_SINGLE_ACT_VSI_ID_M;
3535                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
3536                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
3537                                 ICE_SINGLE_ACT_VALID_BIT;
3538                 break;
3539         case ICE_FWD_TO_VSI_LIST:
3540                 act |= ICE_SINGLE_ACT_VSI_LIST;
3541                 act |= (f_info->fwd_id.vsi_list_id <<
3542                         ICE_SINGLE_ACT_VSI_LIST_ID_S) &
3543                         ICE_SINGLE_ACT_VSI_LIST_ID_M;
3544                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
3545                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
3546                                 ICE_SINGLE_ACT_VALID_BIT;
3547                 break;
3548         case ICE_FWD_TO_Q:
3549                 act |= ICE_SINGLE_ACT_TO_Q;
3550                 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
3551                         ICE_SINGLE_ACT_Q_INDEX_M;
3552                 break;
3553         case ICE_DROP_PACKET:
3554                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
3555                         ICE_SINGLE_ACT_VALID_BIT;
3556                 break;
3557         case ICE_FWD_TO_QGRP:
3558                 q_rgn = f_info->qgrp_size > 0 ?
3559                         (u8)ice_ilog2(f_info->qgrp_size) : 0;
3560                 act |= ICE_SINGLE_ACT_TO_Q;
3561                 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
3562                         ICE_SINGLE_ACT_Q_INDEX_M;
3563                 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
3564                         ICE_SINGLE_ACT_Q_REGION_M;
3565                 break;
3566         default:
3567                 return;
3568         }
3569
3570         if (f_info->lb_en)
3571                 act |= ICE_SINGLE_ACT_LB_ENABLE;
3572         if (f_info->lan_en)
3573                 act |= ICE_SINGLE_ACT_LAN_ENABLE;
3574
3575         switch (f_info->lkup_type) {
3576         case ICE_SW_LKUP_MAC:
3577                 daddr = f_info->l_data.mac.mac_addr;
3578                 break;
3579         case ICE_SW_LKUP_VLAN:
3580                 vlan_id = f_info->l_data.vlan.vlan_id;
3581                 if (f_info->l_data.vlan.tpid_valid)
3582                         vlan_tpid = f_info->l_data.vlan.tpid;
3583                 if (f_info->fltr_act == ICE_FWD_TO_VSI ||
3584                     f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3585                         act |= ICE_SINGLE_ACT_PRUNE;
3586                         act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
3587                 }
3588                 break;
3589         case ICE_SW_LKUP_ETHERTYPE_MAC:
3590                 daddr = f_info->l_data.ethertype_mac.mac_addr;
3591                 /* fall-through */
3592         case ICE_SW_LKUP_ETHERTYPE:
3593                 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
3594                 *off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype);
3595                 break;
3596         case ICE_SW_LKUP_MAC_VLAN:
3597                 daddr = f_info->l_data.mac_vlan.mac_addr;
3598                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
3599                 break;
3600         case ICE_SW_LKUP_PROMISC_VLAN:
3601                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
3602                 /* fall-through */
3603         case ICE_SW_LKUP_PROMISC:
3604                 daddr = f_info->l_data.mac_vlan.mac_addr;
3605                 break;
3606         default:
3607                 break;
3608         }
3609
3610         s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
3611                 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) :
3612                 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
3613
3614         /* Recipe set depending on lookup type */
3615         s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(f_info->lkup_type);
3616         s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(f_info->src);
3617         s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
3618
3619         if (daddr)
3620                 ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN,
3621                            ICE_NONDMA_TO_NONDMA);
3622
3623         if (!(vlan_id > ICE_MAX_VLAN_ID)) {
3624                 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
3625                 *off = CPU_TO_BE16(vlan_id);
3626                 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
3627                 *off = CPU_TO_BE16(vlan_tpid);
3628         }
3629
3630         /* Create the switch rule with the final dummy Ethernet header */
3631         if (opc != ice_aqc_opc_update_sw_rules)
3632                 s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(eth_hdr_sz);
3633 }
3634
3635 /**
3636  * ice_add_marker_act
3637  * @hw: pointer to the hardware structure
3638  * @m_ent: the management entry for which sw marker needs to be added
3639  * @sw_marker: sw marker to tag the Rx descriptor with
3640  * @l_id: large action resource ID
3641  *
3642  * Create a large action to hold software marker and update the switch rule
3643  * entry pointed by m_ent with newly created large action
3644  */
3645 static enum ice_status
3646 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
3647                    u16 sw_marker, u16 l_id)
3648 {
3649         struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
3650         /* For software marker we need 3 large actions
3651          * 1. FWD action: FWD TO VSI or VSI LIST
3652          * 2. GENERIC VALUE action to hold the profile ID
3653          * 3. GENERIC VALUE action to hold the software marker ID
3654          */
3655         const u16 num_lg_acts = 3;
3656         enum ice_status status;
3657         u16 lg_act_size;
3658         u16 rules_size;
3659         u32 act;
3660         u16 id;
3661
3662         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
3663                 return ICE_ERR_PARAM;
3664
3665         /* Create two back-to-back switch rules and submit them to the HW using
3666          * one memory buffer:
3667          *    1. Large Action
3668          *    2. Look up Tx Rx
3669          */
3670         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
3671         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
3672         lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
3673         if (!lg_act)
3674                 return ICE_ERR_NO_MEMORY;
3675
3676         rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
3677
3678         /* Fill in the first switch rule i.e. large action */
3679         lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
3680         lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
3681         lg_act->pdata.lg_act.size = CPU_TO_LE16(num_lg_acts);
3682
3683         /* First action VSI forwarding or VSI list forwarding depending on how
3684          * many VSIs
3685          */
3686         id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
3687                 m_ent->fltr_info.fwd_id.hw_vsi_id;
3688
3689         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
3690         act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
3691         if (m_ent->vsi_count > 1)
3692                 act |= ICE_LG_ACT_VSI_LIST;
3693         lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
3694
3695         /* Second action descriptor type */
3696         act = ICE_LG_ACT_GENERIC;
3697
3698         act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
3699         lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
3700
3701         act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
3702                ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
3703
3704         /* Third action Marker value */
3705         act |= ICE_LG_ACT_GENERIC;
3706         act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
3707                 ICE_LG_ACT_GENERIC_VALUE_M;
3708
3709         lg_act->pdata.lg_act.act[2] = CPU_TO_LE32(act);
3710
3711         /* call the fill switch rule to fill the lookup Tx Rx structure */
3712         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
3713                          ice_aqc_opc_update_sw_rules);
3714
3715         /* Update the action to point to the large action ID */
3716         rx_tx->pdata.lkup_tx_rx.act =
3717                 CPU_TO_LE32(ICE_SINGLE_ACT_PTR |
3718                             ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
3719                              ICE_SINGLE_ACT_PTR_VAL_M));
3720
3721         /* Use the filter rule ID of the previously created rule with single
3722          * act. Once the update happens, hardware will treat this as large
3723          * action
3724          */
3725         rx_tx->pdata.lkup_tx_rx.index =
3726                 CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id);
3727
3728         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
3729                                  ice_aqc_opc_update_sw_rules, NULL);
3730         if (!status) {
3731                 m_ent->lg_act_idx = l_id;
3732                 m_ent->sw_marker_id = sw_marker;
3733         }
3734
3735         ice_free(hw, lg_act);
3736         return status;
3737 }
3738
3739 /**
3740  * ice_add_counter_act - add/update filter rule with counter action
3741  * @hw: pointer to the hardware structure
3742  * @m_ent: the management entry for which counter needs to be added
3743  * @counter_id: VLAN counter ID returned as part of allocate resource
3744  * @l_id: large action resource ID
3745  */
3746 static enum ice_status
3747 ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
3748                     u16 counter_id, u16 l_id)
3749 {
3750         struct ice_aqc_sw_rules_elem *lg_act;
3751         struct ice_aqc_sw_rules_elem *rx_tx;
3752         enum ice_status status;
3753         /* 2 actions will be added while adding a large action counter */
3754         const int num_acts = 2;
3755         u16 lg_act_size;
3756         u16 rules_size;
3757         u16 f_rule_id;
3758         u32 act;
3759         u16 id;
3760
3761         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
3762                 return ICE_ERR_PARAM;
3763
3764         /* Create two back-to-back switch rules and submit them to the HW using
3765          * one memory buffer:
3766          * 1. Large Action
3767          * 2. Look up Tx Rx
3768          */
3769         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_acts);
3770         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
3771         lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
3772         if (!lg_act)
3773                 return ICE_ERR_NO_MEMORY;
3774
3775         rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
3776
3777         /* Fill in the first switch rule i.e. large action */
3778         lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
3779         lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
3780         lg_act->pdata.lg_act.size = CPU_TO_LE16(num_acts);
3781
3782         /* First action VSI forwarding or VSI list forwarding depending on how
3783          * many VSIs
3784          */
3785         id = (m_ent->vsi_count > 1) ?  m_ent->fltr_info.fwd_id.vsi_list_id :
3786                 m_ent->fltr_info.fwd_id.hw_vsi_id;
3787
3788         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
3789         act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
3790                 ICE_LG_ACT_VSI_LIST_ID_M;
3791         if (m_ent->vsi_count > 1)
3792                 act |= ICE_LG_ACT_VSI_LIST;
3793         lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
3794
3795         /* Second action counter ID */
3796         act = ICE_LG_ACT_STAT_COUNT;
3797         act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) &
3798                 ICE_LG_ACT_STAT_COUNT_M;
3799         lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
3800
3801         /* call the fill switch rule to fill the lookup Tx Rx structure */
3802         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
3803                          ice_aqc_opc_update_sw_rules);
3804
3805         act = ICE_SINGLE_ACT_PTR;
3806         act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M;
3807         rx_tx->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
3808
3809         /* Use the filter rule ID of the previously created rule with single
3810          * act. Once the update happens, hardware will treat this as large
3811          * action
3812          */
3813         f_rule_id = m_ent->fltr_info.fltr_rule_id;
3814         rx_tx->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_rule_id);
3815
3816         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
3817                                  ice_aqc_opc_update_sw_rules, NULL);
3818         if (!status) {
3819                 m_ent->lg_act_idx = l_id;
3820                 m_ent->counter_index = counter_id;
3821         }
3822
3823         ice_free(hw, lg_act);
3824         return status;
3825 }
3826
3827 /**
3828  * ice_create_vsi_list_map
3829  * @hw: pointer to the hardware structure
3830  * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
3831  * @num_vsi: number of VSI handles in the array
3832  * @vsi_list_id: VSI list ID generated as part of allocate resource
3833  *
3834  * Helper function to create a new entry of VSI list ID to VSI mapping
3835  * using the given VSI list ID
3836  */
3837 static struct ice_vsi_list_map_info *
3838 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3839                         u16 vsi_list_id)
3840 {
3841         struct ice_switch_info *sw = hw->switch_info;
3842         struct ice_vsi_list_map_info *v_map;
3843         int i;
3844
3845         v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map));
3846         if (!v_map)
3847                 return NULL;
3848
3849         v_map->vsi_list_id = vsi_list_id;
3850         v_map->ref_cnt = 1;
3851         for (i = 0; i < num_vsi; i++)
3852                 ice_set_bit(vsi_handle_arr[i], v_map->vsi_map);
3853
3854         LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head);
3855         return v_map;
3856 }
3857
3858 /**
3859  * ice_update_vsi_list_rule
3860  * @hw: pointer to the hardware structure
3861  * @vsi_handle_arr: array of VSI handles to form a VSI list
3862  * @num_vsi: number of VSI handles in the array
3863  * @vsi_list_id: VSI list ID generated as part of allocate resource
3864  * @remove: Boolean value to indicate if this is a remove action
3865  * @opc: switch rules population command type - pass in the command opcode
3866  * @lkup_type: lookup type of the filter
3867  *
3868  * Call AQ command to add a new switch rule or update existing switch rule
3869  * using the given VSI list ID
3870  */
3871 static enum ice_status
3872 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3873                          u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
3874                          enum ice_sw_lkup_type lkup_type)
3875 {
3876         struct ice_aqc_sw_rules_elem *s_rule;
3877         enum ice_status status;
3878         u16 s_rule_size;
3879         u16 rule_type;
3880         int i;
3881
3882         if (!num_vsi)
3883                 return ICE_ERR_PARAM;
3884
3885         if (lkup_type == ICE_SW_LKUP_MAC ||
3886             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
3887             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3888             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3889             lkup_type == ICE_SW_LKUP_PROMISC ||
3890             lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3891             lkup_type == ICE_SW_LKUP_LAST)
3892                 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
3893                         ICE_AQC_SW_RULES_T_VSI_LIST_SET;
3894         else if (lkup_type == ICE_SW_LKUP_VLAN)
3895                 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
3896                         ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
3897         else
3898                 return ICE_ERR_PARAM;
3899
3900         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
3901         s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
3902         if (!s_rule)
3903                 return ICE_ERR_NO_MEMORY;
3904         for (i = 0; i < num_vsi; i++) {
3905                 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
3906                         status = ICE_ERR_PARAM;
3907                         goto exit;
3908                 }
3909                 /* AQ call requires hw_vsi_id(s) */
3910                 s_rule->pdata.vsi_list.vsi[i] =
3911                         CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
3912         }
3913
3914         s_rule->type = CPU_TO_LE16(rule_type);
3915         s_rule->pdata.vsi_list.number_vsi = CPU_TO_LE16(num_vsi);
3916         s_rule->pdata.vsi_list.index = CPU_TO_LE16(vsi_list_id);
3917
3918         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
3919
3920 exit:
3921         ice_free(hw, s_rule);
3922         return status;
3923 }
3924
3925 /**
3926  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
3927  * @hw: pointer to the HW struct
3928  * @vsi_handle_arr: array of VSI handles to form a VSI list
3929  * @num_vsi: number of VSI handles in the array
3930  * @vsi_list_id: stores the ID of the VSI list to be created
3931  * @lkup_type: switch rule filter's lookup type
3932  */
3933 static enum ice_status
3934 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
3935                          u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
3936 {
3937         enum ice_status status;
3938
3939         status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
3940                                             ice_aqc_opc_alloc_res);
3941         if (status)
3942                 return status;
3943
3944         /* Update the newly created VSI list to include the specified VSIs */
3945         return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
3946                                         *vsi_list_id, false,
3947                                         ice_aqc_opc_add_sw_rules, lkup_type);
3948 }
3949
3950 /**
3951  * ice_create_pkt_fwd_rule
3952  * @hw: pointer to the hardware structure
3953  * @recp_list: corresponding filter management list
3954  * @f_entry: entry containing packet forwarding information
3955  *
3956  * Create switch rule with given filter information and add an entry
3957  * to the corresponding filter management list to track this switch rule
3958  * and VSI mapping
3959  */
3960 static enum ice_status
3961 ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
3962                         struct ice_fltr_list_entry *f_entry)
3963 {
3964         struct ice_fltr_mgmt_list_entry *fm_entry;
3965         struct ice_aqc_sw_rules_elem *s_rule;
3966         enum ice_status status;
3967
3968         s_rule = (struct ice_aqc_sw_rules_elem *)
3969                 ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
3970         if (!s_rule)
3971                 return ICE_ERR_NO_MEMORY;
3972         fm_entry = (struct ice_fltr_mgmt_list_entry *)
3973                    ice_malloc(hw, sizeof(*fm_entry));
3974         if (!fm_entry) {
3975                 status = ICE_ERR_NO_MEMORY;
3976                 goto ice_create_pkt_fwd_rule_exit;
3977         }
3978
3979         fm_entry->fltr_info = f_entry->fltr_info;
3980
3981         /* Initialize all the fields for the management entry */
3982         fm_entry->vsi_count = 1;
3983         fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
3984         fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
3985         fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
3986
3987         ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
3988                          ice_aqc_opc_add_sw_rules);
3989
3990         status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
3991                                  ice_aqc_opc_add_sw_rules, NULL);
3992         if (status) {
3993                 ice_free(hw, fm_entry);
3994                 goto ice_create_pkt_fwd_rule_exit;
3995         }
3996
3997         f_entry->fltr_info.fltr_rule_id =
3998                 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
3999         fm_entry->fltr_info.fltr_rule_id =
4000                 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
4001
4002         /* The book keeping entries will get removed when base driver
4003          * calls remove filter AQ command
4004          */
4005         LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules);
4006
4007 ice_create_pkt_fwd_rule_exit:
4008         ice_free(hw, s_rule);
4009         return status;
4010 }
4011
4012 /**
4013  * ice_update_pkt_fwd_rule
4014  * @hw: pointer to the hardware structure
4015  * @f_info: filter information for switch rule
4016  *
4017  * Call AQ command to update a previously created switch rule with a
4018  * VSI list ID
4019  */
4020 static enum ice_status
4021 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
4022 {
4023         struct ice_aqc_sw_rules_elem *s_rule;
4024         enum ice_status status;
4025
4026         s_rule = (struct ice_aqc_sw_rules_elem *)
4027                 ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
4028         if (!s_rule)
4029                 return ICE_ERR_NO_MEMORY;
4030
4031         ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
4032
4033         s_rule->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_info->fltr_rule_id);
4034
4035         /* Update switch rule with new rule set to forward VSI list */
4036         status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
4037                                  ice_aqc_opc_update_sw_rules, NULL);
4038
4039         ice_free(hw, s_rule);
4040         return status;
4041 }
4042
4043 /**
4044  * ice_update_sw_rule_bridge_mode
4045  * @hw: pointer to the HW struct
4046  *
4047  * Updates unicast switch filter rules based on VEB/VEPA mode
4048  */
4049 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
4050 {
4051         struct ice_switch_info *sw = hw->switch_info;
4052         struct ice_fltr_mgmt_list_entry *fm_entry;
4053         enum ice_status status = ICE_SUCCESS;
4054         struct LIST_HEAD_TYPE *rule_head;
4055         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4056
4057         rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
4058         rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4059
4060         ice_acquire_lock(rule_lock);
4061         LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry,
4062                             list_entry) {
4063                 struct ice_fltr_info *fi = &fm_entry->fltr_info;
4064                 u8 *addr = fi->l_data.mac.mac_addr;
4065
4066                 /* Update unicast Tx rules to reflect the selected
4067                  * VEB/VEPA mode
4068                  */
4069                 if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) &&
4070                     (fi->fltr_act == ICE_FWD_TO_VSI ||
4071                      fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
4072                      fi->fltr_act == ICE_FWD_TO_Q ||
4073                      fi->fltr_act == ICE_FWD_TO_QGRP)) {
4074                         status = ice_update_pkt_fwd_rule(hw, fi);
4075                         if (status)
4076                                 break;
4077                 }
4078         }
4079
4080         ice_release_lock(rule_lock);
4081
4082         return status;
4083 }
4084
4085 /**
4086  * ice_add_update_vsi_list
4087  * @hw: pointer to the hardware structure
4088  * @m_entry: pointer to current filter management list entry
4089  * @cur_fltr: filter information from the book keeping entry
4090  * @new_fltr: filter information with the new VSI to be added
4091  *
4092  * Call AQ command to add or update previously created VSI list with new VSI.
4093  *
4094  * Helper function to do book keeping associated with adding filter information
4095  * The algorithm to do the book keeping is described below :
4096  * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
4097  *      if only one VSI has been added till now
4098  *              Allocate a new VSI list and add two VSIs
4099  *              to this list using switch rule command
4100  *              Update the previously created switch rule with the
4101  *              newly created VSI list ID
4102  *      if a VSI list was previously created
4103  *              Add the new VSI to the previously created VSI list set
4104  *              using the update switch rule command
4105  */
4106 static enum ice_status
4107 ice_add_update_vsi_list(struct ice_hw *hw,
4108                         struct ice_fltr_mgmt_list_entry *m_entry,
4109                         struct ice_fltr_info *cur_fltr,
4110                         struct ice_fltr_info *new_fltr)
4111 {
4112         enum ice_status status = ICE_SUCCESS;
4113         u16 vsi_list_id = 0;
4114
4115         if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
4116              cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
4117                 return ICE_ERR_NOT_IMPL;
4118
4119         if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
4120              new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
4121             (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
4122              cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
4123                 return ICE_ERR_NOT_IMPL;
4124
4125         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
4126                 /* Only one entry existed in the mapping and it was not already
4127                  * a part of a VSI list. So, create a VSI list with the old and
4128                  * new VSIs.
4129                  */
4130                 struct ice_fltr_info tmp_fltr;
4131                 u16 vsi_handle_arr[2];
4132
4133                 /* A rule already exists with the new VSI being added */
4134                 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
4135                         return ICE_ERR_ALREADY_EXISTS;
4136
4137                 vsi_handle_arr[0] = cur_fltr->vsi_handle;
4138                 vsi_handle_arr[1] = new_fltr->vsi_handle;
4139                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4140                                                   &vsi_list_id,
4141                                                   new_fltr->lkup_type);
4142                 if (status)
4143                         return status;
4144
4145                 tmp_fltr = *new_fltr;
4146                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
4147                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4148                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4149                 /* Update the previous switch rule of "MAC forward to VSI" to
4150                  * "MAC fwd to VSI list"
4151                  */
4152                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4153                 if (status)
4154                         return status;
4155
4156                 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
4157                 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4158                 m_entry->vsi_list_info =
4159                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4160                                                 vsi_list_id);
4161
4162                 if (!m_entry->vsi_list_info)
4163                         return ICE_ERR_NO_MEMORY;
4164
4165                 /* If this entry was large action then the large action needs
4166                  * to be updated to point to FWD to VSI list
4167                  */
4168                 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
4169                         status =
4170                             ice_add_marker_act(hw, m_entry,
4171                                                m_entry->sw_marker_id,
4172                                                m_entry->lg_act_idx);
4173         } else {
4174                 u16 vsi_handle = new_fltr->vsi_handle;
4175                 enum ice_adminq_opc opcode;
4176
4177                 if (!m_entry->vsi_list_info)
4178                         return ICE_ERR_CFG;
4179
4180                 /* A rule already exists with the new VSI being added */
4181                 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
4182                         return ICE_SUCCESS;
4183
4184                 /* Update the previously created VSI list set with
4185                  * the new VSI ID passed in
4186                  */
4187                 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
4188                 opcode = ice_aqc_opc_update_sw_rules;
4189
4190                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
4191                                                   vsi_list_id, false, opcode,
4192                                                   new_fltr->lkup_type);
4193                 /* update VSI list mapping info with new VSI ID */
4194                 if (!status)
4195                         ice_set_bit(vsi_handle,
4196                                     m_entry->vsi_list_info->vsi_map);
4197         }
4198         if (!status)
4199                 m_entry->vsi_count++;
4200         return status;
4201 }
4202
4203 /**
4204  * ice_find_rule_entry - Search a rule entry
4205  * @list_head: head of rule list
4206  * @f_info: rule information
4207  *
4208  * Helper function to search for a given rule entry
4209  * Returns pointer to entry storing the rule if found
4210  */
4211 static struct ice_fltr_mgmt_list_entry *
4212 ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head,
4213                     struct ice_fltr_info *f_info)
4214 {
4215         struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
4216
4217         LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
4218                             list_entry) {
4219                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
4220                             sizeof(f_info->l_data)) &&
4221                     f_info->flag == list_itr->fltr_info.flag) {
4222                         ret = list_itr;
4223                         break;
4224                 }
4225         }
4226         return ret;
4227 }
4228
4229 /**
4230  * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
4231  * @recp_list: VSI lists needs to be searched
4232  * @vsi_handle: VSI handle to be found in VSI list
4233  * @vsi_list_id: VSI list ID found containing vsi_handle
4234  *
4235  * Helper function to search a VSI list with single entry containing given VSI
4236  * handle element. This can be extended further to search VSI list with more
4237  * than 1 vsi_count. Returns pointer to VSI list entry if found.
4238  */
4239 static struct ice_vsi_list_map_info *
4240 ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle,
4241                         u16 *vsi_list_id)
4242 {
4243         struct ice_vsi_list_map_info *map_info = NULL;
4244         struct LIST_HEAD_TYPE *list_head;
4245
4246         list_head = &recp_list->filt_rules;
4247         if (recp_list->adv_rule) {
4248                 struct ice_adv_fltr_mgmt_list_entry *list_itr;
4249
4250                 LIST_FOR_EACH_ENTRY(list_itr, list_head,
4251                                     ice_adv_fltr_mgmt_list_entry,
4252                                     list_entry) {
4253                         if (list_itr->vsi_list_info) {
4254                                 map_info = list_itr->vsi_list_info;
4255                                 if (ice_is_bit_set(map_info->vsi_map,
4256                                                    vsi_handle)) {
4257                                         *vsi_list_id = map_info->vsi_list_id;
4258                                         return map_info;
4259                                 }
4260                         }
4261                 }
4262         } else {
4263                 struct ice_fltr_mgmt_list_entry *list_itr;
4264
4265                 LIST_FOR_EACH_ENTRY(list_itr, list_head,
4266                                     ice_fltr_mgmt_list_entry,
4267                                     list_entry) {
4268                         if (list_itr->vsi_count == 1 &&
4269                             list_itr->vsi_list_info) {
4270                                 map_info = list_itr->vsi_list_info;
4271                                 if (ice_is_bit_set(map_info->vsi_map,
4272                                                    vsi_handle)) {
4273                                         *vsi_list_id = map_info->vsi_list_id;
4274                                         return map_info;
4275                                 }
4276                         }
4277                 }
4278         }
4279         return NULL;
4280 }
4281
4282 /**
4283  * ice_add_rule_internal - add rule for a given lookup type
4284  * @hw: pointer to the hardware structure
4285  * @recp_list: recipe list for which rule has to be added
4286  * @lport: logic port number on which function add rule
4287  * @f_entry: structure containing MAC forwarding information
4288  *
4289  * Adds or updates the rule lists for a given recipe
4290  */
4291 static enum ice_status
4292 ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4293                       u8 lport, struct ice_fltr_list_entry *f_entry)
4294 {
4295         struct ice_fltr_info *new_fltr, *cur_fltr;
4296         struct ice_fltr_mgmt_list_entry *m_entry;
4297         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4298         enum ice_status status = ICE_SUCCESS;
4299
4300         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4301                 return ICE_ERR_PARAM;
4302
4303         /* Load the hw_vsi_id only if the fwd action is fwd to VSI */
4304         if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI)
4305                 f_entry->fltr_info.fwd_id.hw_vsi_id =
4306                         ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4307
4308         rule_lock = &recp_list->filt_rule_lock;
4309
4310         ice_acquire_lock(rule_lock);
4311         new_fltr = &f_entry->fltr_info;
4312         if (new_fltr->flag & ICE_FLTR_RX)
4313                 new_fltr->src = lport;
4314         else if (new_fltr->flag & ICE_FLTR_TX)
4315                 new_fltr->src =
4316                         ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4317
4318         m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4319         if (!m_entry) {
4320                 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4321                 goto exit_add_rule_internal;
4322         }
4323
4324         cur_fltr = &m_entry->fltr_info;
4325         status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
4326
4327 exit_add_rule_internal:
4328         ice_release_lock(rule_lock);
4329         return status;
4330 }
4331
4332 /**
4333  * ice_remove_vsi_list_rule
4334  * @hw: pointer to the hardware structure
4335  * @vsi_list_id: VSI list ID generated as part of allocate resource
4336  * @lkup_type: switch rule filter lookup type
4337  *
4338  * The VSI list should be emptied before this function is called to remove the
4339  * VSI list.
4340  */
4341 static enum ice_status
4342 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
4343                          enum ice_sw_lkup_type lkup_type)
4344 {
4345         /* Free the vsi_list resource that we allocated. It is assumed that the
4346          * list is empty at this point.
4347          */
4348         return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
4349                                             ice_aqc_opc_free_res);
4350 }
4351
4352 /**
4353  * ice_rem_update_vsi_list
4354  * @hw: pointer to the hardware structure
4355  * @vsi_handle: VSI handle of the VSI to remove
4356  * @fm_list: filter management entry for which the VSI list management needs to
4357  *           be done
4358  */
4359 static enum ice_status
4360 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
4361                         struct ice_fltr_mgmt_list_entry *fm_list)
4362 {
4363         enum ice_sw_lkup_type lkup_type;
4364         enum ice_status status = ICE_SUCCESS;
4365         u16 vsi_list_id;
4366
4367         if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
4368             fm_list->vsi_count == 0)
4369                 return ICE_ERR_PARAM;
4370
4371         /* A rule with the VSI being removed does not exist */
4372         if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
4373                 return ICE_ERR_DOES_NOT_EXIST;
4374
4375         lkup_type = fm_list->fltr_info.lkup_type;
4376         vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
4377         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
4378                                           ice_aqc_opc_update_sw_rules,
4379                                           lkup_type);
4380         if (status)
4381                 return status;
4382
4383         fm_list->vsi_count--;
4384         ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
4385
4386         if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
4387                 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
4388                 struct ice_vsi_list_map_info *vsi_list_info =
4389                         fm_list->vsi_list_info;
4390                 u16 rem_vsi_handle;
4391
4392                 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
4393                                                     ICE_MAX_VSI);
4394                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
4395                         return ICE_ERR_OUT_OF_RANGE;
4396
4397                 /* Make sure VSI list is empty before removing it below */
4398                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
4399                                                   vsi_list_id, true,
4400                                                   ice_aqc_opc_update_sw_rules,
4401                                                   lkup_type);
4402                 if (status)
4403                         return status;
4404
4405                 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
4406                 tmp_fltr_info.fwd_id.hw_vsi_id =
4407                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
4408                 tmp_fltr_info.vsi_handle = rem_vsi_handle;
4409                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
4410                 if (status) {
4411                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
4412                                   tmp_fltr_info.fwd_id.hw_vsi_id, status);
4413                         return status;
4414                 }
4415
4416                 fm_list->fltr_info = tmp_fltr_info;
4417         }
4418
4419         if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
4420             (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
4421                 struct ice_vsi_list_map_info *vsi_list_info =
4422                         fm_list->vsi_list_info;
4423
4424                 /* Remove the VSI list since it is no longer used */
4425                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
4426                 if (status) {
4427                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
4428                                   vsi_list_id, status);
4429                         return status;
4430                 }
4431
4432                 LIST_DEL(&vsi_list_info->list_entry);
4433                 ice_free(hw, vsi_list_info);
4434                 fm_list->vsi_list_info = NULL;
4435         }
4436
4437         return status;
4438 }
4439
4440 /**
4441  * ice_remove_rule_internal - Remove a filter rule of a given type
4442  *
4443  * @hw: pointer to the hardware structure
4444  * @recp_list: recipe list for which the rule needs to removed
4445  * @f_entry: rule entry containing filter information
4446  */
4447 static enum ice_status
4448 ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4449                          struct ice_fltr_list_entry *f_entry)
4450 {
4451         struct ice_fltr_mgmt_list_entry *list_elem;
4452         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4453         enum ice_status status = ICE_SUCCESS;
4454         bool remove_rule = false;
4455         u16 vsi_handle;
4456
4457         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4458                 return ICE_ERR_PARAM;
4459         f_entry->fltr_info.fwd_id.hw_vsi_id =
4460                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4461
4462         rule_lock = &recp_list->filt_rule_lock;
4463         ice_acquire_lock(rule_lock);
4464         list_elem = ice_find_rule_entry(&recp_list->filt_rules,
4465                                         &f_entry->fltr_info);
4466         if (!list_elem) {
4467                 status = ICE_ERR_DOES_NOT_EXIST;
4468                 goto exit;
4469         }
4470
4471         if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
4472                 remove_rule = true;
4473         } else if (!list_elem->vsi_list_info) {
4474                 status = ICE_ERR_DOES_NOT_EXIST;
4475                 goto exit;
4476         } else if (list_elem->vsi_list_info->ref_cnt > 1) {
4477                 /* a ref_cnt > 1 indicates that the vsi_list is being
4478                  * shared by multiple rules. Decrement the ref_cnt and
4479                  * remove this rule, but do not modify the list, as it
4480                  * is in-use by other rules.
4481                  */
4482                 list_elem->vsi_list_info->ref_cnt--;
4483                 remove_rule = true;
4484         } else {
4485                 /* a ref_cnt of 1 indicates the vsi_list is only used
4486                  * by one rule. However, the original removal request is only
4487                  * for a single VSI. Update the vsi_list first, and only
4488                  * remove the rule if there are no further VSIs in this list.
4489                  */
4490                 vsi_handle = f_entry->fltr_info.vsi_handle;
4491                 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
4492                 if (status)
4493                         goto exit;
4494                 /* if VSI count goes to zero after updating the VSI list */
4495                 if (list_elem->vsi_count == 0)
4496                         remove_rule = true;
4497         }
4498
4499         if (remove_rule) {
4500                 /* Remove the lookup rule */
4501                 struct ice_aqc_sw_rules_elem *s_rule;
4502
4503                 s_rule = (struct ice_aqc_sw_rules_elem *)
4504                         ice_malloc(hw, ICE_SW_RULE_RX_TX_NO_HDR_SIZE);
4505                 if (!s_rule) {
4506                         status = ICE_ERR_NO_MEMORY;
4507                         goto exit;
4508                 }
4509
4510                 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
4511                                  ice_aqc_opc_remove_sw_rules);
4512
4513                 status = ice_aq_sw_rules(hw, s_rule,
4514                                          ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
4515                                          ice_aqc_opc_remove_sw_rules, NULL);
4516
4517                 /* Remove a book keeping from the list */
4518                 ice_free(hw, s_rule);
4519
4520                 if (status)
4521                         goto exit;
4522
4523                 LIST_DEL(&list_elem->list_entry);
4524                 ice_free(hw, list_elem);
4525         }
4526 exit:
4527         ice_release_lock(rule_lock);
4528         return status;
4529 }
4530
4531 /**
4532  * ice_aq_get_res_alloc - get allocated resources
4533  * @hw: pointer to the HW struct
4534  * @num_entries: pointer to u16 to store the number of resource entries returned
4535  * @buf: pointer to buffer
4536  * @buf_size: size of buf
4537  * @cd: pointer to command details structure or NULL
4538  *
4539  * The caller-supplied buffer must be large enough to store the resource
4540  * information for all resource types. Each resource type is an
4541  * ice_aqc_get_res_resp_elem structure.
4542  */
4543 enum ice_status
4544 ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries,
4545                      struct ice_aqc_get_res_resp_elem *buf, u16 buf_size,
4546                      struct ice_sq_cd *cd)
4547 {
4548         struct ice_aqc_get_res_alloc *resp;
4549         enum ice_status status;
4550         struct ice_aq_desc desc;
4551
4552         if (!buf)
4553                 return ICE_ERR_BAD_PTR;
4554
4555         if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN)
4556                 return ICE_ERR_INVAL_SIZE;
4557
4558         resp = &desc.params.get_res;
4559
4560         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc);
4561         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4562
4563         if (!status && num_entries)
4564                 *num_entries = LE16_TO_CPU(resp->resp_elem_num);
4565
4566         return status;
4567 }
4568
4569 /**
4570  * ice_aq_get_res_descs - get allocated resource descriptors
4571  * @hw: pointer to the hardware structure
4572  * @num_entries: number of resource entries in buffer
4573  * @buf: structure to hold response data buffer
4574  * @buf_size: size of buffer
4575  * @res_type: resource type
4576  * @res_shared: is resource shared
4577  * @desc_id: input - first desc ID to start; output - next desc ID
4578  * @cd: pointer to command details structure or NULL
4579  */
4580 enum ice_status
4581 ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries,
4582                      struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type,
4583                      bool res_shared, u16 *desc_id, struct ice_sq_cd *cd)
4584 {
4585         struct ice_aqc_get_allocd_res_desc *cmd;
4586         struct ice_aq_desc desc;
4587         enum ice_status status;
4588
4589         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
4590
4591         cmd = &desc.params.get_res_desc;
4592
4593         if (!buf)
4594                 return ICE_ERR_PARAM;
4595
4596         if (buf_size != (num_entries * sizeof(*buf)))
4597                 return ICE_ERR_PARAM;
4598
4599         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc);
4600
4601         cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) &
4602                                          ICE_AQC_RES_TYPE_M) | (res_shared ?
4603                                         ICE_AQC_RES_TYPE_FLAG_SHARED : 0));
4604         cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id);
4605
4606         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
4607         if (!status)
4608                 *desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc);
4609
4610         return status;
4611 }
4612
4613 /**
4614  * ice_add_mac_rule - Add a MAC address based filter rule
4615  * @hw: pointer to the hardware structure
4616  * @m_list: list of MAC addresses and forwarding information
4617  * @sw: pointer to switch info struct for which function add rule
4618  * @lport: logic port number on which function add rule
4619  *
4620  * IMPORTANT: When the ucast_shared flag is set to false and m_list has
4621  * multiple unicast addresses, the function assumes that all the
4622  * addresses are unique in a given add_mac call. It doesn't
4623  * check for duplicates in this case, removing duplicates from a given
4624  * list should be taken care of in the caller of this function.
4625  */
4626 static enum ice_status
4627 ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
4628                  struct ice_switch_info *sw, u8 lport)
4629 {
4630         struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC];
4631         struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
4632         struct ice_fltr_list_entry *m_list_itr;
4633         struct LIST_HEAD_TYPE *rule_head;
4634         u16 total_elem_left, s_rule_size;
4635         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4636         enum ice_status status = ICE_SUCCESS;
4637         u16 num_unicast = 0;
4638         u8 elem_sent;
4639
4640         s_rule = NULL;
4641         rule_lock = &recp_list->filt_rule_lock;
4642         rule_head = &recp_list->filt_rules;
4643
4644         LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4645                             list_entry) {
4646                 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
4647                 u16 vsi_handle;
4648                 u16 hw_vsi_id;
4649
4650                 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
4651                 vsi_handle = m_list_itr->fltr_info.vsi_handle;
4652                 if (!ice_is_vsi_valid(hw, vsi_handle))
4653                         return ICE_ERR_PARAM;
4654                 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4655                 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
4656                 /* update the src in case it is VSI num */
4657                 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
4658                         return ICE_ERR_PARAM;
4659                 m_list_itr->fltr_info.src = hw_vsi_id;
4660                 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
4661                     IS_ZERO_ETHER_ADDR(add))
4662                         return ICE_ERR_PARAM;
4663                 if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) {
4664                         /* Don't overwrite the unicast address */
4665                         ice_acquire_lock(rule_lock);
4666                         if (ice_find_rule_entry(rule_head,
4667                                                 &m_list_itr->fltr_info)) {
4668                                 ice_release_lock(rule_lock);
4669                                 return ICE_ERR_ALREADY_EXISTS;
4670                         }
4671                         ice_release_lock(rule_lock);
4672                         num_unicast++;
4673                 } else if (IS_MULTICAST_ETHER_ADDR(add) ||
4674                            (IS_UNICAST_ETHER_ADDR(add) && hw->ucast_shared)) {
4675                         m_list_itr->status =
4676                                 ice_add_rule_internal(hw, recp_list, lport,
4677                                                       m_list_itr);
4678                         if (m_list_itr->status)
4679                                 return m_list_itr->status;
4680                 }
4681         }
4682
4683         ice_acquire_lock(rule_lock);
4684         /* Exit if no suitable entries were found for adding bulk switch rule */
4685         if (!num_unicast) {
4686                 status = ICE_SUCCESS;
4687                 goto ice_add_mac_exit;
4688         }
4689
4690         /* Allocate switch rule buffer for the bulk update for unicast */
4691         s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
4692         s_rule = (struct ice_aqc_sw_rules_elem *)
4693                 ice_calloc(hw, num_unicast, s_rule_size);
4694         if (!s_rule) {
4695                 status = ICE_ERR_NO_MEMORY;
4696                 goto ice_add_mac_exit;
4697         }
4698
4699         r_iter = s_rule;
4700         LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4701                             list_entry) {
4702                 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
4703                 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
4704
4705                 if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
4706                         ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
4707                                          ice_aqc_opc_add_sw_rules);
4708                         r_iter = (struct ice_aqc_sw_rules_elem *)
4709                                 ((u8 *)r_iter + s_rule_size);
4710                 }
4711         }
4712
4713         /* Call AQ bulk switch rule update for all unicast addresses */
4714         r_iter = s_rule;
4715         /* Call AQ switch rule in AQ_MAX chunk */
4716         for (total_elem_left = num_unicast; total_elem_left > 0;
4717              total_elem_left -= elem_sent) {
4718                 struct ice_aqc_sw_rules_elem *entry = r_iter;
4719
4720                 elem_sent = MIN_T(u8, total_elem_left,
4721                                   (ICE_AQ_MAX_BUF_LEN / s_rule_size));
4722                 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
4723                                          elem_sent, ice_aqc_opc_add_sw_rules,
4724                                          NULL);
4725                 if (status)
4726                         goto ice_add_mac_exit;
4727                 r_iter = (struct ice_aqc_sw_rules_elem *)
4728                         ((u8 *)r_iter + (elem_sent * s_rule_size));
4729         }
4730
4731         /* Fill up rule ID based on the value returned from FW */
4732         r_iter = s_rule;
4733         LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
4734                             list_entry) {
4735                 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
4736                 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
4737                 struct ice_fltr_mgmt_list_entry *fm_entry;
4738
4739                 if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
4740                         f_info->fltr_rule_id =
4741                                 LE16_TO_CPU(r_iter->pdata.lkup_tx_rx.index);
4742                         f_info->fltr_act = ICE_FWD_TO_VSI;
4743                         /* Create an entry to track this MAC address */
4744                         fm_entry = (struct ice_fltr_mgmt_list_entry *)
4745                                 ice_malloc(hw, sizeof(*fm_entry));
4746                         if (!fm_entry) {
4747                                 status = ICE_ERR_NO_MEMORY;
4748                                 goto ice_add_mac_exit;
4749                         }
4750                         fm_entry->fltr_info = *f_info;
4751                         fm_entry->vsi_count = 1;
4752                         /* The book keeping entries will get removed when
4753                          * base driver calls remove filter AQ command
4754                          */
4755
4756                         LIST_ADD(&fm_entry->list_entry, rule_head);
4757                         r_iter = (struct ice_aqc_sw_rules_elem *)
4758                                 ((u8 *)r_iter + s_rule_size);
4759                 }
4760         }
4761
4762 ice_add_mac_exit:
4763         ice_release_lock(rule_lock);
4764         if (s_rule)
4765                 ice_free(hw, s_rule);
4766         return status;
4767 }
4768
4769 /**
4770  * ice_add_mac - Add a MAC address based filter rule
4771  * @hw: pointer to the hardware structure
4772  * @m_list: list of MAC addresses and forwarding information
4773  *
4774  * Function add MAC rule for logical port from HW struct
4775  */
4776 enum ice_status ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
4777 {
4778         if (!m_list || !hw)
4779                 return ICE_ERR_PARAM;
4780
4781         return ice_add_mac_rule(hw, m_list, hw->switch_info,
4782                                 hw->port_info->lport);
4783 }
4784
4785 /**
4786  * ice_add_vlan_internal - Add one VLAN based filter rule
4787  * @hw: pointer to the hardware structure
4788  * @recp_list: recipe list for which rule has to be added
4789  * @f_entry: filter entry containing one VLAN information
4790  */
4791 static enum ice_status
4792 ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4793                       struct ice_fltr_list_entry *f_entry)
4794 {
4795         struct ice_fltr_mgmt_list_entry *v_list_itr;
4796         struct ice_fltr_info *new_fltr, *cur_fltr;
4797         enum ice_sw_lkup_type lkup_type;
4798         u16 vsi_list_id = 0, vsi_handle;
4799         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4800         enum ice_status status = ICE_SUCCESS;
4801
4802         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4803                 return ICE_ERR_PARAM;
4804
4805         f_entry->fltr_info.fwd_id.hw_vsi_id =
4806                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4807         new_fltr = &f_entry->fltr_info;
4808
4809         /* VLAN ID should only be 12 bits */
4810         if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
4811                 return ICE_ERR_PARAM;
4812
4813         if (new_fltr->src_id != ICE_SRC_ID_VSI)
4814                 return ICE_ERR_PARAM;
4815
4816         new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
4817         lkup_type = new_fltr->lkup_type;
4818         vsi_handle = new_fltr->vsi_handle;
4819         rule_lock = &recp_list->filt_rule_lock;
4820         ice_acquire_lock(rule_lock);
4821         v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4822         if (!v_list_itr) {
4823                 struct ice_vsi_list_map_info *map_info = NULL;
4824
4825                 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
4826                         /* All VLAN pruning rules use a VSI list. Check if
4827                          * there is already a VSI list containing VSI that we
4828                          * want to add. If found, use the same vsi_list_id for
4829                          * this new VLAN rule or else create a new list.
4830                          */
4831                         map_info = ice_find_vsi_list_entry(recp_list,
4832                                                            vsi_handle,
4833                                                            &vsi_list_id);
4834                         if (!map_info) {
4835                                 status = ice_create_vsi_list_rule(hw,
4836                                                                   &vsi_handle,
4837                                                                   1,
4838                                                                   &vsi_list_id,
4839                                                                   lkup_type);
4840                                 if (status)
4841                                         goto exit;
4842                         }
4843                         /* Convert the action to forwarding to a VSI list. */
4844                         new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4845                         new_fltr->fwd_id.vsi_list_id = vsi_list_id;
4846                 }
4847
4848                 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4849                 if (!status) {
4850                         v_list_itr = ice_find_rule_entry(&recp_list->filt_rules,
4851                                                          new_fltr);
4852                         if (!v_list_itr) {
4853                                 status = ICE_ERR_DOES_NOT_EXIST;
4854                                 goto exit;
4855                         }
4856                         /* reuse VSI list for new rule and increment ref_cnt */
4857                         if (map_info) {
4858                                 v_list_itr->vsi_list_info = map_info;
4859                                 map_info->ref_cnt++;
4860                         } else {
4861                                 v_list_itr->vsi_list_info =
4862                                         ice_create_vsi_list_map(hw, &vsi_handle,
4863                                                                 1, vsi_list_id);
4864                         }
4865                 }
4866         } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
4867                 /* Update existing VSI list to add new VSI ID only if it used
4868                  * by one VLAN rule.
4869                  */
4870                 cur_fltr = &v_list_itr->fltr_info;
4871                 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
4872                                                  new_fltr);
4873         } else {
4874                 /* If VLAN rule exists and VSI list being used by this rule is
4875                  * referenced by more than 1 VLAN rule. Then create a new VSI
4876                  * list appending previous VSI with new VSI and update existing
4877                  * VLAN rule to point to new VSI list ID
4878                  */
4879                 struct ice_fltr_info tmp_fltr;
4880                 u16 vsi_handle_arr[2];
4881                 u16 cur_handle;
4882
4883                 /* Current implementation only supports reusing VSI list with
4884                  * one VSI count. We should never hit below condition
4885                  */
4886                 if (v_list_itr->vsi_count > 1 &&
4887                     v_list_itr->vsi_list_info->ref_cnt > 1) {
4888                         ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
4889                         status = ICE_ERR_CFG;
4890                         goto exit;
4891                 }
4892
4893                 cur_handle =
4894                         ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map,
4895                                            ICE_MAX_VSI);
4896
4897                 /* A rule already exists with the new VSI being added */
4898                 if (cur_handle == vsi_handle) {
4899                         status = ICE_ERR_ALREADY_EXISTS;
4900                         goto exit;
4901                 }
4902
4903                 vsi_handle_arr[0] = cur_handle;
4904                 vsi_handle_arr[1] = vsi_handle;
4905                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4906                                                   &vsi_list_id, lkup_type);
4907                 if (status)
4908                         goto exit;
4909
4910                 tmp_fltr = v_list_itr->fltr_info;
4911                 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
4912                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4913                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4914                 /* Update the previous switch rule to a new VSI list which
4915                  * includes current VSI that is requested
4916                  */
4917                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4918                 if (status)
4919                         goto exit;
4920
4921                 /* before overriding VSI list map info. decrement ref_cnt of
4922                  * previous VSI list
4923                  */
4924                 v_list_itr->vsi_list_info->ref_cnt--;
4925
4926                 /* now update to newly created list */
4927                 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
4928                 v_list_itr->vsi_list_info =
4929                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4930                                                 vsi_list_id);
4931                 v_list_itr->vsi_count++;
4932         }
4933
4934 exit:
4935         ice_release_lock(rule_lock);
4936         return status;
4937 }
4938
4939 /**
4940  * ice_add_vlan_rule - Add VLAN based filter rule
4941  * @hw: pointer to the hardware structure
4942  * @v_list: list of VLAN entries and forwarding information
4943  * @sw: pointer to switch info struct for which function add rule
4944  */
4945 static enum ice_status
4946 ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
4947                   struct ice_switch_info *sw)
4948 {
4949         struct ice_fltr_list_entry *v_list_itr;
4950         struct ice_sw_recipe *recp_list;
4951
4952         recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN];
4953         LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry,
4954                             list_entry) {
4955                 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
4956                         return ICE_ERR_PARAM;
4957                 v_list_itr->fltr_info.flag = ICE_FLTR_TX;
4958                 v_list_itr->status = ice_add_vlan_internal(hw, recp_list,
4959                                                            v_list_itr);
4960                 if (v_list_itr->status)
4961                         return v_list_itr->status;
4962         }
4963         return ICE_SUCCESS;
4964 }
4965
4966 /**
4967  * ice_add_vlan - Add a VLAN based filter rule
4968  * @hw: pointer to the hardware structure
4969  * @v_list: list of VLAN and forwarding information
4970  *
4971  * Function add VLAN rule for logical port from HW struct
4972  */
4973 enum ice_status ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
4974 {
4975         if (!v_list || !hw)
4976                 return ICE_ERR_PARAM;
4977
4978         return ice_add_vlan_rule(hw, v_list, hw->switch_info);
4979 }
4980
4981 /**
4982  * ice_add_mac_vlan - Add MAC and VLAN pair based filter rule
4983  * @hw: pointer to the hardware structure
4984  * @mv_list: list of MAC and VLAN filters
4985  * @sw: pointer to switch info struct for which function add rule
4986  * @lport: logic port number on which function add rule
4987  *
4988  * If the VSI on which the MAC-VLAN pair has to be added has Rx and Tx VLAN
4989  * pruning bits enabled, then it is the responsibility of the caller to make
4990  * sure to add a VLAN only filter on the same VSI. Packets belonging to that
4991  * VLAN won't be received on that VSI otherwise.
4992  */
4993 static enum ice_status
4994 ice_add_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list,
4995                       struct ice_switch_info *sw, u8 lport)
4996 {
4997         struct ice_fltr_list_entry *mv_list_itr;
4998         struct ice_sw_recipe *recp_list;
4999
5000         if (!mv_list || !hw)
5001                 return ICE_ERR_PARAM;
5002
5003         recp_list = &sw->recp_list[ICE_SW_LKUP_MAC_VLAN];
5004         LIST_FOR_EACH_ENTRY(mv_list_itr, mv_list, ice_fltr_list_entry,
5005                             list_entry) {
5006                 enum ice_sw_lkup_type l_type =
5007                         mv_list_itr->fltr_info.lkup_type;
5008
5009                 if (l_type != ICE_SW_LKUP_MAC_VLAN)
5010                         return ICE_ERR_PARAM;
5011                 mv_list_itr->fltr_info.flag = ICE_FLTR_TX;
5012                 mv_list_itr->status =
5013                         ice_add_rule_internal(hw, recp_list, lport,
5014                                               mv_list_itr);
5015                 if (mv_list_itr->status)
5016                         return mv_list_itr->status;
5017         }
5018         return ICE_SUCCESS;
5019 }
5020
5021 /**
5022  * ice_add_mac_vlan - Add a MAC VLAN address based filter rule
5023  * @hw: pointer to the hardware structure
5024  * @mv_list: list of MAC VLAN addresses and forwarding information
5025  *
5026  * Function add MAC VLAN rule for logical port from HW struct
5027  */
5028 enum ice_status
5029 ice_add_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5030 {
5031         if (!mv_list || !hw)
5032                 return ICE_ERR_PARAM;
5033
5034         return ice_add_mac_vlan_rule(hw, mv_list, hw->switch_info,
5035                                      hw->port_info->lport);
5036 }
5037
5038 /**
5039  * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule
5040  * @hw: pointer to the hardware structure
5041  * @em_list: list of ether type MAC filter, MAC is optional
5042  * @sw: pointer to switch info struct for which function add rule
5043  * @lport: logic port number on which function add rule
5044  *
5045  * This function requires the caller to populate the entries in
5046  * the filter list with the necessary fields (including flags to
5047  * indicate Tx or Rx rules).
5048  */
5049 static enum ice_status
5050 ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5051                      struct ice_switch_info *sw, u8 lport)
5052 {
5053         struct ice_fltr_list_entry *em_list_itr;
5054
5055         LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry,
5056                             list_entry) {
5057                 struct ice_sw_recipe *recp_list;
5058                 enum ice_sw_lkup_type l_type;
5059
5060                 l_type = em_list_itr->fltr_info.lkup_type;
5061                 recp_list = &sw->recp_list[l_type];
5062
5063                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5064                     l_type != ICE_SW_LKUP_ETHERTYPE)
5065                         return ICE_ERR_PARAM;
5066
5067                 em_list_itr->status = ice_add_rule_internal(hw, recp_list,
5068                                                             lport,
5069                                                             em_list_itr);
5070                 if (em_list_itr->status)
5071                         return em_list_itr->status;
5072         }
5073         return ICE_SUCCESS;
5074 }
5075
5076 /**
5077  * ice_add_eth_mac - Add a ethertype based filter rule
5078  * @hw: pointer to the hardware structure
5079  * @em_list: list of ethertype and forwarding information
5080  *
5081  * Function add ethertype rule for logical port from HW struct
5082  */
5083 enum ice_status
5084 ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5085 {
5086         if (!em_list || !hw)
5087                 return ICE_ERR_PARAM;
5088
5089         return ice_add_eth_mac_rule(hw, em_list, hw->switch_info,
5090                                     hw->port_info->lport);
5091 }
5092
5093 /**
5094  * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule
5095  * @hw: pointer to the hardware structure
5096  * @em_list: list of ethertype or ethertype MAC entries
5097  * @sw: pointer to switch info struct for which function add rule
5098  */
5099 static enum ice_status
5100 ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5101                         struct ice_switch_info *sw)
5102 {
5103         struct ice_fltr_list_entry *em_list_itr, *tmp;
5104
5105         LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry,
5106                                  list_entry) {
5107                 struct ice_sw_recipe *recp_list;
5108                 enum ice_sw_lkup_type l_type;
5109
5110                 l_type = em_list_itr->fltr_info.lkup_type;
5111
5112                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5113                     l_type != ICE_SW_LKUP_ETHERTYPE)
5114                         return ICE_ERR_PARAM;
5115
5116                 recp_list = &sw->recp_list[l_type];
5117                 em_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5118                                                                em_list_itr);
5119                 if (em_list_itr->status)
5120                         return em_list_itr->status;
5121         }
5122         return ICE_SUCCESS;
5123 }
5124
5125 /**
5126  * ice_remove_eth_mac - remove a ethertype based filter rule
5127  * @hw: pointer to the hardware structure
5128  * @em_list: list of ethertype and forwarding information
5129  *
5130  */
5131 enum ice_status
5132 ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5133 {
5134         if (!em_list || !hw)
5135                 return ICE_ERR_PARAM;
5136
5137         return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info);
5138 }
5139
5140 /**
5141  * ice_rem_sw_rule_info
5142  * @hw: pointer to the hardware structure
5143  * @rule_head: pointer to the switch list structure that we want to delete
5144  */
5145 static void
5146 ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5147 {
5148         if (!LIST_EMPTY(rule_head)) {
5149                 struct ice_fltr_mgmt_list_entry *entry;
5150                 struct ice_fltr_mgmt_list_entry *tmp;
5151
5152                 LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head,
5153                                          ice_fltr_mgmt_list_entry, list_entry) {
5154                         LIST_DEL(&entry->list_entry);
5155                         ice_free(hw, entry);
5156                 }
5157         }
5158 }
5159
5160 /**
5161  * ice_rem_adv_rule_info
5162  * @hw: pointer to the hardware structure
5163  * @rule_head: pointer to the switch list structure that we want to delete
5164  */
5165 static void
5166 ice_rem_adv_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5167 {
5168         struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
5169         struct ice_adv_fltr_mgmt_list_entry *lst_itr;
5170
5171         if (LIST_EMPTY(rule_head))
5172                 return;
5173
5174         LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry, rule_head,
5175                                  ice_adv_fltr_mgmt_list_entry, list_entry) {
5176                 LIST_DEL(&lst_itr->list_entry);
5177                 ice_free(hw, lst_itr->lkups);
5178                 ice_free(hw, lst_itr);
5179         }
5180 }
5181
5182 /**
5183  * ice_rem_all_sw_rules_info
5184  * @hw: pointer to the hardware structure
5185  */
5186 void ice_rem_all_sw_rules_info(struct ice_hw *hw)
5187 {
5188         struct ice_switch_info *sw = hw->switch_info;
5189         u8 i;
5190
5191         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
5192                 struct LIST_HEAD_TYPE *rule_head;
5193
5194                 rule_head = &sw->recp_list[i].filt_rules;
5195                 if (!sw->recp_list[i].adv_rule)
5196                         ice_rem_sw_rule_info(hw, rule_head);
5197                 else
5198                         ice_rem_adv_rule_info(hw, rule_head);
5199                 if (sw->recp_list[i].adv_rule &&
5200                     LIST_EMPTY(&sw->recp_list[i].filt_rules))
5201                         sw->recp_list[i].adv_rule = false;
5202         }
5203 }
5204
5205 /**
5206  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
5207  * @pi: pointer to the port_info structure
5208  * @vsi_handle: VSI handle to set as default
5209  * @set: true to add the above mentioned switch rule, false to remove it
5210  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
5211  *
5212  * add filter rule to set/unset given VSI as default VSI for the switch
5213  * (represented by swid)
5214  */
5215 enum ice_status
5216 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
5217                  u8 direction)
5218 {
5219         struct ice_aqc_sw_rules_elem *s_rule;
5220         struct ice_fltr_info f_info;
5221         struct ice_hw *hw = pi->hw;
5222         enum ice_adminq_opc opcode;
5223         enum ice_status status;
5224         u16 s_rule_size;
5225         u16 hw_vsi_id;
5226
5227         if (!ice_is_vsi_valid(hw, vsi_handle))
5228                 return ICE_ERR_PARAM;
5229         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5230
5231         s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE :
5232                 ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
5233
5234         s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
5235         if (!s_rule)
5236                 return ICE_ERR_NO_MEMORY;
5237
5238         ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM);
5239
5240         f_info.lkup_type = ICE_SW_LKUP_DFLT;
5241         f_info.flag = direction;
5242         f_info.fltr_act = ICE_FWD_TO_VSI;
5243         f_info.fwd_id.hw_vsi_id = hw_vsi_id;
5244
5245         if (f_info.flag & ICE_FLTR_RX) {
5246                 f_info.src = pi->lport;
5247                 f_info.src_id = ICE_SRC_ID_LPORT;
5248                 if (!set)
5249                         f_info.fltr_rule_id =
5250                                 pi->dflt_rx_vsi_rule_id;
5251         } else if (f_info.flag & ICE_FLTR_TX) {
5252                 f_info.src_id = ICE_SRC_ID_VSI;
5253                 f_info.src = hw_vsi_id;
5254                 if (!set)
5255                         f_info.fltr_rule_id =
5256                                 pi->dflt_tx_vsi_rule_id;
5257         }
5258
5259         if (set)
5260                 opcode = ice_aqc_opc_add_sw_rules;
5261         else
5262                 opcode = ice_aqc_opc_remove_sw_rules;
5263
5264         ice_fill_sw_rule(hw, &f_info, s_rule, opcode);
5265
5266         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL);
5267         if (status || !(f_info.flag & ICE_FLTR_TX_RX))
5268                 goto out;
5269         if (set) {
5270                 u16 index = LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
5271
5272                 if (f_info.flag & ICE_FLTR_TX) {
5273                         pi->dflt_tx_vsi_num = hw_vsi_id;
5274                         pi->dflt_tx_vsi_rule_id = index;
5275                 } else if (f_info.flag & ICE_FLTR_RX) {
5276                         pi->dflt_rx_vsi_num = hw_vsi_id;
5277                         pi->dflt_rx_vsi_rule_id = index;
5278                 }
5279         } else {
5280                 if (f_info.flag & ICE_FLTR_TX) {
5281                         pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL;
5282                         pi->dflt_tx_vsi_rule_id = ICE_INVAL_ACT;
5283                 } else if (f_info.flag & ICE_FLTR_RX) {
5284                         pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL;
5285                         pi->dflt_rx_vsi_rule_id = ICE_INVAL_ACT;
5286                 }
5287         }
5288
5289 out:
5290         ice_free(hw, s_rule);
5291         return status;
5292 }
5293
5294 /**
5295  * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
5296  * @list_head: head of rule list
5297  * @f_info: rule information
5298  *
5299  * Helper function to search for a unicast rule entry - this is to be used
5300  * to remove unicast MAC filter that is not shared with other VSIs on the
5301  * PF switch.
5302  *
5303  * Returns pointer to entry storing the rule if found
5304  */
5305 static struct ice_fltr_mgmt_list_entry *
5306 ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head,
5307                           struct ice_fltr_info *f_info)
5308 {
5309         struct ice_fltr_mgmt_list_entry *list_itr;
5310
5311         LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
5312                             list_entry) {
5313                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
5314                             sizeof(f_info->l_data)) &&
5315                     f_info->fwd_id.hw_vsi_id ==
5316                     list_itr->fltr_info.fwd_id.hw_vsi_id &&
5317                     f_info->flag == list_itr->fltr_info.flag)
5318                         return list_itr;
5319         }
5320         return NULL;
5321 }
5322
5323 /**
5324  * ice_remove_mac_rule - remove a MAC based filter rule
5325  * @hw: pointer to the hardware structure
5326  * @m_list: list of MAC addresses and forwarding information
5327  * @recp_list: list from which function remove MAC address
5328  *
5329  * This function removes either a MAC filter rule or a specific VSI from a
5330  * VSI list for a multicast MAC address.
5331  *
5332  * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
5333  * ice_add_mac. Caller should be aware that this call will only work if all
5334  * the entries passed into m_list were added previously. It will not attempt to
5335  * do a partial remove of entries that were found.
5336  */
5337 static enum ice_status
5338 ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5339                     struct ice_sw_recipe *recp_list)
5340 {
5341         struct ice_fltr_list_entry *list_itr, *tmp;
5342         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5343
5344         if (!m_list)
5345                 return ICE_ERR_PARAM;
5346
5347         rule_lock = &recp_list->filt_rule_lock;
5348         LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry,
5349                                  list_entry) {
5350                 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
5351                 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
5352                 u16 vsi_handle;
5353
5354                 if (l_type != ICE_SW_LKUP_MAC)
5355                         return ICE_ERR_PARAM;
5356
5357                 vsi_handle = list_itr->fltr_info.vsi_handle;
5358                 if (!ice_is_vsi_valid(hw, vsi_handle))
5359                         return ICE_ERR_PARAM;
5360
5361                 list_itr->fltr_info.fwd_id.hw_vsi_id =
5362                                         ice_get_hw_vsi_num(hw, vsi_handle);
5363                 if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) {
5364                         /* Don't remove the unicast address that belongs to
5365                          * another VSI on the switch, since it is not being
5366                          * shared...
5367                          */
5368                         ice_acquire_lock(rule_lock);
5369                         if (!ice_find_ucast_rule_entry(&recp_list->filt_rules,
5370                                                        &list_itr->fltr_info)) {
5371                                 ice_release_lock(rule_lock);
5372                                 return ICE_ERR_DOES_NOT_EXIST;
5373                         }
5374                         ice_release_lock(rule_lock);
5375                 }
5376                 list_itr->status = ice_remove_rule_internal(hw, recp_list,
5377                                                             list_itr);
5378                 if (list_itr->status)
5379                         return list_itr->status;
5380         }
5381         return ICE_SUCCESS;
5382 }
5383
5384 /**
5385  * ice_remove_mac - remove a MAC address based filter rule
5386  * @hw: pointer to the hardware structure
5387  * @m_list: list of MAC addresses and forwarding information
5388  *
5389  */
5390 enum ice_status ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5391 {
5392         struct ice_sw_recipe *recp_list;
5393
5394         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
5395         return ice_remove_mac_rule(hw, m_list, recp_list);
5396 }
5397
5398 /**
5399  * ice_remove_vlan_rule - Remove VLAN based filter rule
5400  * @hw: pointer to the hardware structure
5401  * @v_list: list of VLAN entries and forwarding information
5402  * @recp_list: list from which function remove VLAN
5403  */
5404 static enum ice_status
5405 ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5406                      struct ice_sw_recipe *recp_list)
5407 {
5408         struct ice_fltr_list_entry *v_list_itr, *tmp;
5409
5410         LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5411                                  list_entry) {
5412                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5413
5414                 if (l_type != ICE_SW_LKUP_VLAN)
5415                         return ICE_ERR_PARAM;
5416                 v_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5417                                                               v_list_itr);
5418                 if (v_list_itr->status)
5419                         return v_list_itr->status;
5420         }
5421         return ICE_SUCCESS;
5422 }
5423
5424 /**
5425  * ice_remove_vlan - remove a VLAN address based filter rule
5426  * @hw: pointer to the hardware structure
5427  * @v_list: list of VLAN and forwarding information
5428  *
5429  */
5430 enum ice_status
5431 ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5432 {
5433         struct ice_sw_recipe *recp_list;
5434
5435         if (!v_list || !hw)
5436                 return ICE_ERR_PARAM;
5437
5438         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN];
5439         return ice_remove_vlan_rule(hw, v_list, recp_list);
5440 }
5441
5442 /**
5443  * ice_remove_mac_vlan_rule - Remove MAC VLAN based filter rule
5444  * @hw: pointer to the hardware structure
5445  * @v_list: list of MAC VLAN entries and forwarding information
5446  * @recp_list: list from which function remove MAC VLAN
5447  */
5448 static enum ice_status
5449 ice_remove_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5450                          struct ice_sw_recipe *recp_list)
5451 {
5452         struct ice_fltr_list_entry *v_list_itr, *tmp;
5453
5454         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
5455         LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5456                                  list_entry) {
5457                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5458
5459                 if (l_type != ICE_SW_LKUP_MAC_VLAN)
5460                         return ICE_ERR_PARAM;
5461                 v_list_itr->status =
5462                         ice_remove_rule_internal(hw, recp_list,
5463                                                  v_list_itr);
5464                 if (v_list_itr->status)
5465                         return v_list_itr->status;
5466         }
5467         return ICE_SUCCESS;
5468 }
5469
5470 /**
5471  * ice_remove_mac_vlan - remove a MAC VLAN address based filter rule
5472  * @hw: pointer to the hardware structure
5473  * @mv_list: list of MAC VLAN and forwarding information
5474  */
5475 enum ice_status
5476 ice_remove_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5477 {
5478         struct ice_sw_recipe *recp_list;
5479
5480         if (!mv_list || !hw)
5481                 return ICE_ERR_PARAM;
5482
5483         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
5484         return ice_remove_mac_vlan_rule(hw, mv_list, recp_list);
5485 }
5486
5487 /**
5488  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
5489  * @fm_entry: filter entry to inspect
5490  * @vsi_handle: VSI handle to compare with filter info
5491  */
5492 static bool
5493 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
5494 {
5495         return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
5496                  fm_entry->fltr_info.vsi_handle == vsi_handle) ||
5497                 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
5498                  fm_entry->vsi_list_info &&
5499                  (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map,
5500                                  vsi_handle))));
5501 }
5502
5503 /**
5504  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
5505  * @hw: pointer to the hardware structure
5506  * @vsi_handle: VSI handle to remove filters from
5507  * @vsi_list_head: pointer to the list to add entry to
5508  * @fi: pointer to fltr_info of filter entry to copy & add
5509  *
5510  * Helper function, used when creating a list of filters to remove from
5511  * a specific VSI. The entry added to vsi_list_head is a COPY of the
5512  * original filter entry, with the exception of fltr_info.fltr_act and
5513  * fltr_info.fwd_id fields. These are set such that later logic can
5514  * extract which VSI to remove the fltr from, and pass on that information.
5515  */
5516 static enum ice_status
5517 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
5518                                struct LIST_HEAD_TYPE *vsi_list_head,
5519                                struct ice_fltr_info *fi)
5520 {
5521         struct ice_fltr_list_entry *tmp;
5522
5523         /* this memory is freed up in the caller function
5524          * once filters for this VSI are removed
5525          */
5526         tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp));
5527         if (!tmp)
5528                 return ICE_ERR_NO_MEMORY;
5529
5530         tmp->fltr_info = *fi;
5531
5532         /* Overwrite these fields to indicate which VSI to remove filter from,
5533          * so find and remove logic can extract the information from the
5534          * list entries. Note that original entries will still have proper
5535          * values.
5536          */
5537         tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
5538         tmp->fltr_info.vsi_handle = vsi_handle;
5539         tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5540
5541         LIST_ADD(&tmp->list_entry, vsi_list_head);
5542
5543         return ICE_SUCCESS;
5544 }
5545
5546 /**
5547  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
5548  * @hw: pointer to the hardware structure
5549  * @vsi_handle: VSI handle to remove filters from
5550  * @lkup_list_head: pointer to the list that has certain lookup type filters
5551  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
5552  *
5553  * Locates all filters in lkup_list_head that are used by the given VSI,
5554  * and adds COPIES of those entries to vsi_list_head (intended to be used
5555  * to remove the listed filters).
5556  * Note that this means all entries in vsi_list_head must be explicitly
5557  * deallocated by the caller when done with list.
5558  */
5559 static enum ice_status
5560 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
5561                          struct LIST_HEAD_TYPE *lkup_list_head,
5562                          struct LIST_HEAD_TYPE *vsi_list_head)
5563 {
5564         struct ice_fltr_mgmt_list_entry *fm_entry;
5565         enum ice_status status = ICE_SUCCESS;
5566
5567         /* check to make sure VSI ID is valid and within boundary */
5568         if (!ice_is_vsi_valid(hw, vsi_handle))
5569                 return ICE_ERR_PARAM;
5570
5571         LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head,
5572                             ice_fltr_mgmt_list_entry, list_entry) {
5573                 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
5574                         continue;
5575
5576                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
5577                                                         vsi_list_head,
5578                                                         &fm_entry->fltr_info);
5579                 if (status)
5580                         return status;
5581         }
5582         return status;
5583 }
5584
5585 /**
5586  * ice_determine_promisc_mask
5587  * @fi: filter info to parse
5588  *
5589  * Helper function to determine which ICE_PROMISC_ mask corresponds
5590  * to given filter into.
5591  */
5592 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
5593 {
5594         u16 vid = fi->l_data.mac_vlan.vlan_id;
5595         u8 *macaddr = fi->l_data.mac.mac_addr;
5596         bool is_tx_fltr = false;
5597         u8 promisc_mask = 0;
5598
5599         if (fi->flag == ICE_FLTR_TX)
5600                 is_tx_fltr = true;
5601
5602         if (IS_BROADCAST_ETHER_ADDR(macaddr))
5603                 promisc_mask |= is_tx_fltr ?
5604                         ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
5605         else if (IS_MULTICAST_ETHER_ADDR(macaddr))
5606                 promisc_mask |= is_tx_fltr ?
5607                         ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
5608         else if (IS_UNICAST_ETHER_ADDR(macaddr))
5609                 promisc_mask |= is_tx_fltr ?
5610                         ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
5611         if (vid)
5612                 promisc_mask |= is_tx_fltr ?
5613                         ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
5614
5615         return promisc_mask;
5616 }
5617
5618 /**
5619  * _ice_get_vsi_promisc - get promiscuous mode of given VSI
5620  * @hw: pointer to the hardware structure
5621  * @vsi_handle: VSI handle to retrieve info from
5622  * @promisc_mask: pointer to mask to be filled in
5623  * @vid: VLAN ID of promisc VLAN VSI
5624  * @sw: pointer to switch info struct for which function add rule
5625  */
5626 static enum ice_status
5627 _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5628                      u16 *vid, struct ice_switch_info *sw)
5629 {
5630         struct ice_fltr_mgmt_list_entry *itr;
5631         struct LIST_HEAD_TYPE *rule_head;
5632         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
5633
5634         if (!ice_is_vsi_valid(hw, vsi_handle))
5635                 return ICE_ERR_PARAM;
5636
5637         *vid = 0;
5638         *promisc_mask = 0;
5639         rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rules;
5640         rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rule_lock;
5641
5642         ice_acquire_lock(rule_lock);
5643         LIST_FOR_EACH_ENTRY(itr, rule_head,
5644                             ice_fltr_mgmt_list_entry, list_entry) {
5645                 /* Continue if this filter doesn't apply to this VSI or the
5646                  * VSI ID is not in the VSI map for this filter
5647                  */
5648                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
5649                         continue;
5650
5651                 *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
5652         }
5653         ice_release_lock(rule_lock);
5654
5655         return ICE_SUCCESS;
5656 }
5657
5658 /**
5659  * ice_get_vsi_promisc - get promiscuous mode of given VSI
5660  * @hw: pointer to the hardware structure
5661  * @vsi_handle: VSI handle to retrieve info from
5662  * @promisc_mask: pointer to mask to be filled in
5663  * @vid: VLAN ID of promisc VLAN VSI
5664  */
5665 enum ice_status
5666 ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5667                     u16 *vid)
5668 {
5669         return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
5670                                     vid, hw->switch_info);
5671 }
5672
5673 /**
5674  * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
5675  * @hw: pointer to the hardware structure
5676  * @vsi_handle: VSI handle to retrieve info from
5677  * @promisc_mask: pointer to mask to be filled in
5678  * @vid: VLAN ID of promisc VLAN VSI
5679  * @sw: pointer to switch info struct for which function add rule
5680  */
5681 static enum ice_status
5682 _ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5683                           u16 *vid, struct ice_switch_info *sw)
5684 {
5685         struct ice_fltr_mgmt_list_entry *itr;
5686         struct LIST_HEAD_TYPE *rule_head;
5687         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
5688
5689         if (!ice_is_vsi_valid(hw, vsi_handle))
5690                 return ICE_ERR_PARAM;
5691
5692         *vid = 0;
5693         *promisc_mask = 0;
5694         rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rules;
5695         rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rule_lock;
5696
5697         ice_acquire_lock(rule_lock);
5698         LIST_FOR_EACH_ENTRY(itr, rule_head, ice_fltr_mgmt_list_entry,
5699                             list_entry) {
5700                 /* Continue if this filter doesn't apply to this VSI or the
5701                  * VSI ID is not in the VSI map for this filter
5702                  */
5703                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
5704                         continue;
5705
5706                 *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
5707         }
5708         ice_release_lock(rule_lock);
5709
5710         return ICE_SUCCESS;
5711 }
5712
5713 /**
5714  * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
5715  * @hw: pointer to the hardware structure
5716  * @vsi_handle: VSI handle to retrieve info from
5717  * @promisc_mask: pointer to mask to be filled in
5718  * @vid: VLAN ID of promisc VLAN VSI
5719  */
5720 enum ice_status
5721 ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
5722                          u16 *vid)
5723 {
5724         return _ice_get_vsi_vlan_promisc(hw, vsi_handle, promisc_mask,
5725                                          vid, hw->switch_info);
5726 }
5727
5728 /**
5729  * ice_remove_promisc - Remove promisc based filter rules
5730  * @hw: pointer to the hardware structure
5731  * @recp_id: recipe ID for which the rule needs to removed
5732  * @v_list: list of promisc entries
5733  */
5734 static enum ice_status
5735 ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
5736                    struct LIST_HEAD_TYPE *v_list)
5737 {
5738         struct ice_fltr_list_entry *v_list_itr, *tmp;
5739         struct ice_sw_recipe *recp_list;
5740
5741         recp_list = &hw->switch_info->recp_list[recp_id];
5742         LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
5743                                  list_entry) {
5744                 v_list_itr->status =
5745                         ice_remove_rule_internal(hw, recp_list, v_list_itr);
5746                 if (v_list_itr->status)
5747                         return v_list_itr->status;
5748         }
5749         return ICE_SUCCESS;
5750 }
5751
5752 /**
5753  * _ice_clear_vsi_promisc - clear specified promiscuous mode(s)
5754  * @hw: pointer to the hardware structure
5755  * @vsi_handle: VSI handle to clear mode
5756  * @promisc_mask: mask of promiscuous config bits to clear
5757  * @vid: VLAN ID to clear VLAN promiscuous
5758  * @sw: pointer to switch info struct for which function add rule
5759  */
5760 static enum ice_status
5761 _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5762                        u16 vid, struct ice_switch_info *sw)
5763 {
5764         struct ice_fltr_list_entry *fm_entry, *tmp;
5765         struct LIST_HEAD_TYPE remove_list_head;
5766         struct ice_fltr_mgmt_list_entry *itr;
5767         struct LIST_HEAD_TYPE *rule_head;
5768         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
5769         enum ice_status status = ICE_SUCCESS;
5770         u8 recipe_id;
5771
5772         if (!ice_is_vsi_valid(hw, vsi_handle))
5773                 return ICE_ERR_PARAM;
5774
5775         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
5776                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
5777         else
5778                 recipe_id = ICE_SW_LKUP_PROMISC;
5779
5780         rule_head = &sw->recp_list[recipe_id].filt_rules;
5781         rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
5782
5783         INIT_LIST_HEAD(&remove_list_head);
5784
5785         ice_acquire_lock(rule_lock);
5786         LIST_FOR_EACH_ENTRY(itr, rule_head,
5787                             ice_fltr_mgmt_list_entry, list_entry) {
5788                 struct ice_fltr_info *fltr_info;
5789                 u8 fltr_promisc_mask = 0;
5790
5791                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
5792                         continue;
5793                 fltr_info = &itr->fltr_info;
5794
5795                 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
5796                     vid != fltr_info->l_data.mac_vlan.vlan_id)
5797                         continue;
5798
5799                 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
5800
5801                 /* Skip if filter is not completely specified by given mask */
5802                 if (fltr_promisc_mask & ~promisc_mask)
5803                         continue;
5804
5805                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
5806                                                         &remove_list_head,
5807                                                         fltr_info);
5808                 if (status) {
5809                         ice_release_lock(rule_lock);
5810                         goto free_fltr_list;
5811                 }
5812         }
5813         ice_release_lock(rule_lock);
5814
5815         status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
5816
5817 free_fltr_list:
5818         LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
5819                                  ice_fltr_list_entry, list_entry) {
5820                 LIST_DEL(&fm_entry->list_entry);
5821                 ice_free(hw, fm_entry);
5822         }
5823
5824         return status;
5825 }
5826
5827 /**
5828  * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
5829  * @hw: pointer to the hardware structure
5830  * @vsi_handle: VSI handle to clear mode
5831  * @promisc_mask: mask of promiscuous config bits to clear
5832  * @vid: VLAN ID to clear VLAN promiscuous
5833  */
5834 enum ice_status
5835 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
5836                       u8 promisc_mask, u16 vid)
5837 {
5838         return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask,
5839                                       vid, hw->switch_info);
5840 }
5841
5842 /**
5843  * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
5844  * @hw: pointer to the hardware structure
5845  * @vsi_handle: VSI handle to configure
5846  * @promisc_mask: mask of promiscuous config bits
5847  * @vid: VLAN ID to set VLAN promiscuous
5848  * @lport: logical port number to configure promisc mode
5849  * @sw: pointer to switch info struct for which function add rule
5850  */
5851 static enum ice_status
5852 _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5853                      u16 vid, u8 lport, struct ice_switch_info *sw)
5854 {
5855         enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
5856         struct ice_fltr_list_entry f_list_entry;
5857         struct ice_fltr_info new_fltr;
5858         enum ice_status status = ICE_SUCCESS;
5859         bool is_tx_fltr;
5860         u16 hw_vsi_id;
5861         int pkt_type;
5862         u8 recipe_id;
5863
5864         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
5865
5866         if (!ice_is_vsi_valid(hw, vsi_handle))
5867                 return ICE_ERR_PARAM;
5868         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5869
5870         ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM);
5871
5872         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
5873                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
5874                 new_fltr.l_data.mac_vlan.vlan_id = vid;
5875                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
5876         } else {
5877                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
5878                 recipe_id = ICE_SW_LKUP_PROMISC;
5879         }
5880
5881         /* Separate filters must be set for each direction/packet type
5882          * combination, so we will loop over the mask value, store the
5883          * individual type, and clear it out in the input mask as it
5884          * is found.
5885          */
5886         while (promisc_mask) {
5887                 struct ice_sw_recipe *recp_list;
5888                 u8 *mac_addr;
5889
5890                 pkt_type = 0;
5891                 is_tx_fltr = false;
5892
5893                 if (promisc_mask & ICE_PROMISC_UCAST_RX) {
5894                         promisc_mask &= ~ICE_PROMISC_UCAST_RX;
5895                         pkt_type = UCAST_FLTR;
5896                 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
5897                         promisc_mask &= ~ICE_PROMISC_UCAST_TX;
5898                         pkt_type = UCAST_FLTR;
5899                         is_tx_fltr = true;
5900                 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
5901                         promisc_mask &= ~ICE_PROMISC_MCAST_RX;
5902                         pkt_type = MCAST_FLTR;
5903                 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
5904                         promisc_mask &= ~ICE_PROMISC_MCAST_TX;
5905                         pkt_type = MCAST_FLTR;
5906                         is_tx_fltr = true;
5907                 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
5908                         promisc_mask &= ~ICE_PROMISC_BCAST_RX;
5909                         pkt_type = BCAST_FLTR;
5910                 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
5911                         promisc_mask &= ~ICE_PROMISC_BCAST_TX;
5912                         pkt_type = BCAST_FLTR;
5913                         is_tx_fltr = true;
5914                 }
5915
5916                 /* Check for VLAN promiscuous flag */
5917                 if (promisc_mask & ICE_PROMISC_VLAN_RX) {
5918                         promisc_mask &= ~ICE_PROMISC_VLAN_RX;
5919                 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
5920                         promisc_mask &= ~ICE_PROMISC_VLAN_TX;
5921                         is_tx_fltr = true;
5922                 }
5923
5924                 /* Set filter DA based on packet type */
5925                 mac_addr = new_fltr.l_data.mac.mac_addr;
5926                 if (pkt_type == BCAST_FLTR) {
5927                         ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM);
5928                 } else if (pkt_type == MCAST_FLTR ||
5929                            pkt_type == UCAST_FLTR) {
5930                         /* Use the dummy ether header DA */
5931                         ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN,
5932                                    ICE_NONDMA_TO_NONDMA);
5933                         if (pkt_type == MCAST_FLTR)
5934                                 mac_addr[0] |= 0x1;     /* Set multicast bit */
5935                 }
5936
5937                 /* Need to reset this to zero for all iterations */
5938                 new_fltr.flag = 0;
5939                 if (is_tx_fltr) {
5940                         new_fltr.flag |= ICE_FLTR_TX;
5941                         new_fltr.src = hw_vsi_id;
5942                 } else {
5943                         new_fltr.flag |= ICE_FLTR_RX;
5944                         new_fltr.src = lport;
5945                 }
5946
5947                 new_fltr.fltr_act = ICE_FWD_TO_VSI;
5948                 new_fltr.vsi_handle = vsi_handle;
5949                 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
5950                 f_list_entry.fltr_info = new_fltr;
5951                 recp_list = &sw->recp_list[recipe_id];
5952
5953                 status = ice_add_rule_internal(hw, recp_list, lport,
5954                                                &f_list_entry);
5955                 if (status != ICE_SUCCESS)
5956                         goto set_promisc_exit;
5957         }
5958
5959 set_promisc_exit:
5960         return status;
5961 }
5962
5963 /**
5964  * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
5965  * @hw: pointer to the hardware structure
5966  * @vsi_handle: VSI handle to configure
5967  * @promisc_mask: mask of promiscuous config bits
5968  * @vid: VLAN ID to set VLAN promiscuous
5969  */
5970 enum ice_status
5971 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5972                     u16 vid)
5973 {
5974         return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid,
5975                                     hw->port_info->lport,
5976                                     hw->switch_info);
5977 }
5978
5979 /**
5980  * _ice_set_vlan_vsi_promisc
5981  * @hw: pointer to the hardware structure
5982  * @vsi_handle: VSI handle to configure
5983  * @promisc_mask: mask of promiscuous config bits
5984  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
5985  * @lport: logical port number to configure promisc mode
5986  * @sw: pointer to switch info struct for which function add rule
5987  *
5988  * Configure VSI with all associated VLANs to given promiscuous mode(s)
5989  */
5990 static enum ice_status
5991 _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
5992                           bool rm_vlan_promisc, u8 lport,
5993                           struct ice_switch_info *sw)
5994 {
5995         struct ice_fltr_list_entry *list_itr, *tmp;
5996         struct LIST_HEAD_TYPE vsi_list_head;
5997         struct LIST_HEAD_TYPE *vlan_head;
5998         struct ice_lock *vlan_lock; /* Lock to protect filter rule list */
5999         enum ice_status status;
6000         u16 vlan_id;
6001
6002         INIT_LIST_HEAD(&vsi_list_head);
6003         vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
6004         vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
6005         ice_acquire_lock(vlan_lock);
6006         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
6007                                           &vsi_list_head);
6008         ice_release_lock(vlan_lock);
6009         if (status)
6010                 goto free_fltr_list;
6011
6012         LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry,
6013                             list_entry) {
6014                 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
6015                 if (rm_vlan_promisc)
6016                         status =  _ice_clear_vsi_promisc(hw, vsi_handle,
6017                                                          promisc_mask,
6018                                                          vlan_id, sw);
6019                 else
6020                         status =  _ice_set_vsi_promisc(hw, vsi_handle,
6021                                                        promisc_mask, vlan_id,
6022                                                        lport, sw);
6023                 if (status)
6024                         break;
6025         }
6026
6027 free_fltr_list:
6028         LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head,
6029                                  ice_fltr_list_entry, list_entry) {
6030                 LIST_DEL(&list_itr->list_entry);
6031                 ice_free(hw, list_itr);
6032         }
6033         return status;
6034 }
6035
6036 /**
6037  * ice_set_vlan_vsi_promisc
6038  * @hw: pointer to the hardware structure
6039  * @vsi_handle: VSI handle to configure
6040  * @promisc_mask: mask of promiscuous config bits
6041  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6042  *
6043  * Configure VSI with all associated VLANs to given promiscuous mode(s)
6044  */
6045 enum ice_status
6046 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6047                          bool rm_vlan_promisc)
6048 {
6049         return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask,
6050                                          rm_vlan_promisc, hw->port_info->lport,
6051                                          hw->switch_info);
6052 }
6053
6054 /**
6055  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
6056  * @hw: pointer to the hardware structure
6057  * @vsi_handle: VSI handle to remove filters from
6058  * @recp_list: recipe list from which function remove fltr
6059  * @lkup: switch rule filter lookup type
6060  */
6061 static void
6062 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
6063                          struct ice_sw_recipe *recp_list,
6064                          enum ice_sw_lkup_type lkup)
6065 {
6066         struct ice_fltr_list_entry *fm_entry;
6067         struct LIST_HEAD_TYPE remove_list_head;
6068         struct LIST_HEAD_TYPE *rule_head;
6069         struct ice_fltr_list_entry *tmp;
6070         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
6071         enum ice_status status;
6072
6073         INIT_LIST_HEAD(&remove_list_head);
6074         rule_lock = &recp_list[lkup].filt_rule_lock;
6075         rule_head = &recp_list[lkup].filt_rules;
6076         ice_acquire_lock(rule_lock);
6077         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
6078                                           &remove_list_head);
6079         ice_release_lock(rule_lock);
6080         if (status)
6081                 goto free_fltr_list;
6082
6083         switch (lkup) {
6084         case ICE_SW_LKUP_MAC:
6085                 ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]);
6086                 break;
6087         case ICE_SW_LKUP_VLAN:
6088                 ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]);
6089                 break;
6090         case ICE_SW_LKUP_PROMISC:
6091         case ICE_SW_LKUP_PROMISC_VLAN:
6092                 ice_remove_promisc(hw, lkup, &remove_list_head);
6093                 break;
6094         case ICE_SW_LKUP_MAC_VLAN:
6095                 ice_remove_mac_vlan(hw, &remove_list_head);
6096                 break;
6097         case ICE_SW_LKUP_ETHERTYPE:
6098         case ICE_SW_LKUP_ETHERTYPE_MAC:
6099                 ice_remove_eth_mac(hw, &remove_list_head);
6100                 break;
6101         case ICE_SW_LKUP_DFLT:
6102                 ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n");
6103                 break;
6104         case ICE_SW_LKUP_LAST:
6105                 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n");
6106                 break;
6107         }
6108
6109 free_fltr_list:
6110         LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
6111                                  ice_fltr_list_entry, list_entry) {
6112                 LIST_DEL(&fm_entry->list_entry);
6113                 ice_free(hw, fm_entry);
6114         }
6115 }
6116
6117 /**
6118  * ice_remove_vsi_fltr_rule - Remove all filters for a VSI
6119  * @hw: pointer to the hardware structure
6120  * @vsi_handle: VSI handle to remove filters from
6121  * @sw: pointer to switch info struct
6122  */
6123 static void
6124 ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle,
6125                          struct ice_switch_info *sw)
6126 {
6127         ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6128
6129         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6130                                  sw->recp_list, ICE_SW_LKUP_MAC);
6131         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6132                                  sw->recp_list, ICE_SW_LKUP_MAC_VLAN);
6133         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6134                                  sw->recp_list, ICE_SW_LKUP_PROMISC);
6135         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6136                                  sw->recp_list, ICE_SW_LKUP_VLAN);
6137         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6138                                  sw->recp_list, ICE_SW_LKUP_DFLT);
6139         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6140                                  sw->recp_list, ICE_SW_LKUP_ETHERTYPE);
6141         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6142                                  sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC);
6143         ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6144                                  sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN);
6145 }
6146
6147 /**
6148  * ice_remove_vsi_fltr - Remove all filters for a VSI
6149  * @hw: pointer to the hardware structure
6150  * @vsi_handle: VSI handle to remove filters from
6151  */
6152 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
6153 {
6154         ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info);
6155 }
6156
6157 /**
6158  * ice_alloc_res_cntr - allocating resource counter
6159  * @hw: pointer to the hardware structure
6160  * @type: type of resource
6161  * @alloc_shared: if set it is shared else dedicated
6162  * @num_items: number of entries requested for FD resource type
6163  * @counter_id: counter index returned by AQ call
6164  */
6165 enum ice_status
6166 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6167                    u16 *counter_id)
6168 {
6169         struct ice_aqc_alloc_free_res_elem *buf;
6170         enum ice_status status;
6171         u16 buf_len;
6172
6173         /* Allocate resource */
6174         buf_len = ice_struct_size(buf, elem, 1);
6175         buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6176         if (!buf)
6177                 return ICE_ERR_NO_MEMORY;
6178
6179         buf->num_elems = CPU_TO_LE16(num_items);
6180         buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6181                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
6182
6183         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6184                                        ice_aqc_opc_alloc_res, NULL);
6185         if (status)
6186                 goto exit;
6187
6188         *counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp);
6189
6190 exit:
6191         ice_free(hw, buf);
6192         return status;
6193 }
6194
6195 /**
6196  * ice_free_res_cntr - free resource counter
6197  * @hw: pointer to the hardware structure
6198  * @type: type of resource
6199  * @alloc_shared: if set it is shared else dedicated
6200  * @num_items: number of entries to be freed for FD resource type
6201  * @counter_id: counter ID resource which needs to be freed
6202  */
6203 enum ice_status
6204 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6205                   u16 counter_id)
6206 {
6207         struct ice_aqc_alloc_free_res_elem *buf;
6208         enum ice_status status;
6209         u16 buf_len;
6210
6211         /* Free resource */
6212         buf_len = ice_struct_size(buf, elem, 1);
6213         buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6214         if (!buf)
6215                 return ICE_ERR_NO_MEMORY;
6216
6217         buf->num_elems = CPU_TO_LE16(num_items);
6218         buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6219                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
6220         buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
6221
6222         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6223                                        ice_aqc_opc_free_res, NULL);
6224         if (status)
6225                 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
6226
6227         ice_free(hw, buf);
6228         return status;
6229 }
6230
6231 /**
6232  * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type
6233  * @hw: pointer to the hardware structure
6234  * @counter_id: returns counter index
6235  */
6236 enum ice_status ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id)
6237 {
6238         return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6239                                   ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6240                                   counter_id);
6241 }
6242
6243 /**
6244  * ice_free_vlan_res_counter - Free counter resource for VLAN type
6245  * @hw: pointer to the hardware structure
6246  * @counter_id: counter index to be freed
6247  */
6248 enum ice_status ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id)
6249 {
6250         return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6251                                  ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6252                                  counter_id);
6253 }
6254
6255 /**
6256  * ice_alloc_res_lg_act - add large action resource
6257  * @hw: pointer to the hardware structure
6258  * @l_id: large action ID to fill it in
6259  * @num_acts: number of actions to hold with a large action entry
6260  */
6261 static enum ice_status
6262 ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts)
6263 {
6264         struct ice_aqc_alloc_free_res_elem *sw_buf;
6265         enum ice_status status;
6266         u16 buf_len;
6267
6268         if (num_acts > ICE_MAX_LG_ACT || num_acts == 0)
6269                 return ICE_ERR_PARAM;
6270
6271         /* Allocate resource for large action */
6272         buf_len = ice_struct_size(sw_buf, elem, 1);
6273         sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6274         if (!sw_buf)
6275                 return ICE_ERR_NO_MEMORY;
6276
6277         sw_buf->num_elems = CPU_TO_LE16(1);
6278
6279         /* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1.
6280          * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3.
6281          * If num_acts is greater than 2, then use
6282          * ICE_AQC_RES_TYPE_WIDE_TABLE_4.
6283          * The num_acts cannot exceed 4. This was ensured at the
6284          * beginning of the function.
6285          */
6286         if (num_acts == 1)
6287                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_1);
6288         else if (num_acts == 2)
6289                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_2);
6290         else
6291                 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_4);
6292
6293         status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
6294                                        ice_aqc_opc_alloc_res, NULL);
6295         if (!status)
6296                 *l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
6297
6298         ice_free(hw, sw_buf);
6299         return status;
6300 }
6301
6302 /**
6303  * ice_add_mac_with_sw_marker - add filter with sw marker
6304  * @hw: pointer to the hardware structure
6305  * @f_info: filter info structure containing the MAC filter information
6306  * @sw_marker: sw marker to tag the Rx descriptor with
6307  */
6308 enum ice_status
6309 ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info,
6310                            u16 sw_marker)
6311 {
6312         struct ice_fltr_mgmt_list_entry *m_entry;
6313         struct ice_fltr_list_entry fl_info;
6314         struct ice_sw_recipe *recp_list;
6315         struct LIST_HEAD_TYPE l_head;
6316         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
6317         enum ice_status ret;
6318         bool entry_exists;
6319         u16 lg_act_id;
6320
6321         if (f_info->fltr_act != ICE_FWD_TO_VSI)
6322                 return ICE_ERR_PARAM;
6323
6324         if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6325                 return ICE_ERR_PARAM;
6326
6327         if (sw_marker == ICE_INVAL_SW_MARKER_ID)
6328                 return ICE_ERR_PARAM;
6329
6330         if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6331                 return ICE_ERR_PARAM;
6332         f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6333
6334         /* Add filter if it doesn't exist so then the adding of large
6335          * action always results in update
6336          */
6337
6338         INIT_LIST_HEAD(&l_head);
6339         fl_info.fltr_info = *f_info;
6340         LIST_ADD(&fl_info.list_entry, &l_head);
6341
6342         entry_exists = false;
6343         ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6344                                hw->port_info->lport);
6345         if (ret == ICE_ERR_ALREADY_EXISTS)
6346                 entry_exists = true;
6347         else if (ret)
6348                 return ret;
6349
6350         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6351         rule_lock = &recp_list->filt_rule_lock;
6352         ice_acquire_lock(rule_lock);
6353         /* Get the book keeping entry for the filter */
6354         m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6355         if (!m_entry)
6356                 goto exit_error;
6357
6358         /* If counter action was enabled for this rule then don't enable
6359          * sw marker large action
6360          */
6361         if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6362                 ret = ICE_ERR_PARAM;
6363                 goto exit_error;
6364         }
6365
6366         /* if same marker was added before */
6367         if (m_entry->sw_marker_id == sw_marker) {
6368                 ret = ICE_ERR_ALREADY_EXISTS;
6369                 goto exit_error;
6370         }
6371
6372         /* Allocate a hardware table entry to hold large act. Three actions
6373          * for marker based large action
6374          */
6375         ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3);
6376         if (ret)
6377                 goto exit_error;
6378
6379         if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6380                 goto exit_error;
6381
6382         /* Update the switch rule to add the marker action */
6383         ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id);
6384         if (!ret) {
6385                 ice_release_lock(rule_lock);
6386                 return ret;
6387         }
6388
6389 exit_error:
6390         ice_release_lock(rule_lock);
6391         /* only remove entry if it did not exist previously */
6392         if (!entry_exists)
6393                 ret = ice_remove_mac(hw, &l_head);
6394
6395         return ret;
6396 }
6397
6398 /**
6399  * ice_add_mac_with_counter - add filter with counter enabled
6400  * @hw: pointer to the hardware structure
6401  * @f_info: pointer to filter info structure containing the MAC filter
6402  *          information
6403  */
6404 enum ice_status
6405 ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info)
6406 {
6407         struct ice_fltr_mgmt_list_entry *m_entry;
6408         struct ice_fltr_list_entry fl_info;
6409         struct ice_sw_recipe *recp_list;
6410         struct LIST_HEAD_TYPE l_head;
6411         struct ice_lock *rule_lock;     /* Lock to protect filter rule list */
6412         enum ice_status ret;
6413         bool entry_exist;
6414         u16 counter_id;
6415         u16 lg_act_id;
6416
6417         if (f_info->fltr_act != ICE_FWD_TO_VSI)
6418                 return ICE_ERR_PARAM;
6419
6420         if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6421                 return ICE_ERR_PARAM;
6422
6423         if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6424                 return ICE_ERR_PARAM;
6425         f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6426         recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6427
6428         entry_exist = false;
6429
6430         rule_lock = &recp_list->filt_rule_lock;
6431
6432         /* Add filter if it doesn't exist so then the adding of large
6433          * action always results in update
6434          */
6435         INIT_LIST_HEAD(&l_head);
6436
6437         fl_info.fltr_info = *f_info;
6438         LIST_ADD(&fl_info.list_entry, &l_head);
6439
6440         ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6441                                hw->port_info->lport);
6442         if (ret == ICE_ERR_ALREADY_EXISTS)
6443                 entry_exist = true;
6444         else if (ret)
6445                 return ret;
6446
6447         ice_acquire_lock(rule_lock);
6448         m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6449         if (!m_entry) {
6450                 ret = ICE_ERR_BAD_PTR;
6451                 goto exit_error;
6452         }
6453
6454         /* Don't enable counter for a filter for which sw marker was enabled */
6455         if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) {
6456                 ret = ICE_ERR_PARAM;
6457                 goto exit_error;
6458         }
6459
6460         /* If a counter was already enabled then don't need to add again */
6461         if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6462                 ret = ICE_ERR_ALREADY_EXISTS;
6463                 goto exit_error;
6464         }
6465
6466         /* Allocate a hardware table entry to VLAN counter */
6467         ret = ice_alloc_vlan_res_counter(hw, &counter_id);
6468         if (ret)
6469                 goto exit_error;
6470
6471         /* Allocate a hardware table entry to hold large act. Two actions for
6472          * counter based large action
6473          */
6474         ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2);
6475         if (ret)
6476                 goto exit_error;
6477
6478         if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6479                 goto exit_error;
6480
6481         /* Update the switch rule to add the counter action */
6482         ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id);
6483         if (!ret) {
6484                 ice_release_lock(rule_lock);
6485                 return ret;
6486         }
6487
6488 exit_error:
6489         ice_release_lock(rule_lock);
6490         /* only remove entry if it did not exist previously */
6491         if (!entry_exist)
6492                 ret = ice_remove_mac(hw, &l_head);
6493
6494         return ret;
6495 }
6496
6497 /* This is mapping table entry that maps every word within a given protocol
6498  * structure to the real byte offset as per the specification of that
6499  * protocol header.
6500  * for example dst address is 3 words in ethertype header and corresponding
6501  * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
6502  * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
6503  * matching entry describing its field. This needs to be updated if new
6504  * structure is added to that union.
6505  */
6506 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
6507         { ICE_MAC_OFOS,         { 0, 2, 4, 6, 8, 10, 12 } },
6508         { ICE_MAC_IL,           { 0, 2, 4, 6, 8, 10, 12 } },
6509         { ICE_ETYPE_OL,         { 0 } },
6510         { ICE_VLAN_OFOS,        { 0, 2 } },
6511         { ICE_IPV4_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6512         { ICE_IPV4_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6513         { ICE_IPV6_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6514                                  26, 28, 30, 32, 34, 36, 38 } },
6515         { ICE_IPV6_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6516                                  26, 28, 30, 32, 34, 36, 38 } },
6517         { ICE_TCP_IL,           { 0, 2 } },
6518         { ICE_UDP_OF,           { 0, 2 } },
6519         { ICE_UDP_ILOS,         { 0, 2 } },
6520         { ICE_SCTP_IL,          { 0, 2 } },
6521         { ICE_VXLAN,            { 8, 10, 12, 14 } },
6522         { ICE_GENEVE,           { 8, 10, 12, 14 } },
6523         { ICE_VXLAN_GPE,        { 8, 10, 12, 14 } },
6524         { ICE_NVGRE,            { 0, 2, 4, 6 } },
6525         { ICE_GTP,              { 8, 10, 12, 14, 16, 18, 20 } },
6526         { ICE_PPPOE,            { 0, 2, 4, 6 } },
6527         { ICE_PFCP,             { 8, 10, 12, 14, 16, 18, 20, 22 } },
6528         { ICE_L2TPV3,           { 0, 2, 4, 6, 8, 10 } },
6529         { ICE_ESP,              { 0, 2, 4, 6 } },
6530         { ICE_AH,               { 0, 2, 4, 6, 8, 10 } },
6531         { ICE_NAT_T,            { 8, 10, 12, 14 } },
6532         { ICE_GTP_NO_PAY,       { 8, 10, 12, 14 } },
6533         { ICE_VLAN_EX,          { 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 const 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 };
6569
6570 /**
6571  * ice_find_recp - find a recipe
6572  * @hw: pointer to the hardware structure
6573  * @lkup_exts: extension sequence to match
6574  *
6575  * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
6576  */
6577 static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
6578                          enum ice_sw_tunnel_type tun_type)
6579 {
6580         bool refresh_required = true;
6581         struct ice_sw_recipe *recp;
6582         u8 i;
6583
6584         /* Walk through existing recipes to find a match */
6585         recp = hw->switch_info->recp_list;
6586         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6587                 /* If recipe was not created for this ID, in SW bookkeeping,
6588                  * check if FW has an entry for this recipe. If the FW has an
6589                  * entry update it in our SW bookkeeping and continue with the
6590                  * matching.
6591                  */
6592                 if (!recp[i].recp_created)
6593                         if (ice_get_recp_frm_fw(hw,
6594                                                 hw->switch_info->recp_list, i,
6595                                                 &refresh_required))
6596                                 continue;
6597
6598                 /* Skip inverse action recipes */
6599                 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
6600                     ICE_AQ_RECIPE_ACT_INV_ACT)
6601                         continue;
6602
6603                 /* if number of words we are looking for match */
6604                 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
6605                         struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
6606                         struct ice_fv_word *be = lkup_exts->fv_words;
6607                         u16 *cr = recp[i].lkup_exts.field_mask;
6608                         u16 *de = lkup_exts->field_mask;
6609                         bool found = true;
6610                         u8 pe, qr;
6611
6612                         /* ar, cr, and qr are related to the recipe words, while
6613                          * be, de, and pe are related to the lookup words
6614                          */
6615                         for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
6616                                 for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
6617                                      qr++) {
6618                                         if (ar[qr].off == be[pe].off &&
6619                                             ar[qr].prot_id == be[pe].prot_id &&
6620                                             cr[qr] == de[pe])
6621                                                 /* Found the "pe"th word in the
6622                                                  * given recipe
6623                                                  */
6624                                                 break;
6625                                 }
6626                                 /* After walking through all the words in the
6627                                  * "i"th recipe if "p"th word was not found then
6628                                  * this recipe is not what we are looking for.
6629                                  * So break out from this loop and try the next
6630                                  * recipe
6631                                  */
6632                                 if (qr >= recp[i].lkup_exts.n_val_words) {
6633                                         found = false;
6634                                         break;
6635                                 }
6636                         }
6637                         /* If for "i"th recipe the found was never set to false
6638                          * then it means we found our match
6639                          */
6640                         if (tun_type == recp[i].tun_type && found)
6641                                 return i; /* Return the recipe ID */
6642                 }
6643         }
6644         return ICE_MAX_NUM_RECIPES;
6645 }
6646
6647 /**
6648  * ice_prot_type_to_id - get protocol ID from protocol type
6649  * @type: protocol type
6650  * @id: pointer to variable that will receive the ID
6651  *
6652  * Returns true if found, false otherwise
6653  */
6654 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
6655 {
6656         u8 i;
6657
6658         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
6659                 if (ice_prot_id_tbl[i].type == type) {
6660                         *id = ice_prot_id_tbl[i].protocol_id;
6661                         return true;
6662                 }
6663         return false;
6664 }
6665
6666 /**
6667  * ice_find_valid_words - count valid words
6668  * @rule: advanced rule with lookup information
6669  * @lkup_exts: byte offset extractions of the words that are valid
6670  *
6671  * calculate valid words in a lookup rule using mask value
6672  */
6673 static u8
6674 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
6675                      struct ice_prot_lkup_ext *lkup_exts)
6676 {
6677         u8 j, word, prot_id, ret_val;
6678
6679         if (!ice_prot_type_to_id(rule->type, &prot_id))
6680                 return 0;
6681
6682         word = lkup_exts->n_val_words;
6683
6684         for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
6685                 if (((u16 *)&rule->m_u)[j] &&
6686                     rule->type < ARRAY_SIZE(ice_prot_ext)) {
6687                         /* No more space to accommodate */
6688                         if (word >= ICE_MAX_CHAIN_WORDS)
6689                                 return 0;
6690                         lkup_exts->fv_words[word].off =
6691                                 ice_prot_ext[rule->type].offs[j];
6692                         lkup_exts->fv_words[word].prot_id =
6693                                 ice_prot_id_tbl[rule->type].protocol_id;
6694                         lkup_exts->field_mask[word] =
6695                                 BE16_TO_CPU(((_FORCE_ __be16 *)&rule->m_u)[j]);
6696                         word++;
6697                 }
6698
6699         ret_val = word - lkup_exts->n_val_words;
6700         lkup_exts->n_val_words = word;
6701
6702         return ret_val;
6703 }
6704
6705 /**
6706  * ice_create_first_fit_recp_def - Create a recipe grouping
6707  * @hw: pointer to the hardware structure
6708  * @lkup_exts: an array of protocol header extractions
6709  * @rg_list: pointer to a list that stores new recipe groups
6710  * @recp_cnt: pointer to a variable that stores returned number of recipe groups
6711  *
6712  * Using first fit algorithm, take all the words that are still not done
6713  * and start grouping them in 4-word groups. Each group makes up one
6714  * recipe.
6715  */
6716 static enum ice_status
6717 ice_create_first_fit_recp_def(struct ice_hw *hw,
6718                               struct ice_prot_lkup_ext *lkup_exts,
6719                               struct LIST_HEAD_TYPE *rg_list,
6720                               u8 *recp_cnt)
6721 {
6722         struct ice_pref_recipe_group *grp = NULL;
6723         u8 j;
6724
6725         *recp_cnt = 0;
6726
6727         if (!lkup_exts->n_val_words) {
6728                 struct ice_recp_grp_entry *entry;
6729
6730                 entry = (struct ice_recp_grp_entry *)
6731                         ice_malloc(hw, sizeof(*entry));
6732                 if (!entry)
6733                         return ICE_ERR_NO_MEMORY;
6734                 LIST_ADD(&entry->l_entry, rg_list);
6735                 grp = &entry->r_group;
6736                 (*recp_cnt)++;
6737                 grp->n_val_pairs = 0;
6738         }
6739
6740         /* Walk through every word in the rule to check if it is not done. If so
6741          * then this word needs to be part of a new recipe.
6742          */
6743         for (j = 0; j < lkup_exts->n_val_words; j++)
6744                 if (!ice_is_bit_set(lkup_exts->done, j)) {
6745                         if (!grp ||
6746                             grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
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                         }
6757
6758                         grp->pairs[grp->n_val_pairs].prot_id =
6759                                 lkup_exts->fv_words[j].prot_id;
6760                         grp->pairs[grp->n_val_pairs].off =
6761                                 lkup_exts->fv_words[j].off;
6762                         grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
6763                         grp->n_val_pairs++;
6764                 }
6765
6766         return ICE_SUCCESS;
6767 }
6768
6769 /**
6770  * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
6771  * @hw: pointer to the hardware structure
6772  * @fv_list: field vector with the extraction sequence information
6773  * @rg_list: recipe groupings with protocol-offset pairs
6774  *
6775  * Helper function to fill in the field vector indices for protocol-offset
6776  * pairs. These indexes are then ultimately programmed into a recipe.
6777  */
6778 static enum ice_status
6779 ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,
6780                        struct LIST_HEAD_TYPE *rg_list)
6781 {
6782         struct ice_sw_fv_list_entry *fv;
6783         struct ice_recp_grp_entry *rg;
6784         struct ice_fv_word *fv_ext;
6785
6786         if (LIST_EMPTY(fv_list))
6787                 return ICE_SUCCESS;
6788
6789         fv = LIST_FIRST_ENTRY(fv_list, struct ice_sw_fv_list_entry, list_entry);
6790         fv_ext = fv->fv_ptr->ew;
6791
6792         LIST_FOR_EACH_ENTRY(rg, rg_list, ice_recp_grp_entry, l_entry) {
6793                 u8 i;
6794
6795                 for (i = 0; i < rg->r_group.n_val_pairs; i++) {
6796                         struct ice_fv_word *pr;
6797                         bool found = false;
6798                         u16 mask;
6799                         u8 j;
6800
6801                         pr = &rg->r_group.pairs[i];
6802                         mask = rg->r_group.mask[i];
6803
6804                         for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
6805                                 if (fv_ext[j].prot_id == pr->prot_id &&
6806                                     fv_ext[j].off == pr->off) {
6807                                         found = true;
6808
6809                                         /* Store index of field vector */
6810                                         rg->fv_idx[i] = j;
6811                                         rg->fv_mask[i] = mask;
6812                                         break;
6813                                 }
6814
6815                         /* Protocol/offset could not be found, caller gave an
6816                          * invalid pair
6817                          */
6818                         if (!found)
6819                                 return ICE_ERR_PARAM;
6820                 }
6821         }
6822
6823         return ICE_SUCCESS;
6824 }
6825
6826 /**
6827  * ice_find_free_recp_res_idx - find free result indexes for recipe
6828  * @hw: pointer to hardware structure
6829  * @profiles: bitmap of profiles that will be associated with the new recipe
6830  * @free_idx: pointer to variable to receive the free index bitmap
6831  *
6832  * The algorithm used here is:
6833  *      1. When creating a new recipe, create a set P which contains all
6834  *         Profiles that will be associated with our new recipe
6835  *
6836  *      2. For each Profile p in set P:
6837  *          a. Add all recipes associated with Profile p into set R
6838  *          b. Optional : PossibleIndexes &= profile[p].possibleIndexes
6839  *              [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
6840  *              i. Or just assume they all have the same possible indexes:
6841  *                      44, 45, 46, 47
6842  *                      i.e., PossibleIndexes = 0x0000F00000000000
6843  *
6844  *      3. For each Recipe r in set R:
6845  *          a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
6846  *          b. FreeIndexes = UsedIndexes ^ PossibleIndexes
6847  *
6848  *      FreeIndexes will contain the bits indicating the indexes free for use,
6849  *      then the code needs to update the recipe[r].used_result_idx_bits to
6850  *      indicate which indexes were selected for use by this recipe.
6851  */
6852 static u16
6853 ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles,
6854                            ice_bitmap_t *free_idx)
6855 {
6856         ice_declare_bitmap(possible_idx, ICE_MAX_FV_WORDS);
6857         ice_declare_bitmap(recipes, ICE_MAX_NUM_RECIPES);
6858         ice_declare_bitmap(used_idx, ICE_MAX_FV_WORDS);
6859         u16 bit;
6860
6861         ice_zero_bitmap(possible_idx, ICE_MAX_FV_WORDS);
6862         ice_zero_bitmap(recipes, ICE_MAX_NUM_RECIPES);
6863         ice_zero_bitmap(used_idx, ICE_MAX_FV_WORDS);
6864         ice_zero_bitmap(free_idx, ICE_MAX_FV_WORDS);
6865
6866         ice_bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);
6867
6868         /* For each profile we are going to associate the recipe with, add the
6869          * recipes that are associated with that profile. This will give us
6870          * the set of recipes that our recipe may collide with. Also, determine
6871          * what possible result indexes are usable given this set of profiles.
6872          */
6873         ice_for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
6874                 ice_or_bitmap(recipes, recipes, profile_to_recipe[bit],
6875                               ICE_MAX_NUM_RECIPES);
6876                 ice_and_bitmap(possible_idx, possible_idx,
6877                                hw->switch_info->prof_res_bm[bit],
6878                                ICE_MAX_FV_WORDS);
6879         }
6880
6881         /* For each recipe that our new recipe may collide with, determine
6882          * which indexes have been used.
6883          */
6884         ice_for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
6885                 ice_or_bitmap(used_idx, used_idx,
6886                               hw->switch_info->recp_list[bit].res_idxs,
6887                               ICE_MAX_FV_WORDS);
6888
6889         ice_xor_bitmap(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
6890
6891         /* return number of free indexes */
6892         return (u16)ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS);
6893 }
6894
6895 /**
6896  * ice_add_sw_recipe - function to call AQ calls to create switch recipe
6897  * @hw: pointer to hardware structure
6898  * @rm: recipe management list entry
6899  * @profiles: bitmap of profiles that will be associated.
6900  */
6901 static enum ice_status
6902 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
6903                   ice_bitmap_t *profiles)
6904 {
6905         ice_declare_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
6906         struct ice_aqc_recipe_data_elem *tmp;
6907         struct ice_aqc_recipe_data_elem *buf;
6908         struct ice_recp_grp_entry *entry;
6909         enum ice_status status;
6910         u16 free_res_idx;
6911         u16 recipe_count;
6912         u8 chain_idx;
6913         u8 recps = 0;
6914
6915         /* When more than one recipe are required, another recipe is needed to
6916          * chain them together. Matching a tunnel metadata ID takes up one of
6917          * the match fields in the chaining recipe reducing the number of
6918          * chained recipes by one.
6919          */
6920          /* check number of free result indices */
6921         ice_zero_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
6922         free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
6923
6924         ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
6925                   free_res_idx, rm->n_grp_count);
6926
6927         if (rm->n_grp_count > 1) {
6928                 if (rm->n_grp_count > free_res_idx)
6929                         return ICE_ERR_MAX_LIMIT;
6930
6931                 rm->n_grp_count++;
6932         }
6933
6934         if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
6935                 return ICE_ERR_MAX_LIMIT;
6936
6937         tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
6938                                                             ICE_MAX_NUM_RECIPES,
6939                                                             sizeof(*tmp));
6940         if (!tmp)
6941                 return ICE_ERR_NO_MEMORY;
6942
6943         buf = (struct ice_aqc_recipe_data_elem *)
6944                 ice_calloc(hw, rm->n_grp_count, sizeof(*buf));
6945         if (!buf) {
6946                 status = ICE_ERR_NO_MEMORY;
6947                 goto err_mem;
6948         }
6949
6950         ice_zero_bitmap(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
6951         recipe_count = ICE_MAX_NUM_RECIPES;
6952         status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
6953                                    NULL);
6954         if (status || recipe_count == 0)
6955                 goto err_unroll;
6956
6957         /* Allocate the recipe resources, and configure them according to the
6958          * match fields from protocol headers and extracted field vectors.
6959          */
6960         chain_idx = ice_find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
6961         LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
6962                 u8 i;
6963
6964                 status = ice_alloc_recipe(hw, &entry->rid);
6965                 if (status)
6966                         goto err_unroll;
6967
6968                 /* Clear the result index of the located recipe, as this will be
6969                  * updated, if needed, later in the recipe creation process.
6970                  */
6971                 tmp[0].content.result_indx = 0;
6972
6973                 buf[recps] = tmp[0];
6974                 buf[recps].recipe_indx = (u8)entry->rid;
6975                 /* if the recipe is a non-root recipe RID should be programmed
6976                  * as 0 for the rules to be applied correctly.
6977                  */
6978                 buf[recps].content.rid = 0;
6979                 ice_memset(&buf[recps].content.lkup_indx, 0,
6980                            sizeof(buf[recps].content.lkup_indx),
6981                            ICE_NONDMA_MEM);
6982
6983                 /* All recipes use look-up index 0 to match switch ID. */
6984                 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
6985                 buf[recps].content.mask[0] =
6986                         CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
6987                 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
6988                  * to be 0
6989                  */
6990                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
6991                         buf[recps].content.lkup_indx[i] = 0x80;
6992                         buf[recps].content.mask[i] = 0;
6993                 }
6994
6995                 for (i = 0; i < entry->r_group.n_val_pairs; i++) {
6996                         buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
6997                         buf[recps].content.mask[i + 1] =
6998                                 CPU_TO_LE16(entry->fv_mask[i]);
6999                 }
7000
7001                 if (rm->n_grp_count > 1) {
7002                         /* Checks to see if there really is a valid result index
7003                          * that can be used.
7004                          */
7005                         if (chain_idx >= ICE_MAX_FV_WORDS) {
7006                                 ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
7007                                 status = ICE_ERR_MAX_LIMIT;
7008                                 goto err_unroll;
7009                         }
7010
7011                         entry->chain_idx = chain_idx;
7012                         buf[recps].content.result_indx =
7013                                 ICE_AQ_RECIPE_RESULT_EN |
7014                                 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
7015                                  ICE_AQ_RECIPE_RESULT_DATA_M);
7016                         ice_clear_bit(chain_idx, result_idx_bm);
7017                         chain_idx = ice_find_first_bit(result_idx_bm,
7018                                                        ICE_MAX_FV_WORDS);
7019                 }
7020
7021                 /* fill recipe dependencies */
7022                 ice_zero_bitmap((ice_bitmap_t *)buf[recps].recipe_bitmap,
7023                                 ICE_MAX_NUM_RECIPES);
7024                 ice_set_bit(buf[recps].recipe_indx,
7025                             (ice_bitmap_t *)buf[recps].recipe_bitmap);
7026                 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7027                 recps++;
7028         }
7029
7030         if (rm->n_grp_count == 1) {
7031                 rm->root_rid = buf[0].recipe_indx;
7032                 ice_set_bit(buf[0].recipe_indx, rm->r_bitmap);
7033                 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
7034                 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
7035                         ice_memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
7036                                    sizeof(buf[0].recipe_bitmap),
7037                                    ICE_NONDMA_TO_NONDMA);
7038                 } else {
7039                         status = ICE_ERR_BAD_PTR;
7040                         goto err_unroll;
7041                 }
7042                 /* Applicable only for ROOT_RECIPE, set the fwd_priority for
7043                  * the recipe which is getting created if specified
7044                  * by user. Usually any advanced switch filter, which results
7045                  * into new extraction sequence, ended up creating a new recipe
7046                  * of type ROOT and usually recipes are associated with profiles
7047                  * Switch rule referreing newly created recipe, needs to have
7048                  * either/or 'fwd' or 'join' priority, otherwise switch rule
7049                  * evaluation will not happen correctly. In other words, if
7050                  * switch rule to be evaluated on priority basis, then recipe
7051                  * needs to have priority, otherwise it will be evaluated last.
7052                  */
7053                 buf[0].content.act_ctrl_fwd_priority = rm->priority;
7054         } else {
7055                 struct ice_recp_grp_entry *last_chain_entry;
7056                 u16 rid, i;
7057
7058                 /* Allocate the last recipe that will chain the outcomes of the
7059                  * other recipes together
7060                  */
7061                 status = ice_alloc_recipe(hw, &rid);
7062                 if (status)
7063                         goto err_unroll;
7064
7065                 buf[recps].recipe_indx = (u8)rid;
7066                 buf[recps].content.rid = (u8)rid;
7067                 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
7068                 /* the new entry created should also be part of rg_list to
7069                  * make sure we have complete recipe
7070                  */
7071                 last_chain_entry = (struct ice_recp_grp_entry *)ice_malloc(hw,
7072                         sizeof(*last_chain_entry));
7073                 if (!last_chain_entry) {
7074                         status = ICE_ERR_NO_MEMORY;
7075                         goto err_unroll;
7076                 }
7077                 last_chain_entry->rid = rid;
7078                 ice_memset(&buf[recps].content.lkup_indx, 0,
7079                            sizeof(buf[recps].content.lkup_indx),
7080                            ICE_NONDMA_MEM);
7081                 /* All recipes use look-up index 0 to match switch ID. */
7082                 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7083                 buf[recps].content.mask[0] =
7084                         CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7085                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7086                         buf[recps].content.lkup_indx[i] =
7087                                 ICE_AQ_RECIPE_LKUP_IGNORE;
7088                         buf[recps].content.mask[i] = 0;
7089                 }
7090
7091                 i = 1;
7092                 /* update r_bitmap with the recp that is used for chaining */
7093                 ice_set_bit(rid, rm->r_bitmap);
7094                 /* this is the recipe that chains all the other recipes so it
7095                  * should not have a chaining ID to indicate the same
7096                  */
7097                 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
7098                 LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry,
7099                                     l_entry) {
7100                         last_chain_entry->fv_idx[i] = entry->chain_idx;
7101                         buf[recps].content.lkup_indx[i] = entry->chain_idx;
7102                         buf[recps].content.mask[i++] = CPU_TO_LE16(0xFFFF);
7103                         ice_set_bit(entry->rid, rm->r_bitmap);
7104                 }
7105                 LIST_ADD(&last_chain_entry->l_entry, &rm->rg_list);
7106                 if (sizeof(buf[recps].recipe_bitmap) >=
7107                     sizeof(rm->r_bitmap)) {
7108                         ice_memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
7109                                    sizeof(buf[recps].recipe_bitmap),
7110                                    ICE_NONDMA_TO_NONDMA);
7111                 } else {
7112                         status = ICE_ERR_BAD_PTR;
7113                         goto err_unroll;
7114                 }
7115                 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7116
7117                 recps++;
7118                 rm->root_rid = (u8)rid;
7119         }
7120         status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7121         if (status)
7122                 goto err_unroll;
7123
7124         status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
7125         ice_release_change_lock(hw);
7126         if (status)
7127                 goto err_unroll;
7128
7129         /* Every recipe that just got created add it to the recipe
7130          * book keeping list
7131          */
7132         LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7133                 struct ice_switch_info *sw = hw->switch_info;
7134                 bool is_root, idx_found = false;
7135                 struct ice_sw_recipe *recp;
7136                 u16 idx, buf_idx = 0;
7137
7138                 /* find buffer index for copying some data */
7139                 for (idx = 0; idx < rm->n_grp_count; idx++)
7140                         if (buf[idx].recipe_indx == entry->rid) {
7141                                 buf_idx = idx;
7142                                 idx_found = true;
7143                         }
7144
7145                 if (!idx_found) {
7146                         status = ICE_ERR_OUT_OF_RANGE;
7147                         goto err_unroll;
7148                 }
7149
7150                 recp = &sw->recp_list[entry->rid];
7151                 is_root = (rm->root_rid == entry->rid);
7152                 recp->is_root = is_root;
7153
7154                 recp->root_rid = entry->rid;
7155                 recp->big_recp = (is_root && rm->n_grp_count > 1);
7156
7157                 ice_memcpy(&recp->ext_words, entry->r_group.pairs,
7158                            entry->r_group.n_val_pairs *
7159                            sizeof(struct ice_fv_word),
7160                            ICE_NONDMA_TO_NONDMA);
7161
7162                 ice_memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
7163                            sizeof(recp->r_bitmap), ICE_NONDMA_TO_NONDMA);
7164
7165                 /* Copy non-result fv index values and masks to recipe. This
7166                  * call will also update the result recipe bitmask.
7167                  */
7168                 ice_collect_result_idx(&buf[buf_idx], recp);
7169
7170                 /* for non-root recipes, also copy to the root, this allows
7171                  * easier matching of a complete chained recipe
7172                  */
7173                 if (!is_root)
7174                         ice_collect_result_idx(&buf[buf_idx],
7175                                                &sw->recp_list[rm->root_rid]);
7176
7177                 recp->n_ext_words = entry->r_group.n_val_pairs;
7178                 recp->chain_idx = entry->chain_idx;
7179                 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
7180                 recp->n_grp_count = rm->n_grp_count;
7181                 recp->tun_type = rm->tun_type;
7182                 recp->recp_created = true;
7183         }
7184         rm->root_buf = buf;
7185         ice_free(hw, tmp);
7186         return status;
7187
7188 err_unroll:
7189 err_mem:
7190         ice_free(hw, tmp);
7191         ice_free(hw, buf);
7192         return status;
7193 }
7194
7195 /**
7196  * ice_create_recipe_group - creates recipe group
7197  * @hw: pointer to hardware structure
7198  * @rm: recipe management list entry
7199  * @lkup_exts: lookup elements
7200  */
7201 static enum ice_status
7202 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
7203                         struct ice_prot_lkup_ext *lkup_exts)
7204 {
7205         enum ice_status status;
7206         u8 recp_count = 0;
7207
7208         rm->n_grp_count = 0;
7209
7210         /* Create recipes for words that are marked not done by packing them
7211          * as best fit.
7212          */
7213         status = ice_create_first_fit_recp_def(hw, lkup_exts,
7214                                                &rm->rg_list, &recp_count);
7215         if (!status) {
7216                 rm->n_grp_count += recp_count;
7217                 rm->n_ext_words = lkup_exts->n_val_words;
7218                 ice_memcpy(&rm->ext_words, lkup_exts->fv_words,
7219                            sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA);
7220                 ice_memcpy(rm->word_masks, lkup_exts->field_mask,
7221                            sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA);
7222         }
7223
7224         return status;
7225 }
7226
7227 /**
7228  * ice_get_fv - get field vectors/extraction sequences for spec. lookup types
7229  * @hw: pointer to hardware structure
7230  * @lkups: lookup elements or match criteria for the advanced recipe, one
7231  *         structure per protocol header
7232  * @lkups_cnt: number of protocols
7233  * @bm: bitmap of field vectors to consider
7234  * @fv_list: pointer to a list that holds the returned field vectors
7235  */
7236 static enum ice_status
7237 ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
7238            ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)
7239 {
7240         enum ice_status status;
7241         u8 *prot_ids;
7242         u16 i;
7243
7244         if (!lkups_cnt)
7245                 return ICE_SUCCESS;
7246
7247         prot_ids = (u8 *)ice_calloc(hw, lkups_cnt, sizeof(*prot_ids));
7248         if (!prot_ids)
7249                 return ICE_ERR_NO_MEMORY;
7250
7251         for (i = 0; i < lkups_cnt; i++)
7252                 if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) {
7253                         status = ICE_ERR_CFG;
7254                         goto free_mem;
7255                 }
7256
7257         /* Find field vectors that include all specified protocol types */
7258         status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list);
7259
7260 free_mem:
7261         ice_free(hw, prot_ids);
7262         return status;
7263 }
7264
7265 /**
7266  * ice_tun_type_match_mask - determine if tun type needs a match mask
7267  * @tun_type: tunnel type
7268  * @mask: mask to be used for the tunnel
7269  */
7270 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
7271 {
7272         switch (tun_type) {
7273         case ICE_SW_TUN_VXLAN_GPE:
7274         case ICE_SW_TUN_GENEVE:
7275         case ICE_SW_TUN_VXLAN:
7276         case ICE_SW_TUN_NVGRE:
7277         case ICE_SW_TUN_UDP:
7278         case ICE_ALL_TUNNELS:
7279         case ICE_SW_TUN_AND_NON_TUN_QINQ:
7280         case ICE_NON_TUN_QINQ:
7281         case ICE_SW_TUN_PPPOE_QINQ:
7282         case ICE_SW_TUN_PPPOE_PAY_QINQ:
7283         case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7284         case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7285                 *mask = ICE_TUN_FLAG_MASK;
7286                 return true;
7287
7288         case ICE_SW_TUN_GENEVE_VLAN:
7289         case ICE_SW_TUN_VXLAN_VLAN:
7290                 *mask = ICE_TUN_FLAG_MASK & ~ICE_TUN_FLAG_VLAN_MASK;
7291                 return true;
7292
7293         default:
7294                 *mask = 0;
7295                 return false;
7296         }
7297 }
7298
7299 /**
7300  * ice_add_special_words - Add words that are not protocols, such as metadata
7301  * @rinfo: other information regarding the rule e.g. priority and action info
7302  * @lkup_exts: lookup word structure
7303  */
7304 static enum ice_status
7305 ice_add_special_words(struct ice_adv_rule_info *rinfo,
7306                       struct ice_prot_lkup_ext *lkup_exts)
7307 {
7308         u16 mask;
7309
7310         /* If this is a tunneled packet, then add recipe index to match the
7311          * tunnel bit in the packet metadata flags.
7312          */
7313         if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
7314                 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7315                         u8 word = lkup_exts->n_val_words++;
7316
7317                         lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7318                         lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
7319                         lkup_exts->field_mask[word] = mask;
7320                 } else {
7321                         return ICE_ERR_MAX_LIMIT;
7322                 }
7323         }
7324
7325         return ICE_SUCCESS;
7326 }
7327
7328 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
7329  * @hw: pointer to hardware structure
7330  * @rinfo: other information regarding the rule e.g. priority and action info
7331  * @bm: pointer to memory for returning the bitmap of field vectors
7332  */
7333 static void
7334 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
7335                          ice_bitmap_t *bm)
7336 {
7337         enum ice_prof_type prof_type;
7338
7339         ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
7340
7341         switch (rinfo->tun_type) {
7342         case ICE_NON_TUN:
7343         case ICE_NON_TUN_QINQ:
7344                 prof_type = ICE_PROF_NON_TUN;
7345                 break;
7346         case ICE_ALL_TUNNELS:
7347                 prof_type = ICE_PROF_TUN_ALL;
7348                 break;
7349         case ICE_SW_TUN_VXLAN_GPE:
7350         case ICE_SW_TUN_GENEVE:
7351         case ICE_SW_TUN_GENEVE_VLAN:
7352         case ICE_SW_TUN_VXLAN:
7353         case ICE_SW_TUN_VXLAN_VLAN:
7354         case ICE_SW_TUN_UDP:
7355         case ICE_SW_TUN_GTP:
7356                 prof_type = ICE_PROF_TUN_UDP;
7357                 break;
7358         case ICE_SW_TUN_NVGRE:
7359                 prof_type = ICE_PROF_TUN_GRE;
7360                 break;
7361         case ICE_SW_TUN_PPPOE:
7362         case ICE_SW_TUN_PPPOE_QINQ:
7363                 prof_type = ICE_PROF_TUN_PPPOE;
7364                 break;
7365         case ICE_SW_TUN_PPPOE_PAY:
7366         case ICE_SW_TUN_PPPOE_PAY_QINQ:
7367                 ice_set_bit(ICE_PROFID_PPPOE_PAY, bm);
7368                 return;
7369         case ICE_SW_TUN_PPPOE_IPV4:
7370         case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7371                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_OTHER, bm);
7372                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7373                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7374                 return;
7375         case ICE_SW_TUN_PPPOE_IPV4_TCP:
7376                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7377                 return;
7378         case ICE_SW_TUN_PPPOE_IPV4_UDP:
7379                 ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7380                 return;
7381         case ICE_SW_TUN_PPPOE_IPV6:
7382         case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7383                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_OTHER, bm);
7384                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7385                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7386                 return;
7387         case ICE_SW_TUN_PPPOE_IPV6_TCP:
7388                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7389                 return;
7390         case ICE_SW_TUN_PPPOE_IPV6_UDP:
7391                 ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7392                 return;
7393         case ICE_SW_TUN_PROFID_IPV6_ESP:
7394         case ICE_SW_TUN_IPV6_ESP:
7395                 ice_set_bit(ICE_PROFID_IPV6_ESP, bm);
7396                 return;
7397         case ICE_SW_TUN_PROFID_IPV6_AH:
7398         case ICE_SW_TUN_IPV6_AH:
7399                 ice_set_bit(ICE_PROFID_IPV6_AH, bm);
7400                 return;
7401         case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7402         case ICE_SW_TUN_IPV6_L2TPV3:
7403                 ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm);
7404                 return;
7405         case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7406         case ICE_SW_TUN_IPV6_NAT_T:
7407                 ice_set_bit(ICE_PROFID_IPV6_NAT_T, bm);
7408                 return;
7409         case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7410                 ice_set_bit(ICE_PROFID_IPV4_PFCP_NODE, bm);
7411                 return;
7412         case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7413                 ice_set_bit(ICE_PROFID_IPV4_PFCP_SESSION, bm);
7414                 return;
7415         case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7416                 ice_set_bit(ICE_PROFID_IPV6_PFCP_NODE, bm);
7417                 return;
7418         case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7419                 ice_set_bit(ICE_PROFID_IPV6_PFCP_SESSION, bm);
7420                 return;
7421         case ICE_SW_TUN_IPV4_NAT_T:
7422                 ice_set_bit(ICE_PROFID_IPV4_NAT_T, bm);
7423                 return;
7424         case ICE_SW_TUN_IPV4_L2TPV3:
7425                 ice_set_bit(ICE_PROFID_MAC_IPV4_L2TPV3, bm);
7426                 return;
7427         case ICE_SW_TUN_IPV4_ESP:
7428                 ice_set_bit(ICE_PROFID_IPV4_ESP, bm);
7429                 return;
7430         case ICE_SW_TUN_IPV4_AH:
7431                 ice_set_bit(ICE_PROFID_IPV4_AH, bm);
7432                 return;
7433         case ICE_SW_IPV4_TCP:
7434                 ice_set_bit(ICE_PROFID_IPV4_TCP, bm);
7435                 return;
7436         case ICE_SW_IPV4_UDP:
7437                 ice_set_bit(ICE_PROFID_IPV4_UDP, bm);
7438                 return;
7439         case ICE_SW_IPV6_TCP:
7440                 ice_set_bit(ICE_PROFID_IPV6_TCP, bm);
7441                 return;
7442         case ICE_SW_IPV6_UDP:
7443                 ice_set_bit(ICE_PROFID_IPV6_UDP, bm);
7444                 return;
7445         case ICE_SW_TUN_IPV4_GTPU_IPV4:
7446                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, bm);
7447                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_OTHER, bm);
7448                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
7449                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
7450                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
7451                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
7452                 return;
7453         case ICE_SW_TUN_IPV6_GTPU_IPV4:
7454                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, bm);
7455                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_OTHER, bm);
7456                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
7457                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
7458                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
7459                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
7460                 return;
7461         case ICE_SW_TUN_IPV4_GTPU_IPV6:
7462                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, bm);
7463                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_OTHER, bm);
7464                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
7465                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
7466                 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
7467                 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
7468                 return;
7469         case ICE_SW_TUN_IPV6_GTPU_IPV6:
7470                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, bm);
7471                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_OTHER, bm);
7472                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
7473                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
7474                 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
7475                 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
7476                 return;
7477         case ICE_SW_TUN_AND_NON_TUN:
7478         case ICE_SW_TUN_AND_NON_TUN_QINQ:
7479         default:
7480                 prof_type = ICE_PROF_ALL;
7481                 break;
7482         }
7483
7484         ice_get_sw_fv_bitmap(hw, prof_type, bm);
7485 }
7486
7487 /**
7488  * ice_is_prof_rule - determine if rule type is a profile rule
7489  * @type: the rule type
7490  *
7491  * if the rule type is a profile rule, that means that there no field value
7492  * match required, in this case just a profile hit is required.
7493  */
7494 bool ice_is_prof_rule(enum ice_sw_tunnel_type type)
7495 {
7496         switch (type) {
7497         case ICE_SW_TUN_PROFID_IPV6_ESP:
7498         case ICE_SW_TUN_PROFID_IPV6_AH:
7499         case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7500         case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7501         case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7502         case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7503         case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7504         case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7505                 return true;
7506         default:
7507                 break;
7508         }
7509
7510         return false;
7511 }
7512
7513 /**
7514  * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
7515  * @hw: pointer to hardware structure
7516  * @lkups: lookup elements or match criteria for the advanced recipe, one
7517  *  structure per protocol header
7518  * @lkups_cnt: number of protocols
7519  * @rinfo: other information regarding the rule e.g. priority and action info
7520  * @rid: return the recipe ID of the recipe created
7521  */
7522 static enum ice_status
7523 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
7524                    u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
7525 {
7526         ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES);
7527         ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES);
7528         struct ice_prot_lkup_ext *lkup_exts;
7529         struct ice_recp_grp_entry *r_entry;
7530         struct ice_sw_fv_list_entry *fvit;
7531         struct ice_recp_grp_entry *r_tmp;
7532         struct ice_sw_fv_list_entry *tmp;
7533         enum ice_status status = ICE_SUCCESS;
7534         struct ice_sw_recipe *rm;
7535         u8 i;
7536
7537         if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt)
7538                 return ICE_ERR_PARAM;
7539
7540         lkup_exts = (struct ice_prot_lkup_ext *)
7541                 ice_malloc(hw, sizeof(*lkup_exts));
7542         if (!lkup_exts)
7543                 return ICE_ERR_NO_MEMORY;
7544
7545         /* Determine the number of words to be matched and if it exceeds a
7546          * recipe's restrictions
7547          */
7548         for (i = 0; i < lkups_cnt; i++) {
7549                 u16 count;
7550
7551                 if (lkups[i].type >= ICE_PROTOCOL_LAST) {
7552                         status = ICE_ERR_CFG;
7553                         goto err_free_lkup_exts;
7554                 }
7555
7556                 count = ice_fill_valid_words(&lkups[i], lkup_exts);
7557                 if (!count) {
7558                         status = ICE_ERR_CFG;
7559                         goto err_free_lkup_exts;
7560                 }
7561         }
7562
7563         rm = (struct ice_sw_recipe *)ice_malloc(hw, sizeof(*rm));
7564         if (!rm) {
7565                 status = ICE_ERR_NO_MEMORY;
7566                 goto err_free_lkup_exts;
7567         }
7568
7569         /* Get field vectors that contain fields extracted from all the protocol
7570          * headers being programmed.
7571          */
7572         INIT_LIST_HEAD(&rm->fv_list);
7573         INIT_LIST_HEAD(&rm->rg_list);
7574
7575         /* Get bitmap of field vectors (profiles) that are compatible with the
7576          * rule request; only these will be searched in the subsequent call to
7577          * ice_get_fv.
7578          */
7579         ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
7580
7581         status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list);
7582         if (status)
7583                 goto err_unroll;
7584
7585         /* Create any special protocol/offset pairs, such as looking at tunnel
7586          * bits by extracting metadata
7587          */
7588         status = ice_add_special_words(rinfo, lkup_exts);
7589         if (status)
7590                 goto err_free_lkup_exts;
7591
7592         /* Group match words into recipes using preferred recipe grouping
7593          * criteria.
7594          */
7595         status = ice_create_recipe_group(hw, rm, lkup_exts);
7596         if (status)
7597                 goto err_unroll;
7598
7599         /* set the recipe priority if specified */
7600         rm->priority = (u8)rinfo->priority;
7601
7602         /* Find offsets from the field vector. Pick the first one for all the
7603          * recipes.
7604          */
7605         status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
7606         if (status)
7607                 goto err_unroll;
7608
7609         /* An empty FV list means to use all the profiles returned in the
7610          * profile bitmap
7611          */
7612         if (LIST_EMPTY(&rm->fv_list)) {
7613                 u16 j;
7614
7615                 ice_for_each_set_bit(j, fv_bitmap, ICE_MAX_NUM_PROFILES) {
7616                         struct ice_sw_fv_list_entry *fvl;
7617
7618                         fvl = (struct ice_sw_fv_list_entry *)
7619                                 ice_malloc(hw, sizeof(*fvl));
7620                         if (!fvl)
7621                                 goto err_unroll;
7622                         fvl->fv_ptr = NULL;
7623                         fvl->profile_id = j;
7624                         LIST_ADD(&fvl->list_entry, &rm->fv_list);
7625                 }
7626         }
7627
7628         /* get bitmap of all profiles the recipe will be associated with */
7629         ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES);
7630         LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
7631                             list_entry) {
7632                 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
7633                 ice_set_bit((u16)fvit->profile_id, profiles);
7634         }
7635
7636         /* Look for a recipe which matches our requested fv / mask list */
7637         *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type);
7638         if (*rid < ICE_MAX_NUM_RECIPES)
7639                 /* Success if found a recipe that match the existing criteria */
7640                 goto err_unroll;
7641
7642         rm->tun_type = rinfo->tun_type;
7643         /* Recipe we need does not exist, add a recipe */
7644         status = ice_add_sw_recipe(hw, rm, profiles);
7645         if (status)
7646                 goto err_unroll;
7647
7648         /* Associate all the recipes created with all the profiles in the
7649          * common field vector.
7650          */
7651         LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
7652                             list_entry) {
7653                 ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
7654                 u16 j;
7655
7656                 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
7657                                                       (u8 *)r_bitmap, NULL);
7658                 if (status)
7659                         goto err_unroll;
7660
7661                 ice_or_bitmap(r_bitmap, r_bitmap, rm->r_bitmap,
7662                               ICE_MAX_NUM_RECIPES);
7663                 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7664                 if (status)
7665                         goto err_unroll;
7666
7667                 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
7668                                                       (u8 *)r_bitmap,
7669                                                       NULL);
7670                 ice_release_change_lock(hw);
7671
7672                 if (status)
7673                         goto err_unroll;
7674
7675                 /* Update profile to recipe bitmap array */
7676                 ice_cp_bitmap(profile_to_recipe[fvit->profile_id], r_bitmap,
7677                               ICE_MAX_NUM_RECIPES);
7678
7679                 /* Update recipe to profile bitmap array */
7680                 ice_for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
7681                         ice_set_bit((u16)fvit->profile_id,
7682                                     recipe_to_profile[j]);
7683         }
7684
7685         *rid = rm->root_rid;
7686         ice_memcpy(&hw->switch_info->recp_list[*rid].lkup_exts,
7687                    lkup_exts, sizeof(*lkup_exts), ICE_NONDMA_TO_NONDMA);
7688 err_unroll:
7689         LIST_FOR_EACH_ENTRY_SAFE(r_entry, r_tmp, &rm->rg_list,
7690                                  ice_recp_grp_entry, l_entry) {
7691                 LIST_DEL(&r_entry->l_entry);
7692                 ice_free(hw, r_entry);
7693         }
7694
7695         LIST_FOR_EACH_ENTRY_SAFE(fvit, tmp, &rm->fv_list, ice_sw_fv_list_entry,
7696                                  list_entry) {
7697                 LIST_DEL(&fvit->list_entry);
7698                 ice_free(hw, fvit);
7699         }
7700
7701         if (rm->root_buf)
7702                 ice_free(hw, rm->root_buf);
7703
7704         ice_free(hw, rm);
7705
7706 err_free_lkup_exts:
7707         ice_free(hw, lkup_exts);
7708
7709         return status;
7710 }
7711
7712 /**
7713  * ice_find_dummy_packet - find dummy packet by tunnel type
7714  *
7715  * @lkups: lookup elements or match criteria for the advanced recipe, one
7716  *         structure per protocol header
7717  * @lkups_cnt: number of protocols
7718  * @tun_type: tunnel type from the match criteria
7719  * @pkt: dummy packet to fill according to filter match criteria
7720  * @pkt_len: packet length of dummy packet
7721  * @offsets: pointer to receive the pointer to the offsets for the packet
7722  */
7723 static void
7724 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
7725                       enum ice_sw_tunnel_type tun_type, const u8 **pkt,
7726                       u16 *pkt_len,
7727                       const struct ice_dummy_pkt_offsets **offsets)
7728 {
7729         bool tcp = false, udp = false, ipv6 = false, vlan = false;
7730         bool gre = false;
7731         u16 i;
7732
7733         for (i = 0; i < lkups_cnt; i++) {
7734                 if (lkups[i].type == ICE_UDP_ILOS)
7735                         udp = true;
7736                 else if (lkups[i].type == ICE_TCP_IL)
7737                         tcp = true;
7738                 else if (lkups[i].type == ICE_IPV6_OFOS)
7739                         ipv6 = true;
7740                 else if (lkups[i].type == ICE_VLAN_OFOS)
7741                         vlan = true;
7742                 else if (lkups[i].type == ICE_IPV4_OFOS &&
7743                          lkups[i].h_u.ipv4_hdr.protocol ==
7744                                 ICE_IPV4_NVGRE_PROTO_ID &&
7745                          lkups[i].m_u.ipv4_hdr.protocol ==
7746                                 0xFF)
7747                         gre = true;
7748                 else if (lkups[i].type == ICE_PPPOE &&
7749                          lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
7750                                 CPU_TO_BE16(ICE_PPP_IPV6_PROTO_ID) &&
7751                          lkups[i].m_u.pppoe_hdr.ppp_prot_id ==
7752                                 0xFFFF)
7753                         ipv6 = true;
7754                 else if (lkups[i].type == ICE_ETYPE_OL &&
7755                          lkups[i].h_u.ethertype.ethtype_id ==
7756                                 CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
7757                          lkups[i].m_u.ethertype.ethtype_id ==
7758                                         0xFFFF)
7759                         ipv6 = true;
7760                 else if (lkups[i].type == ICE_IPV4_IL &&
7761                          lkups[i].h_u.ipv4_hdr.protocol ==
7762                                 ICE_TCP_PROTO_ID &&
7763                          lkups[i].m_u.ipv4_hdr.protocol ==
7764                                 0xFF)
7765                         tcp = true;
7766         }
7767
7768         if ((tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
7769              tun_type == ICE_NON_TUN_QINQ) && ipv6) {
7770                 *pkt = dummy_qinq_ipv6_pkt;
7771                 *pkt_len = sizeof(dummy_qinq_ipv6_pkt);
7772                 *offsets = dummy_qinq_ipv6_packet_offsets;
7773                 return;
7774         } else if (tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
7775                            tun_type == ICE_NON_TUN_QINQ) {
7776                 *pkt = dummy_qinq_ipv4_pkt;
7777                 *pkt_len = sizeof(dummy_qinq_ipv4_pkt);
7778                 *offsets = dummy_qinq_ipv4_packet_offsets;
7779                 return;
7780         }
7781
7782         if (tun_type == ICE_SW_TUN_PPPOE_IPV6_QINQ) {
7783                 *pkt = dummy_qinq_pppoe_ipv6_packet;
7784                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
7785                 *offsets = dummy_qinq_pppoe_packet_ipv6_offsets;
7786                 return;
7787         } else if (tun_type == ICE_SW_TUN_PPPOE_IPV4_QINQ) {
7788                 *pkt = dummy_qinq_pppoe_ipv4_pkt;
7789                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
7790                 *offsets = dummy_qinq_pppoe_ipv4_packet_offsets;
7791                 return;
7792         } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ ||
7793                         tun_type == ICE_SW_TUN_PPPOE_PAY_QINQ) {
7794                 *pkt = dummy_qinq_pppoe_ipv4_pkt;
7795                 *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
7796                 *offsets = dummy_qinq_pppoe_packet_offsets;
7797                 return;
7798         }
7799
7800         if (tun_type == ICE_SW_TUN_IPV4_GTPU_NO_PAY) {
7801                 *pkt = dummy_ipv4_gtpu_ipv4_packet;
7802                 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
7803                 *offsets = dummy_ipv4_gtp_no_pay_packet_offsets;
7804                 return;
7805         } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_NO_PAY) {
7806                 *pkt = dummy_ipv6_gtpu_ipv6_packet;
7807                 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
7808                 *offsets = dummy_ipv6_gtp_no_pay_packet_offsets;
7809                 return;
7810         }
7811
7812         if (tun_type == ICE_SW_TUN_IPV4_ESP) {
7813                 *pkt = dummy_ipv4_esp_pkt;
7814                 *pkt_len = sizeof(dummy_ipv4_esp_pkt);
7815                 *offsets = dummy_ipv4_esp_packet_offsets;
7816                 return;
7817         }
7818
7819         if (tun_type == ICE_SW_TUN_IPV6_ESP) {
7820                 *pkt = dummy_ipv6_esp_pkt;
7821                 *pkt_len = sizeof(dummy_ipv6_esp_pkt);
7822                 *offsets = dummy_ipv6_esp_packet_offsets;
7823                 return;
7824         }
7825
7826         if (tun_type == ICE_SW_TUN_IPV4_AH) {
7827                 *pkt = dummy_ipv4_ah_pkt;
7828                 *pkt_len = sizeof(dummy_ipv4_ah_pkt);
7829                 *offsets = dummy_ipv4_ah_packet_offsets;
7830                 return;
7831         }
7832
7833         if (tun_type == ICE_SW_TUN_IPV6_AH) {
7834                 *pkt = dummy_ipv6_ah_pkt;
7835                 *pkt_len = sizeof(dummy_ipv6_ah_pkt);
7836                 *offsets = dummy_ipv6_ah_packet_offsets;
7837                 return;
7838         }
7839
7840         if (tun_type == ICE_SW_TUN_IPV4_NAT_T) {
7841                 *pkt = dummy_ipv4_nat_pkt;
7842                 *pkt_len = sizeof(dummy_ipv4_nat_pkt);
7843                 *offsets = dummy_ipv4_nat_packet_offsets;
7844                 return;
7845         }
7846
7847         if (tun_type == ICE_SW_TUN_IPV6_NAT_T) {
7848                 *pkt = dummy_ipv6_nat_pkt;
7849                 *pkt_len = sizeof(dummy_ipv6_nat_pkt);
7850                 *offsets = dummy_ipv6_nat_packet_offsets;
7851                 return;
7852         }
7853
7854         if (tun_type == ICE_SW_TUN_IPV4_L2TPV3) {
7855                 *pkt = dummy_ipv4_l2tpv3_pkt;
7856                 *pkt_len = sizeof(dummy_ipv4_l2tpv3_pkt);
7857                 *offsets = dummy_ipv4_l2tpv3_packet_offsets;
7858                 return;
7859         }
7860
7861         if (tun_type == ICE_SW_TUN_IPV6_L2TPV3) {
7862                 *pkt = dummy_ipv6_l2tpv3_pkt;
7863                 *pkt_len = sizeof(dummy_ipv6_l2tpv3_pkt);
7864                 *offsets = dummy_ipv6_l2tpv3_packet_offsets;
7865                 return;
7866         }
7867
7868         if (tun_type == ICE_SW_TUN_GTP) {
7869                 *pkt = dummy_udp_gtp_packet;
7870                 *pkt_len = sizeof(dummy_udp_gtp_packet);
7871                 *offsets = dummy_udp_gtp_packet_offsets;
7872                 return;
7873         }
7874
7875         if (tun_type == ICE_SW_TUN_PPPOE && ipv6) {
7876                 *pkt = dummy_pppoe_ipv6_packet;
7877                 *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
7878                 *offsets = dummy_pppoe_packet_offsets;
7879                 return;
7880         } else if (tun_type == ICE_SW_TUN_PPPOE ||
7881                 tun_type == ICE_SW_TUN_PPPOE_PAY) {
7882                 *pkt = dummy_pppoe_ipv4_packet;
7883                 *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
7884                 *offsets = dummy_pppoe_packet_offsets;
7885                 return;
7886         }
7887
7888         if (tun_type == ICE_SW_TUN_PPPOE_IPV4) {
7889                 *pkt = dummy_pppoe_ipv4_packet;
7890                 *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
7891                 *offsets = dummy_pppoe_packet_ipv4_offsets;
7892                 return;
7893         }
7894
7895         if (tun_type == ICE_SW_TUN_PPPOE_IPV4_TCP) {
7896                 *pkt = dummy_pppoe_ipv4_tcp_packet;
7897                 *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
7898                 *offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
7899                 return;
7900         }
7901
7902         if (tun_type == ICE_SW_TUN_PPPOE_IPV4_UDP) {
7903                 *pkt = dummy_pppoe_ipv4_udp_packet;
7904                 *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
7905                 *offsets = dummy_pppoe_ipv4_udp_packet_offsets;
7906                 return;
7907         }
7908
7909         if (tun_type == ICE_SW_TUN_PPPOE_IPV6) {
7910                 *pkt = dummy_pppoe_ipv6_packet;
7911                 *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
7912                 *offsets = dummy_pppoe_packet_ipv6_offsets;
7913                 return;
7914         }
7915
7916         if (tun_type == ICE_SW_TUN_PPPOE_IPV6_TCP) {
7917                 *pkt = dummy_pppoe_ipv6_tcp_packet;
7918                 *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
7919                 *offsets = dummy_pppoe_packet_ipv6_tcp_offsets;
7920                 return;
7921         }
7922
7923         if (tun_type == ICE_SW_TUN_PPPOE_IPV6_UDP) {
7924                 *pkt = dummy_pppoe_ipv6_udp_packet;
7925                 *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
7926                 *offsets = dummy_pppoe_packet_ipv6_udp_offsets;
7927                 return;
7928         }
7929
7930         if (tun_type == ICE_SW_IPV4_TCP) {
7931                 *pkt = dummy_tcp_packet;
7932                 *pkt_len = sizeof(dummy_tcp_packet);
7933                 *offsets = dummy_tcp_packet_offsets;
7934                 return;
7935         }
7936
7937         if (tun_type == ICE_SW_IPV4_UDP) {
7938                 *pkt = dummy_udp_packet;
7939                 *pkt_len = sizeof(dummy_udp_packet);
7940                 *offsets = dummy_udp_packet_offsets;
7941                 return;
7942         }
7943
7944         if (tun_type == ICE_SW_IPV6_TCP) {
7945                 *pkt = dummy_tcp_ipv6_packet;
7946                 *pkt_len = sizeof(dummy_tcp_ipv6_packet);
7947                 *offsets = dummy_tcp_ipv6_packet_offsets;
7948                 return;
7949         }
7950
7951         if (tun_type == ICE_SW_IPV6_UDP) {
7952                 *pkt = dummy_udp_ipv6_packet;
7953                 *pkt_len = sizeof(dummy_udp_ipv6_packet);
7954                 *offsets = dummy_udp_ipv6_packet_offsets;
7955                 return;
7956         }
7957
7958         /* Support GTP tunnel + L3 */
7959         if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4) {
7960                 *pkt = dummy_ipv4_gtpu_ipv4_packet;
7961                 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
7962                 *offsets = dummy_ipv4_gtpu_ipv4_packet_offsets;
7963                 return;
7964         }
7965         if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6) {
7966                 *pkt = dummy_ipv4_gtpu_ipv6_packet;
7967                 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_packet);
7968                 *offsets = dummy_ipv4_gtpu_ipv6_packet_offsets;
7969                 return;
7970         }
7971         if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4) {
7972                 *pkt = dummy_ipv6_gtpu_ipv4_packet;
7973                 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_packet);
7974                 *offsets = dummy_ipv6_gtpu_ipv4_packet_offsets;
7975                 return;
7976         }
7977         if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6) {
7978                 *pkt = dummy_ipv6_gtpu_ipv6_packet;
7979                 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
7980                 *offsets = dummy_ipv6_gtpu_ipv6_packet_offsets;
7981                 return;
7982         }
7983
7984         if (tun_type == ICE_ALL_TUNNELS) {
7985                 *pkt = dummy_gre_udp_packet;
7986                 *pkt_len = sizeof(dummy_gre_udp_packet);
7987                 *offsets = dummy_gre_udp_packet_offsets;
7988                 return;
7989         }
7990
7991         if (tun_type == ICE_SW_TUN_NVGRE || gre) {
7992                 if (tcp) {
7993                         *pkt = dummy_gre_tcp_packet;
7994                         *pkt_len = sizeof(dummy_gre_tcp_packet);
7995                         *offsets = dummy_gre_tcp_packet_offsets;
7996                         return;
7997                 }
7998
7999                 *pkt = dummy_gre_udp_packet;
8000                 *pkt_len = sizeof(dummy_gre_udp_packet);
8001                 *offsets = dummy_gre_udp_packet_offsets;
8002                 return;
8003         }
8004
8005         if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE ||
8006             tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP ||
8007             tun_type == ICE_SW_TUN_GENEVE_VLAN ||
8008             tun_type == ICE_SW_TUN_VXLAN_VLAN) {
8009                 if (tcp) {
8010                         *pkt = dummy_udp_tun_tcp_packet;
8011                         *pkt_len = sizeof(dummy_udp_tun_tcp_packet);
8012                         *offsets = dummy_udp_tun_tcp_packet_offsets;
8013                         return;
8014                 }
8015
8016                 *pkt = dummy_udp_tun_udp_packet;
8017                 *pkt_len = sizeof(dummy_udp_tun_udp_packet);
8018                 *offsets = dummy_udp_tun_udp_packet_offsets;
8019                 return;
8020         }
8021
8022         if (udp && !ipv6) {
8023                 if (vlan) {
8024                         *pkt = dummy_vlan_udp_packet;
8025                         *pkt_len = sizeof(dummy_vlan_udp_packet);
8026                         *offsets = dummy_vlan_udp_packet_offsets;
8027                         return;
8028                 }
8029                 *pkt = dummy_udp_packet;
8030                 *pkt_len = sizeof(dummy_udp_packet);
8031                 *offsets = dummy_udp_packet_offsets;
8032                 return;
8033         } else if (udp && ipv6) {
8034                 if (vlan) {
8035                         *pkt = dummy_vlan_udp_ipv6_packet;
8036                         *pkt_len = sizeof(dummy_vlan_udp_ipv6_packet);
8037                         *offsets = dummy_vlan_udp_ipv6_packet_offsets;
8038                         return;
8039                 }
8040                 *pkt = dummy_udp_ipv6_packet;
8041                 *pkt_len = sizeof(dummy_udp_ipv6_packet);
8042                 *offsets = dummy_udp_ipv6_packet_offsets;
8043                 return;
8044         } else if ((tcp && ipv6) || ipv6) {
8045                 if (vlan) {
8046                         *pkt = dummy_vlan_tcp_ipv6_packet;
8047                         *pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet);
8048                         *offsets = dummy_vlan_tcp_ipv6_packet_offsets;
8049                         return;
8050                 }
8051                 *pkt = dummy_tcp_ipv6_packet;
8052                 *pkt_len = sizeof(dummy_tcp_ipv6_packet);
8053                 *offsets = dummy_tcp_ipv6_packet_offsets;
8054                 return;
8055         }
8056
8057         if (vlan) {
8058                 *pkt = dummy_vlan_tcp_packet;
8059                 *pkt_len = sizeof(dummy_vlan_tcp_packet);
8060                 *offsets = dummy_vlan_tcp_packet_offsets;
8061         } else {
8062                 *pkt = dummy_tcp_packet;
8063                 *pkt_len = sizeof(dummy_tcp_packet);
8064                 *offsets = dummy_tcp_packet_offsets;
8065         }
8066 }
8067
8068 /**
8069  * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
8070  *
8071  * @lkups: lookup elements or match criteria for the advanced recipe, one
8072  *         structure per protocol header
8073  * @lkups_cnt: number of protocols
8074  * @s_rule: stores rule information from the match criteria
8075  * @dummy_pkt: dummy packet to fill according to filter match criteria
8076  * @pkt_len: packet length of dummy packet
8077  * @offsets: offset info for the dummy packet
8078  */
8079 static enum ice_status
8080 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8081                           struct ice_aqc_sw_rules_elem *s_rule,
8082                           const u8 *dummy_pkt, u16 pkt_len,
8083                           const struct ice_dummy_pkt_offsets *offsets)
8084 {
8085         u8 *pkt;
8086         u16 i;
8087
8088         /* Start with a packet with a pre-defined/dummy content. Then, fill
8089          * in the header values to be looked up or matched.
8090          */
8091         pkt = s_rule->pdata.lkup_tx_rx.hdr;
8092
8093         ice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA);
8094
8095         for (i = 0; i < lkups_cnt; i++) {
8096                 enum ice_protocol_type type;
8097                 u16 offset = 0, len = 0, j;
8098                 bool found = false;
8099
8100                 /* find the start of this layer; it should be found since this
8101                  * was already checked when search for the dummy packet
8102                  */
8103                 type = lkups[i].type;
8104                 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
8105                         if (type == offsets[j].type) {
8106                                 offset = offsets[j].offset;
8107                                 found = true;
8108                                 break;
8109                         }
8110                 }
8111                 /* this should never happen in a correct calling sequence */
8112                 if (!found)
8113                         return ICE_ERR_PARAM;
8114
8115                 switch (lkups[i].type) {
8116                 case ICE_MAC_OFOS:
8117                 case ICE_MAC_IL:
8118                         len = sizeof(struct ice_ether_hdr);
8119                         break;
8120                 case ICE_ETYPE_OL:
8121                         len = sizeof(struct ice_ethtype_hdr);
8122                         break;
8123                 case ICE_VLAN_OFOS:
8124                 case ICE_VLAN_EX:
8125                         len = sizeof(struct ice_vlan_hdr);
8126                         break;
8127                 case ICE_IPV4_OFOS:
8128                 case ICE_IPV4_IL:
8129                         len = sizeof(struct ice_ipv4_hdr);
8130                         break;
8131                 case ICE_IPV6_OFOS:
8132                 case ICE_IPV6_IL:
8133                         len = sizeof(struct ice_ipv6_hdr);
8134                         break;
8135                 case ICE_TCP_IL:
8136                 case ICE_UDP_OF:
8137                 case ICE_UDP_ILOS:
8138                         len = sizeof(struct ice_l4_hdr);
8139                         break;
8140                 case ICE_SCTP_IL:
8141                         len = sizeof(struct ice_sctp_hdr);
8142                         break;
8143                 case ICE_NVGRE:
8144                         len = sizeof(struct ice_nvgre);
8145                         break;
8146                 case ICE_VXLAN:
8147                 case ICE_GENEVE:
8148                 case ICE_VXLAN_GPE:
8149                         len = sizeof(struct ice_udp_tnl_hdr);
8150                         break;
8151
8152                 case ICE_GTP:
8153                 case ICE_GTP_NO_PAY:
8154                         len = sizeof(struct ice_udp_gtp_hdr);
8155                         break;
8156                 case ICE_PPPOE:
8157                         len = sizeof(struct ice_pppoe_hdr);
8158                         break;
8159                 case ICE_ESP:
8160                         len = sizeof(struct ice_esp_hdr);
8161                         break;
8162                 case ICE_NAT_T:
8163                         len = sizeof(struct ice_nat_t_hdr);
8164                         break;
8165                 case ICE_AH:
8166                         len = sizeof(struct ice_ah_hdr);
8167                         break;
8168                 case ICE_L2TPV3:
8169                         len = sizeof(struct ice_l2tpv3_sess_hdr);
8170                         break;
8171                 default:
8172                         return ICE_ERR_PARAM;
8173                 }
8174
8175                 /* the length should be a word multiple */
8176                 if (len % ICE_BYTES_PER_WORD)
8177                         return ICE_ERR_CFG;
8178
8179                 /* We have the offset to the header start, the length, the
8180                  * caller's header values and mask. Use this information to
8181                  * copy the data into the dummy packet appropriately based on
8182                  * the mask. Note that we need to only write the bits as
8183                  * indicated by the mask to make sure we don't improperly write
8184                  * over any significant packet data.
8185                  */
8186                 for (j = 0; j < len / sizeof(u16); j++)
8187                         if (((u16 *)&lkups[i].m_u)[j])
8188                                 ((u16 *)(pkt + offset))[j] =
8189                                         (((u16 *)(pkt + offset))[j] &
8190                                          ~((u16 *)&lkups[i].m_u)[j]) |
8191                                         (((u16 *)&lkups[i].h_u)[j] &
8192                                          ((u16 *)&lkups[i].m_u)[j]);
8193         }
8194
8195         s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(pkt_len);
8196
8197         return ICE_SUCCESS;
8198 }
8199
8200 /**
8201  * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
8202  * @hw: pointer to the hardware structure
8203  * @tun_type: tunnel type
8204  * @pkt: dummy packet to fill in
8205  * @offsets: offset info for the dummy packet
8206  */
8207 static enum ice_status
8208 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
8209                         u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
8210 {
8211         u16 open_port, i;
8212
8213         switch (tun_type) {
8214         case ICE_SW_TUN_AND_NON_TUN:
8215         case ICE_SW_TUN_VXLAN_GPE:
8216         case ICE_SW_TUN_VXLAN:
8217         case ICE_SW_TUN_VXLAN_VLAN:
8218         case ICE_SW_TUN_UDP:
8219                 if (!ice_get_open_tunnel_port(hw, TNL_VXLAN, &open_port))
8220                         return ICE_ERR_CFG;
8221                 break;
8222
8223         case ICE_SW_TUN_GENEVE:
8224         case ICE_SW_TUN_GENEVE_VLAN:
8225                 if (!ice_get_open_tunnel_port(hw, TNL_GENEVE, &open_port))
8226                         return ICE_ERR_CFG;
8227                 break;
8228
8229         default:
8230                 /* Nothing needs to be done for this tunnel type */
8231                 return ICE_SUCCESS;
8232         }
8233
8234         /* Find the outer UDP protocol header and insert the port number */
8235         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
8236                 if (offsets[i].type == ICE_UDP_OF) {
8237                         struct ice_l4_hdr *hdr;
8238                         u16 offset;
8239
8240                         offset = offsets[i].offset;
8241                         hdr = (struct ice_l4_hdr *)&pkt[offset];
8242                         hdr->dst_port = CPU_TO_BE16(open_port);
8243
8244                         return ICE_SUCCESS;
8245                 }
8246         }
8247
8248         return ICE_ERR_CFG;
8249 }
8250
8251 /**
8252  * ice_find_adv_rule_entry - Search a rule entry
8253  * @hw: pointer to the hardware structure
8254  * @lkups: lookup elements or match criteria for the advanced recipe, one
8255  *         structure per protocol header
8256  * @lkups_cnt: number of protocols
8257  * @recp_id: recipe ID for which we are finding the rule
8258  * @rinfo: other information regarding the rule e.g. priority and action info
8259  *
8260  * Helper function to search for a given advance rule entry
8261  * Returns pointer to entry storing the rule if found
8262  */
8263 static struct ice_adv_fltr_mgmt_list_entry *
8264 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8265                         u16 lkups_cnt, u16 recp_id,
8266                         struct ice_adv_rule_info *rinfo)
8267 {
8268         struct ice_adv_fltr_mgmt_list_entry *list_itr;
8269         struct ice_switch_info *sw = hw->switch_info;
8270         int i;
8271
8272         LIST_FOR_EACH_ENTRY(list_itr, &sw->recp_list[recp_id].filt_rules,
8273                             ice_adv_fltr_mgmt_list_entry, list_entry) {
8274                 bool lkups_matched = true;
8275
8276                 if (lkups_cnt != list_itr->lkups_cnt)
8277                         continue;
8278                 for (i = 0; i < list_itr->lkups_cnt; i++)
8279                         if (memcmp(&list_itr->lkups[i], &lkups[i],
8280                                    sizeof(*lkups))) {
8281                                 lkups_matched = false;
8282                                 break;
8283                         }
8284                 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
8285                     rinfo->tun_type == list_itr->rule_info.tun_type &&
8286                     lkups_matched)
8287                         return list_itr;
8288         }
8289         return NULL;
8290 }
8291
8292 /**
8293  * ice_adv_add_update_vsi_list
8294  * @hw: pointer to the hardware structure
8295  * @m_entry: pointer to current adv filter management list entry
8296  * @cur_fltr: filter information from the book keeping entry
8297  * @new_fltr: filter information with the new VSI to be added
8298  *
8299  * Call AQ command to add or update previously created VSI list with new VSI.
8300  *
8301  * Helper function to do book keeping associated with adding filter information
8302  * The algorithm to do the booking keeping is described below :
8303  * When a VSI needs to subscribe to a given advanced filter
8304  *      if only one VSI has been added till now
8305  *              Allocate a new VSI list and add two VSIs
8306  *              to this list using switch rule command
8307  *              Update the previously created switch rule with the
8308  *              newly created VSI list ID
8309  *      if a VSI list was previously created
8310  *              Add the new VSI to the previously created VSI list set
8311  *              using the update switch rule command
8312  */
8313 static enum ice_status
8314 ice_adv_add_update_vsi_list(struct ice_hw *hw,
8315                             struct ice_adv_fltr_mgmt_list_entry *m_entry,
8316                             struct ice_adv_rule_info *cur_fltr,
8317                             struct ice_adv_rule_info *new_fltr)
8318 {
8319         enum ice_status status;
8320         u16 vsi_list_id = 0;
8321
8322         if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
8323             cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
8324             cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
8325                 return ICE_ERR_NOT_IMPL;
8326
8327         if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
8328              new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
8329             (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
8330              cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
8331                 return ICE_ERR_NOT_IMPL;
8332
8333         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
8334                  /* Only one entry existed in the mapping and it was not already
8335                   * a part of a VSI list. So, create a VSI list with the old and
8336                   * new VSIs.
8337                   */
8338                 struct ice_fltr_info tmp_fltr;
8339                 u16 vsi_handle_arr[2];
8340
8341                 /* A rule already exists with the new VSI being added */
8342                 if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
8343                     new_fltr->sw_act.fwd_id.hw_vsi_id)
8344                         return ICE_ERR_ALREADY_EXISTS;
8345
8346                 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
8347                 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
8348                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
8349                                                   &vsi_list_id,
8350                                                   ICE_SW_LKUP_LAST);
8351                 if (status)
8352                         return status;
8353
8354                 ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
8355                 tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
8356                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
8357                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
8358                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
8359                 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
8360
8361                 /* Update the previous switch rule of "forward to VSI" to
8362                  * "fwd to VSI list"
8363                  */
8364                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
8365                 if (status)
8366                         return status;
8367
8368                 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
8369                 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
8370                 m_entry->vsi_list_info =
8371                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
8372                                                 vsi_list_id);
8373         } else {
8374                 u16 vsi_handle = new_fltr->sw_act.vsi_handle;
8375
8376                 if (!m_entry->vsi_list_info)
8377                         return ICE_ERR_CFG;
8378
8379                 /* A rule already exists with the new VSI being added */
8380                 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
8381                         return ICE_SUCCESS;
8382
8383                 /* Update the previously created VSI list set with
8384                  * the new VSI ID passed in
8385                  */
8386                 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
8387
8388                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
8389                                                   vsi_list_id, false,
8390                                                   ice_aqc_opc_update_sw_rules,
8391                                                   ICE_SW_LKUP_LAST);
8392                 /* update VSI list mapping info with new VSI ID */
8393                 if (!status)
8394                         ice_set_bit(vsi_handle,
8395                                     m_entry->vsi_list_info->vsi_map);
8396         }
8397         if (!status)
8398                 m_entry->vsi_count++;
8399         return status;
8400 }
8401
8402 /**
8403  * ice_add_adv_rule - helper function to create an advanced switch rule
8404  * @hw: pointer to the hardware structure
8405  * @lkups: information on the words that needs to be looked up. All words
8406  * together makes one recipe
8407  * @lkups_cnt: num of entries in the lkups array
8408  * @rinfo: other information related to the rule that needs to be programmed
8409  * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
8410  *               ignored is case of error.
8411  *
8412  * This function can program only 1 rule at a time. The lkups is used to
8413  * describe the all the words that forms the "lookup" portion of the recipe.
8414  * These words can span multiple protocols. Callers to this function need to
8415  * pass in a list of protocol headers with lookup information along and mask
8416  * that determines which words are valid from the given protocol header.
8417  * rinfo describes other information related to this rule such as forwarding
8418  * IDs, priority of this rule, etc.
8419  */
8420 enum ice_status
8421 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8422                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
8423                  struct ice_rule_query_data *added_entry)
8424 {
8425         struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
8426         u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;
8427         const struct ice_dummy_pkt_offsets *pkt_offsets;
8428         struct ice_aqc_sw_rules_elem *s_rule = NULL;
8429         struct LIST_HEAD_TYPE *rule_head;
8430         struct ice_switch_info *sw;
8431         enum ice_status status;
8432         const u8 *pkt = NULL;
8433         bool prof_rule;
8434         u16 word_cnt;
8435         u32 act = 0;
8436         u8 q_rgn;
8437
8438         /* Initialize profile to result index bitmap */
8439         if (!hw->switch_info->prof_res_bm_init) {
8440                 hw->switch_info->prof_res_bm_init = 1;
8441                 ice_init_prof_result_bm(hw);
8442         }
8443
8444         prof_rule = ice_is_prof_rule(rinfo->tun_type);
8445         if (!prof_rule && !lkups_cnt)
8446                 return ICE_ERR_PARAM;
8447
8448         /* get # of words we need to match */
8449         word_cnt = 0;
8450         for (i = 0; i < lkups_cnt; i++) {
8451                 u16 j, *ptr;
8452
8453                 ptr = (u16 *)&lkups[i].m_u;
8454                 for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)
8455                         if (ptr[j] != 0)
8456                                 word_cnt++;
8457         }
8458
8459         if (prof_rule) {
8460                 if (word_cnt > ICE_MAX_CHAIN_WORDS)
8461                         return ICE_ERR_PARAM;
8462         } else {
8463                 if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS)
8464                         return ICE_ERR_PARAM;
8465         }
8466
8467         /* make sure that we can locate a dummy packet */
8468         ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
8469                               &pkt_offsets);
8470         if (!pkt) {
8471                 status = ICE_ERR_PARAM;
8472                 goto err_ice_add_adv_rule;
8473         }
8474
8475         if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
8476               rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
8477               rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
8478               rinfo->sw_act.fltr_act == ICE_DROP_PACKET))
8479                 return ICE_ERR_CFG;
8480
8481         vsi_handle = rinfo->sw_act.vsi_handle;
8482         if (!ice_is_vsi_valid(hw, vsi_handle))
8483                 return ICE_ERR_PARAM;
8484
8485         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
8486                 rinfo->sw_act.fwd_id.hw_vsi_id =
8487                         ice_get_hw_vsi_num(hw, vsi_handle);
8488         if (rinfo->sw_act.flag & ICE_FLTR_TX)
8489                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
8490
8491         status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
8492         if (status)
8493                 return status;
8494         m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
8495         if (m_entry) {
8496                 /* we have to add VSI to VSI_LIST and increment vsi_count.
8497                  * Also Update VSI list so that we can change forwarding rule
8498                  * if the rule already exists, we will check if it exists with
8499                  * same vsi_id, if not then add it to the VSI list if it already
8500                  * exists if not then create a VSI list and add the existing VSI
8501                  * ID and the new VSI ID to the list
8502                  * We will add that VSI to the list
8503                  */
8504                 status = ice_adv_add_update_vsi_list(hw, m_entry,
8505                                                      &m_entry->rule_info,
8506                                                      rinfo);
8507                 if (added_entry) {
8508                         added_entry->rid = rid;
8509                         added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
8510                         added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
8511                 }
8512                 return status;
8513         }
8514         rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;
8515         s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rule_buf_sz);
8516         if (!s_rule)
8517                 return ICE_ERR_NO_MEMORY;
8518         act |= ICE_SINGLE_ACT_LAN_ENABLE;
8519         switch (rinfo->sw_act.fltr_act) {
8520         case ICE_FWD_TO_VSI:
8521                 act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
8522                         ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
8523                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
8524                 break;
8525         case ICE_FWD_TO_Q:
8526                 act |= ICE_SINGLE_ACT_TO_Q;
8527                 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
8528                        ICE_SINGLE_ACT_Q_INDEX_M;
8529                 break;
8530         case ICE_FWD_TO_QGRP:
8531                 q_rgn = rinfo->sw_act.qgrp_size > 0 ?
8532                         (u8)ice_ilog2(rinfo->sw_act.qgrp_size) : 0;
8533                 act |= ICE_SINGLE_ACT_TO_Q;
8534                 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
8535                        ICE_SINGLE_ACT_Q_INDEX_M;
8536                 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
8537                        ICE_SINGLE_ACT_Q_REGION_M;
8538                 break;
8539         case ICE_DROP_PACKET:
8540                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
8541                        ICE_SINGLE_ACT_VALID_BIT;
8542                 break;
8543         default:
8544                 status = ICE_ERR_CFG;
8545                 goto err_ice_add_adv_rule;
8546         }
8547
8548         /* set the rule LOOKUP type based on caller specified 'RX'
8549          * instead of hardcoding it to be either LOOKUP_TX/RX
8550          *
8551          * for 'RX' set the source to be the port number
8552          * for 'TX' set the source to be the source HW VSI number (determined
8553          * by caller)
8554          */
8555         if (rinfo->rx) {
8556                 s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX);
8557                 s_rule->pdata.lkup_tx_rx.src =
8558                         CPU_TO_LE16(hw->port_info->lport);
8559         } else {
8560                 s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
8561                 s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(rinfo->sw_act.src);
8562         }
8563
8564         s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(rid);
8565         s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
8566
8567         status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt,
8568                                            pkt_len, pkt_offsets);
8569         if (status)
8570                 goto err_ice_add_adv_rule;
8571
8572         if (rinfo->tun_type != ICE_NON_TUN &&
8573             rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
8574                 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
8575                                                  s_rule->pdata.lkup_tx_rx.hdr,
8576                                                  pkt_offsets);
8577                 if (status)
8578                         goto err_ice_add_adv_rule;
8579         }
8580
8581         status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
8582                                  rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
8583                                  NULL);
8584         if (status)
8585                 goto err_ice_add_adv_rule;
8586         adv_fltr = (struct ice_adv_fltr_mgmt_list_entry *)
8587                 ice_malloc(hw, sizeof(struct ice_adv_fltr_mgmt_list_entry));
8588         if (!adv_fltr) {
8589                 status = ICE_ERR_NO_MEMORY;
8590                 goto err_ice_add_adv_rule;
8591         }
8592
8593         adv_fltr->lkups = (struct ice_adv_lkup_elem *)
8594                 ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups),
8595                            ICE_NONDMA_TO_NONDMA);
8596         if (!adv_fltr->lkups && !prof_rule) {
8597                 status = ICE_ERR_NO_MEMORY;
8598                 goto err_ice_add_adv_rule;
8599         }
8600
8601         adv_fltr->lkups_cnt = lkups_cnt;
8602         adv_fltr->rule_info = *rinfo;
8603         adv_fltr->rule_info.fltr_rule_id =
8604                 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
8605         sw = hw->switch_info;
8606         sw->recp_list[rid].adv_rule = true;
8607         rule_head = &sw->recp_list[rid].filt_rules;
8608
8609         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
8610                 adv_fltr->vsi_count = 1;
8611
8612         /* Add rule entry to book keeping list */
8613         LIST_ADD(&adv_fltr->list_entry, rule_head);
8614         if (added_entry) {
8615                 added_entry->rid = rid;
8616                 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
8617                 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
8618         }
8619 err_ice_add_adv_rule:
8620         if (status && adv_fltr) {
8621                 ice_free(hw, adv_fltr->lkups);
8622                 ice_free(hw, adv_fltr);
8623         }
8624
8625         ice_free(hw, s_rule);
8626
8627         return status;
8628 }
8629
8630 /**
8631  * ice_adv_rem_update_vsi_list
8632  * @hw: pointer to the hardware structure
8633  * @vsi_handle: VSI handle of the VSI to remove
8634  * @fm_list: filter management entry for which the VSI list management needs to
8635  *           be done
8636  */
8637 static enum ice_status
8638 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
8639                             struct ice_adv_fltr_mgmt_list_entry *fm_list)
8640 {
8641         struct ice_vsi_list_map_info *vsi_list_info;
8642         enum ice_sw_lkup_type lkup_type;
8643         enum ice_status status;
8644         u16 vsi_list_id;
8645
8646         if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
8647             fm_list->vsi_count == 0)
8648                 return ICE_ERR_PARAM;
8649
8650         /* A rule with the VSI being removed does not exist */
8651         if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
8652                 return ICE_ERR_DOES_NOT_EXIST;
8653
8654         lkup_type = ICE_SW_LKUP_LAST;
8655         vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
8656         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
8657                                           ice_aqc_opc_update_sw_rules,
8658                                           lkup_type);
8659         if (status)
8660                 return status;
8661
8662         fm_list->vsi_count--;
8663         ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
8664         vsi_list_info = fm_list->vsi_list_info;
8665         if (fm_list->vsi_count == 1) {
8666                 struct ice_fltr_info tmp_fltr;
8667                 u16 rem_vsi_handle;
8668
8669                 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
8670                                                     ICE_MAX_VSI);
8671                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
8672                         return ICE_ERR_OUT_OF_RANGE;
8673
8674                 /* Make sure VSI list is empty before removing it below */
8675                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
8676                                                   vsi_list_id, true,
8677                                                   ice_aqc_opc_update_sw_rules,
8678                                                   lkup_type);
8679                 if (status)
8680                         return status;
8681
8682                 ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
8683                 tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
8684                 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
8685                 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
8686                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
8687                 tmp_fltr.fwd_id.hw_vsi_id =
8688                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
8689                 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
8690                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
8691                 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
8692
8693                 /* Update the previous switch rule of "MAC forward to VSI" to
8694                  * "MAC fwd to VSI list"
8695                  */
8696                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
8697                 if (status) {
8698                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
8699                                   tmp_fltr.fwd_id.hw_vsi_id, status);
8700                         return status;
8701                 }
8702                 fm_list->vsi_list_info->ref_cnt--;
8703
8704                 /* Remove the VSI list since it is no longer used */
8705                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
8706                 if (status) {
8707                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
8708                                   vsi_list_id, status);
8709                         return status;
8710                 }
8711
8712                 LIST_DEL(&vsi_list_info->list_entry);
8713                 ice_free(hw, vsi_list_info);
8714                 fm_list->vsi_list_info = NULL;
8715         }
8716
8717         return status;
8718 }
8719
8720 /**
8721  * ice_rem_adv_rule - removes existing advanced switch rule
8722  * @hw: pointer to the hardware structure
8723  * @lkups: information on the words that needs to be looked up. All words
8724  *         together makes one recipe
8725  * @lkups_cnt: num of entries in the lkups array
8726  * @rinfo: Its the pointer to the rule information for the rule
8727  *
8728  * This function can be used to remove 1 rule at a time. The lkups is
8729  * used to describe all the words that forms the "lookup" portion of the
8730  * rule. These words can span multiple protocols. Callers to this function
8731  * need to pass in a list of protocol headers with lookup information along
8732  * and mask that determines which words are valid from the given protocol
8733  * header. rinfo describes other information related to this rule such as
8734  * forwarding IDs, priority of this rule, etc.
8735  */
8736 enum ice_status
8737 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8738                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
8739 {
8740         struct ice_adv_fltr_mgmt_list_entry *list_elem;
8741         struct ice_prot_lkup_ext lkup_exts;
8742         struct ice_lock *rule_lock; /* Lock to protect filter rule list */
8743         enum ice_status status = ICE_SUCCESS;
8744         bool remove_rule = false;
8745         u16 i, rid, vsi_handle;
8746
8747         ice_memset(&lkup_exts, 0, sizeof(lkup_exts), ICE_NONDMA_MEM);
8748         for (i = 0; i < lkups_cnt; i++) {
8749                 u16 count;
8750
8751                 if (lkups[i].type >= ICE_PROTOCOL_LAST)
8752                         return ICE_ERR_CFG;
8753
8754                 count = ice_fill_valid_words(&lkups[i], &lkup_exts);
8755                 if (!count)
8756                         return ICE_ERR_CFG;
8757         }
8758
8759         /* Create any special protocol/offset pairs, such as looking at tunnel
8760          * bits by extracting metadata
8761          */
8762         status = ice_add_special_words(rinfo, &lkup_exts);
8763         if (status)
8764                 return status;
8765
8766         rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type);
8767         /* If did not find a recipe that match the existing criteria */
8768         if (rid == ICE_MAX_NUM_RECIPES)
8769                 return ICE_ERR_PARAM;
8770
8771         rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
8772         list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
8773         /* the rule is already removed */
8774         if (!list_elem)
8775                 return ICE_SUCCESS;
8776         ice_acquire_lock(rule_lock);
8777         if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
8778                 remove_rule = true;
8779         } else if (list_elem->vsi_count > 1) {
8780                 remove_rule = false;
8781                 vsi_handle = rinfo->sw_act.vsi_handle;
8782                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
8783         } else {
8784                 vsi_handle = rinfo->sw_act.vsi_handle;
8785                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
8786                 if (status) {
8787                         ice_release_lock(rule_lock);
8788                         return status;
8789                 }
8790                 if (list_elem->vsi_count == 0)
8791                         remove_rule = true;
8792         }
8793         ice_release_lock(rule_lock);
8794         if (remove_rule) {
8795                 struct ice_aqc_sw_rules_elem *s_rule;
8796                 u16 rule_buf_sz;
8797
8798                 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
8799                 s_rule = (struct ice_aqc_sw_rules_elem *)
8800                         ice_malloc(hw, rule_buf_sz);
8801                 if (!s_rule)
8802                         return ICE_ERR_NO_MEMORY;
8803                 s_rule->pdata.lkup_tx_rx.act = 0;
8804                 s_rule->pdata.lkup_tx_rx.index =
8805                         CPU_TO_LE16(list_elem->rule_info.fltr_rule_id);
8806                 s_rule->pdata.lkup_tx_rx.hdr_len = 0;
8807                 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
8808                                          rule_buf_sz, 1,
8809                                          ice_aqc_opc_remove_sw_rules, NULL);
8810                 if (status == ICE_SUCCESS || status == ICE_ERR_DOES_NOT_EXIST) {
8811                         struct ice_switch_info *sw = hw->switch_info;
8812
8813                         ice_acquire_lock(rule_lock);
8814                         LIST_DEL(&list_elem->list_entry);
8815                         ice_free(hw, list_elem->lkups);
8816                         ice_free(hw, list_elem);
8817                         ice_release_lock(rule_lock);
8818                         if (LIST_EMPTY(&sw->recp_list[rid].filt_rules))
8819                                 sw->recp_list[rid].adv_rule = false;
8820                 }
8821                 ice_free(hw, s_rule);
8822         }
8823         return status;
8824 }
8825
8826 /**
8827  * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
8828  * @hw: pointer to the hardware structure
8829  * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
8830  *
8831  * This function is used to remove 1 rule at a time. The removal is based on
8832  * the remove_entry parameter. This function will remove rule for a given
8833  * vsi_handle with a given rule_id which is passed as parameter in remove_entry
8834  */
8835 enum ice_status
8836 ice_rem_adv_rule_by_id(struct ice_hw *hw,
8837                        struct ice_rule_query_data *remove_entry)
8838 {
8839         struct ice_adv_fltr_mgmt_list_entry *list_itr;
8840         struct LIST_HEAD_TYPE *list_head;
8841         struct ice_adv_rule_info rinfo;
8842         struct ice_switch_info *sw;
8843
8844         sw = hw->switch_info;
8845         if (!sw->recp_list[remove_entry->rid].recp_created)
8846                 return ICE_ERR_PARAM;
8847         list_head = &sw->recp_list[remove_entry->rid].filt_rules;
8848         LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_adv_fltr_mgmt_list_entry,
8849                             list_entry) {
8850                 if (list_itr->rule_info.fltr_rule_id ==
8851                     remove_entry->rule_id) {
8852                         rinfo = list_itr->rule_info;
8853                         rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
8854                         return ice_rem_adv_rule(hw, list_itr->lkups,
8855                                                 list_itr->lkups_cnt, &rinfo);
8856                 }
8857         }
8858         /* either list is empty or unable to find rule */
8859         return ICE_ERR_DOES_NOT_EXIST;
8860 }
8861
8862 /**
8863  * ice_rem_adv_for_vsi - removes existing advanced switch rules for a
8864  *                       given VSI handle
8865  * @hw: pointer to the hardware structure
8866  * @vsi_handle: VSI handle for which we are supposed to remove all the rules.
8867  *
8868  * This function is used to remove all the rules for a given VSI and as soon
8869  * as removing a rule fails, it will return immediately with the error code,
8870  * else it will return ICE_SUCCESS
8871  */
8872 enum ice_status ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
8873 {
8874         struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
8875         struct ice_vsi_list_map_info *map_info;
8876         struct LIST_HEAD_TYPE *list_head;
8877         struct ice_adv_rule_info rinfo;
8878         struct ice_switch_info *sw;
8879         enum ice_status status;
8880         u8 rid;
8881
8882         sw = hw->switch_info;
8883         for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
8884                 if (!sw->recp_list[rid].recp_created)
8885                         continue;
8886                 if (!sw->recp_list[rid].adv_rule)
8887                         continue;
8888
8889                 list_head = &sw->recp_list[rid].filt_rules;
8890                 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp_entry, list_head,
8891                                          ice_adv_fltr_mgmt_list_entry,
8892                                          list_entry) {
8893                         rinfo = list_itr->rule_info;
8894
8895                         if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
8896                                 map_info = list_itr->vsi_list_info;
8897                                 if (!map_info)
8898                                         continue;
8899
8900                                 if (!ice_is_bit_set(map_info->vsi_map,
8901                                                     vsi_handle))
8902                                         continue;
8903                         } else if (rinfo.sw_act.vsi_handle != vsi_handle) {
8904                                 continue;
8905                         }
8906
8907                         rinfo.sw_act.vsi_handle = vsi_handle;
8908                         status = ice_rem_adv_rule(hw, list_itr->lkups,
8909                                                   list_itr->lkups_cnt, &rinfo);
8910
8911                         if (status)
8912                                 return status;
8913                 }
8914         }
8915         return ICE_SUCCESS;
8916 }
8917
8918 /**
8919  * ice_replay_fltr - Replay all the filters stored by a specific list head
8920  * @hw: pointer to the hardware structure
8921  * @list_head: list for which filters needs to be replayed
8922  * @recp_id: Recipe ID for which rules need to be replayed
8923  */
8924 static enum ice_status
8925 ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head)
8926 {
8927         struct ice_fltr_mgmt_list_entry *itr;
8928         enum ice_status status = ICE_SUCCESS;
8929         struct ice_sw_recipe *recp_list;
8930         u8 lport = hw->port_info->lport;
8931         struct LIST_HEAD_TYPE l_head;
8932
8933         if (LIST_EMPTY(list_head))
8934                 return status;
8935
8936         recp_list = &hw->switch_info->recp_list[recp_id];
8937         /* Move entries from the given list_head to a temporary l_head so that
8938          * they can be replayed. Otherwise when trying to re-add the same
8939          * filter, the function will return already exists
8940          */
8941         LIST_REPLACE_INIT(list_head, &l_head);
8942
8943         /* Mark the given list_head empty by reinitializing it so filters
8944          * could be added again by *handler
8945          */
8946         LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry,
8947                             list_entry) {
8948                 struct ice_fltr_list_entry f_entry;
8949                 u16 vsi_handle;
8950
8951                 f_entry.fltr_info = itr->fltr_info;
8952                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
8953                         status = ice_add_rule_internal(hw, recp_list, lport,
8954                                                        &f_entry);
8955                         if (status != ICE_SUCCESS)
8956                                 goto end;
8957                         continue;
8958                 }
8959
8960                 /* Add a filter per VSI separately */
8961                 ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map,
8962                                      ICE_MAX_VSI) {
8963                         if (!ice_is_vsi_valid(hw, vsi_handle))
8964                                 break;
8965
8966                         ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
8967                         f_entry.fltr_info.vsi_handle = vsi_handle;
8968                         f_entry.fltr_info.fwd_id.hw_vsi_id =
8969                                 ice_get_hw_vsi_num(hw, vsi_handle);
8970                         f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
8971                         if (recp_id == ICE_SW_LKUP_VLAN)
8972                                 status = ice_add_vlan_internal(hw, recp_list,
8973                                                                &f_entry);
8974                         else
8975                                 status = ice_add_rule_internal(hw, recp_list,
8976                                                                lport,
8977                                                                &f_entry);
8978                         if (status != ICE_SUCCESS)
8979                                 goto end;
8980                 }
8981         }
8982 end:
8983         /* Clear the filter management list */
8984         ice_rem_sw_rule_info(hw, &l_head);
8985         return status;
8986 }
8987
8988 /**
8989  * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
8990  * @hw: pointer to the hardware structure
8991  *
8992  * NOTE: This function does not clean up partially added filters on error.
8993  * It is up to caller of the function to issue a reset or fail early.
8994  */
8995 enum ice_status ice_replay_all_fltr(struct ice_hw *hw)
8996 {
8997         struct ice_switch_info *sw = hw->switch_info;
8998         enum ice_status status = ICE_SUCCESS;
8999         u8 i;
9000
9001         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9002                 struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules;
9003
9004                 status = ice_replay_fltr(hw, i, head);
9005                 if (status != ICE_SUCCESS)
9006                         return status;
9007         }
9008         return status;
9009 }
9010
9011 /**
9012  * ice_replay_vsi_fltr - Replay filters for requested VSI
9013  * @hw: pointer to the hardware structure
9014  * @pi: pointer to port information structure
9015  * @sw: pointer to switch info struct for which function replays filters
9016  * @vsi_handle: driver VSI handle
9017  * @recp_id: Recipe ID for which rules need to be replayed
9018  * @list_head: list for which filters need to be replayed
9019  *
9020  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
9021  * It is required to pass valid VSI handle.
9022  */
9023 static enum ice_status
9024 ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9025                     struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id,
9026                     struct LIST_HEAD_TYPE *list_head)
9027 {
9028         struct ice_fltr_mgmt_list_entry *itr;
9029         enum ice_status status = ICE_SUCCESS;
9030         struct ice_sw_recipe *recp_list;
9031         u16 hw_vsi_id;
9032
9033         if (LIST_EMPTY(list_head))
9034                 return status;
9035         recp_list = &sw->recp_list[recp_id];
9036         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
9037
9038         LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry,
9039                             list_entry) {
9040                 struct ice_fltr_list_entry f_entry;
9041
9042                 f_entry.fltr_info = itr->fltr_info;
9043                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
9044                     itr->fltr_info.vsi_handle == vsi_handle) {
9045                         /* update the src in case it is VSI num */
9046                         if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
9047                                 f_entry.fltr_info.src = hw_vsi_id;
9048                         status = ice_add_rule_internal(hw, recp_list,
9049                                                        pi->lport,
9050                                                        &f_entry);
9051                         if (status != ICE_SUCCESS)
9052                                 goto end;
9053                         continue;
9054                 }
9055                 if (!itr->vsi_list_info ||
9056                     !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle))
9057                         continue;
9058                 /* Clearing it so that the logic can add it back */
9059                 ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
9060                 f_entry.fltr_info.vsi_handle = vsi_handle;
9061                 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
9062                 /* update the src in case it is VSI num */
9063                 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
9064                         f_entry.fltr_info.src = hw_vsi_id;
9065                 if (recp_id == ICE_SW_LKUP_VLAN)
9066                         status = ice_add_vlan_internal(hw, recp_list, &f_entry);
9067                 else
9068                         status = ice_add_rule_internal(hw, recp_list,
9069                                                        pi->lport,
9070                                                        &f_entry);
9071                 if (status != ICE_SUCCESS)
9072                         goto end;
9073         }
9074 end:
9075         return status;
9076 }
9077
9078 /**
9079  * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
9080  * @hw: pointer to the hardware structure
9081  * @vsi_handle: driver VSI handle
9082  * @list_head: list for which filters need to be replayed
9083  *
9084  * Replay the advanced rule for the given VSI.
9085  */
9086 static enum ice_status
9087 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
9088                         struct LIST_HEAD_TYPE *list_head)
9089 {
9090         struct ice_rule_query_data added_entry = { 0 };
9091         struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
9092         enum ice_status status = ICE_SUCCESS;
9093
9094         if (LIST_EMPTY(list_head))
9095                 return status;
9096         LIST_FOR_EACH_ENTRY(adv_fltr, list_head, ice_adv_fltr_mgmt_list_entry,
9097                             list_entry) {
9098                 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
9099                 u16 lk_cnt = adv_fltr->lkups_cnt;
9100
9101                 if (vsi_handle != rinfo->sw_act.vsi_handle)
9102                         continue;
9103                 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
9104                                           &added_entry);
9105                 if (status)
9106                         break;
9107         }
9108         return status;
9109 }
9110
9111 /**
9112  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
9113  * @hw: pointer to the hardware structure
9114  * @pi: pointer to port information structure
9115  * @vsi_handle: driver VSI handle
9116  *
9117  * Replays filters for requested VSI via vsi_handle.
9118  */
9119 enum ice_status
9120 ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9121                         u16 vsi_handle)
9122 {
9123         struct ice_switch_info *sw = hw->switch_info;
9124         enum ice_status status;
9125         u8 i;
9126
9127         /* Update the recipes that were created */
9128         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9129                 struct LIST_HEAD_TYPE *head;
9130
9131                 head = &sw->recp_list[i].filt_replay_rules;
9132                 if (!sw->recp_list[i].adv_rule)
9133                         status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i,
9134                                                      head);
9135                 else
9136                         status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
9137                 if (status != ICE_SUCCESS)
9138                         return status;
9139         }
9140
9141         return ICE_SUCCESS;
9142 }
9143
9144 /**
9145  * ice_rm_all_sw_replay_rule - helper function to delete filter replay rules
9146  * @hw: pointer to the HW struct
9147  * @sw: pointer to switch info struct for which function removes filters
9148  *
9149  * Deletes the filter replay rules for given switch
9150  */
9151 void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw)
9152 {
9153         u8 i;
9154
9155         if (!sw)
9156                 return;
9157
9158         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9159                 if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) {
9160                         struct LIST_HEAD_TYPE *l_head;
9161
9162                         l_head = &sw->recp_list[i].filt_replay_rules;
9163                         if (!sw->recp_list[i].adv_rule)
9164                                 ice_rem_sw_rule_info(hw, l_head);
9165                         else
9166                                 ice_rem_adv_rule_info(hw, l_head);
9167                 }
9168         }
9169 }
9170
9171 /**
9172  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
9173  * @hw: pointer to the HW struct
9174  *
9175  * Deletes the filter replay rules.
9176  */
9177 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
9178 {
9179         ice_rm_sw_replay_rule_info(hw, hw->switch_info);
9180 }