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