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