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