Merge tag 'net-6.9-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-block.git] / drivers / net / ethernet / intel / ice / ice_switch.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2018, Intel Corporation. */
3
4 #include "ice_lib.h"
5 #include "ice_switch.h"
6
7 #define ICE_ETH_DA_OFFSET               0
8 #define ICE_ETH_ETHTYPE_OFFSET          12
9 #define ICE_ETH_VLAN_TCI_OFFSET         14
10 #define ICE_MAX_VLAN_ID                 0xFFF
11 #define ICE_IPV6_ETHER_ID               0x86DD
12
13 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
14  * struct to configure any switch filter rules.
15  * {DA (6 bytes), SA(6 bytes),
16  * Ether type (2 bytes for header without VLAN tag) OR
17  * VLAN tag (4 bytes for header with VLAN tag) }
18  *
19  * Word on Hardcoded values
20  * byte 0 = 0x2: to identify it as locally administered DA MAC
21  * byte 6 = 0x2: to identify it as locally administered SA MAC
22  * byte 12 = 0x81 & byte 13 = 0x00:
23  *      In case of VLAN filter first two bytes defines ether type (0x8100)
24  *      and remaining two bytes are placeholder for programming a given VLAN ID
25  *      In case of Ether type filter it is treated as header without VLAN tag
26  *      and byte 12 and 13 is used to program a given Ether type instead
27  */
28 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
29                                                         0x2, 0, 0, 0, 0, 0,
30                                                         0x81, 0, 0, 0};
31
32 enum {
33         ICE_PKT_OUTER_IPV6      = BIT(0),
34         ICE_PKT_TUN_GTPC        = BIT(1),
35         ICE_PKT_TUN_GTPU        = BIT(2),
36         ICE_PKT_TUN_NVGRE       = BIT(3),
37         ICE_PKT_TUN_UDP         = BIT(4),
38         ICE_PKT_INNER_IPV6      = BIT(5),
39         ICE_PKT_INNER_TCP       = BIT(6),
40         ICE_PKT_INNER_UDP       = BIT(7),
41         ICE_PKT_GTP_NOPAY       = BIT(8),
42         ICE_PKT_KMALLOC         = BIT(9),
43         ICE_PKT_PPPOE           = BIT(10),
44         ICE_PKT_L2TPV3          = BIT(11),
45 };
46
47 struct ice_dummy_pkt_offsets {
48         enum ice_protocol_type type;
49         u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
50 };
51
52 struct ice_dummy_pkt_profile {
53         const struct ice_dummy_pkt_offsets *offsets;
54         const u8 *pkt;
55         u32 match;
56         u16 pkt_len;
57         u16 offsets_len;
58 };
59
60 #define ICE_DECLARE_PKT_OFFSETS(type)                                   \
61         static const struct ice_dummy_pkt_offsets                       \
62         ice_dummy_##type##_packet_offsets[]
63
64 #define ICE_DECLARE_PKT_TEMPLATE(type)                                  \
65         static const u8 ice_dummy_##type##_packet[]
66
67 #define ICE_PKT_PROFILE(type, m) {                                      \
68         .match          = (m),                                          \
69         .pkt            = ice_dummy_##type##_packet,                    \
70         .pkt_len        = sizeof(ice_dummy_##type##_packet),            \
71         .offsets        = ice_dummy_##type##_packet_offsets,            \
72         .offsets_len    = sizeof(ice_dummy_##type##_packet_offsets),    \
73 }
74
75 ICE_DECLARE_PKT_OFFSETS(vlan) = {
76         { ICE_VLAN_OFOS,        12 },
77 };
78
79 ICE_DECLARE_PKT_TEMPLATE(vlan) = {
80         0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
81 };
82
83 ICE_DECLARE_PKT_OFFSETS(qinq) = {
84         { ICE_VLAN_EX,          12 },
85         { ICE_VLAN_IN,          16 },
86 };
87
88 ICE_DECLARE_PKT_TEMPLATE(qinq) = {
89         0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
90         0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
91 };
92
93 ICE_DECLARE_PKT_OFFSETS(gre_tcp) = {
94         { ICE_MAC_OFOS,         0 },
95         { ICE_ETYPE_OL,         12 },
96         { ICE_IPV4_OFOS,        14 },
97         { ICE_NVGRE,            34 },
98         { ICE_MAC_IL,           42 },
99         { ICE_ETYPE_IL,         54 },
100         { ICE_IPV4_IL,          56 },
101         { ICE_TCP_IL,           76 },
102         { ICE_PROTOCOL_LAST,    0 },
103 };
104
105 ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = {
106         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
107         0x00, 0x00, 0x00, 0x00,
108         0x00, 0x00, 0x00, 0x00,
109
110         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
111
112         0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
113         0x00, 0x00, 0x00, 0x00,
114         0x00, 0x2F, 0x00, 0x00,
115         0x00, 0x00, 0x00, 0x00,
116         0x00, 0x00, 0x00, 0x00,
117
118         0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
119         0x00, 0x00, 0x00, 0x00,
120
121         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
122         0x00, 0x00, 0x00, 0x00,
123         0x00, 0x00, 0x00, 0x00,
124
125         0x08, 0x00,             /* ICE_ETYPE_IL 54 */
126
127         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
128         0x00, 0x00, 0x00, 0x00,
129         0x00, 0x06, 0x00, 0x00,
130         0x00, 0x00, 0x00, 0x00,
131         0x00, 0x00, 0x00, 0x00,
132
133         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */
134         0x00, 0x00, 0x00, 0x00,
135         0x00, 0x00, 0x00, 0x00,
136         0x50, 0x02, 0x20, 0x00,
137         0x00, 0x00, 0x00, 0x00
138 };
139
140 ICE_DECLARE_PKT_OFFSETS(gre_udp) = {
141         { ICE_MAC_OFOS,         0 },
142         { ICE_ETYPE_OL,         12 },
143         { ICE_IPV4_OFOS,        14 },
144         { ICE_NVGRE,            34 },
145         { ICE_MAC_IL,           42 },
146         { ICE_ETYPE_IL,         54 },
147         { ICE_IPV4_IL,          56 },
148         { ICE_UDP_ILOS,         76 },
149         { ICE_PROTOCOL_LAST,    0 },
150 };
151
152 ICE_DECLARE_PKT_TEMPLATE(gre_udp) = {
153         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
154         0x00, 0x00, 0x00, 0x00,
155         0x00, 0x00, 0x00, 0x00,
156
157         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
158
159         0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
160         0x00, 0x00, 0x00, 0x00,
161         0x00, 0x2F, 0x00, 0x00,
162         0x00, 0x00, 0x00, 0x00,
163         0x00, 0x00, 0x00, 0x00,
164
165         0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
166         0x00, 0x00, 0x00, 0x00,
167
168         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
169         0x00, 0x00, 0x00, 0x00,
170         0x00, 0x00, 0x00, 0x00,
171
172         0x08, 0x00,             /* ICE_ETYPE_IL 54 */
173
174         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
175         0x00, 0x00, 0x00, 0x00,
176         0x00, 0x11, 0x00, 0x00,
177         0x00, 0x00, 0x00, 0x00,
178         0x00, 0x00, 0x00, 0x00,
179
180         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */
181         0x00, 0x08, 0x00, 0x00,
182 };
183
184 ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = {
185         { ICE_MAC_OFOS,         0 },
186         { ICE_ETYPE_OL,         12 },
187         { ICE_IPV4_OFOS,        14 },
188         { ICE_UDP_OF,           34 },
189         { ICE_VXLAN,            42 },
190         { ICE_GENEVE,           42 },
191         { ICE_VXLAN_GPE,        42 },
192         { ICE_MAC_IL,           50 },
193         { ICE_ETYPE_IL,         62 },
194         { ICE_IPV4_IL,          64 },
195         { ICE_TCP_IL,           84 },
196         { ICE_PROTOCOL_LAST,    0 },
197 };
198
199 ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = {
200         0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
201         0x00, 0x00, 0x00, 0x00,
202         0x00, 0x00, 0x00, 0x00,
203
204         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
205
206         0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
207         0x00, 0x01, 0x00, 0x00,
208         0x40, 0x11, 0x00, 0x00,
209         0x00, 0x00, 0x00, 0x00,
210         0x00, 0x00, 0x00, 0x00,
211
212         0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
213         0x00, 0x46, 0x00, 0x00,
214
215         0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
216         0x00, 0x00, 0x00, 0x00,
217
218         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
219         0x00, 0x00, 0x00, 0x00,
220         0x00, 0x00, 0x00, 0x00,
221
222         0x08, 0x00,             /* ICE_ETYPE_IL 62 */
223
224         0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
225         0x00, 0x01, 0x00, 0x00,
226         0x40, 0x06, 0x00, 0x00,
227         0x00, 0x00, 0x00, 0x00,
228         0x00, 0x00, 0x00, 0x00,
229
230         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
231         0x00, 0x00, 0x00, 0x00,
232         0x00, 0x00, 0x00, 0x00,
233         0x50, 0x02, 0x20, 0x00,
234         0x00, 0x00, 0x00, 0x00
235 };
236
237 ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = {
238         { ICE_MAC_OFOS,         0 },
239         { ICE_ETYPE_OL,         12 },
240         { ICE_IPV4_OFOS,        14 },
241         { ICE_UDP_OF,           34 },
242         { ICE_VXLAN,            42 },
243         { ICE_GENEVE,           42 },
244         { ICE_VXLAN_GPE,        42 },
245         { ICE_MAC_IL,           50 },
246         { ICE_ETYPE_IL,         62 },
247         { ICE_IPV4_IL,          64 },
248         { ICE_UDP_ILOS,         84 },
249         { ICE_PROTOCOL_LAST,    0 },
250 };
251
252 ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = {
253         0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
254         0x00, 0x00, 0x00, 0x00,
255         0x00, 0x00, 0x00, 0x00,
256
257         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
258
259         0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
260         0x00, 0x01, 0x00, 0x00,
261         0x00, 0x11, 0x00, 0x00,
262         0x00, 0x00, 0x00, 0x00,
263         0x00, 0x00, 0x00, 0x00,
264
265         0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
266         0x00, 0x3a, 0x00, 0x00,
267
268         0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
269         0x00, 0x00, 0x00, 0x00,
270
271         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
272         0x00, 0x00, 0x00, 0x00,
273         0x00, 0x00, 0x00, 0x00,
274
275         0x08, 0x00,             /* ICE_ETYPE_IL 62 */
276
277         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
278         0x00, 0x01, 0x00, 0x00,
279         0x00, 0x11, 0x00, 0x00,
280         0x00, 0x00, 0x00, 0x00,
281         0x00, 0x00, 0x00, 0x00,
282
283         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
284         0x00, 0x08, 0x00, 0x00,
285 };
286
287 ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = {
288         { ICE_MAC_OFOS,         0 },
289         { ICE_ETYPE_OL,         12 },
290         { ICE_IPV4_OFOS,        14 },
291         { ICE_NVGRE,            34 },
292         { ICE_MAC_IL,           42 },
293         { ICE_ETYPE_IL,         54 },
294         { ICE_IPV6_IL,          56 },
295         { ICE_TCP_IL,           96 },
296         { ICE_PROTOCOL_LAST,    0 },
297 };
298
299 ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = {
300         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
301         0x00, 0x00, 0x00, 0x00,
302         0x00, 0x00, 0x00, 0x00,
303
304         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
305
306         0x45, 0x00, 0x00, 0x66, /* ICE_IPV4_OFOS 14 */
307         0x00, 0x00, 0x00, 0x00,
308         0x00, 0x2F, 0x00, 0x00,
309         0x00, 0x00, 0x00, 0x00,
310         0x00, 0x00, 0x00, 0x00,
311
312         0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
313         0x00, 0x00, 0x00, 0x00,
314
315         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
316         0x00, 0x00, 0x00, 0x00,
317         0x00, 0x00, 0x00, 0x00,
318
319         0x86, 0xdd,             /* ICE_ETYPE_IL 54 */
320
321         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
322         0x00, 0x08, 0x06, 0x40,
323         0x00, 0x00, 0x00, 0x00,
324         0x00, 0x00, 0x00, 0x00,
325         0x00, 0x00, 0x00, 0x00,
326         0x00, 0x00, 0x00, 0x00,
327         0x00, 0x00, 0x00, 0x00,
328         0x00, 0x00, 0x00, 0x00,
329         0x00, 0x00, 0x00, 0x00,
330         0x00, 0x00, 0x00, 0x00,
331
332         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */
333         0x00, 0x00, 0x00, 0x00,
334         0x00, 0x00, 0x00, 0x00,
335         0x50, 0x02, 0x20, 0x00,
336         0x00, 0x00, 0x00, 0x00
337 };
338
339 ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = {
340         { ICE_MAC_OFOS,         0 },
341         { ICE_ETYPE_OL,         12 },
342         { ICE_IPV4_OFOS,        14 },
343         { ICE_NVGRE,            34 },
344         { ICE_MAC_IL,           42 },
345         { ICE_ETYPE_IL,         54 },
346         { ICE_IPV6_IL,          56 },
347         { ICE_UDP_ILOS,         96 },
348         { ICE_PROTOCOL_LAST,    0 },
349 };
350
351 ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = {
352         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
353         0x00, 0x00, 0x00, 0x00,
354         0x00, 0x00, 0x00, 0x00,
355
356         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
357
358         0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
359         0x00, 0x00, 0x00, 0x00,
360         0x00, 0x2F, 0x00, 0x00,
361         0x00, 0x00, 0x00, 0x00,
362         0x00, 0x00, 0x00, 0x00,
363
364         0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
365         0x00, 0x00, 0x00, 0x00,
366
367         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
368         0x00, 0x00, 0x00, 0x00,
369         0x00, 0x00, 0x00, 0x00,
370
371         0x86, 0xdd,             /* ICE_ETYPE_IL 54 */
372
373         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
374         0x00, 0x08, 0x11, 0x40,
375         0x00, 0x00, 0x00, 0x00,
376         0x00, 0x00, 0x00, 0x00,
377         0x00, 0x00, 0x00, 0x00,
378         0x00, 0x00, 0x00, 0x00,
379         0x00, 0x00, 0x00, 0x00,
380         0x00, 0x00, 0x00, 0x00,
381         0x00, 0x00, 0x00, 0x00,
382         0x00, 0x00, 0x00, 0x00,
383
384         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */
385         0x00, 0x08, 0x00, 0x00,
386 };
387
388 ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = {
389         { ICE_MAC_OFOS,         0 },
390         { ICE_ETYPE_OL,         12 },
391         { ICE_IPV4_OFOS,        14 },
392         { ICE_UDP_OF,           34 },
393         { ICE_VXLAN,            42 },
394         { ICE_GENEVE,           42 },
395         { ICE_VXLAN_GPE,        42 },
396         { ICE_MAC_IL,           50 },
397         { ICE_ETYPE_IL,         62 },
398         { ICE_IPV6_IL,          64 },
399         { ICE_TCP_IL,           104 },
400         { ICE_PROTOCOL_LAST,    0 },
401 };
402
403 ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = {
404         0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
405         0x00, 0x00, 0x00, 0x00,
406         0x00, 0x00, 0x00, 0x00,
407
408         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
409
410         0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */
411         0x00, 0x01, 0x00, 0x00,
412         0x40, 0x11, 0x00, 0x00,
413         0x00, 0x00, 0x00, 0x00,
414         0x00, 0x00, 0x00, 0x00,
415
416         0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
417         0x00, 0x5a, 0x00, 0x00,
418
419         0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
420         0x00, 0x00, 0x00, 0x00,
421
422         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
423         0x00, 0x00, 0x00, 0x00,
424         0x00, 0x00, 0x00, 0x00,
425
426         0x86, 0xdd,             /* ICE_ETYPE_IL 62 */
427
428         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
429         0x00, 0x08, 0x06, 0x40,
430         0x00, 0x00, 0x00, 0x00,
431         0x00, 0x00, 0x00, 0x00,
432         0x00, 0x00, 0x00, 0x00,
433         0x00, 0x00, 0x00, 0x00,
434         0x00, 0x00, 0x00, 0x00,
435         0x00, 0x00, 0x00, 0x00,
436         0x00, 0x00, 0x00, 0x00,
437         0x00, 0x00, 0x00, 0x00,
438
439         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */
440         0x00, 0x00, 0x00, 0x00,
441         0x00, 0x00, 0x00, 0x00,
442         0x50, 0x02, 0x20, 0x00,
443         0x00, 0x00, 0x00, 0x00
444 };
445
446 ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = {
447         { ICE_MAC_OFOS,         0 },
448         { ICE_ETYPE_OL,         12 },
449         { ICE_IPV4_OFOS,        14 },
450         { ICE_UDP_OF,           34 },
451         { ICE_VXLAN,            42 },
452         { ICE_GENEVE,           42 },
453         { ICE_VXLAN_GPE,        42 },
454         { ICE_MAC_IL,           50 },
455         { ICE_ETYPE_IL,         62 },
456         { ICE_IPV6_IL,          64 },
457         { ICE_UDP_ILOS,         104 },
458         { ICE_PROTOCOL_LAST,    0 },
459 };
460
461 ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = {
462         0x00, 0x00, 0x00, 0x00,  /* ICE_MAC_OFOS 0 */
463         0x00, 0x00, 0x00, 0x00,
464         0x00, 0x00, 0x00, 0x00,
465
466         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
467
468         0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */
469         0x00, 0x01, 0x00, 0x00,
470         0x00, 0x11, 0x00, 0x00,
471         0x00, 0x00, 0x00, 0x00,
472         0x00, 0x00, 0x00, 0x00,
473
474         0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
475         0x00, 0x4e, 0x00, 0x00,
476
477         0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
478         0x00, 0x00, 0x00, 0x00,
479
480         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
481         0x00, 0x00, 0x00, 0x00,
482         0x00, 0x00, 0x00, 0x00,
483
484         0x86, 0xdd,             /* ICE_ETYPE_IL 62 */
485
486         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
487         0x00, 0x08, 0x11, 0x40,
488         0x00, 0x00, 0x00, 0x00,
489         0x00, 0x00, 0x00, 0x00,
490         0x00, 0x00, 0x00, 0x00,
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
497         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */
498         0x00, 0x08, 0x00, 0x00,
499 };
500
501 /* offset info for MAC + IPv4 + UDP dummy packet */
502 ICE_DECLARE_PKT_OFFSETS(udp) = {
503         { ICE_MAC_OFOS,         0 },
504         { ICE_ETYPE_OL,         12 },
505         { ICE_IPV4_OFOS,        14 },
506         { ICE_UDP_ILOS,         34 },
507         { ICE_PROTOCOL_LAST,    0 },
508 };
509
510 /* Dummy packet for MAC + IPv4 + UDP */
511 ICE_DECLARE_PKT_TEMPLATE(udp) = {
512         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
513         0x00, 0x00, 0x00, 0x00,
514         0x00, 0x00, 0x00, 0x00,
515
516         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
517
518         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
519         0x00, 0x01, 0x00, 0x00,
520         0x00, 0x11, 0x00, 0x00,
521         0x00, 0x00, 0x00, 0x00,
522         0x00, 0x00, 0x00, 0x00,
523
524         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
525         0x00, 0x08, 0x00, 0x00,
526
527         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
528 };
529
530 /* offset info for MAC + IPv4 + TCP dummy packet */
531 ICE_DECLARE_PKT_OFFSETS(tcp) = {
532         { ICE_MAC_OFOS,         0 },
533         { ICE_ETYPE_OL,         12 },
534         { ICE_IPV4_OFOS,        14 },
535         { ICE_TCP_IL,           34 },
536         { ICE_PROTOCOL_LAST,    0 },
537 };
538
539 /* Dummy packet for MAC + IPv4 + TCP */
540 ICE_DECLARE_PKT_TEMPLATE(tcp) = {
541         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
542         0x00, 0x00, 0x00, 0x00,
543         0x00, 0x00, 0x00, 0x00,
544
545         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
546
547         0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
548         0x00, 0x01, 0x00, 0x00,
549         0x00, 0x06, 0x00, 0x00,
550         0x00, 0x00, 0x00, 0x00,
551         0x00, 0x00, 0x00, 0x00,
552
553         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
554         0x00, 0x00, 0x00, 0x00,
555         0x00, 0x00, 0x00, 0x00,
556         0x50, 0x00, 0x00, 0x00,
557         0x00, 0x00, 0x00, 0x00,
558
559         0x00, 0x00,     /* 2 bytes for 4 byte alignment */
560 };
561
562 ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = {
563         { ICE_MAC_OFOS,         0 },
564         { ICE_ETYPE_OL,         12 },
565         { ICE_IPV6_OFOS,        14 },
566         { ICE_TCP_IL,           54 },
567         { ICE_PROTOCOL_LAST,    0 },
568 };
569
570 ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = {
571         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
572         0x00, 0x00, 0x00, 0x00,
573         0x00, 0x00, 0x00, 0x00,
574
575         0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
576
577         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
578         0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
579         0x00, 0x00, 0x00, 0x00,
580         0x00, 0x00, 0x00, 0x00,
581         0x00, 0x00, 0x00, 0x00,
582         0x00, 0x00, 0x00, 0x00,
583         0x00, 0x00, 0x00, 0x00,
584         0x00, 0x00, 0x00, 0x00,
585         0x00, 0x00, 0x00, 0x00,
586         0x00, 0x00, 0x00, 0x00,
587
588         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
589         0x00, 0x00, 0x00, 0x00,
590         0x00, 0x00, 0x00, 0x00,
591         0x50, 0x00, 0x00, 0x00,
592         0x00, 0x00, 0x00, 0x00,
593
594         0x00, 0x00, /* 2 bytes for 4 byte alignment */
595 };
596
597 /* IPv6 + UDP */
598 ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = {
599         { ICE_MAC_OFOS,         0 },
600         { ICE_ETYPE_OL,         12 },
601         { ICE_IPV6_OFOS,        14 },
602         { ICE_UDP_ILOS,         54 },
603         { ICE_PROTOCOL_LAST,    0 },
604 };
605
606 /* IPv6 + UDP dummy packet */
607 ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = {
608         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
609         0x00, 0x00, 0x00, 0x00,
610         0x00, 0x00, 0x00, 0x00,
611
612         0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
613
614         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
615         0x00, 0x10, 0x11, 0x00, /* Next header UDP */
616         0x00, 0x00, 0x00, 0x00,
617         0x00, 0x00, 0x00, 0x00,
618         0x00, 0x00, 0x00, 0x00,
619         0x00, 0x00, 0x00, 0x00,
620         0x00, 0x00, 0x00, 0x00,
621         0x00, 0x00, 0x00, 0x00,
622         0x00, 0x00, 0x00, 0x00,
623         0x00, 0x00, 0x00, 0x00,
624
625         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
626         0x00, 0x10, 0x00, 0x00,
627
628         0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
629         0x00, 0x00, 0x00, 0x00,
630
631         0x00, 0x00, /* 2 bytes for 4 byte alignment */
632 };
633
634 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
635 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = {
636         { ICE_MAC_OFOS,         0 },
637         { ICE_IPV4_OFOS,        14 },
638         { ICE_UDP_OF,           34 },
639         { ICE_GTP,              42 },
640         { ICE_IPV4_IL,          62 },
641         { ICE_TCP_IL,           82 },
642         { ICE_PROTOCOL_LAST,    0 },
643 };
644
645 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = {
646         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
647         0x00, 0x00, 0x00, 0x00,
648         0x00, 0x00, 0x00, 0x00,
649         0x08, 0x00,
650
651         0x45, 0x00, 0x00, 0x58, /* IP 14 */
652         0x00, 0x00, 0x00, 0x00,
653         0x00, 0x11, 0x00, 0x00,
654         0x00, 0x00, 0x00, 0x00,
655         0x00, 0x00, 0x00, 0x00,
656
657         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
658         0x00, 0x44, 0x00, 0x00,
659
660         0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 42 */
661         0x00, 0x00, 0x00, 0x00,
662         0x00, 0x00, 0x00, 0x85,
663
664         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
665         0x00, 0x00, 0x00, 0x00,
666
667         0x45, 0x00, 0x00, 0x28, /* IP 62 */
668         0x00, 0x00, 0x00, 0x00,
669         0x00, 0x06, 0x00, 0x00,
670         0x00, 0x00, 0x00, 0x00,
671         0x00, 0x00, 0x00, 0x00,
672
673         0x00, 0x00, 0x00, 0x00, /* TCP 82 */
674         0x00, 0x00, 0x00, 0x00,
675         0x00, 0x00, 0x00, 0x00,
676         0x50, 0x00, 0x00, 0x00,
677         0x00, 0x00, 0x00, 0x00,
678
679         0x00, 0x00, /* 2 bytes for 4 byte alignment */
680 };
681
682 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
683 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = {
684         { ICE_MAC_OFOS,         0 },
685         { ICE_IPV4_OFOS,        14 },
686         { ICE_UDP_OF,           34 },
687         { ICE_GTP,              42 },
688         { ICE_IPV4_IL,          62 },
689         { ICE_UDP_ILOS,         82 },
690         { ICE_PROTOCOL_LAST,    0 },
691 };
692
693 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = {
694         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
695         0x00, 0x00, 0x00, 0x00,
696         0x00, 0x00, 0x00, 0x00,
697         0x08, 0x00,
698
699         0x45, 0x00, 0x00, 0x4c, /* IP 14 */
700         0x00, 0x00, 0x00, 0x00,
701         0x00, 0x11, 0x00, 0x00,
702         0x00, 0x00, 0x00, 0x00,
703         0x00, 0x00, 0x00, 0x00,
704
705         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
706         0x00, 0x38, 0x00, 0x00,
707
708         0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 42 */
709         0x00, 0x00, 0x00, 0x00,
710         0x00, 0x00, 0x00, 0x85,
711
712         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
713         0x00, 0x00, 0x00, 0x00,
714
715         0x45, 0x00, 0x00, 0x1c, /* IP 62 */
716         0x00, 0x00, 0x00, 0x00,
717         0x00, 0x11, 0x00, 0x00,
718         0x00, 0x00, 0x00, 0x00,
719         0x00, 0x00, 0x00, 0x00,
720
721         0x00, 0x00, 0x00, 0x00, /* UDP 82 */
722         0x00, 0x08, 0x00, 0x00,
723
724         0x00, 0x00, /* 2 bytes for 4 byte alignment */
725 };
726
727 /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
728 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = {
729         { ICE_MAC_OFOS,         0 },
730         { ICE_IPV4_OFOS,        14 },
731         { ICE_UDP_OF,           34 },
732         { ICE_GTP,              42 },
733         { ICE_IPV6_IL,          62 },
734         { ICE_TCP_IL,           102 },
735         { ICE_PROTOCOL_LAST,    0 },
736 };
737
738 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = {
739         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
740         0x00, 0x00, 0x00, 0x00,
741         0x00, 0x00, 0x00, 0x00,
742         0x08, 0x00,
743
744         0x45, 0x00, 0x00, 0x6c, /* IP 14 */
745         0x00, 0x00, 0x00, 0x00,
746         0x00, 0x11, 0x00, 0x00,
747         0x00, 0x00, 0x00, 0x00,
748         0x00, 0x00, 0x00, 0x00,
749
750         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
751         0x00, 0x58, 0x00, 0x00,
752
753         0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 42 */
754         0x00, 0x00, 0x00, 0x00,
755         0x00, 0x00, 0x00, 0x85,
756
757         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
758         0x00, 0x00, 0x00, 0x00,
759
760         0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
761         0x00, 0x14, 0x06, 0x00,
762         0x00, 0x00, 0x00, 0x00,
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
771         0x00, 0x00, 0x00, 0x00, /* TCP 102 */
772         0x00, 0x00, 0x00, 0x00,
773         0x00, 0x00, 0x00, 0x00,
774         0x50, 0x00, 0x00, 0x00,
775         0x00, 0x00, 0x00, 0x00,
776
777         0x00, 0x00, /* 2 bytes for 4 byte alignment */
778 };
779
780 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = {
781         { ICE_MAC_OFOS,         0 },
782         { ICE_IPV4_OFOS,        14 },
783         { ICE_UDP_OF,           34 },
784         { ICE_GTP,              42 },
785         { ICE_IPV6_IL,          62 },
786         { ICE_UDP_ILOS,         102 },
787         { ICE_PROTOCOL_LAST,    0 },
788 };
789
790 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = {
791         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
792         0x00, 0x00, 0x00, 0x00,
793         0x00, 0x00, 0x00, 0x00,
794         0x08, 0x00,
795
796         0x45, 0x00, 0x00, 0x60, /* IP 14 */
797         0x00, 0x00, 0x00, 0x00,
798         0x00, 0x11, 0x00, 0x00,
799         0x00, 0x00, 0x00, 0x00,
800         0x00, 0x00, 0x00, 0x00,
801
802         0x00, 0x00, 0x08, 0x68, /* UDP 34 */
803         0x00, 0x4c, 0x00, 0x00,
804
805         0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 42 */
806         0x00, 0x00, 0x00, 0x00,
807         0x00, 0x00, 0x00, 0x85,
808
809         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
810         0x00, 0x00, 0x00, 0x00,
811
812         0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
813         0x00, 0x08, 0x11, 0x00,
814         0x00, 0x00, 0x00, 0x00,
815         0x00, 0x00, 0x00, 0x00,
816         0x00, 0x00, 0x00, 0x00,
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
823         0x00, 0x00, 0x00, 0x00, /* UDP 102 */
824         0x00, 0x08, 0x00, 0x00,
825
826         0x00, 0x00, /* 2 bytes for 4 byte alignment */
827 };
828
829 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = {
830         { ICE_MAC_OFOS,         0 },
831         { ICE_IPV6_OFOS,        14 },
832         { ICE_UDP_OF,           54 },
833         { ICE_GTP,              62 },
834         { ICE_IPV4_IL,          82 },
835         { ICE_TCP_IL,           102 },
836         { ICE_PROTOCOL_LAST,    0 },
837 };
838
839 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = {
840         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
841         0x00, 0x00, 0x00, 0x00,
842         0x00, 0x00, 0x00, 0x00,
843         0x86, 0xdd,
844
845         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
846         0x00, 0x44, 0x11, 0x00,
847         0x00, 0x00, 0x00, 0x00,
848         0x00, 0x00, 0x00, 0x00,
849         0x00, 0x00, 0x00, 0x00,
850         0x00, 0x00, 0x00, 0x00,
851         0x00, 0x00, 0x00, 0x00,
852         0x00, 0x00, 0x00, 0x00,
853         0x00, 0x00, 0x00, 0x00,
854         0x00, 0x00, 0x00, 0x00,
855
856         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
857         0x00, 0x44, 0x00, 0x00,
858
859         0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 62 */
860         0x00, 0x00, 0x00, 0x00,
861         0x00, 0x00, 0x00, 0x85,
862
863         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
864         0x00, 0x00, 0x00, 0x00,
865
866         0x45, 0x00, 0x00, 0x28, /* IP 82 */
867         0x00, 0x00, 0x00, 0x00,
868         0x00, 0x06, 0x00, 0x00,
869         0x00, 0x00, 0x00, 0x00,
870         0x00, 0x00, 0x00, 0x00,
871
872         0x00, 0x00, 0x00, 0x00, /* TCP 102 */
873         0x00, 0x00, 0x00, 0x00,
874         0x00, 0x00, 0x00, 0x00,
875         0x50, 0x00, 0x00, 0x00,
876         0x00, 0x00, 0x00, 0x00,
877
878         0x00, 0x00, /* 2 bytes for 4 byte alignment */
879 };
880
881 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = {
882         { ICE_MAC_OFOS,         0 },
883         { ICE_IPV6_OFOS,        14 },
884         { ICE_UDP_OF,           54 },
885         { ICE_GTP,              62 },
886         { ICE_IPV4_IL,          82 },
887         { ICE_UDP_ILOS,         102 },
888         { ICE_PROTOCOL_LAST,    0 },
889 };
890
891 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = {
892         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
893         0x00, 0x00, 0x00, 0x00,
894         0x00, 0x00, 0x00, 0x00,
895         0x86, 0xdd,
896
897         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
898         0x00, 0x38, 0x11, 0x00,
899         0x00, 0x00, 0x00, 0x00,
900         0x00, 0x00, 0x00, 0x00,
901         0x00, 0x00, 0x00, 0x00,
902         0x00, 0x00, 0x00, 0x00,
903         0x00, 0x00, 0x00, 0x00,
904         0x00, 0x00, 0x00, 0x00,
905         0x00, 0x00, 0x00, 0x00,
906         0x00, 0x00, 0x00, 0x00,
907
908         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
909         0x00, 0x38, 0x00, 0x00,
910
911         0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 62 */
912         0x00, 0x00, 0x00, 0x00,
913         0x00, 0x00, 0x00, 0x85,
914
915         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
916         0x00, 0x00, 0x00, 0x00,
917
918         0x45, 0x00, 0x00, 0x1c, /* IP 82 */
919         0x00, 0x00, 0x00, 0x00,
920         0x00, 0x11, 0x00, 0x00,
921         0x00, 0x00, 0x00, 0x00,
922         0x00, 0x00, 0x00, 0x00,
923
924         0x00, 0x00, 0x00, 0x00, /* UDP 102 */
925         0x00, 0x08, 0x00, 0x00,
926
927         0x00, 0x00, /* 2 bytes for 4 byte alignment */
928 };
929
930 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = {
931         { ICE_MAC_OFOS,         0 },
932         { ICE_IPV6_OFOS,        14 },
933         { ICE_UDP_OF,           54 },
934         { ICE_GTP,              62 },
935         { ICE_IPV6_IL,          82 },
936         { ICE_TCP_IL,           122 },
937         { ICE_PROTOCOL_LAST,    0 },
938 };
939
940 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = {
941         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
942         0x00, 0x00, 0x00, 0x00,
943         0x00, 0x00, 0x00, 0x00,
944         0x86, 0xdd,
945
946         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
947         0x00, 0x58, 0x11, 0x00,
948         0x00, 0x00, 0x00, 0x00,
949         0x00, 0x00, 0x00, 0x00,
950         0x00, 0x00, 0x00, 0x00,
951         0x00, 0x00, 0x00, 0x00,
952         0x00, 0x00, 0x00, 0x00,
953         0x00, 0x00, 0x00, 0x00,
954         0x00, 0x00, 0x00, 0x00,
955         0x00, 0x00, 0x00, 0x00,
956
957         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
958         0x00, 0x58, 0x00, 0x00,
959
960         0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 62 */
961         0x00, 0x00, 0x00, 0x00,
962         0x00, 0x00, 0x00, 0x85,
963
964         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
965         0x00, 0x00, 0x00, 0x00,
966
967         0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
968         0x00, 0x14, 0x06, 0x00,
969         0x00, 0x00, 0x00, 0x00,
970         0x00, 0x00, 0x00, 0x00,
971         0x00, 0x00, 0x00, 0x00,
972         0x00, 0x00, 0x00, 0x00,
973         0x00, 0x00, 0x00, 0x00,
974         0x00, 0x00, 0x00, 0x00,
975         0x00, 0x00, 0x00, 0x00,
976         0x00, 0x00, 0x00, 0x00,
977
978         0x00, 0x00, 0x00, 0x00, /* TCP 122 */
979         0x00, 0x00, 0x00, 0x00,
980         0x00, 0x00, 0x00, 0x00,
981         0x50, 0x00, 0x00, 0x00,
982         0x00, 0x00, 0x00, 0x00,
983
984         0x00, 0x00, /* 2 bytes for 4 byte alignment */
985 };
986
987 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = {
988         { ICE_MAC_OFOS,         0 },
989         { ICE_IPV6_OFOS,        14 },
990         { ICE_UDP_OF,           54 },
991         { ICE_GTP,              62 },
992         { ICE_IPV6_IL,          82 },
993         { ICE_UDP_ILOS,         122 },
994         { ICE_PROTOCOL_LAST,    0 },
995 };
996
997 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = {
998         0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
999         0x00, 0x00, 0x00, 0x00,
1000         0x00, 0x00, 0x00, 0x00,
1001         0x86, 0xdd,
1002
1003         0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1004         0x00, 0x4c, 0x11, 0x00,
1005         0x00, 0x00, 0x00, 0x00,
1006         0x00, 0x00, 0x00, 0x00,
1007         0x00, 0x00, 0x00, 0x00,
1008         0x00, 0x00, 0x00, 0x00,
1009         0x00, 0x00, 0x00, 0x00,
1010         0x00, 0x00, 0x00, 0x00,
1011         0x00, 0x00, 0x00, 0x00,
1012         0x00, 0x00, 0x00, 0x00,
1013
1014         0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1015         0x00, 0x4c, 0x00, 0x00,
1016
1017         0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 62 */
1018         0x00, 0x00, 0x00, 0x00,
1019         0x00, 0x00, 0x00, 0x85,
1020
1021         0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1022         0x00, 0x00, 0x00, 0x00,
1023
1024         0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
1025         0x00, 0x08, 0x11, 0x00,
1026         0x00, 0x00, 0x00, 0x00,
1027         0x00, 0x00, 0x00, 0x00,
1028         0x00, 0x00, 0x00, 0x00,
1029         0x00, 0x00, 0x00, 0x00,
1030         0x00, 0x00, 0x00, 0x00,
1031         0x00, 0x00, 0x00, 0x00,
1032         0x00, 0x00, 0x00, 0x00,
1033         0x00, 0x00, 0x00, 0x00,
1034
1035         0x00, 0x00, 0x00, 0x00, /* UDP 122 */
1036         0x00, 0x08, 0x00, 0x00,
1037
1038         0x00, 0x00, /* 2 bytes for 4 byte alignment */
1039 };
1040
1041 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = {
1042         { ICE_MAC_OFOS,         0 },
1043         { ICE_IPV4_OFOS,        14 },
1044         { ICE_UDP_OF,           34 },
1045         { ICE_GTP_NO_PAY,       42 },
1046         { ICE_PROTOCOL_LAST,    0 },
1047 };
1048
1049 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = {
1050         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1051         0x00, 0x00, 0x00, 0x00,
1052         0x00, 0x00, 0x00, 0x00,
1053         0x08, 0x00,
1054
1055         0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
1056         0x00, 0x00, 0x40, 0x00,
1057         0x40, 0x11, 0x00, 0x00,
1058         0x00, 0x00, 0x00, 0x00,
1059         0x00, 0x00, 0x00, 0x00,
1060
1061         0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
1062         0x00, 0x00, 0x00, 0x00,
1063
1064         0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
1065         0x00, 0x00, 0x00, 0x00,
1066         0x00, 0x00, 0x00, 0x85,
1067
1068         0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1069         0x00, 0x00, 0x00, 0x00,
1070
1071         0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
1072         0x00, 0x00, 0x40, 0x00,
1073         0x40, 0x00, 0x00, 0x00,
1074         0x00, 0x00, 0x00, 0x00,
1075         0x00, 0x00, 0x00, 0x00,
1076         0x00, 0x00,
1077 };
1078
1079 ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = {
1080         { ICE_MAC_OFOS,         0 },
1081         { ICE_IPV6_OFOS,        14 },
1082         { ICE_UDP_OF,           54 },
1083         { ICE_GTP_NO_PAY,       62 },
1084         { ICE_PROTOCOL_LAST,    0 },
1085 };
1086
1087 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
1088         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1089         0x00, 0x00, 0x00, 0x00,
1090         0x00, 0x00, 0x00, 0x00,
1091         0x86, 0xdd,
1092
1093         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1094         0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1095         0x00, 0x00, 0x00, 0x00,
1096         0x00, 0x00, 0x00, 0x00,
1097         0x00, 0x00, 0x00, 0x00,
1098         0x00, 0x00, 0x00, 0x00,
1099         0x00, 0x00, 0x00, 0x00,
1100         0x00, 0x00, 0x00, 0x00,
1101         0x00, 0x00, 0x00, 0x00,
1102         0x00, 0x00, 0x00, 0x00,
1103
1104         0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1105         0x00, 0x00, 0x00, 0x00,
1106
1107         0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */
1108         0x00, 0x00, 0x00, 0x00,
1109
1110         0x00, 0x00,
1111 };
1112
1113 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
1114         { ICE_MAC_OFOS,         0 },
1115         { ICE_ETYPE_OL,         12 },
1116         { ICE_PPPOE,            14 },
1117         { ICE_IPV4_OFOS,        22 },
1118         { ICE_TCP_IL,           42 },
1119         { ICE_PROTOCOL_LAST,    0 },
1120 };
1121
1122 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = {
1123         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1124         0x00, 0x00, 0x00, 0x00,
1125         0x00, 0x00, 0x00, 0x00,
1126
1127         0x88, 0x64,             /* ICE_ETYPE_OL 12 */
1128
1129         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1130         0x00, 0x16,
1131
1132         0x00, 0x21,             /* PPP Link Layer 20 */
1133
1134         0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */
1135         0x00, 0x01, 0x00, 0x00,
1136         0x00, 0x06, 0x00, 0x00,
1137         0x00, 0x00, 0x00, 0x00,
1138         0x00, 0x00, 0x00, 0x00,
1139
1140         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */
1141         0x00, 0x00, 0x00, 0x00,
1142         0x00, 0x00, 0x00, 0x00,
1143         0x50, 0x00, 0x00, 0x00,
1144         0x00, 0x00, 0x00, 0x00,
1145
1146         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1147 };
1148
1149 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = {
1150         { ICE_MAC_OFOS,         0 },
1151         { ICE_ETYPE_OL,         12 },
1152         { ICE_PPPOE,            14 },
1153         { ICE_IPV4_OFOS,        22 },
1154         { ICE_UDP_ILOS,         42 },
1155         { ICE_PROTOCOL_LAST,    0 },
1156 };
1157
1158 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = {
1159         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1160         0x00, 0x00, 0x00, 0x00,
1161         0x00, 0x00, 0x00, 0x00,
1162
1163         0x88, 0x64,             /* ICE_ETYPE_OL 12 */
1164
1165         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1166         0x00, 0x16,
1167
1168         0x00, 0x21,             /* PPP Link Layer 20 */
1169
1170         0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
1171         0x00, 0x01, 0x00, 0x00,
1172         0x00, 0x11, 0x00, 0x00,
1173         0x00, 0x00, 0x00, 0x00,
1174         0x00, 0x00, 0x00, 0x00,
1175
1176         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
1177         0x00, 0x08, 0x00, 0x00,
1178
1179         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1180 };
1181
1182 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = {
1183         { ICE_MAC_OFOS,         0 },
1184         { ICE_ETYPE_OL,         12 },
1185         { ICE_PPPOE,            14 },
1186         { ICE_IPV6_OFOS,        22 },
1187         { ICE_TCP_IL,           62 },
1188         { ICE_PROTOCOL_LAST,    0 },
1189 };
1190
1191 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = {
1192         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1193         0x00, 0x00, 0x00, 0x00,
1194         0x00, 0x00, 0x00, 0x00,
1195
1196         0x88, 0x64,             /* ICE_ETYPE_OL 12 */
1197
1198         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1199         0x00, 0x2a,
1200
1201         0x00, 0x57,             /* PPP Link Layer 20 */
1202
1203         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1204         0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
1205         0x00, 0x00, 0x00, 0x00,
1206         0x00, 0x00, 0x00, 0x00,
1207         0x00, 0x00, 0x00, 0x00,
1208         0x00, 0x00, 0x00, 0x00,
1209         0x00, 0x00, 0x00, 0x00,
1210         0x00, 0x00, 0x00, 0x00,
1211         0x00, 0x00, 0x00, 0x00,
1212         0x00, 0x00, 0x00, 0x00,
1213
1214         0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */
1215         0x00, 0x00, 0x00, 0x00,
1216         0x00, 0x00, 0x00, 0x00,
1217         0x50, 0x00, 0x00, 0x00,
1218         0x00, 0x00, 0x00, 0x00,
1219
1220         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1221 };
1222
1223 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = {
1224         { ICE_MAC_OFOS,         0 },
1225         { ICE_ETYPE_OL,         12 },
1226         { ICE_PPPOE,            14 },
1227         { ICE_IPV6_OFOS,        22 },
1228         { ICE_UDP_ILOS,         62 },
1229         { ICE_PROTOCOL_LAST,    0 },
1230 };
1231
1232 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = {
1233         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1234         0x00, 0x00, 0x00, 0x00,
1235         0x00, 0x00, 0x00, 0x00,
1236
1237         0x88, 0x64,             /* ICE_ETYPE_OL 12 */
1238
1239         0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
1240         0x00, 0x2a,
1241
1242         0x00, 0x57,             /* PPP Link Layer 20 */
1243
1244         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1245         0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
1246         0x00, 0x00, 0x00, 0x00,
1247         0x00, 0x00, 0x00, 0x00,
1248         0x00, 0x00, 0x00, 0x00,
1249         0x00, 0x00, 0x00, 0x00,
1250         0x00, 0x00, 0x00, 0x00,
1251         0x00, 0x00, 0x00, 0x00,
1252         0x00, 0x00, 0x00, 0x00,
1253         0x00, 0x00, 0x00, 0x00,
1254
1255         0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
1256         0x00, 0x08, 0x00, 0x00,
1257
1258         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1259 };
1260
1261 ICE_DECLARE_PKT_OFFSETS(ipv4_l2tpv3) = {
1262         { ICE_MAC_OFOS,         0 },
1263         { ICE_ETYPE_OL,         12 },
1264         { ICE_IPV4_OFOS,        14 },
1265         { ICE_L2TPV3,           34 },
1266         { ICE_PROTOCOL_LAST,    0 },
1267 };
1268
1269 ICE_DECLARE_PKT_TEMPLATE(ipv4_l2tpv3) = {
1270         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1271         0x00, 0x00, 0x00, 0x00,
1272         0x00, 0x00, 0x00, 0x00,
1273
1274         0x08, 0x00,             /* ICE_ETYPE_OL 12 */
1275
1276         0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1277         0x00, 0x00, 0x40, 0x00,
1278         0x40, 0x73, 0x00, 0x00,
1279         0x00, 0x00, 0x00, 0x00,
1280         0x00, 0x00, 0x00, 0x00,
1281
1282         0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
1283         0x00, 0x00, 0x00, 0x00,
1284         0x00, 0x00, 0x00, 0x00,
1285         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1286 };
1287
1288 ICE_DECLARE_PKT_OFFSETS(ipv6_l2tpv3) = {
1289         { ICE_MAC_OFOS,         0 },
1290         { ICE_ETYPE_OL,         12 },
1291         { ICE_IPV6_OFOS,        14 },
1292         { ICE_L2TPV3,           54 },
1293         { ICE_PROTOCOL_LAST,    0 },
1294 };
1295
1296 ICE_DECLARE_PKT_TEMPLATE(ipv6_l2tpv3) = {
1297         0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1298         0x00, 0x00, 0x00, 0x00,
1299         0x00, 0x00, 0x00, 0x00,
1300
1301         0x86, 0xDD,             /* ICE_ETYPE_OL 12 */
1302
1303         0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
1304         0x00, 0x0c, 0x73, 0x40,
1305         0x00, 0x00, 0x00, 0x00,
1306         0x00, 0x00, 0x00, 0x00,
1307         0x00, 0x00, 0x00, 0x00,
1308         0x00, 0x00, 0x00, 0x00,
1309         0x00, 0x00, 0x00, 0x00,
1310         0x00, 0x00, 0x00, 0x00,
1311         0x00, 0x00, 0x00, 0x00,
1312         0x00, 0x00, 0x00, 0x00,
1313
1314         0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
1315         0x00, 0x00, 0x00, 0x00,
1316         0x00, 0x00, 0x00, 0x00,
1317         0x00, 0x00,             /* 2 bytes for 4 bytes alignment */
1318 };
1319
1320 static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
1321         ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 |
1322                                   ICE_PKT_GTP_NOPAY),
1323         ICE_PKT_PROFILE(ipv6_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
1324                                             ICE_PKT_OUTER_IPV6 |
1325                                             ICE_PKT_INNER_IPV6 |
1326                                             ICE_PKT_INNER_UDP),
1327         ICE_PKT_PROFILE(ipv6_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
1328                                             ICE_PKT_OUTER_IPV6 |
1329                                             ICE_PKT_INNER_IPV6),
1330         ICE_PKT_PROFILE(ipv6_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
1331                                             ICE_PKT_OUTER_IPV6 |
1332                                             ICE_PKT_INNER_UDP),
1333         ICE_PKT_PROFILE(ipv6_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU |
1334                                             ICE_PKT_OUTER_IPV6),
1335         ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPU | ICE_PKT_GTP_NOPAY),
1336         ICE_PKT_PROFILE(ipv4_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
1337                                             ICE_PKT_INNER_IPV6 |
1338                                             ICE_PKT_INNER_UDP),
1339         ICE_PKT_PROFILE(ipv4_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
1340                                             ICE_PKT_INNER_IPV6),
1341         ICE_PKT_PROFILE(ipv4_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
1342                                             ICE_PKT_INNER_UDP),
1343         ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
1344         ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
1345         ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
1346         ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
1347                                         ICE_PKT_INNER_UDP),
1348         ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6),
1349         ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP),
1350         ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE),
1351         ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 |
1352                                       ICE_PKT_INNER_TCP),
1353         ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
1354         ICE_PKT_PROFILE(gre_ipv6_udp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6),
1355         ICE_PKT_PROFILE(gre_udp, ICE_PKT_TUN_NVGRE),
1356         ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP |
1357                                           ICE_PKT_INNER_IPV6 |
1358                                           ICE_PKT_INNER_TCP),
1359         ICE_PKT_PROFILE(ipv6_l2tpv3, ICE_PKT_L2TPV3 | ICE_PKT_OUTER_IPV6),
1360         ICE_PKT_PROFILE(ipv4_l2tpv3, ICE_PKT_L2TPV3),
1361         ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP),
1362         ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP |
1363                                           ICE_PKT_INNER_IPV6),
1364         ICE_PKT_PROFILE(udp_tun_udp, ICE_PKT_TUN_UDP),
1365         ICE_PKT_PROFILE(udp_ipv6, ICE_PKT_OUTER_IPV6 | ICE_PKT_INNER_UDP),
1366         ICE_PKT_PROFILE(udp, ICE_PKT_INNER_UDP),
1367         ICE_PKT_PROFILE(tcp_ipv6, ICE_PKT_OUTER_IPV6),
1368         ICE_PKT_PROFILE(tcp, 0),
1369 };
1370
1371 /* this is a recipe to profile association bitmap */
1372 static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES],
1373                           ICE_MAX_NUM_PROFILES);
1374
1375 /* this is a profile to recipe association bitmap */
1376 static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES],
1377                           ICE_MAX_NUM_RECIPES);
1378
1379 /**
1380  * ice_init_def_sw_recp - initialize the recipe book keeping tables
1381  * @hw: pointer to the HW struct
1382  *
1383  * Allocate memory for the entire recipe table and initialize the structures/
1384  * entries corresponding to basic recipes.
1385  */
1386 int ice_init_def_sw_recp(struct ice_hw *hw)
1387 {
1388         struct ice_sw_recipe *recps;
1389         u8 i;
1390
1391         recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
1392                              sizeof(*recps), GFP_KERNEL);
1393         if (!recps)
1394                 return -ENOMEM;
1395
1396         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
1397                 recps[i].root_rid = i;
1398                 INIT_LIST_HEAD(&recps[i].filt_rules);
1399                 INIT_LIST_HEAD(&recps[i].filt_replay_rules);
1400                 INIT_LIST_HEAD(&recps[i].rg_list);
1401                 mutex_init(&recps[i].filt_rule_lock);
1402         }
1403
1404         hw->switch_info->recp_list = recps;
1405
1406         return 0;
1407 }
1408
1409 /**
1410  * ice_aq_get_sw_cfg - get switch configuration
1411  * @hw: pointer to the hardware structure
1412  * @buf: pointer to the result buffer
1413  * @buf_size: length of the buffer available for response
1414  * @req_desc: pointer to requested descriptor
1415  * @num_elems: pointer to number of elements
1416  * @cd: pointer to command details structure or NULL
1417  *
1418  * Get switch configuration (0x0200) to be placed in buf.
1419  * This admin command returns information such as initial VSI/port number
1420  * and switch ID it belongs to.
1421  *
1422  * NOTE: *req_desc is both an input/output parameter.
1423  * The caller of this function first calls this function with *request_desc set
1424  * to 0. If the response from f/w has *req_desc set to 0, all the switch
1425  * configuration information has been returned; if non-zero (meaning not all
1426  * the information was returned), the caller should call this function again
1427  * with *req_desc set to the previous value returned by f/w to get the
1428  * next block of switch configuration information.
1429  *
1430  * *num_elems is output only parameter. This reflects the number of elements
1431  * in response buffer. The caller of this function to use *num_elems while
1432  * parsing the response buffer.
1433  */
1434 static int
1435 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
1436                   u16 buf_size, u16 *req_desc, u16 *num_elems,
1437                   struct ice_sq_cd *cd)
1438 {
1439         struct ice_aqc_get_sw_cfg *cmd;
1440         struct ice_aq_desc desc;
1441         int status;
1442
1443         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
1444         cmd = &desc.params.get_sw_conf;
1445         cmd->element = cpu_to_le16(*req_desc);
1446
1447         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
1448         if (!status) {
1449                 *req_desc = le16_to_cpu(cmd->element);
1450                 *num_elems = le16_to_cpu(cmd->num_elems);
1451         }
1452
1453         return status;
1454 }
1455
1456 /**
1457  * ice_aq_add_vsi
1458  * @hw: pointer to the HW struct
1459  * @vsi_ctx: pointer to a VSI context struct
1460  * @cd: pointer to command details structure or NULL
1461  *
1462  * Add a VSI context to the hardware (0x0210)
1463  */
1464 static int
1465 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1466                struct ice_sq_cd *cd)
1467 {
1468         struct ice_aqc_add_update_free_vsi_resp *res;
1469         struct ice_aqc_add_get_update_free_vsi *cmd;
1470         struct ice_aq_desc desc;
1471         int status;
1472
1473         cmd = &desc.params.vsi_cmd;
1474         res = &desc.params.add_update_free_vsi_res;
1475
1476         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
1477
1478         if (!vsi_ctx->alloc_from_pool)
1479                 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
1480                                            ICE_AQ_VSI_IS_VALID);
1481         cmd->vf_id = vsi_ctx->vf_num;
1482
1483         cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
1484
1485         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1486
1487         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
1488                                  sizeof(vsi_ctx->info), cd);
1489
1490         if (!status) {
1491                 vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
1492                 vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
1493                 vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
1494         }
1495
1496         return status;
1497 }
1498
1499 /**
1500  * ice_aq_free_vsi
1501  * @hw: pointer to the HW struct
1502  * @vsi_ctx: pointer to a VSI context struct
1503  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
1504  * @cd: pointer to command details structure or NULL
1505  *
1506  * Free VSI context info from hardware (0x0213)
1507  */
1508 static int
1509 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1510                 bool keep_vsi_alloc, struct ice_sq_cd *cd)
1511 {
1512         struct ice_aqc_add_update_free_vsi_resp *resp;
1513         struct ice_aqc_add_get_update_free_vsi *cmd;
1514         struct ice_aq_desc desc;
1515         int status;
1516
1517         cmd = &desc.params.vsi_cmd;
1518         resp = &desc.params.add_update_free_vsi_res;
1519
1520         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
1521
1522         cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
1523         if (keep_vsi_alloc)
1524                 cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
1525
1526         status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1527         if (!status) {
1528                 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
1529                 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1530         }
1531
1532         return status;
1533 }
1534
1535 /**
1536  * ice_aq_update_vsi
1537  * @hw: pointer to the HW struct
1538  * @vsi_ctx: pointer to a VSI context struct
1539  * @cd: pointer to command details structure or NULL
1540  *
1541  * Update VSI context in the hardware (0x0211)
1542  */
1543 static int
1544 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1545                   struct ice_sq_cd *cd)
1546 {
1547         struct ice_aqc_add_update_free_vsi_resp *resp;
1548         struct ice_aqc_add_get_update_free_vsi *cmd;
1549         struct ice_aq_desc desc;
1550         int status;
1551
1552         cmd = &desc.params.vsi_cmd;
1553         resp = &desc.params.add_update_free_vsi_res;
1554
1555         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
1556
1557         cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
1558
1559         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1560
1561         status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
1562                                  sizeof(vsi_ctx->info), cd);
1563
1564         if (!status) {
1565                 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
1566                 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1567         }
1568
1569         return status;
1570 }
1571
1572 /**
1573  * ice_is_vsi_valid - check whether the VSI is valid or not
1574  * @hw: pointer to the HW struct
1575  * @vsi_handle: VSI handle
1576  *
1577  * check whether the VSI is valid or not
1578  */
1579 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
1580 {
1581         return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
1582 }
1583
1584 /**
1585  * ice_get_hw_vsi_num - return the HW VSI number
1586  * @hw: pointer to the HW struct
1587  * @vsi_handle: VSI handle
1588  *
1589  * return the HW VSI number
1590  * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
1591  */
1592 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
1593 {
1594         return hw->vsi_ctx[vsi_handle]->vsi_num;
1595 }
1596
1597 /**
1598  * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
1599  * @hw: pointer to the HW struct
1600  * @vsi_handle: VSI handle
1601  *
1602  * return the VSI context entry for a given VSI handle
1603  */
1604 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
1605 {
1606         return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
1607 }
1608
1609 /**
1610  * ice_save_vsi_ctx - save the VSI context for a given VSI handle
1611  * @hw: pointer to the HW struct
1612  * @vsi_handle: VSI handle
1613  * @vsi: VSI context pointer
1614  *
1615  * save the VSI context entry for a given VSI handle
1616  */
1617 static void
1618 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
1619 {
1620         hw->vsi_ctx[vsi_handle] = vsi;
1621 }
1622
1623 /**
1624  * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
1625  * @hw: pointer to the HW struct
1626  * @vsi_handle: VSI handle
1627  */
1628 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
1629 {
1630         struct ice_vsi_ctx *vsi = ice_get_vsi_ctx(hw, vsi_handle);
1631         u8 i;
1632
1633         if (!vsi)
1634                 return;
1635         ice_for_each_traffic_class(i) {
1636                 devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]);
1637                 vsi->lan_q_ctx[i] = NULL;
1638                 devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]);
1639                 vsi->rdma_q_ctx[i] = NULL;
1640         }
1641 }
1642
1643 /**
1644  * ice_clear_vsi_ctx - clear the VSI context entry
1645  * @hw: pointer to the HW struct
1646  * @vsi_handle: VSI handle
1647  *
1648  * clear the VSI context entry
1649  */
1650 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
1651 {
1652         struct ice_vsi_ctx *vsi;
1653
1654         vsi = ice_get_vsi_ctx(hw, vsi_handle);
1655         if (vsi) {
1656                 ice_clear_vsi_q_ctx(hw, vsi_handle);
1657                 devm_kfree(ice_hw_to_dev(hw), vsi);
1658                 hw->vsi_ctx[vsi_handle] = NULL;
1659         }
1660 }
1661
1662 /**
1663  * ice_clear_all_vsi_ctx - clear all the VSI context entries
1664  * @hw: pointer to the HW struct
1665  */
1666 void ice_clear_all_vsi_ctx(struct ice_hw *hw)
1667 {
1668         u16 i;
1669
1670         for (i = 0; i < ICE_MAX_VSI; i++)
1671                 ice_clear_vsi_ctx(hw, i);
1672 }
1673
1674 /**
1675  * ice_add_vsi - add VSI context to the hardware and VSI handle list
1676  * @hw: pointer to the HW struct
1677  * @vsi_handle: unique VSI handle provided by drivers
1678  * @vsi_ctx: pointer to a VSI context struct
1679  * @cd: pointer to command details structure or NULL
1680  *
1681  * Add a VSI context to the hardware also add it into the VSI handle list.
1682  * If this function gets called after reset for existing VSIs then update
1683  * with the new HW VSI number in the corresponding VSI handle list entry.
1684  */
1685 int
1686 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1687             struct ice_sq_cd *cd)
1688 {
1689         struct ice_vsi_ctx *tmp_vsi_ctx;
1690         int status;
1691
1692         if (vsi_handle >= ICE_MAX_VSI)
1693                 return -EINVAL;
1694         status = ice_aq_add_vsi(hw, vsi_ctx, cd);
1695         if (status)
1696                 return status;
1697         tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1698         if (!tmp_vsi_ctx) {
1699                 /* Create a new VSI context */
1700                 tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
1701                                            sizeof(*tmp_vsi_ctx), GFP_KERNEL);
1702                 if (!tmp_vsi_ctx) {
1703                         ice_aq_free_vsi(hw, vsi_ctx, false, cd);
1704                         return -ENOMEM;
1705                 }
1706                 *tmp_vsi_ctx = *vsi_ctx;
1707                 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
1708         } else {
1709                 /* update with new HW VSI num */
1710                 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
1711         }
1712
1713         return 0;
1714 }
1715
1716 /**
1717  * ice_free_vsi- free VSI context from hardware and VSI handle list
1718  * @hw: pointer to the HW struct
1719  * @vsi_handle: unique VSI handle
1720  * @vsi_ctx: pointer to a VSI context struct
1721  * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
1722  * @cd: pointer to command details structure or NULL
1723  *
1724  * Free VSI context info from hardware as well as from VSI handle list
1725  */
1726 int
1727 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1728              bool keep_vsi_alloc, struct ice_sq_cd *cd)
1729 {
1730         int status;
1731
1732         if (!ice_is_vsi_valid(hw, vsi_handle))
1733                 return -EINVAL;
1734         vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
1735         status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
1736         if (!status)
1737                 ice_clear_vsi_ctx(hw, vsi_handle);
1738         return status;
1739 }
1740
1741 /**
1742  * ice_update_vsi
1743  * @hw: pointer to the HW struct
1744  * @vsi_handle: unique VSI handle
1745  * @vsi_ctx: pointer to a VSI context struct
1746  * @cd: pointer to command details structure or NULL
1747  *
1748  * Update VSI context in the hardware
1749  */
1750 int
1751 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1752                struct ice_sq_cd *cd)
1753 {
1754         if (!ice_is_vsi_valid(hw, vsi_handle))
1755                 return -EINVAL;
1756         vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
1757         return ice_aq_update_vsi(hw, vsi_ctx, cd);
1758 }
1759
1760 /**
1761  * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI
1762  * @hw: pointer to HW struct
1763  * @vsi_handle: VSI SW index
1764  * @enable: boolean for enable/disable
1765  */
1766 int
1767 ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
1768 {
1769         struct ice_vsi_ctx *ctx, *cached_ctx;
1770         int status;
1771
1772         cached_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1773         if (!cached_ctx)
1774                 return -ENOENT;
1775
1776         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1777         if (!ctx)
1778                 return -ENOMEM;
1779
1780         ctx->info.q_opt_rss = cached_ctx->info.q_opt_rss;
1781         ctx->info.q_opt_tc = cached_ctx->info.q_opt_tc;
1782         ctx->info.q_opt_flags = cached_ctx->info.q_opt_flags;
1783
1784         ctx->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_Q_OPT_VALID);
1785
1786         if (enable)
1787                 ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
1788         else
1789                 ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
1790
1791         status = ice_update_vsi(hw, vsi_handle, ctx, NULL);
1792         if (!status) {
1793                 cached_ctx->info.q_opt_flags = ctx->info.q_opt_flags;
1794                 cached_ctx->info.valid_sections |= ctx->info.valid_sections;
1795         }
1796
1797         kfree(ctx);
1798         return status;
1799 }
1800
1801 /**
1802  * ice_aq_alloc_free_vsi_list
1803  * @hw: pointer to the HW struct
1804  * @vsi_list_id: VSI list ID returned or used for lookup
1805  * @lkup_type: switch rule filter lookup type
1806  * @opc: switch rules population command type - pass in the command opcode
1807  *
1808  * allocates or free a VSI list resource
1809  */
1810 static int
1811 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
1812                            enum ice_sw_lkup_type lkup_type,
1813                            enum ice_adminq_opc opc)
1814 {
1815         DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
1816         u16 buf_len = __struct_size(sw_buf);
1817         struct ice_aqc_res_elem *vsi_ele;
1818         int status;
1819
1820         sw_buf->num_elems = cpu_to_le16(1);
1821
1822         if (lkup_type == ICE_SW_LKUP_MAC ||
1823             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
1824             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
1825             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
1826             lkup_type == ICE_SW_LKUP_PROMISC ||
1827             lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
1828             lkup_type == ICE_SW_LKUP_DFLT) {
1829                 sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
1830         } else if (lkup_type == ICE_SW_LKUP_VLAN) {
1831                 if (opc == ice_aqc_opc_alloc_res)
1832                         sw_buf->res_type =
1833                                 cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE |
1834                                             ICE_AQC_RES_TYPE_FLAG_SHARED);
1835                 else
1836                         sw_buf->res_type =
1837                                 cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
1838         } else {
1839                 return -EINVAL;
1840         }
1841
1842         if (opc == ice_aqc_opc_free_res)
1843                 sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
1844
1845         status = ice_aq_alloc_free_res(hw, sw_buf, buf_len, opc);
1846         if (status)
1847                 return status;
1848
1849         if (opc == ice_aqc_opc_alloc_res) {
1850                 vsi_ele = &sw_buf->elem[0];
1851                 *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
1852         }
1853
1854         return 0;
1855 }
1856
1857 /**
1858  * ice_aq_sw_rules - add/update/remove switch rules
1859  * @hw: pointer to the HW struct
1860  * @rule_list: pointer to switch rule population list
1861  * @rule_list_sz: total size of the rule list in bytes
1862  * @num_rules: number of switch rules in the rule_list
1863  * @opc: switch rules population command type - pass in the command opcode
1864  * @cd: pointer to command details structure or NULL
1865  *
1866  * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
1867  */
1868 int
1869 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
1870                 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
1871 {
1872         struct ice_aq_desc desc;
1873         int status;
1874
1875         if (opc != ice_aqc_opc_add_sw_rules &&
1876             opc != ice_aqc_opc_update_sw_rules &&
1877             opc != ice_aqc_opc_remove_sw_rules)
1878                 return -EINVAL;
1879
1880         ice_fill_dflt_direct_cmd_desc(&desc, opc);
1881
1882         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1883         desc.params.sw_rules.num_rules_fltr_entry_index =
1884                 cpu_to_le16(num_rules);
1885         status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
1886         if (opc != ice_aqc_opc_add_sw_rules &&
1887             hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
1888                 status = -ENOENT;
1889
1890         return status;
1891 }
1892
1893 /**
1894  * ice_aq_add_recipe - add switch recipe
1895  * @hw: pointer to the HW struct
1896  * @s_recipe_list: pointer to switch rule population list
1897  * @num_recipes: number of switch recipes in the list
1898  * @cd: pointer to command details structure or NULL
1899  *
1900  * Add(0x0290)
1901  */
1902 int
1903 ice_aq_add_recipe(struct ice_hw *hw,
1904                   struct ice_aqc_recipe_data_elem *s_recipe_list,
1905                   u16 num_recipes, struct ice_sq_cd *cd)
1906 {
1907         struct ice_aqc_add_get_recipe *cmd;
1908         struct ice_aq_desc desc;
1909         u16 buf_size;
1910
1911         cmd = &desc.params.add_get_recipe;
1912         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
1913
1914         cmd->num_sub_recipes = cpu_to_le16(num_recipes);
1915         desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1916
1917         buf_size = num_recipes * sizeof(*s_recipe_list);
1918
1919         return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
1920 }
1921
1922 /**
1923  * ice_aq_get_recipe - get switch recipe
1924  * @hw: pointer to the HW struct
1925  * @s_recipe_list: pointer to switch rule population list
1926  * @num_recipes: pointer to the number of recipes (input and output)
1927  * @recipe_root: root recipe number of recipe(s) to retrieve
1928  * @cd: pointer to command details structure or NULL
1929  *
1930  * Get(0x0292)
1931  *
1932  * On input, *num_recipes should equal the number of entries in s_recipe_list.
1933  * On output, *num_recipes will equal the number of entries returned in
1934  * s_recipe_list.
1935  *
1936  * The caller must supply enough space in s_recipe_list to hold all possible
1937  * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
1938  */
1939 int
1940 ice_aq_get_recipe(struct ice_hw *hw,
1941                   struct ice_aqc_recipe_data_elem *s_recipe_list,
1942                   u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
1943 {
1944         struct ice_aqc_add_get_recipe *cmd;
1945         struct ice_aq_desc desc;
1946         u16 buf_size;
1947         int status;
1948
1949         if (*num_recipes != ICE_MAX_NUM_RECIPES)
1950                 return -EINVAL;
1951
1952         cmd = &desc.params.add_get_recipe;
1953         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
1954
1955         cmd->return_index = cpu_to_le16(recipe_root);
1956         cmd->num_sub_recipes = 0;
1957
1958         buf_size = *num_recipes * sizeof(*s_recipe_list);
1959
1960         status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
1961         *num_recipes = le16_to_cpu(cmd->num_sub_recipes);
1962
1963         return status;
1964 }
1965
1966 /**
1967  * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
1968  * @hw: pointer to the HW struct
1969  * @params: parameters used to update the default recipe
1970  *
1971  * This function only supports updating default recipes and it only supports
1972  * updating a single recipe based on the lkup_idx at a time.
1973  *
1974  * This is done as a read-modify-write operation. First, get the current recipe
1975  * contents based on the recipe's ID. Then modify the field vector index and
1976  * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
1977  * the pre-existing recipe with the modifications.
1978  */
1979 int
1980 ice_update_recipe_lkup_idx(struct ice_hw *hw,
1981                            struct ice_update_recipe_lkup_idx_params *params)
1982 {
1983         struct ice_aqc_recipe_data_elem *rcp_list;
1984         u16 num_recps = ICE_MAX_NUM_RECIPES;
1985         int status;
1986
1987         rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL);
1988         if (!rcp_list)
1989                 return -ENOMEM;
1990
1991         /* read current recipe list from firmware */
1992         rcp_list->recipe_indx = params->rid;
1993         status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
1994         if (status) {
1995                 ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
1996                           params->rid, status);
1997                 goto error_out;
1998         }
1999
2000         /* only modify existing recipe's lkup_idx and mask if valid, while
2001          * leaving all other fields the same, then update the recipe firmware
2002          */
2003         rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
2004         if (params->mask_valid)
2005                 rcp_list->content.mask[params->lkup_idx] =
2006                         cpu_to_le16(params->mask);
2007
2008         if (params->ignore_valid)
2009                 rcp_list->content.lkup_indx[params->lkup_idx] |=
2010                         ICE_AQ_RECIPE_LKUP_IGNORE;
2011
2012         status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
2013         if (status)
2014                 ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
2015                           params->rid, params->lkup_idx, params->fv_idx,
2016                           params->mask, params->mask_valid ? "true" : "false",
2017                           status);
2018
2019 error_out:
2020         kfree(rcp_list);
2021         return status;
2022 }
2023
2024 /**
2025  * ice_aq_map_recipe_to_profile - Map recipe to packet profile
2026  * @hw: pointer to the HW struct
2027  * @profile_id: package profile ID to associate the recipe with
2028  * @r_assoc: Recipe bitmap filled in and need to be returned as response
2029  * @cd: pointer to command details structure or NULL
2030  * Recipe to profile association (0x0291)
2031  */
2032 int
2033 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 r_assoc,
2034                              struct ice_sq_cd *cd)
2035 {
2036         struct ice_aqc_recipe_to_profile *cmd;
2037         struct ice_aq_desc desc;
2038
2039         cmd = &desc.params.recipe_to_profile;
2040         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
2041         cmd->profile_id = cpu_to_le16(profile_id);
2042         /* Set the recipe ID bit in the bitmask to let the device know which
2043          * profile we are associating the recipe to
2044          */
2045         cmd->recipe_assoc = cpu_to_le64(r_assoc);
2046
2047         return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2048 }
2049
2050 /**
2051  * ice_aq_get_recipe_to_profile - Map recipe to packet profile
2052  * @hw: pointer to the HW struct
2053  * @profile_id: package profile ID to associate the recipe with
2054  * @r_assoc: Recipe bitmap filled in and need to be returned as response
2055  * @cd: pointer to command details structure or NULL
2056  * Associate profile ID with given recipe (0x0293)
2057  */
2058 int
2059 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 *r_assoc,
2060                              struct ice_sq_cd *cd)
2061 {
2062         struct ice_aqc_recipe_to_profile *cmd;
2063         struct ice_aq_desc desc;
2064         int status;
2065
2066         cmd = &desc.params.recipe_to_profile;
2067         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
2068         cmd->profile_id = cpu_to_le16(profile_id);
2069
2070         status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2071         if (!status)
2072                 *r_assoc = le64_to_cpu(cmd->recipe_assoc);
2073
2074         return status;
2075 }
2076
2077 /**
2078  * ice_alloc_recipe - add recipe resource
2079  * @hw: pointer to the hardware structure
2080  * @rid: recipe ID returned as response to AQ call
2081  */
2082 int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
2083 {
2084         DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
2085         u16 buf_len = __struct_size(sw_buf);
2086         int status;
2087
2088         sw_buf->num_elems = cpu_to_le16(1);
2089         sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE <<
2090                                         ICE_AQC_RES_TYPE_S) |
2091                                         ICE_AQC_RES_TYPE_FLAG_SHARED);
2092         status = ice_aq_alloc_free_res(hw, sw_buf, buf_len,
2093                                        ice_aqc_opc_alloc_res);
2094         if (!status)
2095                 *rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
2096
2097         return status;
2098 }
2099
2100 /**
2101  * ice_get_recp_to_prof_map - updates recipe to profile mapping
2102  * @hw: pointer to hardware structure
2103  *
2104  * This function is used to populate recipe_to_profile matrix where index to
2105  * this array is the recipe ID and the element is the mapping of which profiles
2106  * is this recipe mapped to.
2107  */
2108 static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2109 {
2110         DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
2111         u64 recp_assoc;
2112         u16 i;
2113
2114         for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2115                 u16 j;
2116
2117                 bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2118                 bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
2119                 if (ice_aq_get_recipe_to_profile(hw, i, &recp_assoc, NULL))
2120                         continue;
2121                 bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
2122                 bitmap_copy(profile_to_recipe[i], r_bitmap,
2123                             ICE_MAX_NUM_RECIPES);
2124                 for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2125                         set_bit(i, recipe_to_profile[j]);
2126         }
2127 }
2128
2129 /**
2130  * ice_collect_result_idx - copy result index values
2131  * @buf: buffer that contains the result index
2132  * @recp: the recipe struct to copy data into
2133  */
2134 static void
2135 ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
2136                        struct ice_sw_recipe *recp)
2137 {
2138         if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2139                 set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2140                         recp->res_idxs);
2141 }
2142
2143 /**
2144  * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
2145  * @hw: pointer to hardware structure
2146  * @recps: struct that we need to populate
2147  * @rid: recipe ID that we are populating
2148  * @refresh_required: true if we should get recipe to profile mapping from FW
2149  *
2150  * This function is used to populate all the necessary entries into our
2151  * bookkeeping so that we have a current list of all the recipes that are
2152  * programmed in the firmware.
2153  */
2154 static int
2155 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2156                     bool *refresh_required)
2157 {
2158         DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS);
2159         struct ice_aqc_recipe_data_elem *tmp;
2160         u16 num_recps = ICE_MAX_NUM_RECIPES;
2161         struct ice_prot_lkup_ext *lkup_exts;
2162         u8 fv_word_idx = 0;
2163         u16 sub_recps;
2164         int status;
2165
2166         bitmap_zero(result_bm, ICE_MAX_FV_WORDS);
2167
2168         /* we need a buffer big enough to accommodate all the recipes */
2169         tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
2170         if (!tmp)
2171                 return -ENOMEM;
2172
2173         tmp[0].recipe_indx = rid;
2174         status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2175         /* non-zero status meaning recipe doesn't exist */
2176         if (status)
2177                 goto err_unroll;
2178
2179         /* Get recipe to profile map so that we can get the fv from lkups that
2180          * we read for a recipe from FW. Since we want to minimize the number of
2181          * times we make this FW call, just make one call and cache the copy
2182          * until a new recipe is added. This operation is only required the
2183          * first time to get the changes from FW. Then to search existing
2184          * entries we don't need to update the cache again until another recipe
2185          * gets added.
2186          */
2187         if (*refresh_required) {
2188                 ice_get_recp_to_prof_map(hw);
2189                 *refresh_required = false;
2190         }
2191
2192         /* Start populating all the entries for recps[rid] based on lkups from
2193          * firmware. Note that we are only creating the root recipe in our
2194          * database.
2195          */
2196         lkup_exts = &recps[rid].lkup_exts;
2197
2198         for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2199                 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2200                 struct ice_recp_grp_entry *rg_entry;
2201                 u8 i, prof, idx, prot = 0;
2202                 bool is_root;
2203                 u16 off = 0;
2204
2205                 rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry),
2206                                         GFP_KERNEL);
2207                 if (!rg_entry) {
2208                         status = -ENOMEM;
2209                         goto err_unroll;
2210                 }
2211
2212                 idx = root_bufs.recipe_indx;
2213                 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2214
2215                 /* Mark all result indices in this chain */
2216                 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2217                         set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2218                                 result_bm);
2219
2220                 /* get the first profile that is associated with rid */
2221                 prof = find_first_bit(recipe_to_profile[idx],
2222                                       ICE_MAX_NUM_PROFILES);
2223                 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2224                         u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2225
2226                         rg_entry->fv_idx[i] = lkup_indx;
2227                         rg_entry->fv_mask[i] =
2228                                 le16_to_cpu(root_bufs.content.mask[i + 1]);
2229
2230                         /* If the recipe is a chained recipe then all its
2231                          * child recipe's result will have a result index.
2232                          * To fill fv_words we should not use those result
2233                          * index, we only need the protocol ids and offsets.
2234                          * We will skip all the fv_idx which stores result
2235                          * index in them. We also need to skip any fv_idx which
2236                          * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2237                          * valid offset value.
2238                          */
2239                         if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) ||
2240                             rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2241                             rg_entry->fv_idx[i] == 0)
2242                                 continue;
2243
2244                         ice_find_prot_off(hw, ICE_BLK_SW, prof,
2245                                           rg_entry->fv_idx[i], &prot, &off);
2246                         lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2247                         lkup_exts->fv_words[fv_word_idx].off = off;
2248                         lkup_exts->field_mask[fv_word_idx] =
2249                                 rg_entry->fv_mask[i];
2250                         fv_word_idx++;
2251                 }
2252                 /* populate rg_list with the data from the child entry of this
2253                  * recipe
2254                  */
2255                 list_add(&rg_entry->l_entry, &recps[rid].rg_list);
2256
2257                 /* Propagate some data to the recipe database */
2258                 recps[idx].is_root = !!is_root;
2259                 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2260                 recps[idx].need_pass_l2 = root_bufs.content.act_ctrl &
2261                                           ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
2262                 recps[idx].allow_pass_l2 = root_bufs.content.act_ctrl &
2263                                            ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
2264                 bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2265                 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2266                         recps[idx].chain_idx = root_bufs.content.result_indx &
2267                                 ~ICE_AQ_RECIPE_RESULT_EN;
2268                         set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2269                 } else {
2270                         recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2271                 }
2272
2273                 if (!is_root)
2274                         continue;
2275
2276                 /* Only do the following for root recipes entries */
2277                 memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2278                        sizeof(recps[idx].r_bitmap));
2279                 recps[idx].root_rid = root_bufs.content.rid &
2280                         ~ICE_AQ_RECIPE_ID_IS_ROOT;
2281                 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2282         }
2283
2284         /* Complete initialization of the root recipe entry */
2285         lkup_exts->n_val_words = fv_word_idx;
2286         recps[rid].big_recp = (num_recps > 1);
2287         recps[rid].n_grp_count = (u8)num_recps;
2288         recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp,
2289                                            recps[rid].n_grp_count * sizeof(*recps[rid].root_buf),
2290                                            GFP_KERNEL);
2291         if (!recps[rid].root_buf) {
2292                 status = -ENOMEM;
2293                 goto err_unroll;
2294         }
2295
2296         /* Copy result indexes */
2297         bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2298         recps[rid].recp_created = true;
2299
2300 err_unroll:
2301         kfree(tmp);
2302         return status;
2303 }
2304
2305 /* ice_init_port_info - Initialize port_info with switch configuration data
2306  * @pi: pointer to port_info
2307  * @vsi_port_num: VSI number or port number
2308  * @type: Type of switch element (port or VSI)
2309  * @swid: switch ID of the switch the element is attached to
2310  * @pf_vf_num: PF or VF number
2311  * @is_vf: true if the element is a VF, false otherwise
2312  */
2313 static void
2314 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
2315                    u16 swid, u16 pf_vf_num, bool is_vf)
2316 {
2317         switch (type) {
2318         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
2319                 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
2320                 pi->sw_id = swid;
2321                 pi->pf_vf_num = pf_vf_num;
2322                 pi->is_vf = is_vf;
2323                 break;
2324         default:
2325                 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
2326                 break;
2327         }
2328 }
2329
2330 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
2331  * @hw: pointer to the hardware structure
2332  */
2333 int ice_get_initial_sw_cfg(struct ice_hw *hw)
2334 {
2335         struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
2336         u16 req_desc = 0;
2337         u16 num_elems;
2338         int status;
2339         u16 i;
2340
2341         rbuf = kzalloc(ICE_SW_CFG_MAX_BUF_LEN, GFP_KERNEL);
2342         if (!rbuf)
2343                 return -ENOMEM;
2344
2345         /* Multiple calls to ice_aq_get_sw_cfg may be required
2346          * to get all the switch configuration information. The need
2347          * for additional calls is indicated by ice_aq_get_sw_cfg
2348          * writing a non-zero value in req_desc
2349          */
2350         do {
2351                 struct ice_aqc_get_sw_cfg_resp_elem *ele;
2352
2353                 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
2354                                            &req_desc, &num_elems, NULL);
2355
2356                 if (status)
2357                         break;
2358
2359                 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
2360                         u16 pf_vf_num, swid, vsi_port_num;
2361                         bool is_vf = false;
2362                         u8 res_type;
2363
2364                         vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
2365                                 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
2366
2367                         pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
2368                                 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
2369
2370                         swid = le16_to_cpu(ele->swid);
2371
2372                         if (le16_to_cpu(ele->pf_vf_num) &
2373                             ICE_AQC_GET_SW_CONF_RESP_IS_VF)
2374                                 is_vf = true;
2375
2376                         res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
2377                                         ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
2378
2379                         if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
2380                                 /* FW VSI is not needed. Just continue. */
2381                                 continue;
2382                         }
2383
2384                         ice_init_port_info(hw->port_info, vsi_port_num,
2385                                            res_type, swid, pf_vf_num, is_vf);
2386                 }
2387         } while (req_desc && !status);
2388
2389         kfree(rbuf);
2390         return status;
2391 }
2392
2393 /**
2394  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
2395  * @hw: pointer to the hardware structure
2396  * @fi: filter info structure to fill/update
2397  *
2398  * This helper function populates the lb_en and lan_en elements of the provided
2399  * ice_fltr_info struct using the switch's type and characteristics of the
2400  * switch rule being configured.
2401  */
2402 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
2403 {
2404         fi->lb_en = false;
2405         fi->lan_en = false;
2406         if ((fi->flag & ICE_FLTR_TX) &&
2407             (fi->fltr_act == ICE_FWD_TO_VSI ||
2408              fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2409              fi->fltr_act == ICE_FWD_TO_Q ||
2410              fi->fltr_act == ICE_FWD_TO_QGRP)) {
2411                 /* Setting LB for prune actions will result in replicated
2412                  * packets to the internal switch that will be dropped.
2413                  */
2414                 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
2415                         fi->lb_en = true;
2416
2417                 /* Set lan_en to TRUE if
2418                  * 1. The switch is a VEB AND
2419                  * 2
2420                  * 2.1 The lookup is a directional lookup like ethertype,
2421                  * promiscuous, ethertype-MAC, promiscuous-VLAN
2422                  * and default-port OR
2423                  * 2.2 The lookup is VLAN, OR
2424                  * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
2425                  * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
2426                  *
2427                  * OR
2428                  *
2429                  * The switch is a VEPA.
2430                  *
2431                  * In all other cases, the LAN enable has to be set to false.
2432                  */
2433                 if (hw->evb_veb) {
2434                         if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2435                             fi->lkup_type == ICE_SW_LKUP_PROMISC ||
2436                             fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2437                             fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2438                             fi->lkup_type == ICE_SW_LKUP_DFLT ||
2439                             fi->lkup_type == ICE_SW_LKUP_VLAN ||
2440                             (fi->lkup_type == ICE_SW_LKUP_MAC &&
2441                              !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
2442                             (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
2443                              !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
2444                                 fi->lan_en = true;
2445                 } else {
2446                         fi->lan_en = true;
2447                 }
2448         }
2449 }
2450
2451 /**
2452  * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer
2453  * @eth_hdr: pointer to buffer to populate
2454  */
2455 void ice_fill_eth_hdr(u8 *eth_hdr)
2456 {
2457         memcpy(eth_hdr, dummy_eth_header, DUMMY_ETH_HDR_LEN);
2458 }
2459
2460 /**
2461  * ice_fill_sw_rule - Helper function to fill switch rule structure
2462  * @hw: pointer to the hardware structure
2463  * @f_info: entry containing packet forwarding information
2464  * @s_rule: switch rule structure to be filled in based on mac_entry
2465  * @opc: switch rules population command type - pass in the command opcode
2466  */
2467 static void
2468 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
2469                  struct ice_sw_rule_lkup_rx_tx *s_rule,
2470                  enum ice_adminq_opc opc)
2471 {
2472         u16 vlan_id = ICE_MAX_VLAN_ID + 1;
2473         u16 vlan_tpid = ETH_P_8021Q;
2474         void *daddr = NULL;
2475         u16 eth_hdr_sz;
2476         u8 *eth_hdr;
2477         u32 act = 0;
2478         __be16 *off;
2479         u8 q_rgn;
2480
2481         if (opc == ice_aqc_opc_remove_sw_rules) {
2482                 s_rule->act = 0;
2483                 s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2484                 s_rule->hdr_len = 0;
2485                 return;
2486         }
2487
2488         eth_hdr_sz = sizeof(dummy_eth_header);
2489         eth_hdr = s_rule->hdr_data;
2490
2491         /* initialize the ether header with a dummy header */
2492         memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
2493         ice_fill_sw_info(hw, f_info);
2494
2495         switch (f_info->fltr_act) {
2496         case ICE_FWD_TO_VSI:
2497                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
2498                                   f_info->fwd_id.hw_vsi_id);
2499                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2500                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2501                                 ICE_SINGLE_ACT_VALID_BIT;
2502                 break;
2503         case ICE_FWD_TO_VSI_LIST:
2504                 act |= ICE_SINGLE_ACT_VSI_LIST;
2505                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_LIST_ID_M,
2506                                   f_info->fwd_id.vsi_list_id);
2507                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2508                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2509                                 ICE_SINGLE_ACT_VALID_BIT;
2510                 break;
2511         case ICE_FWD_TO_Q:
2512                 act |= ICE_SINGLE_ACT_TO_Q;
2513                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
2514                                   f_info->fwd_id.q_id);
2515                 break;
2516         case ICE_DROP_PACKET:
2517                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
2518                         ICE_SINGLE_ACT_VALID_BIT;
2519                 break;
2520         case ICE_FWD_TO_QGRP:
2521                 q_rgn = f_info->qgrp_size > 0 ?
2522                         (u8)ilog2(f_info->qgrp_size) : 0;
2523                 act |= ICE_SINGLE_ACT_TO_Q;
2524                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
2525                                   f_info->fwd_id.q_id);
2526                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
2527                 break;
2528         default:
2529                 return;
2530         }
2531
2532         if (f_info->lb_en)
2533                 act |= ICE_SINGLE_ACT_LB_ENABLE;
2534         if (f_info->lan_en)
2535                 act |= ICE_SINGLE_ACT_LAN_ENABLE;
2536
2537         switch (f_info->lkup_type) {
2538         case ICE_SW_LKUP_MAC:
2539                 daddr = f_info->l_data.mac.mac_addr;
2540                 break;
2541         case ICE_SW_LKUP_VLAN:
2542                 vlan_id = f_info->l_data.vlan.vlan_id;
2543                 if (f_info->l_data.vlan.tpid_valid)
2544                         vlan_tpid = f_info->l_data.vlan.tpid;
2545                 if (f_info->fltr_act == ICE_FWD_TO_VSI ||
2546                     f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
2547                         act |= ICE_SINGLE_ACT_PRUNE;
2548                         act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
2549                 }
2550                 break;
2551         case ICE_SW_LKUP_ETHERTYPE_MAC:
2552                 daddr = f_info->l_data.ethertype_mac.mac_addr;
2553                 fallthrough;
2554         case ICE_SW_LKUP_ETHERTYPE:
2555                 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2556                 *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
2557                 break;
2558         case ICE_SW_LKUP_MAC_VLAN:
2559                 daddr = f_info->l_data.mac_vlan.mac_addr;
2560                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
2561                 break;
2562         case ICE_SW_LKUP_PROMISC_VLAN:
2563                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
2564                 fallthrough;
2565         case ICE_SW_LKUP_PROMISC:
2566                 daddr = f_info->l_data.mac_vlan.mac_addr;
2567                 break;
2568         default:
2569                 break;
2570         }
2571
2572         s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ?
2573                 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
2574                 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
2575
2576         /* Recipe set depending on lookup type */
2577         s_rule->recipe_id = cpu_to_le16(f_info->lkup_type);
2578         s_rule->src = cpu_to_le16(f_info->src);
2579         s_rule->act = cpu_to_le32(act);
2580
2581         if (daddr)
2582                 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
2583
2584         if (!(vlan_id > ICE_MAX_VLAN_ID)) {
2585                 off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
2586                 *off = cpu_to_be16(vlan_id);
2587                 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2588                 *off = cpu_to_be16(vlan_tpid);
2589         }
2590
2591         /* Create the switch rule with the final dummy Ethernet header */
2592         if (opc != ice_aqc_opc_update_sw_rules)
2593                 s_rule->hdr_len = cpu_to_le16(eth_hdr_sz);
2594 }
2595
2596 /**
2597  * ice_add_marker_act
2598  * @hw: pointer to the hardware structure
2599  * @m_ent: the management entry for which sw marker needs to be added
2600  * @sw_marker: sw marker to tag the Rx descriptor with
2601  * @l_id: large action resource ID
2602  *
2603  * Create a large action to hold software marker and update the switch rule
2604  * entry pointed by m_ent with newly created large action
2605  */
2606 static int
2607 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
2608                    u16 sw_marker, u16 l_id)
2609 {
2610         struct ice_sw_rule_lkup_rx_tx *rx_tx;
2611         struct ice_sw_rule_lg_act *lg_act;
2612         /* For software marker we need 3 large actions
2613          * 1. FWD action: FWD TO VSI or VSI LIST
2614          * 2. GENERIC VALUE action to hold the profile ID
2615          * 3. GENERIC VALUE action to hold the software marker ID
2616          */
2617         const u16 num_lg_acts = 3;
2618         u16 lg_act_size;
2619         u16 rules_size;
2620         int status;
2621         u32 act;
2622         u16 id;
2623
2624         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
2625                 return -EINVAL;
2626
2627         /* Create two back-to-back switch rules and submit them to the HW using
2628          * one memory buffer:
2629          *    1. Large Action
2630          *    2. Look up Tx Rx
2631          */
2632         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts);
2633         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx);
2634         lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
2635         if (!lg_act)
2636                 return -ENOMEM;
2637
2638         rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size);
2639
2640         /* Fill in the first switch rule i.e. large action */
2641         lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
2642         lg_act->index = cpu_to_le16(l_id);
2643         lg_act->size = cpu_to_le16(num_lg_acts);
2644
2645         /* First action VSI forwarding or VSI list forwarding depending on how
2646          * many VSIs
2647          */
2648         id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
2649                 m_ent->fltr_info.fwd_id.hw_vsi_id;
2650
2651         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
2652         act |= FIELD_PREP(ICE_LG_ACT_VSI_LIST_ID_M, id);
2653         if (m_ent->vsi_count > 1)
2654                 act |= ICE_LG_ACT_VSI_LIST;
2655         lg_act->act[0] = cpu_to_le32(act);
2656
2657         /* Second action descriptor type */
2658         act = ICE_LG_ACT_GENERIC;
2659
2660         act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, 1);
2661         lg_act->act[1] = cpu_to_le32(act);
2662
2663         act = FIELD_PREP(ICE_LG_ACT_GENERIC_OFFSET_M,
2664                          ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX);
2665
2666         /* Third action Marker value */
2667         act |= ICE_LG_ACT_GENERIC;
2668         act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, sw_marker);
2669
2670         lg_act->act[2] = cpu_to_le32(act);
2671
2672         /* call the fill switch rule to fill the lookup Tx Rx structure */
2673         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
2674                          ice_aqc_opc_update_sw_rules);
2675
2676         /* Update the action to point to the large action ID */
2677         act = ICE_SINGLE_ACT_PTR;
2678         act |= FIELD_PREP(ICE_SINGLE_ACT_PTR_VAL_M, l_id);
2679         rx_tx->act = cpu_to_le32(act);
2680
2681         /* Use the filter rule ID of the previously created rule with single
2682          * act. Once the update happens, hardware will treat this as large
2683          * action
2684          */
2685         rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
2686
2687         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
2688                                  ice_aqc_opc_update_sw_rules, NULL);
2689         if (!status) {
2690                 m_ent->lg_act_idx = l_id;
2691                 m_ent->sw_marker_id = sw_marker;
2692         }
2693
2694         devm_kfree(ice_hw_to_dev(hw), lg_act);
2695         return status;
2696 }
2697
2698 /**
2699  * ice_create_vsi_list_map
2700  * @hw: pointer to the hardware structure
2701  * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
2702  * @num_vsi: number of VSI handles in the array
2703  * @vsi_list_id: VSI list ID generated as part of allocate resource
2704  *
2705  * Helper function to create a new entry of VSI list ID to VSI mapping
2706  * using the given VSI list ID
2707  */
2708 static struct ice_vsi_list_map_info *
2709 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2710                         u16 vsi_list_id)
2711 {
2712         struct ice_switch_info *sw = hw->switch_info;
2713         struct ice_vsi_list_map_info *v_map;
2714         int i;
2715
2716         v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
2717         if (!v_map)
2718                 return NULL;
2719
2720         v_map->vsi_list_id = vsi_list_id;
2721         v_map->ref_cnt = 1;
2722         for (i = 0; i < num_vsi; i++)
2723                 set_bit(vsi_handle_arr[i], v_map->vsi_map);
2724
2725         list_add(&v_map->list_entry, &sw->vsi_list_map_head);
2726         return v_map;
2727 }
2728
2729 /**
2730  * ice_update_vsi_list_rule
2731  * @hw: pointer to the hardware structure
2732  * @vsi_handle_arr: array of VSI handles to form a VSI list
2733  * @num_vsi: number of VSI handles in the array
2734  * @vsi_list_id: VSI list ID generated as part of allocate resource
2735  * @remove: Boolean value to indicate if this is a remove action
2736  * @opc: switch rules population command type - pass in the command opcode
2737  * @lkup_type: lookup type of the filter
2738  *
2739  * Call AQ command to add a new switch rule or update existing switch rule
2740  * using the given VSI list ID
2741  */
2742 static int
2743 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2744                          u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
2745                          enum ice_sw_lkup_type lkup_type)
2746 {
2747         struct ice_sw_rule_vsi_list *s_rule;
2748         u16 s_rule_size;
2749         u16 rule_type;
2750         int status;
2751         int i;
2752
2753         if (!num_vsi)
2754                 return -EINVAL;
2755
2756         if (lkup_type == ICE_SW_LKUP_MAC ||
2757             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
2758             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2759             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2760             lkup_type == ICE_SW_LKUP_PROMISC ||
2761             lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2762             lkup_type == ICE_SW_LKUP_DFLT)
2763                 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
2764                         ICE_AQC_SW_RULES_T_VSI_LIST_SET;
2765         else if (lkup_type == ICE_SW_LKUP_VLAN)
2766                 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
2767                         ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
2768         else
2769                 return -EINVAL;
2770
2771         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
2772         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
2773         if (!s_rule)
2774                 return -ENOMEM;
2775         for (i = 0; i < num_vsi; i++) {
2776                 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
2777                         status = -EINVAL;
2778                         goto exit;
2779                 }
2780                 /* AQ call requires hw_vsi_id(s) */
2781                 s_rule->vsi[i] =
2782                         cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
2783         }
2784
2785         s_rule->hdr.type = cpu_to_le16(rule_type);
2786         s_rule->number_vsi = cpu_to_le16(num_vsi);
2787         s_rule->index = cpu_to_le16(vsi_list_id);
2788
2789         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
2790
2791 exit:
2792         devm_kfree(ice_hw_to_dev(hw), s_rule);
2793         return status;
2794 }
2795
2796 /**
2797  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
2798  * @hw: pointer to the HW struct
2799  * @vsi_handle_arr: array of VSI handles to form a VSI list
2800  * @num_vsi: number of VSI handles in the array
2801  * @vsi_list_id: stores the ID of the VSI list to be created
2802  * @lkup_type: switch rule filter's lookup type
2803  */
2804 static int
2805 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2806                          u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
2807 {
2808         int status;
2809
2810         status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
2811                                             ice_aqc_opc_alloc_res);
2812         if (status)
2813                 return status;
2814
2815         /* Update the newly created VSI list to include the specified VSIs */
2816         return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
2817                                         *vsi_list_id, false,
2818                                         ice_aqc_opc_add_sw_rules, lkup_type);
2819 }
2820
2821 /**
2822  * ice_create_pkt_fwd_rule
2823  * @hw: pointer to the hardware structure
2824  * @f_entry: entry containing packet forwarding information
2825  *
2826  * Create switch rule with given filter information and add an entry
2827  * to the corresponding filter management list to track this switch rule
2828  * and VSI mapping
2829  */
2830 static int
2831 ice_create_pkt_fwd_rule(struct ice_hw *hw,
2832                         struct ice_fltr_list_entry *f_entry)
2833 {
2834         struct ice_fltr_mgmt_list_entry *fm_entry;
2835         struct ice_sw_rule_lkup_rx_tx *s_rule;
2836         enum ice_sw_lkup_type l_type;
2837         struct ice_sw_recipe *recp;
2838         int status;
2839
2840         s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2841                               ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2842                               GFP_KERNEL);
2843         if (!s_rule)
2844                 return -ENOMEM;
2845         fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
2846                                 GFP_KERNEL);
2847         if (!fm_entry) {
2848                 status = -ENOMEM;
2849                 goto ice_create_pkt_fwd_rule_exit;
2850         }
2851
2852         fm_entry->fltr_info = f_entry->fltr_info;
2853
2854         /* Initialize all the fields for the management entry */
2855         fm_entry->vsi_count = 1;
2856         fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
2857         fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
2858         fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
2859
2860         ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
2861                          ice_aqc_opc_add_sw_rules);
2862
2863         status = ice_aq_sw_rules(hw, s_rule,
2864                                  ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
2865                                  ice_aqc_opc_add_sw_rules, NULL);
2866         if (status) {
2867                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
2868                 goto ice_create_pkt_fwd_rule_exit;
2869         }
2870
2871         f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
2872         fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
2873
2874         /* The book keeping entries will get removed when base driver
2875          * calls remove filter AQ command
2876          */
2877         l_type = fm_entry->fltr_info.lkup_type;
2878         recp = &hw->switch_info->recp_list[l_type];
2879         list_add(&fm_entry->list_entry, &recp->filt_rules);
2880
2881 ice_create_pkt_fwd_rule_exit:
2882         devm_kfree(ice_hw_to_dev(hw), s_rule);
2883         return status;
2884 }
2885
2886 /**
2887  * ice_update_pkt_fwd_rule
2888  * @hw: pointer to the hardware structure
2889  * @f_info: filter information for switch rule
2890  *
2891  * Call AQ command to update a previously created switch rule with a
2892  * VSI list ID
2893  */
2894 static int
2895 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
2896 {
2897         struct ice_sw_rule_lkup_rx_tx *s_rule;
2898         int status;
2899
2900         s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2901                               ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2902                               GFP_KERNEL);
2903         if (!s_rule)
2904                 return -ENOMEM;
2905
2906         ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
2907
2908         s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2909
2910         /* Update switch rule with new rule set to forward VSI list */
2911         status = ice_aq_sw_rules(hw, s_rule,
2912                                  ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
2913                                  ice_aqc_opc_update_sw_rules, NULL);
2914
2915         devm_kfree(ice_hw_to_dev(hw), s_rule);
2916         return status;
2917 }
2918
2919 /**
2920  * ice_update_sw_rule_bridge_mode
2921  * @hw: pointer to the HW struct
2922  *
2923  * Updates unicast switch filter rules based on VEB/VEPA mode
2924  */
2925 int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
2926 {
2927         struct ice_switch_info *sw = hw->switch_info;
2928         struct ice_fltr_mgmt_list_entry *fm_entry;
2929         struct list_head *rule_head;
2930         struct mutex *rule_lock; /* Lock to protect filter rule list */
2931         int status = 0;
2932
2933         rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
2934         rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
2935
2936         mutex_lock(rule_lock);
2937         list_for_each_entry(fm_entry, rule_head, list_entry) {
2938                 struct ice_fltr_info *fi = &fm_entry->fltr_info;
2939                 u8 *addr = fi->l_data.mac.mac_addr;
2940
2941                 /* Update unicast Tx rules to reflect the selected
2942                  * VEB/VEPA mode
2943                  */
2944                 if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
2945                     (fi->fltr_act == ICE_FWD_TO_VSI ||
2946                      fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2947                      fi->fltr_act == ICE_FWD_TO_Q ||
2948                      fi->fltr_act == ICE_FWD_TO_QGRP)) {
2949                         status = ice_update_pkt_fwd_rule(hw, fi);
2950                         if (status)
2951                                 break;
2952                 }
2953         }
2954
2955         mutex_unlock(rule_lock);
2956
2957         return status;
2958 }
2959
2960 /**
2961  * ice_add_update_vsi_list
2962  * @hw: pointer to the hardware structure
2963  * @m_entry: pointer to current filter management list entry
2964  * @cur_fltr: filter information from the book keeping entry
2965  * @new_fltr: filter information with the new VSI to be added
2966  *
2967  * Call AQ command to add or update previously created VSI list with new VSI.
2968  *
2969  * Helper function to do book keeping associated with adding filter information
2970  * The algorithm to do the book keeping is described below :
2971  * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
2972  *      if only one VSI has been added till now
2973  *              Allocate a new VSI list and add two VSIs
2974  *              to this list using switch rule command
2975  *              Update the previously created switch rule with the
2976  *              newly created VSI list ID
2977  *      if a VSI list was previously created
2978  *              Add the new VSI to the previously created VSI list set
2979  *              using the update switch rule command
2980  */
2981 static int
2982 ice_add_update_vsi_list(struct ice_hw *hw,
2983                         struct ice_fltr_mgmt_list_entry *m_entry,
2984                         struct ice_fltr_info *cur_fltr,
2985                         struct ice_fltr_info *new_fltr)
2986 {
2987         u16 vsi_list_id = 0;
2988         int status = 0;
2989
2990         if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
2991              cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
2992                 return -EOPNOTSUPP;
2993
2994         if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
2995              new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
2996             (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
2997              cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
2998                 return -EOPNOTSUPP;
2999
3000         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
3001                 /* Only one entry existed in the mapping and it was not already
3002                  * a part of a VSI list. So, create a VSI list with the old and
3003                  * new VSIs.
3004                  */
3005                 struct ice_fltr_info tmp_fltr;
3006                 u16 vsi_handle_arr[2];
3007
3008                 /* A rule already exists with the new VSI being added */
3009                 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
3010                         return -EEXIST;
3011
3012                 vsi_handle_arr[0] = cur_fltr->vsi_handle;
3013                 vsi_handle_arr[1] = new_fltr->vsi_handle;
3014                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3015                                                   &vsi_list_id,
3016                                                   new_fltr->lkup_type);
3017                 if (status)
3018                         return status;
3019
3020                 tmp_fltr = *new_fltr;
3021                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
3022                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3023                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3024                 /* Update the previous switch rule of "MAC forward to VSI" to
3025                  * "MAC fwd to VSI list"
3026                  */
3027                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3028                 if (status)
3029                         return status;
3030
3031                 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
3032                 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3033                 m_entry->vsi_list_info =
3034                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3035                                                 vsi_list_id);
3036
3037                 if (!m_entry->vsi_list_info)
3038                         return -ENOMEM;
3039
3040                 /* If this entry was large action then the large action needs
3041                  * to be updated to point to FWD to VSI list
3042                  */
3043                 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
3044                         status =
3045                             ice_add_marker_act(hw, m_entry,
3046                                                m_entry->sw_marker_id,
3047                                                m_entry->lg_act_idx);
3048         } else {
3049                 u16 vsi_handle = new_fltr->vsi_handle;
3050                 enum ice_adminq_opc opcode;
3051
3052                 if (!m_entry->vsi_list_info)
3053                         return -EIO;
3054
3055                 /* A rule already exists with the new VSI being added */
3056                 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
3057                         return 0;
3058
3059                 /* Update the previously created VSI list set with
3060                  * the new VSI ID passed in
3061                  */
3062                 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
3063                 opcode = ice_aqc_opc_update_sw_rules;
3064
3065                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
3066                                                   vsi_list_id, false, opcode,
3067                                                   new_fltr->lkup_type);
3068                 /* update VSI list mapping info with new VSI ID */
3069                 if (!status)
3070                         set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
3071         }
3072         if (!status)
3073                 m_entry->vsi_count++;
3074         return status;
3075 }
3076
3077 /**
3078  * ice_find_rule_entry - Search a rule entry
3079  * @hw: pointer to the hardware structure
3080  * @recp_id: lookup type for which the specified rule needs to be searched
3081  * @f_info: rule information
3082  *
3083  * Helper function to search for a given rule entry
3084  * Returns pointer to entry storing the rule if found
3085  */
3086 static struct ice_fltr_mgmt_list_entry *
3087 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
3088 {
3089         struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
3090         struct ice_switch_info *sw = hw->switch_info;
3091         struct list_head *list_head;
3092
3093         list_head = &sw->recp_list[recp_id].filt_rules;
3094         list_for_each_entry(list_itr, list_head, list_entry) {
3095                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
3096                             sizeof(f_info->l_data)) &&
3097                     f_info->flag == list_itr->fltr_info.flag) {
3098                         ret = list_itr;
3099                         break;
3100                 }
3101         }
3102         return ret;
3103 }
3104
3105 /**
3106  * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
3107  * @hw: pointer to the hardware structure
3108  * @recp_id: lookup type for which VSI lists needs to be searched
3109  * @vsi_handle: VSI handle to be found in VSI list
3110  * @vsi_list_id: VSI list ID found containing vsi_handle
3111  *
3112  * Helper function to search a VSI list with single entry containing given VSI
3113  * handle element. This can be extended further to search VSI list with more
3114  * than 1 vsi_count. Returns pointer to VSI list entry if found.
3115  */
3116 struct ice_vsi_list_map_info *
3117 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
3118                         u16 *vsi_list_id)
3119 {
3120         struct ice_vsi_list_map_info *map_info = NULL;
3121         struct ice_switch_info *sw = hw->switch_info;
3122         struct ice_fltr_mgmt_list_entry *list_itr;
3123         struct list_head *list_head;
3124
3125         list_head = &sw->recp_list[recp_id].filt_rules;
3126         list_for_each_entry(list_itr, list_head, list_entry) {
3127                 if (list_itr->vsi_list_info) {
3128                         map_info = list_itr->vsi_list_info;
3129                         if (test_bit(vsi_handle, map_info->vsi_map)) {
3130                                 *vsi_list_id = map_info->vsi_list_id;
3131                                 return map_info;
3132                         }
3133                 }
3134         }
3135         return NULL;
3136 }
3137
3138 /**
3139  * ice_add_rule_internal - add rule for a given lookup type
3140  * @hw: pointer to the hardware structure
3141  * @recp_id: lookup type (recipe ID) for which rule has to be added
3142  * @f_entry: structure containing MAC forwarding information
3143  *
3144  * Adds or updates the rule lists for a given recipe
3145  */
3146 static int
3147 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
3148                       struct ice_fltr_list_entry *f_entry)
3149 {
3150         struct ice_switch_info *sw = hw->switch_info;
3151         struct ice_fltr_info *new_fltr, *cur_fltr;
3152         struct ice_fltr_mgmt_list_entry *m_entry;
3153         struct mutex *rule_lock; /* Lock to protect filter rule list */
3154         int status = 0;
3155
3156         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3157                 return -EINVAL;
3158         f_entry->fltr_info.fwd_id.hw_vsi_id =
3159                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3160
3161         rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3162
3163         mutex_lock(rule_lock);
3164         new_fltr = &f_entry->fltr_info;
3165         if (new_fltr->flag & ICE_FLTR_RX)
3166                 new_fltr->src = hw->port_info->lport;
3167         else if (new_fltr->flag & ICE_FLTR_TX)
3168                 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
3169
3170         m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
3171         if (!m_entry) {
3172                 mutex_unlock(rule_lock);
3173                 return ice_create_pkt_fwd_rule(hw, f_entry);
3174         }
3175
3176         cur_fltr = &m_entry->fltr_info;
3177         status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
3178         mutex_unlock(rule_lock);
3179
3180         return status;
3181 }
3182
3183 /**
3184  * ice_remove_vsi_list_rule
3185  * @hw: pointer to the hardware structure
3186  * @vsi_list_id: VSI list ID generated as part of allocate resource
3187  * @lkup_type: switch rule filter lookup type
3188  *
3189  * The VSI list should be emptied before this function is called to remove the
3190  * VSI list.
3191  */
3192 static int
3193 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
3194                          enum ice_sw_lkup_type lkup_type)
3195 {
3196         struct ice_sw_rule_vsi_list *s_rule;
3197         u16 s_rule_size;
3198         int status;
3199
3200         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0);
3201         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
3202         if (!s_rule)
3203                 return -ENOMEM;
3204
3205         s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
3206         s_rule->index = cpu_to_le16(vsi_list_id);
3207
3208         /* Free the vsi_list resource that we allocated. It is assumed that the
3209          * list is empty at this point.
3210          */
3211         status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
3212                                             ice_aqc_opc_free_res);
3213
3214         devm_kfree(ice_hw_to_dev(hw), s_rule);
3215         return status;
3216 }
3217
3218 /**
3219  * ice_rem_update_vsi_list
3220  * @hw: pointer to the hardware structure
3221  * @vsi_handle: VSI handle of the VSI to remove
3222  * @fm_list: filter management entry for which the VSI list management needs to
3223  *           be done
3224  */
3225 static int
3226 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
3227                         struct ice_fltr_mgmt_list_entry *fm_list)
3228 {
3229         enum ice_sw_lkup_type lkup_type;
3230         u16 vsi_list_id;
3231         int status = 0;
3232
3233         if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
3234             fm_list->vsi_count == 0)
3235                 return -EINVAL;
3236
3237         /* A rule with the VSI being removed does not exist */
3238         if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
3239                 return -ENOENT;
3240
3241         lkup_type = fm_list->fltr_info.lkup_type;
3242         vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
3243         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
3244                                           ice_aqc_opc_update_sw_rules,
3245                                           lkup_type);
3246         if (status)
3247                 return status;
3248
3249         fm_list->vsi_count--;
3250         clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
3251
3252         if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
3253                 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
3254                 struct ice_vsi_list_map_info *vsi_list_info =
3255                         fm_list->vsi_list_info;
3256                 u16 rem_vsi_handle;
3257
3258                 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
3259                                                 ICE_MAX_VSI);
3260                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
3261                         return -EIO;
3262
3263                 /* Make sure VSI list is empty before removing it below */
3264                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
3265                                                   vsi_list_id, true,
3266                                                   ice_aqc_opc_update_sw_rules,
3267                                                   lkup_type);
3268                 if (status)
3269                         return status;
3270
3271                 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
3272                 tmp_fltr_info.fwd_id.hw_vsi_id =
3273                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
3274                 tmp_fltr_info.vsi_handle = rem_vsi_handle;
3275                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
3276                 if (status) {
3277                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
3278                                   tmp_fltr_info.fwd_id.hw_vsi_id, status);
3279                         return status;
3280                 }
3281
3282                 fm_list->fltr_info = tmp_fltr_info;
3283         }
3284
3285         if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
3286             (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
3287                 struct ice_vsi_list_map_info *vsi_list_info =
3288                         fm_list->vsi_list_info;
3289
3290                 /* Remove the VSI list since it is no longer used */
3291                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
3292                 if (status) {
3293                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
3294                                   vsi_list_id, status);
3295                         return status;
3296                 }
3297
3298                 list_del(&vsi_list_info->list_entry);
3299                 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
3300                 fm_list->vsi_list_info = NULL;
3301         }
3302
3303         return status;
3304 }
3305
3306 /**
3307  * ice_remove_rule_internal - Remove a filter rule of a given type
3308  * @hw: pointer to the hardware structure
3309  * @recp_id: recipe ID for which the rule needs to removed
3310  * @f_entry: rule entry containing filter information
3311  */
3312 static int
3313 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
3314                          struct ice_fltr_list_entry *f_entry)
3315 {
3316         struct ice_switch_info *sw = hw->switch_info;
3317         struct ice_fltr_mgmt_list_entry *list_elem;
3318         struct mutex *rule_lock; /* Lock to protect filter rule list */
3319         bool remove_rule = false;
3320         u16 vsi_handle;
3321         int status = 0;
3322
3323         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3324                 return -EINVAL;
3325         f_entry->fltr_info.fwd_id.hw_vsi_id =
3326                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3327
3328         rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3329         mutex_lock(rule_lock);
3330         list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
3331         if (!list_elem) {
3332                 status = -ENOENT;
3333                 goto exit;
3334         }
3335
3336         if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
3337                 remove_rule = true;
3338         } else if (!list_elem->vsi_list_info) {
3339                 status = -ENOENT;
3340                 goto exit;
3341         } else if (list_elem->vsi_list_info->ref_cnt > 1) {
3342                 /* a ref_cnt > 1 indicates that the vsi_list is being
3343                  * shared by multiple rules. Decrement the ref_cnt and
3344                  * remove this rule, but do not modify the list, as it
3345                  * is in-use by other rules.
3346                  */
3347                 list_elem->vsi_list_info->ref_cnt--;
3348                 remove_rule = true;
3349         } else {
3350                 /* a ref_cnt of 1 indicates the vsi_list is only used
3351                  * by one rule. However, the original removal request is only
3352                  * for a single VSI. Update the vsi_list first, and only
3353                  * remove the rule if there are no further VSIs in this list.
3354                  */
3355                 vsi_handle = f_entry->fltr_info.vsi_handle;
3356                 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
3357                 if (status)
3358                         goto exit;
3359                 /* if VSI count goes to zero after updating the VSI list */
3360                 if (list_elem->vsi_count == 0)
3361                         remove_rule = true;
3362         }
3363
3364         if (remove_rule) {
3365                 /* Remove the lookup rule */
3366                 struct ice_sw_rule_lkup_rx_tx *s_rule;
3367
3368                 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
3369                                       ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3370                                       GFP_KERNEL);
3371                 if (!s_rule) {
3372                         status = -ENOMEM;
3373                         goto exit;
3374                 }
3375
3376                 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
3377                                  ice_aqc_opc_remove_sw_rules);
3378
3379                 status = ice_aq_sw_rules(hw, s_rule,
3380                                          ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3381                                          1, ice_aqc_opc_remove_sw_rules, NULL);
3382
3383                 /* Remove a book keeping from the list */
3384                 devm_kfree(ice_hw_to_dev(hw), s_rule);
3385
3386                 if (status)
3387                         goto exit;
3388
3389                 list_del(&list_elem->list_entry);
3390                 devm_kfree(ice_hw_to_dev(hw), list_elem);
3391         }
3392 exit:
3393         mutex_unlock(rule_lock);
3394         return status;
3395 }
3396
3397 /**
3398  * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI
3399  * @hw: pointer to the hardware structure
3400  * @vlan_id: VLAN ID
3401  * @vsi_handle: check MAC filter for this VSI
3402  */
3403 bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
3404 {
3405         struct ice_fltr_mgmt_list_entry *entry;
3406         struct list_head *rule_head;
3407         struct ice_switch_info *sw;
3408         struct mutex *rule_lock; /* Lock to protect filter rule list */
3409         u16 hw_vsi_id;
3410
3411         if (vlan_id > ICE_MAX_VLAN_ID)
3412                 return false;
3413
3414         if (!ice_is_vsi_valid(hw, vsi_handle))
3415                 return false;
3416
3417         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3418         sw = hw->switch_info;
3419         rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
3420         if (!rule_head)
3421                 return false;
3422
3423         rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3424         mutex_lock(rule_lock);
3425         list_for_each_entry(entry, rule_head, list_entry) {
3426                 struct ice_fltr_info *f_info = &entry->fltr_info;
3427                 u16 entry_vlan_id = f_info->l_data.vlan.vlan_id;
3428                 struct ice_vsi_list_map_info *map_info;
3429
3430                 if (entry_vlan_id > ICE_MAX_VLAN_ID)
3431                         continue;
3432
3433                 if (f_info->flag != ICE_FLTR_TX ||
3434                     f_info->src_id != ICE_SRC_ID_VSI ||
3435                     f_info->lkup_type != ICE_SW_LKUP_VLAN)
3436                         continue;
3437
3438                 /* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */
3439                 if (f_info->fltr_act != ICE_FWD_TO_VSI &&
3440                     f_info->fltr_act != ICE_FWD_TO_VSI_LIST)
3441                         continue;
3442
3443                 if (f_info->fltr_act == ICE_FWD_TO_VSI) {
3444                         if (hw_vsi_id != f_info->fwd_id.hw_vsi_id)
3445                                 continue;
3446                 } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3447                         /* If filter_action is FWD_TO_VSI_LIST, make sure
3448                          * that VSI being checked is part of VSI list
3449                          */
3450                         if (entry->vsi_count == 1 &&
3451                             entry->vsi_list_info) {
3452                                 map_info = entry->vsi_list_info;
3453                                 if (!test_bit(vsi_handle, map_info->vsi_map))
3454                                         continue;
3455                         }
3456                 }
3457
3458                 if (vlan_id == entry_vlan_id) {
3459                         mutex_unlock(rule_lock);
3460                         return true;
3461                 }
3462         }
3463         mutex_unlock(rule_lock);
3464
3465         return false;
3466 }
3467
3468 /**
3469  * ice_add_mac - Add a MAC address based filter rule
3470  * @hw: pointer to the hardware structure
3471  * @m_list: list of MAC addresses and forwarding information
3472  */
3473 int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
3474 {
3475         struct ice_fltr_list_entry *m_list_itr;
3476         int status = 0;
3477
3478         if (!m_list || !hw)
3479                 return -EINVAL;
3480
3481         list_for_each_entry(m_list_itr, m_list, list_entry) {
3482                 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
3483                 u16 vsi_handle;
3484                 u16 hw_vsi_id;
3485
3486                 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
3487                 vsi_handle = m_list_itr->fltr_info.vsi_handle;
3488                 if (!ice_is_vsi_valid(hw, vsi_handle))
3489                         return -EINVAL;
3490                 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3491                 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
3492                 /* update the src in case it is VSI num */
3493                 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
3494                         return -EINVAL;
3495                 m_list_itr->fltr_info.src = hw_vsi_id;
3496                 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
3497                     is_zero_ether_addr(add))
3498                         return -EINVAL;
3499
3500                 m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
3501                                                            m_list_itr);
3502                 if (m_list_itr->status)
3503                         return m_list_itr->status;
3504         }
3505
3506         return status;
3507 }
3508
3509 /**
3510  * ice_add_vlan_internal - Add one VLAN based filter rule
3511  * @hw: pointer to the hardware structure
3512  * @f_entry: filter entry containing one VLAN information
3513  */
3514 static int
3515 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
3516 {
3517         struct ice_switch_info *sw = hw->switch_info;
3518         struct ice_fltr_mgmt_list_entry *v_list_itr;
3519         struct ice_fltr_info *new_fltr, *cur_fltr;
3520         enum ice_sw_lkup_type lkup_type;
3521         u16 vsi_list_id = 0, vsi_handle;
3522         struct mutex *rule_lock; /* Lock to protect filter rule list */
3523         int status = 0;
3524
3525         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3526                 return -EINVAL;
3527
3528         f_entry->fltr_info.fwd_id.hw_vsi_id =
3529                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3530         new_fltr = &f_entry->fltr_info;
3531
3532         /* VLAN ID should only be 12 bits */
3533         if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
3534                 return -EINVAL;
3535
3536         if (new_fltr->src_id != ICE_SRC_ID_VSI)
3537                 return -EINVAL;
3538
3539         new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
3540         lkup_type = new_fltr->lkup_type;
3541         vsi_handle = new_fltr->vsi_handle;
3542         rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3543         mutex_lock(rule_lock);
3544         v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
3545         if (!v_list_itr) {
3546                 struct ice_vsi_list_map_info *map_info = NULL;
3547
3548                 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
3549                         /* All VLAN pruning rules use a VSI list. Check if
3550                          * there is already a VSI list containing VSI that we
3551                          * want to add. If found, use the same vsi_list_id for
3552                          * this new VLAN rule or else create a new list.
3553                          */
3554                         map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
3555                                                            vsi_handle,
3556                                                            &vsi_list_id);
3557                         if (!map_info) {
3558                                 status = ice_create_vsi_list_rule(hw,
3559                                                                   &vsi_handle,
3560                                                                   1,
3561                                                                   &vsi_list_id,
3562                                                                   lkup_type);
3563                                 if (status)
3564                                         goto exit;
3565                         }
3566                         /* Convert the action to forwarding to a VSI list. */
3567                         new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3568                         new_fltr->fwd_id.vsi_list_id = vsi_list_id;
3569                 }
3570
3571                 status = ice_create_pkt_fwd_rule(hw, f_entry);
3572                 if (!status) {
3573                         v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
3574                                                          new_fltr);
3575                         if (!v_list_itr) {
3576                                 status = -ENOENT;
3577                                 goto exit;
3578                         }
3579                         /* reuse VSI list for new rule and increment ref_cnt */
3580                         if (map_info) {
3581                                 v_list_itr->vsi_list_info = map_info;
3582                                 map_info->ref_cnt++;
3583                         } else {
3584                                 v_list_itr->vsi_list_info =
3585                                         ice_create_vsi_list_map(hw, &vsi_handle,
3586                                                                 1, vsi_list_id);
3587                         }
3588                 }
3589         } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
3590                 /* Update existing VSI list to add new VSI ID only if it used
3591                  * by one VLAN rule.
3592                  */
3593                 cur_fltr = &v_list_itr->fltr_info;
3594                 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
3595                                                  new_fltr);
3596         } else {
3597                 /* If VLAN rule exists and VSI list being used by this rule is
3598                  * referenced by more than 1 VLAN rule. Then create a new VSI
3599                  * list appending previous VSI with new VSI and update existing
3600                  * VLAN rule to point to new VSI list ID
3601                  */
3602                 struct ice_fltr_info tmp_fltr;
3603                 u16 vsi_handle_arr[2];
3604                 u16 cur_handle;
3605
3606                 /* Current implementation only supports reusing VSI list with
3607                  * one VSI count. We should never hit below condition
3608                  */
3609                 if (v_list_itr->vsi_count > 1 &&
3610                     v_list_itr->vsi_list_info->ref_cnt > 1) {
3611                         ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
3612                         status = -EIO;
3613                         goto exit;
3614                 }
3615
3616                 cur_handle =
3617                         find_first_bit(v_list_itr->vsi_list_info->vsi_map,
3618                                        ICE_MAX_VSI);
3619
3620                 /* A rule already exists with the new VSI being added */
3621                 if (cur_handle == vsi_handle) {
3622                         status = -EEXIST;
3623                         goto exit;
3624                 }
3625
3626                 vsi_handle_arr[0] = cur_handle;
3627                 vsi_handle_arr[1] = vsi_handle;
3628                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3629                                                   &vsi_list_id, lkup_type);
3630                 if (status)
3631                         goto exit;
3632
3633                 tmp_fltr = v_list_itr->fltr_info;
3634                 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
3635                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3636                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3637                 /* Update the previous switch rule to a new VSI list which
3638                  * includes current VSI that is requested
3639                  */
3640                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3641                 if (status)
3642                         goto exit;
3643
3644                 /* before overriding VSI list map info. decrement ref_cnt of
3645                  * previous VSI list
3646                  */
3647                 v_list_itr->vsi_list_info->ref_cnt--;
3648
3649                 /* now update to newly created list */
3650                 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
3651                 v_list_itr->vsi_list_info =
3652                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3653                                                 vsi_list_id);
3654                 v_list_itr->vsi_count++;
3655         }
3656
3657 exit:
3658         mutex_unlock(rule_lock);
3659         return status;
3660 }
3661
3662 /**
3663  * ice_add_vlan - Add VLAN based filter rule
3664  * @hw: pointer to the hardware structure
3665  * @v_list: list of VLAN entries and forwarding information
3666  */
3667 int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
3668 {
3669         struct ice_fltr_list_entry *v_list_itr;
3670
3671         if (!v_list || !hw)
3672                 return -EINVAL;
3673
3674         list_for_each_entry(v_list_itr, v_list, list_entry) {
3675                 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
3676                         return -EINVAL;
3677                 v_list_itr->fltr_info.flag = ICE_FLTR_TX;
3678                 v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
3679                 if (v_list_itr->status)
3680                         return v_list_itr->status;
3681         }
3682         return 0;
3683 }
3684
3685 /**
3686  * ice_add_eth_mac - Add ethertype and MAC based filter rule
3687  * @hw: pointer to the hardware structure
3688  * @em_list: list of ether type MAC filter, MAC is optional
3689  *
3690  * This function requires the caller to populate the entries in
3691  * the filter list with the necessary fields (including flags to
3692  * indicate Tx or Rx rules).
3693  */
3694 int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3695 {
3696         struct ice_fltr_list_entry *em_list_itr;
3697
3698         if (!em_list || !hw)
3699                 return -EINVAL;
3700
3701         list_for_each_entry(em_list_itr, em_list, list_entry) {
3702                 enum ice_sw_lkup_type l_type =
3703                         em_list_itr->fltr_info.lkup_type;
3704
3705                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3706                     l_type != ICE_SW_LKUP_ETHERTYPE)
3707                         return -EINVAL;
3708
3709                 em_list_itr->status = ice_add_rule_internal(hw, l_type,
3710                                                             em_list_itr);
3711                 if (em_list_itr->status)
3712                         return em_list_itr->status;
3713         }
3714         return 0;
3715 }
3716
3717 /**
3718  * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule
3719  * @hw: pointer to the hardware structure
3720  * @em_list: list of ethertype or ethertype MAC entries
3721  */
3722 int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3723 {
3724         struct ice_fltr_list_entry *em_list_itr, *tmp;
3725
3726         if (!em_list || !hw)
3727                 return -EINVAL;
3728
3729         list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
3730                 enum ice_sw_lkup_type l_type =
3731                         em_list_itr->fltr_info.lkup_type;
3732
3733                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3734                     l_type != ICE_SW_LKUP_ETHERTYPE)
3735                         return -EINVAL;
3736
3737                 em_list_itr->status = ice_remove_rule_internal(hw, l_type,
3738                                                                em_list_itr);
3739                 if (em_list_itr->status)
3740                         return em_list_itr->status;
3741         }
3742         return 0;
3743 }
3744
3745 /**
3746  * ice_rem_sw_rule_info
3747  * @hw: pointer to the hardware structure
3748  * @rule_head: pointer to the switch list structure that we want to delete
3749  */
3750 static void
3751 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3752 {
3753         if (!list_empty(rule_head)) {
3754                 struct ice_fltr_mgmt_list_entry *entry;
3755                 struct ice_fltr_mgmt_list_entry *tmp;
3756
3757                 list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
3758                         list_del(&entry->list_entry);
3759                         devm_kfree(ice_hw_to_dev(hw), entry);
3760                 }
3761         }
3762 }
3763
3764 /**
3765  * ice_rem_adv_rule_info
3766  * @hw: pointer to the hardware structure
3767  * @rule_head: pointer to the switch list structure that we want to delete
3768  */
3769 static void
3770 ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3771 {
3772         struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
3773         struct ice_adv_fltr_mgmt_list_entry *lst_itr;
3774
3775         if (list_empty(rule_head))
3776                 return;
3777
3778         list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) {
3779                 list_del(&lst_itr->list_entry);
3780                 devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
3781                 devm_kfree(ice_hw_to_dev(hw), lst_itr);
3782         }
3783 }
3784
3785 /**
3786  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
3787  * @pi: pointer to the port_info structure
3788  * @vsi_handle: VSI handle to set as default
3789  * @set: true to add the above mentioned switch rule, false to remove it
3790  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
3791  *
3792  * add filter rule to set/unset given VSI as default VSI for the switch
3793  * (represented by swid)
3794  */
3795 int
3796 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
3797                  u8 direction)
3798 {
3799         struct ice_fltr_list_entry f_list_entry;
3800         struct ice_fltr_info f_info;
3801         struct ice_hw *hw = pi->hw;
3802         u16 hw_vsi_id;
3803         int status;
3804
3805         if (!ice_is_vsi_valid(hw, vsi_handle))
3806                 return -EINVAL;
3807
3808         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3809
3810         memset(&f_info, 0, sizeof(f_info));
3811
3812         f_info.lkup_type = ICE_SW_LKUP_DFLT;
3813         f_info.flag = direction;
3814         f_info.fltr_act = ICE_FWD_TO_VSI;
3815         f_info.fwd_id.hw_vsi_id = hw_vsi_id;
3816         f_info.vsi_handle = vsi_handle;
3817
3818         if (f_info.flag & ICE_FLTR_RX) {
3819                 f_info.src = hw->port_info->lport;
3820                 f_info.src_id = ICE_SRC_ID_LPORT;
3821         } else if (f_info.flag & ICE_FLTR_TX) {
3822                 f_info.src_id = ICE_SRC_ID_VSI;
3823                 f_info.src = hw_vsi_id;
3824         }
3825         f_list_entry.fltr_info = f_info;
3826
3827         if (set)
3828                 status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT,
3829                                                &f_list_entry);
3830         else
3831                 status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT,
3832                                                   &f_list_entry);
3833
3834         return status;
3835 }
3836
3837 /**
3838  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
3839  * @fm_entry: filter entry to inspect
3840  * @vsi_handle: VSI handle to compare with filter info
3841  */
3842 static bool
3843 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
3844 {
3845         return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
3846                  fm_entry->fltr_info.vsi_handle == vsi_handle) ||
3847                 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
3848                  fm_entry->vsi_list_info &&
3849                  (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
3850 }
3851
3852 /**
3853  * ice_check_if_dflt_vsi - check if VSI is default VSI
3854  * @pi: pointer to the port_info structure
3855  * @vsi_handle: vsi handle to check for in filter list
3856  * @rule_exists: indicates if there are any VSI's in the rule list
3857  *
3858  * checks if the VSI is in a default VSI list, and also indicates
3859  * if the default VSI list is empty
3860  */
3861 bool
3862 ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
3863                       bool *rule_exists)
3864 {
3865         struct ice_fltr_mgmt_list_entry *fm_entry;
3866         struct ice_sw_recipe *recp_list;
3867         struct list_head *rule_head;
3868         struct mutex *rule_lock; /* Lock to protect filter rule list */
3869         bool ret = false;
3870
3871         recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
3872         rule_lock = &recp_list->filt_rule_lock;
3873         rule_head = &recp_list->filt_rules;
3874
3875         mutex_lock(rule_lock);
3876
3877         if (rule_exists && !list_empty(rule_head))
3878                 *rule_exists = true;
3879
3880         list_for_each_entry(fm_entry, rule_head, list_entry) {
3881                 if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
3882                         ret = true;
3883                         break;
3884                 }
3885         }
3886
3887         mutex_unlock(rule_lock);
3888
3889         return ret;
3890 }
3891
3892 /**
3893  * ice_remove_mac - remove a MAC address based filter rule
3894  * @hw: pointer to the hardware structure
3895  * @m_list: list of MAC addresses and forwarding information
3896  *
3897  * This function removes either a MAC filter rule or a specific VSI from a
3898  * VSI list for a multicast MAC address.
3899  *
3900  * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should
3901  * be aware that this call will only work if all the entries passed into m_list
3902  * were added previously. It will not attempt to do a partial remove of entries
3903  * that were found.
3904  */
3905 int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
3906 {
3907         struct ice_fltr_list_entry *list_itr, *tmp;
3908
3909         if (!m_list)
3910                 return -EINVAL;
3911
3912         list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
3913                 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
3914                 u16 vsi_handle;
3915
3916                 if (l_type != ICE_SW_LKUP_MAC)
3917                         return -EINVAL;
3918
3919                 vsi_handle = list_itr->fltr_info.vsi_handle;
3920                 if (!ice_is_vsi_valid(hw, vsi_handle))
3921                         return -EINVAL;
3922
3923                 list_itr->fltr_info.fwd_id.hw_vsi_id =
3924                                         ice_get_hw_vsi_num(hw, vsi_handle);
3925
3926                 list_itr->status = ice_remove_rule_internal(hw,
3927                                                             ICE_SW_LKUP_MAC,
3928                                                             list_itr);
3929                 if (list_itr->status)
3930                         return list_itr->status;
3931         }
3932         return 0;
3933 }
3934
3935 /**
3936  * ice_remove_vlan - Remove VLAN based filter rule
3937  * @hw: pointer to the hardware structure
3938  * @v_list: list of VLAN entries and forwarding information
3939  */
3940 int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
3941 {
3942         struct ice_fltr_list_entry *v_list_itr, *tmp;
3943
3944         if (!v_list || !hw)
3945                 return -EINVAL;
3946
3947         list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
3948                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
3949
3950                 if (l_type != ICE_SW_LKUP_VLAN)
3951                         return -EINVAL;
3952                 v_list_itr->status = ice_remove_rule_internal(hw,
3953                                                               ICE_SW_LKUP_VLAN,
3954                                                               v_list_itr);
3955                 if (v_list_itr->status)
3956                         return v_list_itr->status;
3957         }
3958         return 0;
3959 }
3960
3961 /**
3962  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
3963  * @hw: pointer to the hardware structure
3964  * @vsi_handle: VSI handle to remove filters from
3965  * @vsi_list_head: pointer to the list to add entry to
3966  * @fi: pointer to fltr_info of filter entry to copy & add
3967  *
3968  * Helper function, used when creating a list of filters to remove from
3969  * a specific VSI. The entry added to vsi_list_head is a COPY of the
3970  * original filter entry, with the exception of fltr_info.fltr_act and
3971  * fltr_info.fwd_id fields. These are set such that later logic can
3972  * extract which VSI to remove the fltr from, and pass on that information.
3973  */
3974 static int
3975 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
3976                                struct list_head *vsi_list_head,
3977                                struct ice_fltr_info *fi)
3978 {
3979         struct ice_fltr_list_entry *tmp;
3980
3981         /* this memory is freed up in the caller function
3982          * once filters for this VSI are removed
3983          */
3984         tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
3985         if (!tmp)
3986                 return -ENOMEM;
3987
3988         tmp->fltr_info = *fi;
3989
3990         /* Overwrite these fields to indicate which VSI to remove filter from,
3991          * so find and remove logic can extract the information from the
3992          * list entries. Note that original entries will still have proper
3993          * values.
3994          */
3995         tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
3996         tmp->fltr_info.vsi_handle = vsi_handle;
3997         tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3998
3999         list_add(&tmp->list_entry, vsi_list_head);
4000
4001         return 0;
4002 }
4003
4004 /**
4005  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
4006  * @hw: pointer to the hardware structure
4007  * @vsi_handle: VSI handle to remove filters from
4008  * @lkup_list_head: pointer to the list that has certain lookup type filters
4009  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
4010  *
4011  * Locates all filters in lkup_list_head that are used by the given VSI,
4012  * and adds COPIES of those entries to vsi_list_head (intended to be used
4013  * to remove the listed filters).
4014  * Note that this means all entries in vsi_list_head must be explicitly
4015  * deallocated by the caller when done with list.
4016  */
4017 static int
4018 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
4019                          struct list_head *lkup_list_head,
4020                          struct list_head *vsi_list_head)
4021 {
4022         struct ice_fltr_mgmt_list_entry *fm_entry;
4023         int status = 0;
4024
4025         /* check to make sure VSI ID is valid and within boundary */
4026         if (!ice_is_vsi_valid(hw, vsi_handle))
4027                 return -EINVAL;
4028
4029         list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
4030                 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
4031                         continue;
4032
4033                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4034                                                         vsi_list_head,
4035                                                         &fm_entry->fltr_info);
4036                 if (status)
4037                         return status;
4038         }
4039         return status;
4040 }
4041
4042 /**
4043  * ice_determine_promisc_mask
4044  * @fi: filter info to parse
4045  *
4046  * Helper function to determine which ICE_PROMISC_ mask corresponds
4047  * to given filter into.
4048  */
4049 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
4050 {
4051         u16 vid = fi->l_data.mac_vlan.vlan_id;
4052         u8 *macaddr = fi->l_data.mac.mac_addr;
4053         bool is_tx_fltr = false;
4054         u8 promisc_mask = 0;
4055
4056         if (fi->flag == ICE_FLTR_TX)
4057                 is_tx_fltr = true;
4058
4059         if (is_broadcast_ether_addr(macaddr))
4060                 promisc_mask |= is_tx_fltr ?
4061                         ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
4062         else if (is_multicast_ether_addr(macaddr))
4063                 promisc_mask |= is_tx_fltr ?
4064                         ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
4065         else if (is_unicast_ether_addr(macaddr))
4066                 promisc_mask |= is_tx_fltr ?
4067                         ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
4068         if (vid)
4069                 promisc_mask |= is_tx_fltr ?
4070                         ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
4071
4072         return promisc_mask;
4073 }
4074
4075 /**
4076  * ice_remove_promisc - Remove promisc based filter rules
4077  * @hw: pointer to the hardware structure
4078  * @recp_id: recipe ID for which the rule needs to removed
4079  * @v_list: list of promisc entries
4080  */
4081 static int
4082 ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list)
4083 {
4084         struct ice_fltr_list_entry *v_list_itr, *tmp;
4085
4086         list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
4087                 v_list_itr->status =
4088                         ice_remove_rule_internal(hw, recp_id, v_list_itr);
4089                 if (v_list_itr->status)
4090                         return v_list_itr->status;
4091         }
4092         return 0;
4093 }
4094
4095 /**
4096  * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
4097  * @hw: pointer to the hardware structure
4098  * @vsi_handle: VSI handle to clear mode
4099  * @promisc_mask: mask of promiscuous config bits to clear
4100  * @vid: VLAN ID to clear VLAN promiscuous
4101  */
4102 int
4103 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4104                       u16 vid)
4105 {
4106         struct ice_switch_info *sw = hw->switch_info;
4107         struct ice_fltr_list_entry *fm_entry, *tmp;
4108         struct list_head remove_list_head;
4109         struct ice_fltr_mgmt_list_entry *itr;
4110         struct list_head *rule_head;
4111         struct mutex *rule_lock;        /* Lock to protect filter rule list */
4112         int status = 0;
4113         u8 recipe_id;
4114
4115         if (!ice_is_vsi_valid(hw, vsi_handle))
4116                 return -EINVAL;
4117
4118         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
4119                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4120         else
4121                 recipe_id = ICE_SW_LKUP_PROMISC;
4122
4123         rule_head = &sw->recp_list[recipe_id].filt_rules;
4124         rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
4125
4126         INIT_LIST_HEAD(&remove_list_head);
4127
4128         mutex_lock(rule_lock);
4129         list_for_each_entry(itr, rule_head, list_entry) {
4130                 struct ice_fltr_info *fltr_info;
4131                 u8 fltr_promisc_mask = 0;
4132
4133                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
4134                         continue;
4135                 fltr_info = &itr->fltr_info;
4136
4137                 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
4138                     vid != fltr_info->l_data.mac_vlan.vlan_id)
4139                         continue;
4140
4141                 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
4142
4143                 /* Skip if filter is not completely specified by given mask */
4144                 if (fltr_promisc_mask & ~promisc_mask)
4145                         continue;
4146
4147                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4148                                                         &remove_list_head,
4149                                                         fltr_info);
4150                 if (status) {
4151                         mutex_unlock(rule_lock);
4152                         goto free_fltr_list;
4153                 }
4154         }
4155         mutex_unlock(rule_lock);
4156
4157         status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
4158
4159 free_fltr_list:
4160         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4161                 list_del(&fm_entry->list_entry);
4162                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4163         }
4164
4165         return status;
4166 }
4167
4168 /**
4169  * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
4170  * @hw: pointer to the hardware structure
4171  * @vsi_handle: VSI handle to configure
4172  * @promisc_mask: mask of promiscuous config bits
4173  * @vid: VLAN ID to set VLAN promiscuous
4174  */
4175 int
4176 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
4177 {
4178         enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
4179         struct ice_fltr_list_entry f_list_entry;
4180         struct ice_fltr_info new_fltr;
4181         bool is_tx_fltr;
4182         int status = 0;
4183         u16 hw_vsi_id;
4184         int pkt_type;
4185         u8 recipe_id;
4186
4187         if (!ice_is_vsi_valid(hw, vsi_handle))
4188                 return -EINVAL;
4189         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4190
4191         memset(&new_fltr, 0, sizeof(new_fltr));
4192
4193         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
4194                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
4195                 new_fltr.l_data.mac_vlan.vlan_id = vid;
4196                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4197         } else {
4198                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
4199                 recipe_id = ICE_SW_LKUP_PROMISC;
4200         }
4201
4202         /* Separate filters must be set for each direction/packet type
4203          * combination, so we will loop over the mask value, store the
4204          * individual type, and clear it out in the input mask as it
4205          * is found.
4206          */
4207         while (promisc_mask) {
4208                 u8 *mac_addr;
4209
4210                 pkt_type = 0;
4211                 is_tx_fltr = false;
4212
4213                 if (promisc_mask & ICE_PROMISC_UCAST_RX) {
4214                         promisc_mask &= ~ICE_PROMISC_UCAST_RX;
4215                         pkt_type = UCAST_FLTR;
4216                 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
4217                         promisc_mask &= ~ICE_PROMISC_UCAST_TX;
4218                         pkt_type = UCAST_FLTR;
4219                         is_tx_fltr = true;
4220                 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
4221                         promisc_mask &= ~ICE_PROMISC_MCAST_RX;
4222                         pkt_type = MCAST_FLTR;
4223                 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
4224                         promisc_mask &= ~ICE_PROMISC_MCAST_TX;
4225                         pkt_type = MCAST_FLTR;
4226                         is_tx_fltr = true;
4227                 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
4228                         promisc_mask &= ~ICE_PROMISC_BCAST_RX;
4229                         pkt_type = BCAST_FLTR;
4230                 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
4231                         promisc_mask &= ~ICE_PROMISC_BCAST_TX;
4232                         pkt_type = BCAST_FLTR;
4233                         is_tx_fltr = true;
4234                 }
4235
4236                 /* Check for VLAN promiscuous flag */
4237                 if (promisc_mask & ICE_PROMISC_VLAN_RX) {
4238                         promisc_mask &= ~ICE_PROMISC_VLAN_RX;
4239                 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
4240                         promisc_mask &= ~ICE_PROMISC_VLAN_TX;
4241                         is_tx_fltr = true;
4242                 }
4243
4244                 /* Set filter DA based on packet type */
4245                 mac_addr = new_fltr.l_data.mac.mac_addr;
4246                 if (pkt_type == BCAST_FLTR) {
4247                         eth_broadcast_addr(mac_addr);
4248                 } else if (pkt_type == MCAST_FLTR ||
4249                            pkt_type == UCAST_FLTR) {
4250                         /* Use the dummy ether header DA */
4251                         ether_addr_copy(mac_addr, dummy_eth_header);
4252                         if (pkt_type == MCAST_FLTR)
4253                                 mac_addr[0] |= 0x1;     /* Set multicast bit */
4254                 }
4255
4256                 /* Need to reset this to zero for all iterations */
4257                 new_fltr.flag = 0;
4258                 if (is_tx_fltr) {
4259                         new_fltr.flag |= ICE_FLTR_TX;
4260                         new_fltr.src = hw_vsi_id;
4261                 } else {
4262                         new_fltr.flag |= ICE_FLTR_RX;
4263                         new_fltr.src = hw->port_info->lport;
4264                 }
4265
4266                 new_fltr.fltr_act = ICE_FWD_TO_VSI;
4267                 new_fltr.vsi_handle = vsi_handle;
4268                 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
4269                 f_list_entry.fltr_info = new_fltr;
4270
4271                 status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
4272                 if (status)
4273                         goto set_promisc_exit;
4274         }
4275
4276 set_promisc_exit:
4277         return status;
4278 }
4279
4280 /**
4281  * ice_set_vlan_vsi_promisc
4282  * @hw: pointer to the hardware structure
4283  * @vsi_handle: VSI handle to configure
4284  * @promisc_mask: mask of promiscuous config bits
4285  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
4286  *
4287  * Configure VSI with all associated VLANs to given promiscuous mode(s)
4288  */
4289 int
4290 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4291                          bool rm_vlan_promisc)
4292 {
4293         struct ice_switch_info *sw = hw->switch_info;
4294         struct ice_fltr_list_entry *list_itr, *tmp;
4295         struct list_head vsi_list_head;
4296         struct list_head *vlan_head;
4297         struct mutex *vlan_lock; /* Lock to protect filter rule list */
4298         u16 vlan_id;
4299         int status;
4300
4301         INIT_LIST_HEAD(&vsi_list_head);
4302         vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
4303         vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
4304         mutex_lock(vlan_lock);
4305         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
4306                                           &vsi_list_head);
4307         mutex_unlock(vlan_lock);
4308         if (status)
4309                 goto free_fltr_list;
4310
4311         list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
4312                 /* Avoid enabling or disabling VLAN zero twice when in double
4313                  * VLAN mode
4314                  */
4315                 if (ice_is_dvm_ena(hw) &&
4316                     list_itr->fltr_info.l_data.vlan.tpid == 0)
4317                         continue;
4318
4319                 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
4320                 if (rm_vlan_promisc)
4321                         status = ice_clear_vsi_promisc(hw, vsi_handle,
4322                                                        promisc_mask, vlan_id);
4323                 else
4324                         status = ice_set_vsi_promisc(hw, vsi_handle,
4325                                                      promisc_mask, vlan_id);
4326                 if (status && status != -EEXIST)
4327                         break;
4328         }
4329
4330 free_fltr_list:
4331         list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
4332                 list_del(&list_itr->list_entry);
4333                 devm_kfree(ice_hw_to_dev(hw), list_itr);
4334         }
4335         return status;
4336 }
4337
4338 /**
4339  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
4340  * @hw: pointer to the hardware structure
4341  * @vsi_handle: VSI handle to remove filters from
4342  * @lkup: switch rule filter lookup type
4343  */
4344 static void
4345 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
4346                          enum ice_sw_lkup_type lkup)
4347 {
4348         struct ice_switch_info *sw = hw->switch_info;
4349         struct ice_fltr_list_entry *fm_entry;
4350         struct list_head remove_list_head;
4351         struct list_head *rule_head;
4352         struct ice_fltr_list_entry *tmp;
4353         struct mutex *rule_lock;        /* Lock to protect filter rule list */
4354         int status;
4355
4356         INIT_LIST_HEAD(&remove_list_head);
4357         rule_lock = &sw->recp_list[lkup].filt_rule_lock;
4358         rule_head = &sw->recp_list[lkup].filt_rules;
4359         mutex_lock(rule_lock);
4360         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
4361                                           &remove_list_head);
4362         mutex_unlock(rule_lock);
4363         if (status)
4364                 goto free_fltr_list;
4365
4366         switch (lkup) {
4367         case ICE_SW_LKUP_MAC:
4368                 ice_remove_mac(hw, &remove_list_head);
4369                 break;
4370         case ICE_SW_LKUP_VLAN:
4371                 ice_remove_vlan(hw, &remove_list_head);
4372                 break;
4373         case ICE_SW_LKUP_PROMISC:
4374         case ICE_SW_LKUP_PROMISC_VLAN:
4375                 ice_remove_promisc(hw, lkup, &remove_list_head);
4376                 break;
4377         case ICE_SW_LKUP_MAC_VLAN:
4378         case ICE_SW_LKUP_ETHERTYPE:
4379         case ICE_SW_LKUP_ETHERTYPE_MAC:
4380         case ICE_SW_LKUP_DFLT:
4381         case ICE_SW_LKUP_LAST:
4382         default:
4383                 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
4384                 break;
4385         }
4386
4387 free_fltr_list:
4388         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4389                 list_del(&fm_entry->list_entry);
4390                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4391         }
4392 }
4393
4394 /**
4395  * ice_remove_vsi_fltr - Remove all filters for a VSI
4396  * @hw: pointer to the hardware structure
4397  * @vsi_handle: VSI handle to remove filters from
4398  */
4399 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
4400 {
4401         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
4402         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
4403         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
4404         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
4405         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
4406         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
4407         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
4408         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
4409 }
4410
4411 /**
4412  * ice_alloc_res_cntr - allocating resource counter
4413  * @hw: pointer to the hardware structure
4414  * @type: type of resource
4415  * @alloc_shared: if set it is shared else dedicated
4416  * @num_items: number of entries requested for FD resource type
4417  * @counter_id: counter index returned by AQ call
4418  */
4419 int
4420 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4421                    u16 *counter_id)
4422 {
4423         DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4424         u16 buf_len = __struct_size(buf);
4425         int status;
4426
4427         buf->num_elems = cpu_to_le16(num_items);
4428         buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
4429                                     alloc_shared);
4430
4431         status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_alloc_res);
4432         if (status)
4433                 return status;
4434
4435         *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
4436         return status;
4437 }
4438
4439 /**
4440  * ice_free_res_cntr - free resource counter
4441  * @hw: pointer to the hardware structure
4442  * @type: type of resource
4443  * @alloc_shared: if set it is shared else dedicated
4444  * @num_items: number of entries to be freed for FD resource type
4445  * @counter_id: counter ID resource which needs to be freed
4446  */
4447 int
4448 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4449                   u16 counter_id)
4450 {
4451         DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4452         u16 buf_len = __struct_size(buf);
4453         int status;
4454
4455         buf->num_elems = cpu_to_le16(num_items);
4456         buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
4457                                     alloc_shared);
4458         buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
4459
4460         status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_free_res);
4461         if (status)
4462                 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
4463
4464         return status;
4465 }
4466
4467 #define ICE_PROTOCOL_ENTRY(id, ...) {           \
4468         .prot_type      = id,                   \
4469         .offs           = {__VA_ARGS__},        \
4470 }
4471
4472 /**
4473  * ice_share_res - set a resource as shared or dedicated
4474  * @hw: hw struct of original owner of resource
4475  * @type: resource type
4476  * @shared: is the resource being set to shared
4477  * @res_id: resource id (descriptor)
4478  */
4479 int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id)
4480 {
4481         DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4482         u16 buf_len = __struct_size(buf);
4483         u16 res_type;
4484         int status;
4485
4486         buf->num_elems = cpu_to_le16(1);
4487         res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, type);
4488         if (shared)
4489                 res_type |= ICE_AQC_RES_TYPE_FLAG_SHARED;
4490
4491         buf->res_type = cpu_to_le16(res_type);
4492         buf->elem[0].e.sw_resp = cpu_to_le16(res_id);
4493         status = ice_aq_alloc_free_res(hw, buf, buf_len,
4494                                        ice_aqc_opc_share_res);
4495         if (status)
4496                 ice_debug(hw, ICE_DBG_SW, "Could not set resource type %u id %u to %s\n",
4497                           type, res_id, shared ? "SHARED" : "DEDICATED");
4498
4499         return status;
4500 }
4501
4502 /* This is mapping table entry that maps every word within a given protocol
4503  * structure to the real byte offset as per the specification of that
4504  * protocol header.
4505  * for example dst address is 3 words in ethertype header and corresponding
4506  * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
4507  * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
4508  * matching entry describing its field. This needs to be updated if new
4509  * structure is added to that union.
4510  */
4511 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
4512         ICE_PROTOCOL_ENTRY(ICE_MAC_OFOS, 0, 2, 4, 6, 8, 10, 12),
4513         ICE_PROTOCOL_ENTRY(ICE_MAC_IL, 0, 2, 4, 6, 8, 10, 12),
4514         ICE_PROTOCOL_ENTRY(ICE_ETYPE_OL, 0),
4515         ICE_PROTOCOL_ENTRY(ICE_ETYPE_IL, 0),
4516         ICE_PROTOCOL_ENTRY(ICE_VLAN_OFOS, 2, 0),
4517         ICE_PROTOCOL_ENTRY(ICE_IPV4_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
4518         ICE_PROTOCOL_ENTRY(ICE_IPV4_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
4519         ICE_PROTOCOL_ENTRY(ICE_IPV6_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
4520                            20, 22, 24, 26, 28, 30, 32, 34, 36, 38),
4521         ICE_PROTOCOL_ENTRY(ICE_IPV6_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
4522                            22, 24, 26, 28, 30, 32, 34, 36, 38),
4523         ICE_PROTOCOL_ENTRY(ICE_TCP_IL, 0, 2),
4524         ICE_PROTOCOL_ENTRY(ICE_UDP_OF, 0, 2),
4525         ICE_PROTOCOL_ENTRY(ICE_UDP_ILOS, 0, 2),
4526         ICE_PROTOCOL_ENTRY(ICE_VXLAN, 8, 10, 12, 14),
4527         ICE_PROTOCOL_ENTRY(ICE_GENEVE, 8, 10, 12, 14),
4528         ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6),
4529         ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22),
4530         ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14),
4531         ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6),
4532         ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10),
4533         ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0),
4534         ICE_PROTOCOL_ENTRY(ICE_VLAN_IN, 2, 0),
4535         ICE_PROTOCOL_ENTRY(ICE_HW_METADATA,
4536                            ICE_SOURCE_PORT_MDID_OFFSET,
4537                            ICE_PTYPE_MDID_OFFSET,
4538                            ICE_PACKET_LENGTH_MDID_OFFSET,
4539                            ICE_SOURCE_VSI_MDID_OFFSET,
4540                            ICE_PKT_VLAN_MDID_OFFSET,
4541                            ICE_PKT_TUNNEL_MDID_OFFSET,
4542                            ICE_PKT_TCP_MDID_OFFSET,
4543                            ICE_PKT_ERROR_MDID_OFFSET),
4544 };
4545
4546 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
4547         { ICE_MAC_OFOS,         ICE_MAC_OFOS_HW },
4548         { ICE_MAC_IL,           ICE_MAC_IL_HW },
4549         { ICE_ETYPE_OL,         ICE_ETYPE_OL_HW },
4550         { ICE_ETYPE_IL,         ICE_ETYPE_IL_HW },
4551         { ICE_VLAN_OFOS,        ICE_VLAN_OL_HW },
4552         { ICE_IPV4_OFOS,        ICE_IPV4_OFOS_HW },
4553         { ICE_IPV4_IL,          ICE_IPV4_IL_HW },
4554         { ICE_IPV6_OFOS,        ICE_IPV6_OFOS_HW },
4555         { ICE_IPV6_IL,          ICE_IPV6_IL_HW },
4556         { ICE_TCP_IL,           ICE_TCP_IL_HW },
4557         { ICE_UDP_OF,           ICE_UDP_OF_HW },
4558         { ICE_UDP_ILOS,         ICE_UDP_ILOS_HW },
4559         { ICE_VXLAN,            ICE_UDP_OF_HW },
4560         { ICE_GENEVE,           ICE_UDP_OF_HW },
4561         { ICE_NVGRE,            ICE_GRE_OF_HW },
4562         { ICE_GTP,              ICE_UDP_OF_HW },
4563         { ICE_GTP_NO_PAY,       ICE_UDP_ILOS_HW },
4564         { ICE_PPPOE,            ICE_PPPOE_HW },
4565         { ICE_L2TPV3,           ICE_L2TPV3_HW },
4566         { ICE_VLAN_EX,          ICE_VLAN_OF_HW },
4567         { ICE_VLAN_IN,          ICE_VLAN_OL_HW },
4568         { ICE_HW_METADATA,      ICE_META_DATA_ID_HW },
4569 };
4570
4571 /**
4572  * ice_find_recp - find a recipe
4573  * @hw: pointer to the hardware structure
4574  * @lkup_exts: extension sequence to match
4575  * @rinfo: information regarding the rule e.g. priority and action info
4576  *
4577  * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
4578  */
4579 static u16
4580 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
4581               const struct ice_adv_rule_info *rinfo)
4582 {
4583         bool refresh_required = true;
4584         struct ice_sw_recipe *recp;
4585         u8 i;
4586
4587         /* Walk through existing recipes to find a match */
4588         recp = hw->switch_info->recp_list;
4589         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
4590                 /* If recipe was not created for this ID, in SW bookkeeping,
4591                  * check if FW has an entry for this recipe. If the FW has an
4592                  * entry update it in our SW bookkeeping and continue with the
4593                  * matching.
4594                  */
4595                 if (!recp[i].recp_created)
4596                         if (ice_get_recp_frm_fw(hw,
4597                                                 hw->switch_info->recp_list, i,
4598                                                 &refresh_required))
4599                                 continue;
4600
4601                 /* Skip inverse action recipes */
4602                 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
4603                     ICE_AQ_RECIPE_ACT_INV_ACT)
4604                         continue;
4605
4606                 /* if number of words we are looking for match */
4607                 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
4608                         struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
4609                         struct ice_fv_word *be = lkup_exts->fv_words;
4610                         u16 *cr = recp[i].lkup_exts.field_mask;
4611                         u16 *de = lkup_exts->field_mask;
4612                         bool found = true;
4613                         u8 pe, qr;
4614
4615                         /* ar, cr, and qr are related to the recipe words, while
4616                          * be, de, and pe are related to the lookup words
4617                          */
4618                         for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
4619                                 for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
4620                                      qr++) {
4621                                         if (ar[qr].off == be[pe].off &&
4622                                             ar[qr].prot_id == be[pe].prot_id &&
4623                                             cr[qr] == de[pe])
4624                                                 /* Found the "pe"th word in the
4625                                                  * given recipe
4626                                                  */
4627                                                 break;
4628                                 }
4629                                 /* After walking through all the words in the
4630                                  * "i"th recipe if "p"th word was not found then
4631                                  * this recipe is not what we are looking for.
4632                                  * So break out from this loop and try the next
4633                                  * recipe
4634                                  */
4635                                 if (qr >= recp[i].lkup_exts.n_val_words) {
4636                                         found = false;
4637                                         break;
4638                                 }
4639                         }
4640                         /* If for "i"th recipe the found was never set to false
4641                          * then it means we found our match
4642                          * Also tun type and *_pass_l2 of recipe needs to be
4643                          * checked
4644                          */
4645                         if (found && recp[i].tun_type == rinfo->tun_type &&
4646                             recp[i].need_pass_l2 == rinfo->need_pass_l2 &&
4647                             recp[i].allow_pass_l2 == rinfo->allow_pass_l2)
4648                                 return i; /* Return the recipe ID */
4649                 }
4650         }
4651         return ICE_MAX_NUM_RECIPES;
4652 }
4653
4654 /**
4655  * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
4656  *
4657  * As protocol id for outer vlan is different in dvm and svm, if dvm is
4658  * supported protocol array record for outer vlan has to be modified to
4659  * reflect the value proper for DVM.
4660  */
4661 void ice_change_proto_id_to_dvm(void)
4662 {
4663         u8 i;
4664
4665         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4666                 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
4667                     ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
4668                         ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
4669 }
4670
4671 /**
4672  * ice_prot_type_to_id - get protocol ID from protocol type
4673  * @type: protocol type
4674  * @id: pointer to variable that will receive the ID
4675  *
4676  * Returns true if found, false otherwise
4677  */
4678 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
4679 {
4680         u8 i;
4681
4682         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4683                 if (ice_prot_id_tbl[i].type == type) {
4684                         *id = ice_prot_id_tbl[i].protocol_id;
4685                         return true;
4686                 }
4687         return false;
4688 }
4689
4690 /**
4691  * ice_fill_valid_words - count valid words
4692  * @rule: advanced rule with lookup information
4693  * @lkup_exts: byte offset extractions of the words that are valid
4694  *
4695  * calculate valid words in a lookup rule using mask value
4696  */
4697 static u8
4698 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
4699                      struct ice_prot_lkup_ext *lkup_exts)
4700 {
4701         u8 j, word, prot_id, ret_val;
4702
4703         if (!ice_prot_type_to_id(rule->type, &prot_id))
4704                 return 0;
4705
4706         word = lkup_exts->n_val_words;
4707
4708         for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
4709                 if (((u16 *)&rule->m_u)[j] &&
4710                     rule->type < ARRAY_SIZE(ice_prot_ext)) {
4711                         /* No more space to accommodate */
4712                         if (word >= ICE_MAX_CHAIN_WORDS)
4713                                 return 0;
4714                         lkup_exts->fv_words[word].off =
4715                                 ice_prot_ext[rule->type].offs[j];
4716                         lkup_exts->fv_words[word].prot_id =
4717                                 ice_prot_id_tbl[rule->type].protocol_id;
4718                         lkup_exts->field_mask[word] =
4719                                 be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
4720                         word++;
4721                 }
4722
4723         ret_val = word - lkup_exts->n_val_words;
4724         lkup_exts->n_val_words = word;
4725
4726         return ret_val;
4727 }
4728
4729 /**
4730  * ice_create_first_fit_recp_def - Create a recipe grouping
4731  * @hw: pointer to the hardware structure
4732  * @lkup_exts: an array of protocol header extractions
4733  * @rg_list: pointer to a list that stores new recipe groups
4734  * @recp_cnt: pointer to a variable that stores returned number of recipe groups
4735  *
4736  * Using first fit algorithm, take all the words that are still not done
4737  * and start grouping them in 4-word groups. Each group makes up one
4738  * recipe.
4739  */
4740 static int
4741 ice_create_first_fit_recp_def(struct ice_hw *hw,
4742                               struct ice_prot_lkup_ext *lkup_exts,
4743                               struct list_head *rg_list,
4744                               u8 *recp_cnt)
4745 {
4746         struct ice_pref_recipe_group *grp = NULL;
4747         u8 j;
4748
4749         *recp_cnt = 0;
4750
4751         /* Walk through every word in the rule to check if it is not done. If so
4752          * then this word needs to be part of a new recipe.
4753          */
4754         for (j = 0; j < lkup_exts->n_val_words; j++)
4755                 if (!test_bit(j, lkup_exts->done)) {
4756                         if (!grp ||
4757                             grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
4758                                 struct ice_recp_grp_entry *entry;
4759
4760                                 entry = devm_kzalloc(ice_hw_to_dev(hw),
4761                                                      sizeof(*entry),
4762                                                      GFP_KERNEL);
4763                                 if (!entry)
4764                                         return -ENOMEM;
4765                                 list_add(&entry->l_entry, rg_list);
4766                                 grp = &entry->r_group;
4767                                 (*recp_cnt)++;
4768                         }
4769
4770                         grp->pairs[grp->n_val_pairs].prot_id =
4771                                 lkup_exts->fv_words[j].prot_id;
4772                         grp->pairs[grp->n_val_pairs].off =
4773                                 lkup_exts->fv_words[j].off;
4774                         grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
4775                         grp->n_val_pairs++;
4776                 }
4777
4778         return 0;
4779 }
4780
4781 /**
4782  * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
4783  * @hw: pointer to the hardware structure
4784  * @fv_list: field vector with the extraction sequence information
4785  * @rg_list: recipe groupings with protocol-offset pairs
4786  *
4787  * Helper function to fill in the field vector indices for protocol-offset
4788  * pairs. These indexes are then ultimately programmed into a recipe.
4789  */
4790 static int
4791 ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list,
4792                        struct list_head *rg_list)
4793 {
4794         struct ice_sw_fv_list_entry *fv;
4795         struct ice_recp_grp_entry *rg;
4796         struct ice_fv_word *fv_ext;
4797
4798         if (list_empty(fv_list))
4799                 return 0;
4800
4801         fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry,
4802                               list_entry);
4803         fv_ext = fv->fv_ptr->ew;
4804
4805         list_for_each_entry(rg, rg_list, l_entry) {
4806                 u8 i;
4807
4808                 for (i = 0; i < rg->r_group.n_val_pairs; i++) {
4809                         struct ice_fv_word *pr;
4810                         bool found = false;
4811                         u16 mask;
4812                         u8 j;
4813
4814                         pr = &rg->r_group.pairs[i];
4815                         mask = rg->r_group.mask[i];
4816
4817                         for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
4818                                 if (fv_ext[j].prot_id == pr->prot_id &&
4819                                     fv_ext[j].off == pr->off) {
4820                                         found = true;
4821
4822                                         /* Store index of field vector */
4823                                         rg->fv_idx[i] = j;
4824                                         rg->fv_mask[i] = mask;
4825                                         break;
4826                                 }
4827
4828                         /* Protocol/offset could not be found, caller gave an
4829                          * invalid pair
4830                          */
4831                         if (!found)
4832                                 return -EINVAL;
4833                 }
4834         }
4835
4836         return 0;
4837 }
4838
4839 /**
4840  * ice_find_free_recp_res_idx - find free result indexes for recipe
4841  * @hw: pointer to hardware structure
4842  * @profiles: bitmap of profiles that will be associated with the new recipe
4843  * @free_idx: pointer to variable to receive the free index bitmap
4844  *
4845  * The algorithm used here is:
4846  *      1. When creating a new recipe, create a set P which contains all
4847  *         Profiles that will be associated with our new recipe
4848  *
4849  *      2. For each Profile p in set P:
4850  *          a. Add all recipes associated with Profile p into set R
4851  *          b. Optional : PossibleIndexes &= profile[p].possibleIndexes
4852  *              [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
4853  *              i. Or just assume they all have the same possible indexes:
4854  *                      44, 45, 46, 47
4855  *                      i.e., PossibleIndexes = 0x0000F00000000000
4856  *
4857  *      3. For each Recipe r in set R:
4858  *          a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
4859  *          b. FreeIndexes = UsedIndexes ^ PossibleIndexes
4860  *
4861  *      FreeIndexes will contain the bits indicating the indexes free for use,
4862  *      then the code needs to update the recipe[r].used_result_idx_bits to
4863  *      indicate which indexes were selected for use by this recipe.
4864  */
4865 static u16
4866 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
4867                            unsigned long *free_idx)
4868 {
4869         DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
4870         DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
4871         DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
4872         u16 bit;
4873
4874         bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
4875         bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
4876
4877         bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
4878
4879         /* For each profile we are going to associate the recipe with, add the
4880          * recipes that are associated with that profile. This will give us
4881          * the set of recipes that our recipe may collide with. Also, determine
4882          * what possible result indexes are usable given this set of profiles.
4883          */
4884         for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
4885                 bitmap_or(recipes, recipes, profile_to_recipe[bit],
4886                           ICE_MAX_NUM_RECIPES);
4887                 bitmap_and(possible_idx, possible_idx,
4888                            hw->switch_info->prof_res_bm[bit],
4889                            ICE_MAX_FV_WORDS);
4890         }
4891
4892         /* For each recipe that our new recipe may collide with, determine
4893          * which indexes have been used.
4894          */
4895         for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
4896                 bitmap_or(used_idx, used_idx,
4897                           hw->switch_info->recp_list[bit].res_idxs,
4898                           ICE_MAX_FV_WORDS);
4899
4900         bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
4901
4902         /* return number of free indexes */
4903         return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
4904 }
4905
4906 /**
4907  * ice_add_sw_recipe - function to call AQ calls to create switch recipe
4908  * @hw: pointer to hardware structure
4909  * @rm: recipe management list entry
4910  * @profiles: bitmap of profiles that will be associated.
4911  */
4912 static int
4913 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
4914                   unsigned long *profiles)
4915 {
4916         DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
4917         struct ice_aqc_recipe_content *content;
4918         struct ice_aqc_recipe_data_elem *tmp;
4919         struct ice_aqc_recipe_data_elem *buf;
4920         struct ice_recp_grp_entry *entry;
4921         u16 free_res_idx;
4922         u16 recipe_count;
4923         u8 chain_idx;
4924         u8 recps = 0;
4925         int status;
4926
4927         /* When more than one recipe are required, another recipe is needed to
4928          * chain them together. Matching a tunnel metadata ID takes up one of
4929          * the match fields in the chaining recipe reducing the number of
4930          * chained recipes by one.
4931          */
4932          /* check number of free result indices */
4933         bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
4934         free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
4935
4936         ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
4937                   free_res_idx, rm->n_grp_count);
4938
4939         if (rm->n_grp_count > 1) {
4940                 if (rm->n_grp_count > free_res_idx)
4941                         return -ENOSPC;
4942
4943                 rm->n_grp_count++;
4944         }
4945
4946         if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
4947                 return -ENOSPC;
4948
4949         tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
4950         if (!tmp)
4951                 return -ENOMEM;
4952
4953         buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf),
4954                            GFP_KERNEL);
4955         if (!buf) {
4956                 status = -ENOMEM;
4957                 goto err_mem;
4958         }
4959
4960         bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
4961         recipe_count = ICE_MAX_NUM_RECIPES;
4962         status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
4963                                    NULL);
4964         if (status || recipe_count == 0)
4965                 goto err_unroll;
4966
4967         /* Allocate the recipe resources, and configure them according to the
4968          * match fields from protocol headers and extracted field vectors.
4969          */
4970         chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
4971         list_for_each_entry(entry, &rm->rg_list, l_entry) {
4972                 u8 i;
4973
4974                 status = ice_alloc_recipe(hw, &entry->rid);
4975                 if (status)
4976                         goto err_unroll;
4977
4978                 content = &buf[recps].content;
4979
4980                 /* Clear the result index of the located recipe, as this will be
4981                  * updated, if needed, later in the recipe creation process.
4982                  */
4983                 tmp[0].content.result_indx = 0;
4984
4985                 buf[recps] = tmp[0];
4986                 buf[recps].recipe_indx = (u8)entry->rid;
4987                 /* if the recipe is a non-root recipe RID should be programmed
4988                  * as 0 for the rules to be applied correctly.
4989                  */
4990                 content->rid = 0;
4991                 memset(&content->lkup_indx, 0,
4992                        sizeof(content->lkup_indx));
4993
4994                 /* All recipes use look-up index 0 to match switch ID. */
4995                 content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
4996                 content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
4997                 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
4998                  * to be 0
4999                  */
5000                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5001                         content->lkup_indx[i] = 0x80;
5002                         content->mask[i] = 0;
5003                 }
5004
5005                 for (i = 0; i < entry->r_group.n_val_pairs; i++) {
5006                         content->lkup_indx[i + 1] = entry->fv_idx[i];
5007                         content->mask[i + 1] = cpu_to_le16(entry->fv_mask[i]);
5008                 }
5009
5010                 if (rm->n_grp_count > 1) {
5011                         /* Checks to see if there really is a valid result index
5012                          * that can be used.
5013                          */
5014                         if (chain_idx >= ICE_MAX_FV_WORDS) {
5015                                 ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
5016                                 status = -ENOSPC;
5017                                 goto err_unroll;
5018                         }
5019
5020                         entry->chain_idx = chain_idx;
5021                         content->result_indx =
5022                                 ICE_AQ_RECIPE_RESULT_EN |
5023                                 FIELD_PREP(ICE_AQ_RECIPE_RESULT_DATA_M,
5024                                            chain_idx);
5025                         clear_bit(chain_idx, result_idx_bm);
5026                         chain_idx = find_first_bit(result_idx_bm,
5027                                                    ICE_MAX_FV_WORDS);
5028                 }
5029
5030                 /* fill recipe dependencies */
5031                 bitmap_zero((unsigned long *)buf[recps].recipe_bitmap,
5032                             ICE_MAX_NUM_RECIPES);
5033                 set_bit(buf[recps].recipe_indx,
5034                         (unsigned long *)buf[recps].recipe_bitmap);
5035                 content->act_ctrl_fwd_priority = rm->priority;
5036
5037                 if (rm->need_pass_l2)
5038                         content->act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
5039
5040                 if (rm->allow_pass_l2)
5041                         content->act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
5042                 recps++;
5043         }
5044
5045         if (rm->n_grp_count == 1) {
5046                 rm->root_rid = buf[0].recipe_indx;
5047                 set_bit(buf[0].recipe_indx, rm->r_bitmap);
5048                 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
5049                 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
5050                         memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
5051                                sizeof(buf[0].recipe_bitmap));
5052                 } else {
5053                         status = -EINVAL;
5054                         goto err_unroll;
5055                 }
5056                 /* Applicable only for ROOT_RECIPE, set the fwd_priority for
5057                  * the recipe which is getting created if specified
5058                  * by user. Usually any advanced switch filter, which results
5059                  * into new extraction sequence, ended up creating a new recipe
5060                  * of type ROOT and usually recipes are associated with profiles
5061                  * Switch rule referreing newly created recipe, needs to have
5062                  * either/or 'fwd' or 'join' priority, otherwise switch rule
5063                  * evaluation will not happen correctly. In other words, if
5064                  * switch rule to be evaluated on priority basis, then recipe
5065                  * needs to have priority, otherwise it will be evaluated last.
5066                  */
5067                 buf[0].content.act_ctrl_fwd_priority = rm->priority;
5068         } else {
5069                 struct ice_recp_grp_entry *last_chain_entry;
5070                 u16 rid, i;
5071
5072                 /* Allocate the last recipe that will chain the outcomes of the
5073                  * other recipes together
5074                  */
5075                 status = ice_alloc_recipe(hw, &rid);
5076                 if (status)
5077                         goto err_unroll;
5078
5079                 content = &buf[recps].content;
5080
5081                 buf[recps].recipe_indx = (u8)rid;
5082                 content->rid = (u8)rid;
5083                 content->rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
5084                 /* the new entry created should also be part of rg_list to
5085                  * make sure we have complete recipe
5086                  */
5087                 last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw),
5088                                                 sizeof(*last_chain_entry),
5089                                                 GFP_KERNEL);
5090                 if (!last_chain_entry) {
5091                         status = -ENOMEM;
5092                         goto err_unroll;
5093                 }
5094                 last_chain_entry->rid = rid;
5095                 memset(&content->lkup_indx, 0, sizeof(content->lkup_indx));
5096                 /* All recipes use look-up index 0 to match switch ID. */
5097                 content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
5098                 content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
5099                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5100                         content->lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE;
5101                         content->mask[i] = 0;
5102                 }
5103
5104                 i = 1;
5105                 /* update r_bitmap with the recp that is used for chaining */
5106                 set_bit(rid, rm->r_bitmap);
5107                 /* this is the recipe that chains all the other recipes so it
5108                  * should not have a chaining ID to indicate the same
5109                  */
5110                 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
5111                 list_for_each_entry(entry, &rm->rg_list, l_entry) {
5112                         last_chain_entry->fv_idx[i] = entry->chain_idx;
5113                         content->lkup_indx[i] = entry->chain_idx;
5114                         content->mask[i++] = cpu_to_le16(0xFFFF);
5115                         set_bit(entry->rid, rm->r_bitmap);
5116                 }
5117                 list_add(&last_chain_entry->l_entry, &rm->rg_list);
5118                 if (sizeof(buf[recps].recipe_bitmap) >=
5119                     sizeof(rm->r_bitmap)) {
5120                         memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
5121                                sizeof(buf[recps].recipe_bitmap));
5122                 } else {
5123                         status = -EINVAL;
5124                         goto err_unroll;
5125                 }
5126                 content->act_ctrl_fwd_priority = rm->priority;
5127
5128                 recps++;
5129                 rm->root_rid = (u8)rid;
5130         }
5131         status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5132         if (status)
5133                 goto err_unroll;
5134
5135         status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
5136         ice_release_change_lock(hw);
5137         if (status)
5138                 goto err_unroll;
5139
5140         /* Every recipe that just got created add it to the recipe
5141          * book keeping list
5142          */
5143         list_for_each_entry(entry, &rm->rg_list, l_entry) {
5144                 struct ice_switch_info *sw = hw->switch_info;
5145                 bool is_root, idx_found = false;
5146                 struct ice_sw_recipe *recp;
5147                 u16 idx, buf_idx = 0;
5148
5149                 /* find buffer index for copying some data */
5150                 for (idx = 0; idx < rm->n_grp_count; idx++)
5151                         if (buf[idx].recipe_indx == entry->rid) {
5152                                 buf_idx = idx;
5153                                 idx_found = true;
5154                         }
5155
5156                 if (!idx_found) {
5157                         status = -EIO;
5158                         goto err_unroll;
5159                 }
5160
5161                 recp = &sw->recp_list[entry->rid];
5162                 is_root = (rm->root_rid == entry->rid);
5163                 recp->is_root = is_root;
5164
5165                 recp->root_rid = entry->rid;
5166                 recp->big_recp = (is_root && rm->n_grp_count > 1);
5167
5168                 memcpy(&recp->ext_words, entry->r_group.pairs,
5169                        entry->r_group.n_val_pairs * sizeof(struct ice_fv_word));
5170
5171                 memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
5172                        sizeof(recp->r_bitmap));
5173
5174                 /* Copy non-result fv index values and masks to recipe. This
5175                  * call will also update the result recipe bitmask.
5176                  */
5177                 ice_collect_result_idx(&buf[buf_idx], recp);
5178
5179                 /* for non-root recipes, also copy to the root, this allows
5180                  * easier matching of a complete chained recipe
5181                  */
5182                 if (!is_root)
5183                         ice_collect_result_idx(&buf[buf_idx],
5184                                                &sw->recp_list[rm->root_rid]);
5185
5186                 recp->n_ext_words = entry->r_group.n_val_pairs;
5187                 recp->chain_idx = entry->chain_idx;
5188                 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
5189                 recp->n_grp_count = rm->n_grp_count;
5190                 recp->tun_type = rm->tun_type;
5191                 recp->need_pass_l2 = rm->need_pass_l2;
5192                 recp->allow_pass_l2 = rm->allow_pass_l2;
5193                 recp->recp_created = true;
5194         }
5195         rm->root_buf = buf;
5196         kfree(tmp);
5197         return status;
5198
5199 err_unroll:
5200 err_mem:
5201         kfree(tmp);
5202         devm_kfree(ice_hw_to_dev(hw), buf);
5203         return status;
5204 }
5205
5206 /**
5207  * ice_create_recipe_group - creates recipe group
5208  * @hw: pointer to hardware structure
5209  * @rm: recipe management list entry
5210  * @lkup_exts: lookup elements
5211  */
5212 static int
5213 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
5214                         struct ice_prot_lkup_ext *lkup_exts)
5215 {
5216         u8 recp_count = 0;
5217         int status;
5218
5219         rm->n_grp_count = 0;
5220
5221         /* Create recipes for words that are marked not done by packing them
5222          * as best fit.
5223          */
5224         status = ice_create_first_fit_recp_def(hw, lkup_exts,
5225                                                &rm->rg_list, &recp_count);
5226         if (!status) {
5227                 rm->n_grp_count += recp_count;
5228                 rm->n_ext_words = lkup_exts->n_val_words;
5229                 memcpy(&rm->ext_words, lkup_exts->fv_words,
5230                        sizeof(rm->ext_words));
5231                 memcpy(rm->word_masks, lkup_exts->field_mask,
5232                        sizeof(rm->word_masks));
5233         }
5234
5235         return status;
5236 }
5237
5238 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
5239  * @hw: pointer to hardware structure
5240  * @rinfo: other information regarding the rule e.g. priority and action info
5241  * @bm: pointer to memory for returning the bitmap of field vectors
5242  */
5243 static void
5244 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
5245                          unsigned long *bm)
5246 {
5247         enum ice_prof_type prof_type;
5248
5249         bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
5250
5251         switch (rinfo->tun_type) {
5252         case ICE_NON_TUN:
5253                 prof_type = ICE_PROF_NON_TUN;
5254                 break;
5255         case ICE_ALL_TUNNELS:
5256                 prof_type = ICE_PROF_TUN_ALL;
5257                 break;
5258         case ICE_SW_TUN_GENEVE:
5259         case ICE_SW_TUN_VXLAN:
5260                 prof_type = ICE_PROF_TUN_UDP;
5261                 break;
5262         case ICE_SW_TUN_NVGRE:
5263                 prof_type = ICE_PROF_TUN_GRE;
5264                 break;
5265         case ICE_SW_TUN_GTPU:
5266                 prof_type = ICE_PROF_TUN_GTPU;
5267                 break;
5268         case ICE_SW_TUN_GTPC:
5269                 prof_type = ICE_PROF_TUN_GTPC;
5270                 break;
5271         case ICE_SW_TUN_AND_NON_TUN:
5272         default:
5273                 prof_type = ICE_PROF_ALL;
5274                 break;
5275         }
5276
5277         ice_get_sw_fv_bitmap(hw, prof_type, bm);
5278 }
5279
5280 /**
5281  * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
5282  * @hw: pointer to hardware structure
5283  * @lkups: lookup elements or match criteria for the advanced recipe, one
5284  *  structure per protocol header
5285  * @lkups_cnt: number of protocols
5286  * @rinfo: other information regarding the rule e.g. priority and action info
5287  * @rid: return the recipe ID of the recipe created
5288  */
5289 static int
5290 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5291                    u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
5292 {
5293         DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
5294         DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
5295         struct ice_prot_lkup_ext *lkup_exts;
5296         struct ice_recp_grp_entry *r_entry;
5297         struct ice_sw_fv_list_entry *fvit;
5298         struct ice_recp_grp_entry *r_tmp;
5299         struct ice_sw_fv_list_entry *tmp;
5300         struct ice_sw_recipe *rm;
5301         int status = 0;
5302         u8 i;
5303
5304         if (!lkups_cnt)
5305                 return -EINVAL;
5306
5307         lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
5308         if (!lkup_exts)
5309                 return -ENOMEM;
5310
5311         /* Determine the number of words to be matched and if it exceeds a
5312          * recipe's restrictions
5313          */
5314         for (i = 0; i < lkups_cnt; i++) {
5315                 u16 count;
5316
5317                 if (lkups[i].type >= ICE_PROTOCOL_LAST) {
5318                         status = -EIO;
5319                         goto err_free_lkup_exts;
5320                 }
5321
5322                 count = ice_fill_valid_words(&lkups[i], lkup_exts);
5323                 if (!count) {
5324                         status = -EIO;
5325                         goto err_free_lkup_exts;
5326                 }
5327         }
5328
5329         rm = kzalloc(sizeof(*rm), GFP_KERNEL);
5330         if (!rm) {
5331                 status = -ENOMEM;
5332                 goto err_free_lkup_exts;
5333         }
5334
5335         /* Get field vectors that contain fields extracted from all the protocol
5336          * headers being programmed.
5337          */
5338         INIT_LIST_HEAD(&rm->fv_list);
5339         INIT_LIST_HEAD(&rm->rg_list);
5340
5341         /* Get bitmap of field vectors (profiles) that are compatible with the
5342          * rule request; only these will be searched in the subsequent call to
5343          * ice_get_sw_fv_list.
5344          */
5345         ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
5346
5347         status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
5348         if (status)
5349                 goto err_unroll;
5350
5351         /* Group match words into recipes using preferred recipe grouping
5352          * criteria.
5353          */
5354         status = ice_create_recipe_group(hw, rm, lkup_exts);
5355         if (status)
5356                 goto err_unroll;
5357
5358         /* set the recipe priority if specified */
5359         rm->priority = (u8)rinfo->priority;
5360
5361         rm->need_pass_l2 = rinfo->need_pass_l2;
5362         rm->allow_pass_l2 = rinfo->allow_pass_l2;
5363
5364         /* Find offsets from the field vector. Pick the first one for all the
5365          * recipes.
5366          */
5367         status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
5368         if (status)
5369                 goto err_unroll;
5370
5371         /* get bitmap of all profiles the recipe will be associated with */
5372         bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
5373         list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5374                 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
5375                 set_bit((u16)fvit->profile_id, profiles);
5376         }
5377
5378         /* Look for a recipe which matches our requested fv / mask list */
5379         *rid = ice_find_recp(hw, lkup_exts, rinfo);
5380         if (*rid < ICE_MAX_NUM_RECIPES)
5381                 /* Success if found a recipe that match the existing criteria */
5382                 goto err_unroll;
5383
5384         rm->tun_type = rinfo->tun_type;
5385         /* Recipe we need does not exist, add a recipe */
5386         status = ice_add_sw_recipe(hw, rm, profiles);
5387         if (status)
5388                 goto err_unroll;
5389
5390         /* Associate all the recipes created with all the profiles in the
5391          * common field vector.
5392          */
5393         list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5394                 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
5395                 u64 recp_assoc;
5396                 u16 j;
5397
5398                 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
5399                                                       &recp_assoc, NULL);
5400                 if (status)
5401                         goto err_unroll;
5402
5403                 bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
5404                 bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
5405                           ICE_MAX_NUM_RECIPES);
5406                 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5407                 if (status)
5408                         goto err_unroll;
5409
5410                 bitmap_to_arr64(&recp_assoc, r_bitmap, ICE_MAX_NUM_RECIPES);
5411                 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
5412                                                       recp_assoc, NULL);
5413                 ice_release_change_lock(hw);
5414
5415                 if (status)
5416                         goto err_unroll;
5417
5418                 /* Update profile to recipe bitmap array */
5419                 bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
5420                             ICE_MAX_NUM_RECIPES);
5421
5422                 /* Update recipe to profile bitmap array */
5423                 for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
5424                         set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
5425         }
5426
5427         *rid = rm->root_rid;
5428         memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
5429                sizeof(*lkup_exts));
5430 err_unroll:
5431         list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) {
5432                 list_del(&r_entry->l_entry);
5433                 devm_kfree(ice_hw_to_dev(hw), r_entry);
5434         }
5435
5436         list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
5437                 list_del(&fvit->list_entry);
5438                 devm_kfree(ice_hw_to_dev(hw), fvit);
5439         }
5440
5441         devm_kfree(ice_hw_to_dev(hw), rm->root_buf);
5442         kfree(rm);
5443
5444 err_free_lkup_exts:
5445         kfree(lkup_exts);
5446
5447         return status;
5448 }
5449
5450 /**
5451  * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt
5452  *
5453  * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added
5454  * @num_vlan: number of VLAN tags
5455  */
5456 static struct ice_dummy_pkt_profile *
5457 ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt,
5458                           u32 num_vlan)
5459 {
5460         struct ice_dummy_pkt_profile *profile;
5461         struct ice_dummy_pkt_offsets *offsets;
5462         u32 buf_len, off, etype_off, i;
5463         u8 *pkt;
5464
5465         if (num_vlan < 1 || num_vlan > 2)
5466                 return ERR_PTR(-EINVAL);
5467
5468         off = num_vlan * VLAN_HLEN;
5469
5470         buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) +
5471                   dummy_pkt->offsets_len;
5472         offsets = kzalloc(buf_len, GFP_KERNEL);
5473         if (!offsets)
5474                 return ERR_PTR(-ENOMEM);
5475
5476         offsets[0] = dummy_pkt->offsets[0];
5477         if (num_vlan == 2) {
5478                 offsets[1] = ice_dummy_qinq_packet_offsets[0];
5479                 offsets[2] = ice_dummy_qinq_packet_offsets[1];
5480         } else if (num_vlan == 1) {
5481                 offsets[1] = ice_dummy_vlan_packet_offsets[0];
5482         }
5483
5484         for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5485                 offsets[i + num_vlan].type = dummy_pkt->offsets[i].type;
5486                 offsets[i + num_vlan].offset =
5487                         dummy_pkt->offsets[i].offset + off;
5488         }
5489         offsets[i + num_vlan] = dummy_pkt->offsets[i];
5490
5491         etype_off = dummy_pkt->offsets[1].offset;
5492
5493         buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) +
5494                   dummy_pkt->pkt_len;
5495         pkt = kzalloc(buf_len, GFP_KERNEL);
5496         if (!pkt) {
5497                 kfree(offsets);
5498                 return ERR_PTR(-ENOMEM);
5499         }
5500
5501         memcpy(pkt, dummy_pkt->pkt, etype_off);
5502         memcpy(pkt + etype_off,
5503                num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet,
5504                off);
5505         memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off,
5506                dummy_pkt->pkt_len - etype_off);
5507
5508         profile = kzalloc(sizeof(*profile), GFP_KERNEL);
5509         if (!profile) {
5510                 kfree(offsets);
5511                 kfree(pkt);
5512                 return ERR_PTR(-ENOMEM);
5513         }
5514
5515         profile->offsets = offsets;
5516         profile->pkt = pkt;
5517         profile->pkt_len = buf_len;
5518         profile->match |= ICE_PKT_KMALLOC;
5519
5520         return profile;
5521 }
5522
5523 /**
5524  * ice_find_dummy_packet - find dummy packet
5525  *
5526  * @lkups: lookup elements or match criteria for the advanced recipe, one
5527  *         structure per protocol header
5528  * @lkups_cnt: number of protocols
5529  * @tun_type: tunnel type
5530  *
5531  * Returns the &ice_dummy_pkt_profile corresponding to these lookup params.
5532  */
5533 static const struct ice_dummy_pkt_profile *
5534 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5535                       enum ice_sw_tunnel_type tun_type)
5536 {
5537         const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles;
5538         u32 match = 0, vlan_count = 0;
5539         u16 i;
5540
5541         switch (tun_type) {
5542         case ICE_SW_TUN_GTPC:
5543                 match |= ICE_PKT_TUN_GTPC;
5544                 break;
5545         case ICE_SW_TUN_GTPU:
5546                 match |= ICE_PKT_TUN_GTPU;
5547                 break;
5548         case ICE_SW_TUN_NVGRE:
5549                 match |= ICE_PKT_TUN_NVGRE;
5550                 break;
5551         case ICE_SW_TUN_GENEVE:
5552         case ICE_SW_TUN_VXLAN:
5553                 match |= ICE_PKT_TUN_UDP;
5554                 break;
5555         default:
5556                 break;
5557         }
5558
5559         for (i = 0; i < lkups_cnt; i++) {
5560                 if (lkups[i].type == ICE_UDP_ILOS)
5561                         match |= ICE_PKT_INNER_UDP;
5562                 else if (lkups[i].type == ICE_TCP_IL)
5563                         match |= ICE_PKT_INNER_TCP;
5564                 else if (lkups[i].type == ICE_IPV6_OFOS)
5565                         match |= ICE_PKT_OUTER_IPV6;
5566                 else if (lkups[i].type == ICE_VLAN_OFOS ||
5567                          lkups[i].type == ICE_VLAN_EX)
5568                         vlan_count++;
5569                 else if (lkups[i].type == ICE_VLAN_IN)
5570                         vlan_count++;
5571                 else if (lkups[i].type == ICE_ETYPE_OL &&
5572                          lkups[i].h_u.ethertype.ethtype_id ==
5573                                 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5574                          lkups[i].m_u.ethertype.ethtype_id ==
5575                                 cpu_to_be16(0xFFFF))
5576                         match |= ICE_PKT_OUTER_IPV6;
5577                 else if (lkups[i].type == ICE_ETYPE_IL &&
5578                          lkups[i].h_u.ethertype.ethtype_id ==
5579                                 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5580                          lkups[i].m_u.ethertype.ethtype_id ==
5581                                 cpu_to_be16(0xFFFF))
5582                         match |= ICE_PKT_INNER_IPV6;
5583                 else if (lkups[i].type == ICE_IPV6_IL)
5584                         match |= ICE_PKT_INNER_IPV6;
5585                 else if (lkups[i].type == ICE_GTP_NO_PAY)
5586                         match |= ICE_PKT_GTP_NOPAY;
5587                 else if (lkups[i].type == ICE_PPPOE) {
5588                         match |= ICE_PKT_PPPOE;
5589                         if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
5590                             htons(PPP_IPV6))
5591                                 match |= ICE_PKT_OUTER_IPV6;
5592                 } else if (lkups[i].type == ICE_L2TPV3)
5593                         match |= ICE_PKT_L2TPV3;
5594         }
5595
5596         while (ret->match && (match & ret->match) != ret->match)
5597                 ret++;
5598
5599         if (vlan_count != 0)
5600                 ret = ice_dummy_packet_add_vlan(ret, vlan_count);
5601
5602         return ret;
5603 }
5604
5605 /**
5606  * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
5607  *
5608  * @lkups: lookup elements or match criteria for the advanced recipe, one
5609  *         structure per protocol header
5610  * @lkups_cnt: number of protocols
5611  * @s_rule: stores rule information from the match criteria
5612  * @profile: dummy packet profile (the template, its size and header offsets)
5613  */
5614 static int
5615 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5616                           struct ice_sw_rule_lkup_rx_tx *s_rule,
5617                           const struct ice_dummy_pkt_profile *profile)
5618 {
5619         u8 *pkt;
5620         u16 i;
5621
5622         /* Start with a packet with a pre-defined/dummy content. Then, fill
5623          * in the header values to be looked up or matched.
5624          */
5625         pkt = s_rule->hdr_data;
5626
5627         memcpy(pkt, profile->pkt, profile->pkt_len);
5628
5629         for (i = 0; i < lkups_cnt; i++) {
5630                 const struct ice_dummy_pkt_offsets *offsets = profile->offsets;
5631                 enum ice_protocol_type type;
5632                 u16 offset = 0, len = 0, j;
5633                 bool found = false;
5634
5635                 /* find the start of this layer; it should be found since this
5636                  * was already checked when search for the dummy packet
5637                  */
5638                 type = lkups[i].type;
5639                 /* metadata isn't present in the packet */
5640                 if (type == ICE_HW_METADATA)
5641                         continue;
5642
5643                 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
5644                         if (type == offsets[j].type) {
5645                                 offset = offsets[j].offset;
5646                                 found = true;
5647                                 break;
5648                         }
5649                 }
5650                 /* this should never happen in a correct calling sequence */
5651                 if (!found)
5652                         return -EINVAL;
5653
5654                 switch (lkups[i].type) {
5655                 case ICE_MAC_OFOS:
5656                 case ICE_MAC_IL:
5657                         len = sizeof(struct ice_ether_hdr);
5658                         break;
5659                 case ICE_ETYPE_OL:
5660                 case ICE_ETYPE_IL:
5661                         len = sizeof(struct ice_ethtype_hdr);
5662                         break;
5663                 case ICE_VLAN_OFOS:
5664                 case ICE_VLAN_EX:
5665                 case ICE_VLAN_IN:
5666                         len = sizeof(struct ice_vlan_hdr);
5667                         break;
5668                 case ICE_IPV4_OFOS:
5669                 case ICE_IPV4_IL:
5670                         len = sizeof(struct ice_ipv4_hdr);
5671                         break;
5672                 case ICE_IPV6_OFOS:
5673                 case ICE_IPV6_IL:
5674                         len = sizeof(struct ice_ipv6_hdr);
5675                         break;
5676                 case ICE_TCP_IL:
5677                 case ICE_UDP_OF:
5678                 case ICE_UDP_ILOS:
5679                         len = sizeof(struct ice_l4_hdr);
5680                         break;
5681                 case ICE_SCTP_IL:
5682                         len = sizeof(struct ice_sctp_hdr);
5683                         break;
5684                 case ICE_NVGRE:
5685                         len = sizeof(struct ice_nvgre_hdr);
5686                         break;
5687                 case ICE_VXLAN:
5688                 case ICE_GENEVE:
5689                         len = sizeof(struct ice_udp_tnl_hdr);
5690                         break;
5691                 case ICE_GTP_NO_PAY:
5692                 case ICE_GTP:
5693                         len = sizeof(struct ice_udp_gtp_hdr);
5694                         break;
5695                 case ICE_PPPOE:
5696                         len = sizeof(struct ice_pppoe_hdr);
5697                         break;
5698                 case ICE_L2TPV3:
5699                         len = sizeof(struct ice_l2tpv3_sess_hdr);
5700                         break;
5701                 default:
5702                         return -EINVAL;
5703                 }
5704
5705                 /* the length should be a word multiple */
5706                 if (len % ICE_BYTES_PER_WORD)
5707                         return -EIO;
5708
5709                 /* We have the offset to the header start, the length, the
5710                  * caller's header values and mask. Use this information to
5711                  * copy the data into the dummy packet appropriately based on
5712                  * the mask. Note that we need to only write the bits as
5713                  * indicated by the mask to make sure we don't improperly write
5714                  * over any significant packet data.
5715                  */
5716                 for (j = 0; j < len / sizeof(u16); j++) {
5717                         u16 *ptr = (u16 *)(pkt + offset);
5718                         u16 mask = lkups[i].m_raw[j];
5719
5720                         if (!mask)
5721                                 continue;
5722
5723                         ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask);
5724                 }
5725         }
5726
5727         s_rule->hdr_len = cpu_to_le16(profile->pkt_len);
5728
5729         return 0;
5730 }
5731
5732 /**
5733  * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
5734  * @hw: pointer to the hardware structure
5735  * @tun_type: tunnel type
5736  * @pkt: dummy packet to fill in
5737  * @offsets: offset info for the dummy packet
5738  */
5739 static int
5740 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
5741                         u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
5742 {
5743         u16 open_port, i;
5744
5745         switch (tun_type) {
5746         case ICE_SW_TUN_VXLAN:
5747                 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
5748                         return -EIO;
5749                 break;
5750         case ICE_SW_TUN_GENEVE:
5751                 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
5752                         return -EIO;
5753                 break;
5754         default:
5755                 /* Nothing needs to be done for this tunnel type */
5756                 return 0;
5757         }
5758
5759         /* Find the outer UDP protocol header and insert the port number */
5760         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5761                 if (offsets[i].type == ICE_UDP_OF) {
5762                         struct ice_l4_hdr *hdr;
5763                         u16 offset;
5764
5765                         offset = offsets[i].offset;
5766                         hdr = (struct ice_l4_hdr *)&pkt[offset];
5767                         hdr->dst_port = cpu_to_be16(open_port);
5768
5769                         return 0;
5770                 }
5771         }
5772
5773         return -EIO;
5774 }
5775
5776 /**
5777  * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
5778  * @hw: pointer to hw structure
5779  * @vlan_type: VLAN tag type
5780  * @pkt: dummy packet to fill in
5781  * @offsets: offset info for the dummy packet
5782  */
5783 static int
5784 ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt,
5785                          const struct ice_dummy_pkt_offsets *offsets)
5786 {
5787         u16 i;
5788
5789         /* Check if there is something to do */
5790         if (!vlan_type || !ice_is_dvm_ena(hw))
5791                 return 0;
5792
5793         /* Find VLAN header and insert VLAN TPID */
5794         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5795                 if (offsets[i].type == ICE_VLAN_OFOS ||
5796                     offsets[i].type == ICE_VLAN_EX) {
5797                         struct ice_vlan_hdr *hdr;
5798                         u16 offset;
5799
5800                         offset = offsets[i].offset;
5801                         hdr = (struct ice_vlan_hdr *)&pkt[offset];
5802                         hdr->type = cpu_to_be16(vlan_type);
5803
5804                         return 0;
5805                 }
5806         }
5807
5808         return -EIO;
5809 }
5810
5811 static bool ice_rules_equal(const struct ice_adv_rule_info *first,
5812                             const struct ice_adv_rule_info *second)
5813 {
5814         return first->sw_act.flag == second->sw_act.flag &&
5815                first->tun_type == second->tun_type &&
5816                first->vlan_type == second->vlan_type &&
5817                first->src_vsi == second->src_vsi &&
5818                first->need_pass_l2 == second->need_pass_l2 &&
5819                first->allow_pass_l2 == second->allow_pass_l2;
5820 }
5821
5822 /**
5823  * ice_find_adv_rule_entry - Search a rule entry
5824  * @hw: pointer to the hardware structure
5825  * @lkups: lookup elements or match criteria for the advanced recipe, one
5826  *         structure per protocol header
5827  * @lkups_cnt: number of protocols
5828  * @recp_id: recipe ID for which we are finding the rule
5829  * @rinfo: other information regarding the rule e.g. priority and action info
5830  *
5831  * Helper function to search for a given advance rule entry
5832  * Returns pointer to entry storing the rule if found
5833  */
5834 static struct ice_adv_fltr_mgmt_list_entry *
5835 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5836                         u16 lkups_cnt, u16 recp_id,
5837                         struct ice_adv_rule_info *rinfo)
5838 {
5839         struct ice_adv_fltr_mgmt_list_entry *list_itr;
5840         struct ice_switch_info *sw = hw->switch_info;
5841         int i;
5842
5843         list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
5844                             list_entry) {
5845                 bool lkups_matched = true;
5846
5847                 if (lkups_cnt != list_itr->lkups_cnt)
5848                         continue;
5849                 for (i = 0; i < list_itr->lkups_cnt; i++)
5850                         if (memcmp(&list_itr->lkups[i], &lkups[i],
5851                                    sizeof(*lkups))) {
5852                                 lkups_matched = false;
5853                                 break;
5854                         }
5855                 if (ice_rules_equal(rinfo, &list_itr->rule_info) &&
5856                     lkups_matched)
5857                         return list_itr;
5858         }
5859         return NULL;
5860 }
5861
5862 /**
5863  * ice_adv_add_update_vsi_list
5864  * @hw: pointer to the hardware structure
5865  * @m_entry: pointer to current adv filter management list entry
5866  * @cur_fltr: filter information from the book keeping entry
5867  * @new_fltr: filter information with the new VSI to be added
5868  *
5869  * Call AQ command to add or update previously created VSI list with new VSI.
5870  *
5871  * Helper function to do book keeping associated with adding filter information
5872  * The algorithm to do the booking keeping is described below :
5873  * When a VSI needs to subscribe to a given advanced filter
5874  *      if only one VSI has been added till now
5875  *              Allocate a new VSI list and add two VSIs
5876  *              to this list using switch rule command
5877  *              Update the previously created switch rule with the
5878  *              newly created VSI list ID
5879  *      if a VSI list was previously created
5880  *              Add the new VSI to the previously created VSI list set
5881  *              using the update switch rule command
5882  */
5883 static int
5884 ice_adv_add_update_vsi_list(struct ice_hw *hw,
5885                             struct ice_adv_fltr_mgmt_list_entry *m_entry,
5886                             struct ice_adv_rule_info *cur_fltr,
5887                             struct ice_adv_rule_info *new_fltr)
5888 {
5889         u16 vsi_list_id = 0;
5890         int status;
5891
5892         if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
5893             cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
5894             cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
5895                 return -EOPNOTSUPP;
5896
5897         if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
5898              new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
5899             (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
5900              cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
5901                 return -EOPNOTSUPP;
5902
5903         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
5904                  /* Only one entry existed in the mapping and it was not already
5905                   * a part of a VSI list. So, create a VSI list with the old and
5906                   * new VSIs.
5907                   */
5908                 struct ice_fltr_info tmp_fltr;
5909                 u16 vsi_handle_arr[2];
5910
5911                 /* A rule already exists with the new VSI being added */
5912                 if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
5913                     new_fltr->sw_act.fwd_id.hw_vsi_id)
5914                         return -EEXIST;
5915
5916                 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
5917                 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
5918                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
5919                                                   &vsi_list_id,
5920                                                   ICE_SW_LKUP_LAST);
5921                 if (status)
5922                         return status;
5923
5924                 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
5925                 tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
5926                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
5927                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
5928                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
5929                 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
5930
5931                 /* Update the previous switch rule of "forward to VSI" to
5932                  * "fwd to VSI list"
5933                  */
5934                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
5935                 if (status)
5936                         return status;
5937
5938                 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
5939                 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
5940                 m_entry->vsi_list_info =
5941                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
5942                                                 vsi_list_id);
5943         } else {
5944                 u16 vsi_handle = new_fltr->sw_act.vsi_handle;
5945
5946                 if (!m_entry->vsi_list_info)
5947                         return -EIO;
5948
5949                 /* A rule already exists with the new VSI being added */
5950                 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
5951                         return 0;
5952
5953                 /* Update the previously created VSI list set with
5954                  * the new VSI ID passed in
5955                  */
5956                 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
5957
5958                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
5959                                                   vsi_list_id, false,
5960                                                   ice_aqc_opc_update_sw_rules,
5961                                                   ICE_SW_LKUP_LAST);
5962                 /* update VSI list mapping info with new VSI ID */
5963                 if (!status)
5964                         set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
5965         }
5966         if (!status)
5967                 m_entry->vsi_count++;
5968         return status;
5969 }
5970
5971 void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
5972 {
5973         lkup->type = ICE_HW_METADATA;
5974         lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID21] |=
5975                 cpu_to_be16(ICE_PKT_TUNNEL_MASK);
5976 }
5977
5978 void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup)
5979 {
5980         lkup->type = ICE_HW_METADATA;
5981         lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
5982                 cpu_to_be16(ICE_PKT_FROM_NETWORK);
5983 }
5984
5985 void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
5986 {
5987         lkup->type = ICE_HW_METADATA;
5988         lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
5989                 cpu_to_be16(ICE_PKT_VLAN_MASK);
5990 }
5991
5992 void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup)
5993 {
5994         lkup->type = ICE_HW_METADATA;
5995         lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK);
5996 }
5997
5998 /**
5999  * ice_add_adv_rule - helper function to create an advanced switch rule
6000  * @hw: pointer to the hardware structure
6001  * @lkups: information on the words that needs to be looked up. All words
6002  * together makes one recipe
6003  * @lkups_cnt: num of entries in the lkups array
6004  * @rinfo: other information related to the rule that needs to be programmed
6005  * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
6006  *               ignored is case of error.
6007  *
6008  * This function can program only 1 rule at a time. The lkups is used to
6009  * describe the all the words that forms the "lookup" portion of the recipe.
6010  * These words can span multiple protocols. Callers to this function need to
6011  * pass in a list of protocol headers with lookup information along and mask
6012  * that determines which words are valid from the given protocol header.
6013  * rinfo describes other information related to this rule such as forwarding
6014  * IDs, priority of this rule, etc.
6015  */
6016 int
6017 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6018                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
6019                  struct ice_rule_query_data *added_entry)
6020 {
6021         struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
6022         struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
6023         const struct ice_dummy_pkt_profile *profile;
6024         u16 rid = 0, i, rule_buf_sz, vsi_handle;
6025         struct list_head *rule_head;
6026         struct ice_switch_info *sw;
6027         u16 word_cnt;
6028         u32 act = 0;
6029         int status;
6030         u8 q_rgn;
6031
6032         /* Initialize profile to result index bitmap */
6033         if (!hw->switch_info->prof_res_bm_init) {
6034                 hw->switch_info->prof_res_bm_init = 1;
6035                 ice_init_prof_result_bm(hw);
6036         }
6037
6038         if (!lkups_cnt)
6039                 return -EINVAL;
6040
6041         /* get # of words we need to match */
6042         word_cnt = 0;
6043         for (i = 0; i < lkups_cnt; i++) {
6044                 u16 j;
6045
6046                 for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++)
6047                         if (lkups[i].m_raw[j])
6048                                 word_cnt++;
6049         }
6050
6051         if (!word_cnt)
6052                 return -EINVAL;
6053
6054         if (word_cnt > ICE_MAX_CHAIN_WORDS)
6055                 return -ENOSPC;
6056
6057         /* locate a dummy packet */
6058         profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type);
6059         if (IS_ERR(profile))
6060                 return PTR_ERR(profile);
6061
6062         if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6063               rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
6064               rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6065               rinfo->sw_act.fltr_act == ICE_DROP_PACKET ||
6066               rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
6067               rinfo->sw_act.fltr_act == ICE_NOP)) {
6068                 status = -EIO;
6069                 goto free_pkt_profile;
6070         }
6071
6072         vsi_handle = rinfo->sw_act.vsi_handle;
6073         if (!ice_is_vsi_valid(hw, vsi_handle)) {
6074                 status =  -EINVAL;
6075                 goto free_pkt_profile;
6076         }
6077
6078         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6079             rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
6080             rinfo->sw_act.fltr_act == ICE_NOP) {
6081                 rinfo->sw_act.fwd_id.hw_vsi_id =
6082                         ice_get_hw_vsi_num(hw, vsi_handle);
6083         }
6084
6085         if (rinfo->src_vsi)
6086                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, rinfo->src_vsi);
6087         else
6088                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
6089
6090         status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
6091         if (status)
6092                 goto free_pkt_profile;
6093         m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6094         if (m_entry) {
6095                 /* we have to add VSI to VSI_LIST and increment vsi_count.
6096                  * Also Update VSI list so that we can change forwarding rule
6097                  * if the rule already exists, we will check if it exists with
6098                  * same vsi_id, if not then add it to the VSI list if it already
6099                  * exists if not then create a VSI list and add the existing VSI
6100                  * ID and the new VSI ID to the list
6101                  * We will add that VSI to the list
6102                  */
6103                 status = ice_adv_add_update_vsi_list(hw, m_entry,
6104                                                      &m_entry->rule_info,
6105                                                      rinfo);
6106                 if (added_entry) {
6107                         added_entry->rid = rid;
6108                         added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
6109                         added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6110                 }
6111                 goto free_pkt_profile;
6112         }
6113         rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len);
6114         s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6115         if (!s_rule) {
6116                 status = -ENOMEM;
6117                 goto free_pkt_profile;
6118         }
6119
6120         if (rinfo->sw_act.fltr_act != ICE_MIRROR_PACKET) {
6121                 if (!rinfo->flags_info.act_valid) {
6122                         act |= ICE_SINGLE_ACT_LAN_ENABLE;
6123                         act |= ICE_SINGLE_ACT_LB_ENABLE;
6124                 } else {
6125                         act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
6126                                                         ICE_SINGLE_ACT_LB_ENABLE);
6127                 }
6128         }
6129
6130         switch (rinfo->sw_act.fltr_act) {
6131         case ICE_FWD_TO_VSI:
6132                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6133                                   rinfo->sw_act.fwd_id.hw_vsi_id);
6134                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
6135                 break;
6136         case ICE_FWD_TO_Q:
6137                 act |= ICE_SINGLE_ACT_TO_Q;
6138                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
6139                                   rinfo->sw_act.fwd_id.q_id);
6140                 break;
6141         case ICE_FWD_TO_QGRP:
6142                 q_rgn = rinfo->sw_act.qgrp_size > 0 ?
6143                         (u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
6144                 act |= ICE_SINGLE_ACT_TO_Q;
6145                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
6146                                   rinfo->sw_act.fwd_id.q_id);
6147                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
6148                 break;
6149         case ICE_DROP_PACKET:
6150                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
6151                        ICE_SINGLE_ACT_VALID_BIT;
6152                 break;
6153         case ICE_MIRROR_PACKET:
6154                 act |= ICE_SINGLE_ACT_OTHER_ACTS;
6155                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6156                                   rinfo->sw_act.fwd_id.hw_vsi_id);
6157                 break;
6158         case ICE_NOP:
6159                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6160                                   rinfo->sw_act.fwd_id.hw_vsi_id);
6161                 act &= ~ICE_SINGLE_ACT_VALID_BIT;
6162                 break;
6163         default:
6164                 status = -EIO;
6165                 goto err_ice_add_adv_rule;
6166         }
6167
6168         /* If there is no matching criteria for direction there
6169          * is only one difference between Rx and Tx:
6170          * - get switch id base on VSI number from source field (Tx)
6171          * - get switch id base on port number (Rx)
6172          *
6173          * If matching on direction metadata is chose rule direction is
6174          * extracted from type value set here.
6175          */
6176         if (rinfo->sw_act.flag & ICE_FLTR_TX) {
6177                 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
6178                 s_rule->src = cpu_to_le16(rinfo->sw_act.src);
6179         } else {
6180                 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
6181                 s_rule->src = cpu_to_le16(hw->port_info->lport);
6182         }
6183
6184         s_rule->recipe_id = cpu_to_le16(rid);
6185         s_rule->act = cpu_to_le32(act);
6186
6187         status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile);
6188         if (status)
6189                 goto err_ice_add_adv_rule;
6190
6191         status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, s_rule->hdr_data,
6192                                          profile->offsets);
6193         if (status)
6194                 goto err_ice_add_adv_rule;
6195
6196         status = ice_fill_adv_packet_vlan(hw, rinfo->vlan_type,
6197                                           s_rule->hdr_data,
6198                                           profile->offsets);
6199         if (status)
6200                 goto err_ice_add_adv_rule;
6201
6202         status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6203                                  rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
6204                                  NULL);
6205         if (status)
6206                 goto err_ice_add_adv_rule;
6207         adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
6208                                 sizeof(struct ice_adv_fltr_mgmt_list_entry),
6209                                 GFP_KERNEL);
6210         if (!adv_fltr) {
6211                 status = -ENOMEM;
6212                 goto err_ice_add_adv_rule;
6213         }
6214
6215         adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
6216                                        lkups_cnt * sizeof(*lkups), GFP_KERNEL);
6217         if (!adv_fltr->lkups) {
6218                 status = -ENOMEM;
6219                 goto err_ice_add_adv_rule;
6220         }
6221
6222         adv_fltr->lkups_cnt = lkups_cnt;
6223         adv_fltr->rule_info = *rinfo;
6224         adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index);
6225         sw = hw->switch_info;
6226         sw->recp_list[rid].adv_rule = true;
6227         rule_head = &sw->recp_list[rid].filt_rules;
6228
6229         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6230                 adv_fltr->vsi_count = 1;
6231
6232         /* Add rule entry to book keeping list */
6233         list_add(&adv_fltr->list_entry, rule_head);
6234         if (added_entry) {
6235                 added_entry->rid = rid;
6236                 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
6237                 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6238         }
6239 err_ice_add_adv_rule:
6240         if (status && adv_fltr) {
6241                 devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
6242                 devm_kfree(ice_hw_to_dev(hw), adv_fltr);
6243         }
6244
6245         kfree(s_rule);
6246
6247 free_pkt_profile:
6248         if (profile->match & ICE_PKT_KMALLOC) {
6249                 kfree(profile->offsets);
6250                 kfree(profile->pkt);
6251                 kfree(profile);
6252         }
6253
6254         return status;
6255 }
6256
6257 /**
6258  * ice_replay_vsi_fltr - Replay filters for requested VSI
6259  * @hw: pointer to the hardware structure
6260  * @vsi_handle: driver VSI handle
6261  * @recp_id: Recipe ID for which rules need to be replayed
6262  * @list_head: list for which filters need to be replayed
6263  *
6264  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
6265  * It is required to pass valid VSI handle.
6266  */
6267 static int
6268 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
6269                     struct list_head *list_head)
6270 {
6271         struct ice_fltr_mgmt_list_entry *itr;
6272         int status = 0;
6273         u16 hw_vsi_id;
6274
6275         if (list_empty(list_head))
6276                 return status;
6277         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6278
6279         list_for_each_entry(itr, list_head, list_entry) {
6280                 struct ice_fltr_list_entry f_entry;
6281
6282                 f_entry.fltr_info = itr->fltr_info;
6283                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
6284                     itr->fltr_info.vsi_handle == vsi_handle) {
6285                         /* update the src in case it is VSI num */
6286                         if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6287                                 f_entry.fltr_info.src = hw_vsi_id;
6288                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
6289                         if (status)
6290                                 goto end;
6291                         continue;
6292                 }
6293                 if (!itr->vsi_list_info ||
6294                     !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
6295                         continue;
6296                 /* Clearing it so that the logic can add it back */
6297                 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
6298                 f_entry.fltr_info.vsi_handle = vsi_handle;
6299                 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
6300                 /* update the src in case it is VSI num */
6301                 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6302                         f_entry.fltr_info.src = hw_vsi_id;
6303                 if (recp_id == ICE_SW_LKUP_VLAN)
6304                         status = ice_add_vlan_internal(hw, &f_entry);
6305                 else
6306                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
6307                 if (status)
6308                         goto end;
6309         }
6310 end:
6311         return status;
6312 }
6313
6314 /**
6315  * ice_adv_rem_update_vsi_list
6316  * @hw: pointer to the hardware structure
6317  * @vsi_handle: VSI handle of the VSI to remove
6318  * @fm_list: filter management entry for which the VSI list management needs to
6319  *           be done
6320  */
6321 static int
6322 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
6323                             struct ice_adv_fltr_mgmt_list_entry *fm_list)
6324 {
6325         struct ice_vsi_list_map_info *vsi_list_info;
6326         enum ice_sw_lkup_type lkup_type;
6327         u16 vsi_list_id;
6328         int status;
6329
6330         if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
6331             fm_list->vsi_count == 0)
6332                 return -EINVAL;
6333
6334         /* A rule with the VSI being removed does not exist */
6335         if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
6336                 return -ENOENT;
6337
6338         lkup_type = ICE_SW_LKUP_LAST;
6339         vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
6340         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
6341                                           ice_aqc_opc_update_sw_rules,
6342                                           lkup_type);
6343         if (status)
6344                 return status;
6345
6346         fm_list->vsi_count--;
6347         clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
6348         vsi_list_info = fm_list->vsi_list_info;
6349         if (fm_list->vsi_count == 1) {
6350                 struct ice_fltr_info tmp_fltr;
6351                 u16 rem_vsi_handle;
6352
6353                 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
6354                                                 ICE_MAX_VSI);
6355                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
6356                         return -EIO;
6357
6358                 /* Make sure VSI list is empty before removing it below */
6359                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
6360                                                   vsi_list_id, true,
6361                                                   ice_aqc_opc_update_sw_rules,
6362                                                   lkup_type);
6363                 if (status)
6364                         return status;
6365
6366                 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6367                 tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
6368                 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
6369                 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
6370                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
6371                 tmp_fltr.fwd_id.hw_vsi_id =
6372                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
6373                 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
6374                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
6375                 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
6376
6377                 /* Update the previous switch rule of "MAC forward to VSI" to
6378                  * "MAC fwd to VSI list"
6379                  */
6380                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6381                 if (status) {
6382                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
6383                                   tmp_fltr.fwd_id.hw_vsi_id, status);
6384                         return status;
6385                 }
6386                 fm_list->vsi_list_info->ref_cnt--;
6387
6388                 /* Remove the VSI list since it is no longer used */
6389                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
6390                 if (status) {
6391                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
6392                                   vsi_list_id, status);
6393                         return status;
6394                 }
6395
6396                 list_del(&vsi_list_info->list_entry);
6397                 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
6398                 fm_list->vsi_list_info = NULL;
6399         }
6400
6401         return status;
6402 }
6403
6404 /**
6405  * ice_rem_adv_rule - removes existing advanced switch rule
6406  * @hw: pointer to the hardware structure
6407  * @lkups: information on the words that needs to be looked up. All words
6408  *         together makes one recipe
6409  * @lkups_cnt: num of entries in the lkups array
6410  * @rinfo: Its the pointer to the rule information for the rule
6411  *
6412  * This function can be used to remove 1 rule at a time. The lkups is
6413  * used to describe all the words that forms the "lookup" portion of the
6414  * rule. These words can span multiple protocols. Callers to this function
6415  * need to pass in a list of protocol headers with lookup information along
6416  * and mask that determines which words are valid from the given protocol
6417  * header. rinfo describes other information related to this rule such as
6418  * forwarding IDs, priority of this rule, etc.
6419  */
6420 static int
6421 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6422                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
6423 {
6424         struct ice_adv_fltr_mgmt_list_entry *list_elem;
6425         struct ice_prot_lkup_ext lkup_exts;
6426         bool remove_rule = false;
6427         struct mutex *rule_lock; /* Lock to protect filter rule list */
6428         u16 i, rid, vsi_handle;
6429         int status = 0;
6430
6431         memset(&lkup_exts, 0, sizeof(lkup_exts));
6432         for (i = 0; i < lkups_cnt; i++) {
6433                 u16 count;
6434
6435                 if (lkups[i].type >= ICE_PROTOCOL_LAST)
6436                         return -EIO;
6437
6438                 count = ice_fill_valid_words(&lkups[i], &lkup_exts);
6439                 if (!count)
6440                         return -EIO;
6441         }
6442
6443         rid = ice_find_recp(hw, &lkup_exts, rinfo);
6444         /* If did not find a recipe that match the existing criteria */
6445         if (rid == ICE_MAX_NUM_RECIPES)
6446                 return -EINVAL;
6447
6448         rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
6449         list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6450         /* the rule is already removed */
6451         if (!list_elem)
6452                 return 0;
6453         mutex_lock(rule_lock);
6454         if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
6455                 remove_rule = true;
6456         } else if (list_elem->vsi_count > 1) {
6457                 remove_rule = false;
6458                 vsi_handle = rinfo->sw_act.vsi_handle;
6459                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6460         } else {
6461                 vsi_handle = rinfo->sw_act.vsi_handle;
6462                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6463                 if (status) {
6464                         mutex_unlock(rule_lock);
6465                         return status;
6466                 }
6467                 if (list_elem->vsi_count == 0)
6468                         remove_rule = true;
6469         }
6470         mutex_unlock(rule_lock);
6471         if (remove_rule) {
6472                 struct ice_sw_rule_lkup_rx_tx *s_rule;
6473                 u16 rule_buf_sz;
6474
6475                 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule);
6476                 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6477                 if (!s_rule)
6478                         return -ENOMEM;
6479                 s_rule->act = 0;
6480                 s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id);
6481                 s_rule->hdr_len = 0;
6482                 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6483                                          rule_buf_sz, 1,
6484                                          ice_aqc_opc_remove_sw_rules, NULL);
6485                 if (!status || status == -ENOENT) {
6486                         struct ice_switch_info *sw = hw->switch_info;
6487
6488                         mutex_lock(rule_lock);
6489                         list_del(&list_elem->list_entry);
6490                         devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
6491                         devm_kfree(ice_hw_to_dev(hw), list_elem);
6492                         mutex_unlock(rule_lock);
6493                         if (list_empty(&sw->recp_list[rid].filt_rules))
6494                                 sw->recp_list[rid].adv_rule = false;
6495                 }
6496                 kfree(s_rule);
6497         }
6498         return status;
6499 }
6500
6501 /**
6502  * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
6503  * @hw: pointer to the hardware structure
6504  * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
6505  *
6506  * This function is used to remove 1 rule at a time. The removal is based on
6507  * the remove_entry parameter. This function will remove rule for a given
6508  * vsi_handle with a given rule_id which is passed as parameter in remove_entry
6509  */
6510 int
6511 ice_rem_adv_rule_by_id(struct ice_hw *hw,
6512                        struct ice_rule_query_data *remove_entry)
6513 {
6514         struct ice_adv_fltr_mgmt_list_entry *list_itr;
6515         struct list_head *list_head;
6516         struct ice_adv_rule_info rinfo;
6517         struct ice_switch_info *sw;
6518
6519         sw = hw->switch_info;
6520         if (!sw->recp_list[remove_entry->rid].recp_created)
6521                 return -EINVAL;
6522         list_head = &sw->recp_list[remove_entry->rid].filt_rules;
6523         list_for_each_entry(list_itr, list_head, list_entry) {
6524                 if (list_itr->rule_info.fltr_rule_id ==
6525                     remove_entry->rule_id) {
6526                         rinfo = list_itr->rule_info;
6527                         rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
6528                         return ice_rem_adv_rule(hw, list_itr->lkups,
6529                                                 list_itr->lkups_cnt, &rinfo);
6530                 }
6531         }
6532         /* either list is empty or unable to find rule */
6533         return -ENOENT;
6534 }
6535
6536 /**
6537  * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
6538  * @hw: pointer to the hardware structure
6539  * @vsi_handle: driver VSI handle
6540  * @list_head: list for which filters need to be replayed
6541  *
6542  * Replay the advanced rule for the given VSI.
6543  */
6544 static int
6545 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
6546                         struct list_head *list_head)
6547 {
6548         struct ice_rule_query_data added_entry = { 0 };
6549         struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
6550         int status = 0;
6551
6552         if (list_empty(list_head))
6553                 return status;
6554         list_for_each_entry(adv_fltr, list_head, list_entry) {
6555                 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
6556                 u16 lk_cnt = adv_fltr->lkups_cnt;
6557
6558                 if (vsi_handle != rinfo->sw_act.vsi_handle)
6559                         continue;
6560                 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
6561                                           &added_entry);
6562                 if (status)
6563                         break;
6564         }
6565         return status;
6566 }
6567
6568 /**
6569  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
6570  * @hw: pointer to the hardware structure
6571  * @vsi_handle: driver VSI handle
6572  *
6573  * Replays filters for requested VSI via vsi_handle.
6574  */
6575 int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
6576 {
6577         struct ice_switch_info *sw = hw->switch_info;
6578         int status;
6579         u8 i;
6580
6581         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6582                 struct list_head *head;
6583
6584                 head = &sw->recp_list[i].filt_replay_rules;
6585                 if (!sw->recp_list[i].adv_rule)
6586                         status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
6587                 else
6588                         status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
6589                 if (status)
6590                         return status;
6591         }
6592         return status;
6593 }
6594
6595 /**
6596  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
6597  * @hw: pointer to the HW struct
6598  *
6599  * Deletes the filter replay rules.
6600  */
6601 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
6602 {
6603         struct ice_switch_info *sw = hw->switch_info;
6604         u8 i;
6605
6606         if (!sw)
6607                 return;
6608
6609         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6610                 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
6611                         struct list_head *l_head;
6612
6613                         l_head = &sw->recp_list[i].filt_replay_rules;
6614                         if (!sw->recp_list[i].adv_rule)
6615                                 ice_rem_sw_rule_info(hw, l_head);
6616                         else
6617                                 ice_rem_adv_rule_info(hw, l_head);
6618                 }
6619         }
6620 }