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