netfilter: arptables: Select NETFILTER_FAMILY_ARP when building arp_tables.c
[sfrench/cifs-2.6.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_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_bitmap: 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, u8 *r_bitmap,
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         memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_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_bitmap: 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, u8 *r_bitmap,
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                 memcpy(r_bitmap, cmd->recipe_assoc, sizeof(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_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         u16 i;
2112
2113         for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2114                 u16 j;
2115
2116                 bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2117                 bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
2118                 if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
2119                         continue;
2120                 bitmap_copy(profile_to_recipe[i], r_bitmap,
2121                             ICE_MAX_NUM_RECIPES);
2122                 for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2123                         set_bit(i, recipe_to_profile[j]);
2124         }
2125 }
2126
2127 /**
2128  * ice_collect_result_idx - copy result index values
2129  * @buf: buffer that contains the result index
2130  * @recp: the recipe struct to copy data into
2131  */
2132 static void
2133 ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
2134                        struct ice_sw_recipe *recp)
2135 {
2136         if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2137                 set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2138                         recp->res_idxs);
2139 }
2140
2141 /**
2142  * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
2143  * @hw: pointer to hardware structure
2144  * @recps: struct that we need to populate
2145  * @rid: recipe ID that we are populating
2146  * @refresh_required: true if we should get recipe to profile mapping from FW
2147  *
2148  * This function is used to populate all the necessary entries into our
2149  * bookkeeping so that we have a current list of all the recipes that are
2150  * programmed in the firmware.
2151  */
2152 static int
2153 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2154                     bool *refresh_required)
2155 {
2156         DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS);
2157         struct ice_aqc_recipe_data_elem *tmp;
2158         u16 num_recps = ICE_MAX_NUM_RECIPES;
2159         struct ice_prot_lkup_ext *lkup_exts;
2160         u8 fv_word_idx = 0;
2161         u16 sub_recps;
2162         int status;
2163
2164         bitmap_zero(result_bm, ICE_MAX_FV_WORDS);
2165
2166         /* we need a buffer big enough to accommodate all the recipes */
2167         tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
2168         if (!tmp)
2169                 return -ENOMEM;
2170
2171         tmp[0].recipe_indx = rid;
2172         status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2173         /* non-zero status meaning recipe doesn't exist */
2174         if (status)
2175                 goto err_unroll;
2176
2177         /* Get recipe to profile map so that we can get the fv from lkups that
2178          * we read for a recipe from FW. Since we want to minimize the number of
2179          * times we make this FW call, just make one call and cache the copy
2180          * until a new recipe is added. This operation is only required the
2181          * first time to get the changes from FW. Then to search existing
2182          * entries we don't need to update the cache again until another recipe
2183          * gets added.
2184          */
2185         if (*refresh_required) {
2186                 ice_get_recp_to_prof_map(hw);
2187                 *refresh_required = false;
2188         }
2189
2190         /* Start populating all the entries for recps[rid] based on lkups from
2191          * firmware. Note that we are only creating the root recipe in our
2192          * database.
2193          */
2194         lkup_exts = &recps[rid].lkup_exts;
2195
2196         for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2197                 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2198                 struct ice_recp_grp_entry *rg_entry;
2199                 u8 i, prof, idx, prot = 0;
2200                 bool is_root;
2201                 u16 off = 0;
2202
2203                 rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry),
2204                                         GFP_KERNEL);
2205                 if (!rg_entry) {
2206                         status = -ENOMEM;
2207                         goto err_unroll;
2208                 }
2209
2210                 idx = root_bufs.recipe_indx;
2211                 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2212
2213                 /* Mark all result indices in this chain */
2214                 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2215                         set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2216                                 result_bm);
2217
2218                 /* get the first profile that is associated with rid */
2219                 prof = find_first_bit(recipe_to_profile[idx],
2220                                       ICE_MAX_NUM_PROFILES);
2221                 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2222                         u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2223
2224                         rg_entry->fv_idx[i] = lkup_indx;
2225                         rg_entry->fv_mask[i] =
2226                                 le16_to_cpu(root_bufs.content.mask[i + 1]);
2227
2228                         /* If the recipe is a chained recipe then all its
2229                          * child recipe's result will have a result index.
2230                          * To fill fv_words we should not use those result
2231                          * index, we only need the protocol ids and offsets.
2232                          * We will skip all the fv_idx which stores result
2233                          * index in them. We also need to skip any fv_idx which
2234                          * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2235                          * valid offset value.
2236                          */
2237                         if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) ||
2238                             rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2239                             rg_entry->fv_idx[i] == 0)
2240                                 continue;
2241
2242                         ice_find_prot_off(hw, ICE_BLK_SW, prof,
2243                                           rg_entry->fv_idx[i], &prot, &off);
2244                         lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2245                         lkup_exts->fv_words[fv_word_idx].off = off;
2246                         lkup_exts->field_mask[fv_word_idx] =
2247                                 rg_entry->fv_mask[i];
2248                         fv_word_idx++;
2249                 }
2250                 /* populate rg_list with the data from the child entry of this
2251                  * recipe
2252                  */
2253                 list_add(&rg_entry->l_entry, &recps[rid].rg_list);
2254
2255                 /* Propagate some data to the recipe database */
2256                 recps[idx].is_root = !!is_root;
2257                 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2258                 recps[idx].need_pass_l2 = root_bufs.content.act_ctrl &
2259                                           ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
2260                 recps[idx].allow_pass_l2 = root_bufs.content.act_ctrl &
2261                                            ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
2262                 bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2263                 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2264                         recps[idx].chain_idx = root_bufs.content.result_indx &
2265                                 ~ICE_AQ_RECIPE_RESULT_EN;
2266                         set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2267                 } else {
2268                         recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2269                 }
2270
2271                 if (!is_root)
2272                         continue;
2273
2274                 /* Only do the following for root recipes entries */
2275                 memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2276                        sizeof(recps[idx].r_bitmap));
2277                 recps[idx].root_rid = root_bufs.content.rid &
2278                         ~ICE_AQ_RECIPE_ID_IS_ROOT;
2279                 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2280         }
2281
2282         /* Complete initialization of the root recipe entry */
2283         lkup_exts->n_val_words = fv_word_idx;
2284         recps[rid].big_recp = (num_recps > 1);
2285         recps[rid].n_grp_count = (u8)num_recps;
2286         recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp,
2287                                            recps[rid].n_grp_count * sizeof(*recps[rid].root_buf),
2288                                            GFP_KERNEL);
2289         if (!recps[rid].root_buf) {
2290                 status = -ENOMEM;
2291                 goto err_unroll;
2292         }
2293
2294         /* Copy result indexes */
2295         bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2296         recps[rid].recp_created = true;
2297
2298 err_unroll:
2299         kfree(tmp);
2300         return status;
2301 }
2302
2303 /* ice_init_port_info - Initialize port_info with switch configuration data
2304  * @pi: pointer to port_info
2305  * @vsi_port_num: VSI number or port number
2306  * @type: Type of switch element (port or VSI)
2307  * @swid: switch ID of the switch the element is attached to
2308  * @pf_vf_num: PF or VF number
2309  * @is_vf: true if the element is a VF, false otherwise
2310  */
2311 static void
2312 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
2313                    u16 swid, u16 pf_vf_num, bool is_vf)
2314 {
2315         switch (type) {
2316         case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
2317                 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
2318                 pi->sw_id = swid;
2319                 pi->pf_vf_num = pf_vf_num;
2320                 pi->is_vf = is_vf;
2321                 break;
2322         default:
2323                 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
2324                 break;
2325         }
2326 }
2327
2328 /* ice_get_initial_sw_cfg - Get initial port and default VSI data
2329  * @hw: pointer to the hardware structure
2330  */
2331 int ice_get_initial_sw_cfg(struct ice_hw *hw)
2332 {
2333         struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
2334         u16 req_desc = 0;
2335         u16 num_elems;
2336         int status;
2337         u16 i;
2338
2339         rbuf = kzalloc(ICE_SW_CFG_MAX_BUF_LEN, GFP_KERNEL);
2340         if (!rbuf)
2341                 return -ENOMEM;
2342
2343         /* Multiple calls to ice_aq_get_sw_cfg may be required
2344          * to get all the switch configuration information. The need
2345          * for additional calls is indicated by ice_aq_get_sw_cfg
2346          * writing a non-zero value in req_desc
2347          */
2348         do {
2349                 struct ice_aqc_get_sw_cfg_resp_elem *ele;
2350
2351                 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
2352                                            &req_desc, &num_elems, NULL);
2353
2354                 if (status)
2355                         break;
2356
2357                 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
2358                         u16 pf_vf_num, swid, vsi_port_num;
2359                         bool is_vf = false;
2360                         u8 res_type;
2361
2362                         vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
2363                                 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
2364
2365                         pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
2366                                 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
2367
2368                         swid = le16_to_cpu(ele->swid);
2369
2370                         if (le16_to_cpu(ele->pf_vf_num) &
2371                             ICE_AQC_GET_SW_CONF_RESP_IS_VF)
2372                                 is_vf = true;
2373
2374                         res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
2375                                         ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
2376
2377                         if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
2378                                 /* FW VSI is not needed. Just continue. */
2379                                 continue;
2380                         }
2381
2382                         ice_init_port_info(hw->port_info, vsi_port_num,
2383                                            res_type, swid, pf_vf_num, is_vf);
2384                 }
2385         } while (req_desc && !status);
2386
2387         kfree(rbuf);
2388         return status;
2389 }
2390
2391 /**
2392  * ice_fill_sw_info - Helper function to populate lb_en and lan_en
2393  * @hw: pointer to the hardware structure
2394  * @fi: filter info structure to fill/update
2395  *
2396  * This helper function populates the lb_en and lan_en elements of the provided
2397  * ice_fltr_info struct using the switch's type and characteristics of the
2398  * switch rule being configured.
2399  */
2400 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
2401 {
2402         fi->lb_en = false;
2403         fi->lan_en = false;
2404         if ((fi->flag & ICE_FLTR_TX) &&
2405             (fi->fltr_act == ICE_FWD_TO_VSI ||
2406              fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2407              fi->fltr_act == ICE_FWD_TO_Q ||
2408              fi->fltr_act == ICE_FWD_TO_QGRP)) {
2409                 /* Setting LB for prune actions will result in replicated
2410                  * packets to the internal switch that will be dropped.
2411                  */
2412                 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
2413                         fi->lb_en = true;
2414
2415                 /* Set lan_en to TRUE if
2416                  * 1. The switch is a VEB AND
2417                  * 2
2418                  * 2.1 The lookup is a directional lookup like ethertype,
2419                  * promiscuous, ethertype-MAC, promiscuous-VLAN
2420                  * and default-port OR
2421                  * 2.2 The lookup is VLAN, OR
2422                  * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
2423                  * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
2424                  *
2425                  * OR
2426                  *
2427                  * The switch is a VEPA.
2428                  *
2429                  * In all other cases, the LAN enable has to be set to false.
2430                  */
2431                 if (hw->evb_veb) {
2432                         if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2433                             fi->lkup_type == ICE_SW_LKUP_PROMISC ||
2434                             fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2435                             fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2436                             fi->lkup_type == ICE_SW_LKUP_DFLT ||
2437                             fi->lkup_type == ICE_SW_LKUP_VLAN ||
2438                             (fi->lkup_type == ICE_SW_LKUP_MAC &&
2439                              !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
2440                             (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
2441                              !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
2442                                 fi->lan_en = true;
2443                 } else {
2444                         fi->lan_en = true;
2445                 }
2446         }
2447 }
2448
2449 /**
2450  * ice_fill_eth_hdr - helper to copy dummy_eth_hdr into supplied buffer
2451  * @eth_hdr: pointer to buffer to populate
2452  */
2453 void ice_fill_eth_hdr(u8 *eth_hdr)
2454 {
2455         memcpy(eth_hdr, dummy_eth_header, DUMMY_ETH_HDR_LEN);
2456 }
2457
2458 /**
2459  * ice_fill_sw_rule - Helper function to fill switch rule structure
2460  * @hw: pointer to the hardware structure
2461  * @f_info: entry containing packet forwarding information
2462  * @s_rule: switch rule structure to be filled in based on mac_entry
2463  * @opc: switch rules population command type - pass in the command opcode
2464  */
2465 static void
2466 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
2467                  struct ice_sw_rule_lkup_rx_tx *s_rule,
2468                  enum ice_adminq_opc opc)
2469 {
2470         u16 vlan_id = ICE_MAX_VLAN_ID + 1;
2471         u16 vlan_tpid = ETH_P_8021Q;
2472         void *daddr = NULL;
2473         u16 eth_hdr_sz;
2474         u8 *eth_hdr;
2475         u32 act = 0;
2476         __be16 *off;
2477         u8 q_rgn;
2478
2479         if (opc == ice_aqc_opc_remove_sw_rules) {
2480                 s_rule->act = 0;
2481                 s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2482                 s_rule->hdr_len = 0;
2483                 return;
2484         }
2485
2486         eth_hdr_sz = sizeof(dummy_eth_header);
2487         eth_hdr = s_rule->hdr_data;
2488
2489         /* initialize the ether header with a dummy header */
2490         memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
2491         ice_fill_sw_info(hw, f_info);
2492
2493         switch (f_info->fltr_act) {
2494         case ICE_FWD_TO_VSI:
2495                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
2496                                   f_info->fwd_id.hw_vsi_id);
2497                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2498                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2499                                 ICE_SINGLE_ACT_VALID_BIT;
2500                 break;
2501         case ICE_FWD_TO_VSI_LIST:
2502                 act |= ICE_SINGLE_ACT_VSI_LIST;
2503                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_LIST_ID_M,
2504                                   f_info->fwd_id.vsi_list_id);
2505                 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2506                         act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2507                                 ICE_SINGLE_ACT_VALID_BIT;
2508                 break;
2509         case ICE_FWD_TO_Q:
2510                 act |= ICE_SINGLE_ACT_TO_Q;
2511                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
2512                                   f_info->fwd_id.q_id);
2513                 break;
2514         case ICE_DROP_PACKET:
2515                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
2516                         ICE_SINGLE_ACT_VALID_BIT;
2517                 break;
2518         case ICE_FWD_TO_QGRP:
2519                 q_rgn = f_info->qgrp_size > 0 ?
2520                         (u8)ilog2(f_info->qgrp_size) : 0;
2521                 act |= ICE_SINGLE_ACT_TO_Q;
2522                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
2523                                   f_info->fwd_id.q_id);
2524                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
2525                 break;
2526         default:
2527                 return;
2528         }
2529
2530         if (f_info->lb_en)
2531                 act |= ICE_SINGLE_ACT_LB_ENABLE;
2532         if (f_info->lan_en)
2533                 act |= ICE_SINGLE_ACT_LAN_ENABLE;
2534
2535         switch (f_info->lkup_type) {
2536         case ICE_SW_LKUP_MAC:
2537                 daddr = f_info->l_data.mac.mac_addr;
2538                 break;
2539         case ICE_SW_LKUP_VLAN:
2540                 vlan_id = f_info->l_data.vlan.vlan_id;
2541                 if (f_info->l_data.vlan.tpid_valid)
2542                         vlan_tpid = f_info->l_data.vlan.tpid;
2543                 if (f_info->fltr_act == ICE_FWD_TO_VSI ||
2544                     f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
2545                         act |= ICE_SINGLE_ACT_PRUNE;
2546                         act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
2547                 }
2548                 break;
2549         case ICE_SW_LKUP_ETHERTYPE_MAC:
2550                 daddr = f_info->l_data.ethertype_mac.mac_addr;
2551                 fallthrough;
2552         case ICE_SW_LKUP_ETHERTYPE:
2553                 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2554                 *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
2555                 break;
2556         case ICE_SW_LKUP_MAC_VLAN:
2557                 daddr = f_info->l_data.mac_vlan.mac_addr;
2558                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
2559                 break;
2560         case ICE_SW_LKUP_PROMISC_VLAN:
2561                 vlan_id = f_info->l_data.mac_vlan.vlan_id;
2562                 fallthrough;
2563         case ICE_SW_LKUP_PROMISC:
2564                 daddr = f_info->l_data.mac_vlan.mac_addr;
2565                 break;
2566         default:
2567                 break;
2568         }
2569
2570         s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ?
2571                 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
2572                 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
2573
2574         /* Recipe set depending on lookup type */
2575         s_rule->recipe_id = cpu_to_le16(f_info->lkup_type);
2576         s_rule->src = cpu_to_le16(f_info->src);
2577         s_rule->act = cpu_to_le32(act);
2578
2579         if (daddr)
2580                 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
2581
2582         if (!(vlan_id > ICE_MAX_VLAN_ID)) {
2583                 off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
2584                 *off = cpu_to_be16(vlan_id);
2585                 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2586                 *off = cpu_to_be16(vlan_tpid);
2587         }
2588
2589         /* Create the switch rule with the final dummy Ethernet header */
2590         if (opc != ice_aqc_opc_update_sw_rules)
2591                 s_rule->hdr_len = cpu_to_le16(eth_hdr_sz);
2592 }
2593
2594 /**
2595  * ice_add_marker_act
2596  * @hw: pointer to the hardware structure
2597  * @m_ent: the management entry for which sw marker needs to be added
2598  * @sw_marker: sw marker to tag the Rx descriptor with
2599  * @l_id: large action resource ID
2600  *
2601  * Create a large action to hold software marker and update the switch rule
2602  * entry pointed by m_ent with newly created large action
2603  */
2604 static int
2605 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
2606                    u16 sw_marker, u16 l_id)
2607 {
2608         struct ice_sw_rule_lkup_rx_tx *rx_tx;
2609         struct ice_sw_rule_lg_act *lg_act;
2610         /* For software marker we need 3 large actions
2611          * 1. FWD action: FWD TO VSI or VSI LIST
2612          * 2. GENERIC VALUE action to hold the profile ID
2613          * 3. GENERIC VALUE action to hold the software marker ID
2614          */
2615         const u16 num_lg_acts = 3;
2616         u16 lg_act_size;
2617         u16 rules_size;
2618         int status;
2619         u32 act;
2620         u16 id;
2621
2622         if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
2623                 return -EINVAL;
2624
2625         /* Create two back-to-back switch rules and submit them to the HW using
2626          * one memory buffer:
2627          *    1. Large Action
2628          *    2. Look up Tx Rx
2629          */
2630         lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts);
2631         rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx);
2632         lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
2633         if (!lg_act)
2634                 return -ENOMEM;
2635
2636         rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size);
2637
2638         /* Fill in the first switch rule i.e. large action */
2639         lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
2640         lg_act->index = cpu_to_le16(l_id);
2641         lg_act->size = cpu_to_le16(num_lg_acts);
2642
2643         /* First action VSI forwarding or VSI list forwarding depending on how
2644          * many VSIs
2645          */
2646         id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
2647                 m_ent->fltr_info.fwd_id.hw_vsi_id;
2648
2649         act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
2650         act |= FIELD_PREP(ICE_LG_ACT_VSI_LIST_ID_M, id);
2651         if (m_ent->vsi_count > 1)
2652                 act |= ICE_LG_ACT_VSI_LIST;
2653         lg_act->act[0] = cpu_to_le32(act);
2654
2655         /* Second action descriptor type */
2656         act = ICE_LG_ACT_GENERIC;
2657
2658         act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, 1);
2659         lg_act->act[1] = cpu_to_le32(act);
2660
2661         act = FIELD_PREP(ICE_LG_ACT_GENERIC_OFFSET_M,
2662                          ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX);
2663
2664         /* Third action Marker value */
2665         act |= ICE_LG_ACT_GENERIC;
2666         act |= FIELD_PREP(ICE_LG_ACT_GENERIC_VALUE_M, sw_marker);
2667
2668         lg_act->act[2] = cpu_to_le32(act);
2669
2670         /* call the fill switch rule to fill the lookup Tx Rx structure */
2671         ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
2672                          ice_aqc_opc_update_sw_rules);
2673
2674         /* Update the action to point to the large action ID */
2675         act = ICE_SINGLE_ACT_PTR;
2676         act |= FIELD_PREP(ICE_SINGLE_ACT_PTR_VAL_M, l_id);
2677         rx_tx->act = cpu_to_le32(act);
2678
2679         /* Use the filter rule ID of the previously created rule with single
2680          * act. Once the update happens, hardware will treat this as large
2681          * action
2682          */
2683         rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
2684
2685         status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
2686                                  ice_aqc_opc_update_sw_rules, NULL);
2687         if (!status) {
2688                 m_ent->lg_act_idx = l_id;
2689                 m_ent->sw_marker_id = sw_marker;
2690         }
2691
2692         devm_kfree(ice_hw_to_dev(hw), lg_act);
2693         return status;
2694 }
2695
2696 /**
2697  * ice_create_vsi_list_map
2698  * @hw: pointer to the hardware structure
2699  * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
2700  * @num_vsi: number of VSI handles in the array
2701  * @vsi_list_id: VSI list ID generated as part of allocate resource
2702  *
2703  * Helper function to create a new entry of VSI list ID to VSI mapping
2704  * using the given VSI list ID
2705  */
2706 static struct ice_vsi_list_map_info *
2707 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2708                         u16 vsi_list_id)
2709 {
2710         struct ice_switch_info *sw = hw->switch_info;
2711         struct ice_vsi_list_map_info *v_map;
2712         int i;
2713
2714         v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
2715         if (!v_map)
2716                 return NULL;
2717
2718         v_map->vsi_list_id = vsi_list_id;
2719         v_map->ref_cnt = 1;
2720         for (i = 0; i < num_vsi; i++)
2721                 set_bit(vsi_handle_arr[i], v_map->vsi_map);
2722
2723         list_add(&v_map->list_entry, &sw->vsi_list_map_head);
2724         return v_map;
2725 }
2726
2727 /**
2728  * ice_update_vsi_list_rule
2729  * @hw: pointer to the hardware structure
2730  * @vsi_handle_arr: array of VSI handles to form a VSI list
2731  * @num_vsi: number of VSI handles in the array
2732  * @vsi_list_id: VSI list ID generated as part of allocate resource
2733  * @remove: Boolean value to indicate if this is a remove action
2734  * @opc: switch rules population command type - pass in the command opcode
2735  * @lkup_type: lookup type of the filter
2736  *
2737  * Call AQ command to add a new switch rule or update existing switch rule
2738  * using the given VSI list ID
2739  */
2740 static int
2741 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2742                          u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
2743                          enum ice_sw_lkup_type lkup_type)
2744 {
2745         struct ice_sw_rule_vsi_list *s_rule;
2746         u16 s_rule_size;
2747         u16 rule_type;
2748         int status;
2749         int i;
2750
2751         if (!num_vsi)
2752                 return -EINVAL;
2753
2754         if (lkup_type == ICE_SW_LKUP_MAC ||
2755             lkup_type == ICE_SW_LKUP_MAC_VLAN ||
2756             lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2757             lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2758             lkup_type == ICE_SW_LKUP_PROMISC ||
2759             lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2760             lkup_type == ICE_SW_LKUP_DFLT)
2761                 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
2762                         ICE_AQC_SW_RULES_T_VSI_LIST_SET;
2763         else if (lkup_type == ICE_SW_LKUP_VLAN)
2764                 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
2765                         ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
2766         else
2767                 return -EINVAL;
2768
2769         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
2770         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
2771         if (!s_rule)
2772                 return -ENOMEM;
2773         for (i = 0; i < num_vsi; i++) {
2774                 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
2775                         status = -EINVAL;
2776                         goto exit;
2777                 }
2778                 /* AQ call requires hw_vsi_id(s) */
2779                 s_rule->vsi[i] =
2780                         cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
2781         }
2782
2783         s_rule->hdr.type = cpu_to_le16(rule_type);
2784         s_rule->number_vsi = cpu_to_le16(num_vsi);
2785         s_rule->index = cpu_to_le16(vsi_list_id);
2786
2787         status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
2788
2789 exit:
2790         devm_kfree(ice_hw_to_dev(hw), s_rule);
2791         return status;
2792 }
2793
2794 /**
2795  * ice_create_vsi_list_rule - Creates and populates a VSI list rule
2796  * @hw: pointer to the HW struct
2797  * @vsi_handle_arr: array of VSI handles to form a VSI list
2798  * @num_vsi: number of VSI handles in the array
2799  * @vsi_list_id: stores the ID of the VSI list to be created
2800  * @lkup_type: switch rule filter's lookup type
2801  */
2802 static int
2803 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2804                          u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
2805 {
2806         int status;
2807
2808         status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
2809                                             ice_aqc_opc_alloc_res);
2810         if (status)
2811                 return status;
2812
2813         /* Update the newly created VSI list to include the specified VSIs */
2814         return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
2815                                         *vsi_list_id, false,
2816                                         ice_aqc_opc_add_sw_rules, lkup_type);
2817 }
2818
2819 /**
2820  * ice_create_pkt_fwd_rule
2821  * @hw: pointer to the hardware structure
2822  * @f_entry: entry containing packet forwarding information
2823  *
2824  * Create switch rule with given filter information and add an entry
2825  * to the corresponding filter management list to track this switch rule
2826  * and VSI mapping
2827  */
2828 static int
2829 ice_create_pkt_fwd_rule(struct ice_hw *hw,
2830                         struct ice_fltr_list_entry *f_entry)
2831 {
2832         struct ice_fltr_mgmt_list_entry *fm_entry;
2833         struct ice_sw_rule_lkup_rx_tx *s_rule;
2834         enum ice_sw_lkup_type l_type;
2835         struct ice_sw_recipe *recp;
2836         int status;
2837
2838         s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2839                               ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2840                               GFP_KERNEL);
2841         if (!s_rule)
2842                 return -ENOMEM;
2843         fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
2844                                 GFP_KERNEL);
2845         if (!fm_entry) {
2846                 status = -ENOMEM;
2847                 goto ice_create_pkt_fwd_rule_exit;
2848         }
2849
2850         fm_entry->fltr_info = f_entry->fltr_info;
2851
2852         /* Initialize all the fields for the management entry */
2853         fm_entry->vsi_count = 1;
2854         fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
2855         fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
2856         fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
2857
2858         ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
2859                          ice_aqc_opc_add_sw_rules);
2860
2861         status = ice_aq_sw_rules(hw, s_rule,
2862                                  ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
2863                                  ice_aqc_opc_add_sw_rules, NULL);
2864         if (status) {
2865                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
2866                 goto ice_create_pkt_fwd_rule_exit;
2867         }
2868
2869         f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
2870         fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
2871
2872         /* The book keeping entries will get removed when base driver
2873          * calls remove filter AQ command
2874          */
2875         l_type = fm_entry->fltr_info.lkup_type;
2876         recp = &hw->switch_info->recp_list[l_type];
2877         list_add(&fm_entry->list_entry, &recp->filt_rules);
2878
2879 ice_create_pkt_fwd_rule_exit:
2880         devm_kfree(ice_hw_to_dev(hw), s_rule);
2881         return status;
2882 }
2883
2884 /**
2885  * ice_update_pkt_fwd_rule
2886  * @hw: pointer to the hardware structure
2887  * @f_info: filter information for switch rule
2888  *
2889  * Call AQ command to update a previously created switch rule with a
2890  * VSI list ID
2891  */
2892 static int
2893 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
2894 {
2895         struct ice_sw_rule_lkup_rx_tx *s_rule;
2896         int status;
2897
2898         s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2899                               ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2900                               GFP_KERNEL);
2901         if (!s_rule)
2902                 return -ENOMEM;
2903
2904         ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
2905
2906         s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2907
2908         /* Update switch rule with new rule set to forward VSI list */
2909         status = ice_aq_sw_rules(hw, s_rule,
2910                                  ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
2911                                  ice_aqc_opc_update_sw_rules, NULL);
2912
2913         devm_kfree(ice_hw_to_dev(hw), s_rule);
2914         return status;
2915 }
2916
2917 /**
2918  * ice_update_sw_rule_bridge_mode
2919  * @hw: pointer to the HW struct
2920  *
2921  * Updates unicast switch filter rules based on VEB/VEPA mode
2922  */
2923 int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
2924 {
2925         struct ice_switch_info *sw = hw->switch_info;
2926         struct ice_fltr_mgmt_list_entry *fm_entry;
2927         struct list_head *rule_head;
2928         struct mutex *rule_lock; /* Lock to protect filter rule list */
2929         int status = 0;
2930
2931         rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
2932         rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
2933
2934         mutex_lock(rule_lock);
2935         list_for_each_entry(fm_entry, rule_head, list_entry) {
2936                 struct ice_fltr_info *fi = &fm_entry->fltr_info;
2937                 u8 *addr = fi->l_data.mac.mac_addr;
2938
2939                 /* Update unicast Tx rules to reflect the selected
2940                  * VEB/VEPA mode
2941                  */
2942                 if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
2943                     (fi->fltr_act == ICE_FWD_TO_VSI ||
2944                      fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2945                      fi->fltr_act == ICE_FWD_TO_Q ||
2946                      fi->fltr_act == ICE_FWD_TO_QGRP)) {
2947                         status = ice_update_pkt_fwd_rule(hw, fi);
2948                         if (status)
2949                                 break;
2950                 }
2951         }
2952
2953         mutex_unlock(rule_lock);
2954
2955         return status;
2956 }
2957
2958 /**
2959  * ice_add_update_vsi_list
2960  * @hw: pointer to the hardware structure
2961  * @m_entry: pointer to current filter management list entry
2962  * @cur_fltr: filter information from the book keeping entry
2963  * @new_fltr: filter information with the new VSI to be added
2964  *
2965  * Call AQ command to add or update previously created VSI list with new VSI.
2966  *
2967  * Helper function to do book keeping associated with adding filter information
2968  * The algorithm to do the book keeping is described below :
2969  * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
2970  *      if only one VSI has been added till now
2971  *              Allocate a new VSI list and add two VSIs
2972  *              to this list using switch rule command
2973  *              Update the previously created switch rule with the
2974  *              newly created VSI list ID
2975  *      if a VSI list was previously created
2976  *              Add the new VSI to the previously created VSI list set
2977  *              using the update switch rule command
2978  */
2979 static int
2980 ice_add_update_vsi_list(struct ice_hw *hw,
2981                         struct ice_fltr_mgmt_list_entry *m_entry,
2982                         struct ice_fltr_info *cur_fltr,
2983                         struct ice_fltr_info *new_fltr)
2984 {
2985         u16 vsi_list_id = 0;
2986         int status = 0;
2987
2988         if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
2989              cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
2990                 return -EOPNOTSUPP;
2991
2992         if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
2993              new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
2994             (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
2995              cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
2996                 return -EOPNOTSUPP;
2997
2998         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
2999                 /* Only one entry existed in the mapping and it was not already
3000                  * a part of a VSI list. So, create a VSI list with the old and
3001                  * new VSIs.
3002                  */
3003                 struct ice_fltr_info tmp_fltr;
3004                 u16 vsi_handle_arr[2];
3005
3006                 /* A rule already exists with the new VSI being added */
3007                 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
3008                         return -EEXIST;
3009
3010                 vsi_handle_arr[0] = cur_fltr->vsi_handle;
3011                 vsi_handle_arr[1] = new_fltr->vsi_handle;
3012                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3013                                                   &vsi_list_id,
3014                                                   new_fltr->lkup_type);
3015                 if (status)
3016                         return status;
3017
3018                 tmp_fltr = *new_fltr;
3019                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
3020                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3021                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3022                 /* Update the previous switch rule of "MAC forward to VSI" to
3023                  * "MAC fwd to VSI list"
3024                  */
3025                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3026                 if (status)
3027                         return status;
3028
3029                 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
3030                 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3031                 m_entry->vsi_list_info =
3032                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3033                                                 vsi_list_id);
3034
3035                 if (!m_entry->vsi_list_info)
3036                         return -ENOMEM;
3037
3038                 /* If this entry was large action then the large action needs
3039                  * to be updated to point to FWD to VSI list
3040                  */
3041                 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
3042                         status =
3043                             ice_add_marker_act(hw, m_entry,
3044                                                m_entry->sw_marker_id,
3045                                                m_entry->lg_act_idx);
3046         } else {
3047                 u16 vsi_handle = new_fltr->vsi_handle;
3048                 enum ice_adminq_opc opcode;
3049
3050                 if (!m_entry->vsi_list_info)
3051                         return -EIO;
3052
3053                 /* A rule already exists with the new VSI being added */
3054                 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
3055                         return 0;
3056
3057                 /* Update the previously created VSI list set with
3058                  * the new VSI ID passed in
3059                  */
3060                 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
3061                 opcode = ice_aqc_opc_update_sw_rules;
3062
3063                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
3064                                                   vsi_list_id, false, opcode,
3065                                                   new_fltr->lkup_type);
3066                 /* update VSI list mapping info with new VSI ID */
3067                 if (!status)
3068                         set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
3069         }
3070         if (!status)
3071                 m_entry->vsi_count++;
3072         return status;
3073 }
3074
3075 /**
3076  * ice_find_rule_entry - Search a rule entry
3077  * @hw: pointer to the hardware structure
3078  * @recp_id: lookup type for which the specified rule needs to be searched
3079  * @f_info: rule information
3080  *
3081  * Helper function to search for a given rule entry
3082  * Returns pointer to entry storing the rule if found
3083  */
3084 static struct ice_fltr_mgmt_list_entry *
3085 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
3086 {
3087         struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
3088         struct ice_switch_info *sw = hw->switch_info;
3089         struct list_head *list_head;
3090
3091         list_head = &sw->recp_list[recp_id].filt_rules;
3092         list_for_each_entry(list_itr, list_head, list_entry) {
3093                 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
3094                             sizeof(f_info->l_data)) &&
3095                     f_info->flag == list_itr->fltr_info.flag) {
3096                         ret = list_itr;
3097                         break;
3098                 }
3099         }
3100         return ret;
3101 }
3102
3103 /**
3104  * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
3105  * @hw: pointer to the hardware structure
3106  * @recp_id: lookup type for which VSI lists needs to be searched
3107  * @vsi_handle: VSI handle to be found in VSI list
3108  * @vsi_list_id: VSI list ID found containing vsi_handle
3109  *
3110  * Helper function to search a VSI list with single entry containing given VSI
3111  * handle element. This can be extended further to search VSI list with more
3112  * than 1 vsi_count. Returns pointer to VSI list entry if found.
3113  */
3114 struct ice_vsi_list_map_info *
3115 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
3116                         u16 *vsi_list_id)
3117 {
3118         struct ice_vsi_list_map_info *map_info = NULL;
3119         struct ice_switch_info *sw = hw->switch_info;
3120         struct ice_fltr_mgmt_list_entry *list_itr;
3121         struct list_head *list_head;
3122
3123         list_head = &sw->recp_list[recp_id].filt_rules;
3124         list_for_each_entry(list_itr, list_head, list_entry) {
3125                 if (list_itr->vsi_list_info) {
3126                         map_info = list_itr->vsi_list_info;
3127                         if (test_bit(vsi_handle, map_info->vsi_map)) {
3128                                 *vsi_list_id = map_info->vsi_list_id;
3129                                 return map_info;
3130                         }
3131                 }
3132         }
3133         return NULL;
3134 }
3135
3136 /**
3137  * ice_add_rule_internal - add rule for a given lookup type
3138  * @hw: pointer to the hardware structure
3139  * @recp_id: lookup type (recipe ID) for which rule has to be added
3140  * @f_entry: structure containing MAC forwarding information
3141  *
3142  * Adds or updates the rule lists for a given recipe
3143  */
3144 static int
3145 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
3146                       struct ice_fltr_list_entry *f_entry)
3147 {
3148         struct ice_switch_info *sw = hw->switch_info;
3149         struct ice_fltr_info *new_fltr, *cur_fltr;
3150         struct ice_fltr_mgmt_list_entry *m_entry;
3151         struct mutex *rule_lock; /* Lock to protect filter rule list */
3152         int status = 0;
3153
3154         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3155                 return -EINVAL;
3156         f_entry->fltr_info.fwd_id.hw_vsi_id =
3157                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3158
3159         rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3160
3161         mutex_lock(rule_lock);
3162         new_fltr = &f_entry->fltr_info;
3163         if (new_fltr->flag & ICE_FLTR_RX)
3164                 new_fltr->src = hw->port_info->lport;
3165         else if (new_fltr->flag & ICE_FLTR_TX)
3166                 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
3167
3168         m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
3169         if (!m_entry) {
3170                 mutex_unlock(rule_lock);
3171                 return ice_create_pkt_fwd_rule(hw, f_entry);
3172         }
3173
3174         cur_fltr = &m_entry->fltr_info;
3175         status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
3176         mutex_unlock(rule_lock);
3177
3178         return status;
3179 }
3180
3181 /**
3182  * ice_remove_vsi_list_rule
3183  * @hw: pointer to the hardware structure
3184  * @vsi_list_id: VSI list ID generated as part of allocate resource
3185  * @lkup_type: switch rule filter lookup type
3186  *
3187  * The VSI list should be emptied before this function is called to remove the
3188  * VSI list.
3189  */
3190 static int
3191 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
3192                          enum ice_sw_lkup_type lkup_type)
3193 {
3194         struct ice_sw_rule_vsi_list *s_rule;
3195         u16 s_rule_size;
3196         int status;
3197
3198         s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0);
3199         s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
3200         if (!s_rule)
3201                 return -ENOMEM;
3202
3203         s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
3204         s_rule->index = cpu_to_le16(vsi_list_id);
3205
3206         /* Free the vsi_list resource that we allocated. It is assumed that the
3207          * list is empty at this point.
3208          */
3209         status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
3210                                             ice_aqc_opc_free_res);
3211
3212         devm_kfree(ice_hw_to_dev(hw), s_rule);
3213         return status;
3214 }
3215
3216 /**
3217  * ice_rem_update_vsi_list
3218  * @hw: pointer to the hardware structure
3219  * @vsi_handle: VSI handle of the VSI to remove
3220  * @fm_list: filter management entry for which the VSI list management needs to
3221  *           be done
3222  */
3223 static int
3224 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
3225                         struct ice_fltr_mgmt_list_entry *fm_list)
3226 {
3227         enum ice_sw_lkup_type lkup_type;
3228         u16 vsi_list_id;
3229         int status = 0;
3230
3231         if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
3232             fm_list->vsi_count == 0)
3233                 return -EINVAL;
3234
3235         /* A rule with the VSI being removed does not exist */
3236         if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
3237                 return -ENOENT;
3238
3239         lkup_type = fm_list->fltr_info.lkup_type;
3240         vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
3241         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
3242                                           ice_aqc_opc_update_sw_rules,
3243                                           lkup_type);
3244         if (status)
3245                 return status;
3246
3247         fm_list->vsi_count--;
3248         clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
3249
3250         if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
3251                 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
3252                 struct ice_vsi_list_map_info *vsi_list_info =
3253                         fm_list->vsi_list_info;
3254                 u16 rem_vsi_handle;
3255
3256                 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
3257                                                 ICE_MAX_VSI);
3258                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
3259                         return -EIO;
3260
3261                 /* Make sure VSI list is empty before removing it below */
3262                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
3263                                                   vsi_list_id, true,
3264                                                   ice_aqc_opc_update_sw_rules,
3265                                                   lkup_type);
3266                 if (status)
3267                         return status;
3268
3269                 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
3270                 tmp_fltr_info.fwd_id.hw_vsi_id =
3271                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
3272                 tmp_fltr_info.vsi_handle = rem_vsi_handle;
3273                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
3274                 if (status) {
3275                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
3276                                   tmp_fltr_info.fwd_id.hw_vsi_id, status);
3277                         return status;
3278                 }
3279
3280                 fm_list->fltr_info = tmp_fltr_info;
3281         }
3282
3283         if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
3284             (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
3285                 struct ice_vsi_list_map_info *vsi_list_info =
3286                         fm_list->vsi_list_info;
3287
3288                 /* Remove the VSI list since it is no longer used */
3289                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
3290                 if (status) {
3291                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
3292                                   vsi_list_id, status);
3293                         return status;
3294                 }
3295
3296                 list_del(&vsi_list_info->list_entry);
3297                 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
3298                 fm_list->vsi_list_info = NULL;
3299         }
3300
3301         return status;
3302 }
3303
3304 /**
3305  * ice_remove_rule_internal - Remove a filter rule of a given type
3306  * @hw: pointer to the hardware structure
3307  * @recp_id: recipe ID for which the rule needs to removed
3308  * @f_entry: rule entry containing filter information
3309  */
3310 static int
3311 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
3312                          struct ice_fltr_list_entry *f_entry)
3313 {
3314         struct ice_switch_info *sw = hw->switch_info;
3315         struct ice_fltr_mgmt_list_entry *list_elem;
3316         struct mutex *rule_lock; /* Lock to protect filter rule list */
3317         bool remove_rule = false;
3318         u16 vsi_handle;
3319         int status = 0;
3320
3321         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3322                 return -EINVAL;
3323         f_entry->fltr_info.fwd_id.hw_vsi_id =
3324                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3325
3326         rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3327         mutex_lock(rule_lock);
3328         list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
3329         if (!list_elem) {
3330                 status = -ENOENT;
3331                 goto exit;
3332         }
3333
3334         if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
3335                 remove_rule = true;
3336         } else if (!list_elem->vsi_list_info) {
3337                 status = -ENOENT;
3338                 goto exit;
3339         } else if (list_elem->vsi_list_info->ref_cnt > 1) {
3340                 /* a ref_cnt > 1 indicates that the vsi_list is being
3341                  * shared by multiple rules. Decrement the ref_cnt and
3342                  * remove this rule, but do not modify the list, as it
3343                  * is in-use by other rules.
3344                  */
3345                 list_elem->vsi_list_info->ref_cnt--;
3346                 remove_rule = true;
3347         } else {
3348                 /* a ref_cnt of 1 indicates the vsi_list is only used
3349                  * by one rule. However, the original removal request is only
3350                  * for a single VSI. Update the vsi_list first, and only
3351                  * remove the rule if there are no further VSIs in this list.
3352                  */
3353                 vsi_handle = f_entry->fltr_info.vsi_handle;
3354                 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
3355                 if (status)
3356                         goto exit;
3357                 /* if VSI count goes to zero after updating the VSI list */
3358                 if (list_elem->vsi_count == 0)
3359                         remove_rule = true;
3360         }
3361
3362         if (remove_rule) {
3363                 /* Remove the lookup rule */
3364                 struct ice_sw_rule_lkup_rx_tx *s_rule;
3365
3366                 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
3367                                       ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3368                                       GFP_KERNEL);
3369                 if (!s_rule) {
3370                         status = -ENOMEM;
3371                         goto exit;
3372                 }
3373
3374                 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
3375                                  ice_aqc_opc_remove_sw_rules);
3376
3377                 status = ice_aq_sw_rules(hw, s_rule,
3378                                          ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3379                                          1, ice_aqc_opc_remove_sw_rules, NULL);
3380
3381                 /* Remove a book keeping from the list */
3382                 devm_kfree(ice_hw_to_dev(hw), s_rule);
3383
3384                 if (status)
3385                         goto exit;
3386
3387                 list_del(&list_elem->list_entry);
3388                 devm_kfree(ice_hw_to_dev(hw), list_elem);
3389         }
3390 exit:
3391         mutex_unlock(rule_lock);
3392         return status;
3393 }
3394
3395 /**
3396  * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI
3397  * @hw: pointer to the hardware structure
3398  * @vlan_id: VLAN ID
3399  * @vsi_handle: check MAC filter for this VSI
3400  */
3401 bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
3402 {
3403         struct ice_fltr_mgmt_list_entry *entry;
3404         struct list_head *rule_head;
3405         struct ice_switch_info *sw;
3406         struct mutex *rule_lock; /* Lock to protect filter rule list */
3407         u16 hw_vsi_id;
3408
3409         if (vlan_id > ICE_MAX_VLAN_ID)
3410                 return false;
3411
3412         if (!ice_is_vsi_valid(hw, vsi_handle))
3413                 return false;
3414
3415         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3416         sw = hw->switch_info;
3417         rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
3418         if (!rule_head)
3419                 return false;
3420
3421         rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3422         mutex_lock(rule_lock);
3423         list_for_each_entry(entry, rule_head, list_entry) {
3424                 struct ice_fltr_info *f_info = &entry->fltr_info;
3425                 u16 entry_vlan_id = f_info->l_data.vlan.vlan_id;
3426                 struct ice_vsi_list_map_info *map_info;
3427
3428                 if (entry_vlan_id > ICE_MAX_VLAN_ID)
3429                         continue;
3430
3431                 if (f_info->flag != ICE_FLTR_TX ||
3432                     f_info->src_id != ICE_SRC_ID_VSI ||
3433                     f_info->lkup_type != ICE_SW_LKUP_VLAN)
3434                         continue;
3435
3436                 /* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */
3437                 if (f_info->fltr_act != ICE_FWD_TO_VSI &&
3438                     f_info->fltr_act != ICE_FWD_TO_VSI_LIST)
3439                         continue;
3440
3441                 if (f_info->fltr_act == ICE_FWD_TO_VSI) {
3442                         if (hw_vsi_id != f_info->fwd_id.hw_vsi_id)
3443                                 continue;
3444                 } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3445                         /* If filter_action is FWD_TO_VSI_LIST, make sure
3446                          * that VSI being checked is part of VSI list
3447                          */
3448                         if (entry->vsi_count == 1 &&
3449                             entry->vsi_list_info) {
3450                                 map_info = entry->vsi_list_info;
3451                                 if (!test_bit(vsi_handle, map_info->vsi_map))
3452                                         continue;
3453                         }
3454                 }
3455
3456                 if (vlan_id == entry_vlan_id) {
3457                         mutex_unlock(rule_lock);
3458                         return true;
3459                 }
3460         }
3461         mutex_unlock(rule_lock);
3462
3463         return false;
3464 }
3465
3466 /**
3467  * ice_add_mac - Add a MAC address based filter rule
3468  * @hw: pointer to the hardware structure
3469  * @m_list: list of MAC addresses and forwarding information
3470  */
3471 int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
3472 {
3473         struct ice_fltr_list_entry *m_list_itr;
3474         int status = 0;
3475
3476         if (!m_list || !hw)
3477                 return -EINVAL;
3478
3479         list_for_each_entry(m_list_itr, m_list, list_entry) {
3480                 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
3481                 u16 vsi_handle;
3482                 u16 hw_vsi_id;
3483
3484                 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
3485                 vsi_handle = m_list_itr->fltr_info.vsi_handle;
3486                 if (!ice_is_vsi_valid(hw, vsi_handle))
3487                         return -EINVAL;
3488                 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3489                 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
3490                 /* update the src in case it is VSI num */
3491                 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
3492                         return -EINVAL;
3493                 m_list_itr->fltr_info.src = hw_vsi_id;
3494                 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
3495                     is_zero_ether_addr(add))
3496                         return -EINVAL;
3497
3498                 m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
3499                                                            m_list_itr);
3500                 if (m_list_itr->status)
3501                         return m_list_itr->status;
3502         }
3503
3504         return status;
3505 }
3506
3507 /**
3508  * ice_add_vlan_internal - Add one VLAN based filter rule
3509  * @hw: pointer to the hardware structure
3510  * @f_entry: filter entry containing one VLAN information
3511  */
3512 static int
3513 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
3514 {
3515         struct ice_switch_info *sw = hw->switch_info;
3516         struct ice_fltr_mgmt_list_entry *v_list_itr;
3517         struct ice_fltr_info *new_fltr, *cur_fltr;
3518         enum ice_sw_lkup_type lkup_type;
3519         u16 vsi_list_id = 0, vsi_handle;
3520         struct mutex *rule_lock; /* Lock to protect filter rule list */
3521         int status = 0;
3522
3523         if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3524                 return -EINVAL;
3525
3526         f_entry->fltr_info.fwd_id.hw_vsi_id =
3527                 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3528         new_fltr = &f_entry->fltr_info;
3529
3530         /* VLAN ID should only be 12 bits */
3531         if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
3532                 return -EINVAL;
3533
3534         if (new_fltr->src_id != ICE_SRC_ID_VSI)
3535                 return -EINVAL;
3536
3537         new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
3538         lkup_type = new_fltr->lkup_type;
3539         vsi_handle = new_fltr->vsi_handle;
3540         rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3541         mutex_lock(rule_lock);
3542         v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
3543         if (!v_list_itr) {
3544                 struct ice_vsi_list_map_info *map_info = NULL;
3545
3546                 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
3547                         /* All VLAN pruning rules use a VSI list. Check if
3548                          * there is already a VSI list containing VSI that we
3549                          * want to add. If found, use the same vsi_list_id for
3550                          * this new VLAN rule or else create a new list.
3551                          */
3552                         map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
3553                                                            vsi_handle,
3554                                                            &vsi_list_id);
3555                         if (!map_info) {
3556                                 status = ice_create_vsi_list_rule(hw,
3557                                                                   &vsi_handle,
3558                                                                   1,
3559                                                                   &vsi_list_id,
3560                                                                   lkup_type);
3561                                 if (status)
3562                                         goto exit;
3563                         }
3564                         /* Convert the action to forwarding to a VSI list. */
3565                         new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3566                         new_fltr->fwd_id.vsi_list_id = vsi_list_id;
3567                 }
3568
3569                 status = ice_create_pkt_fwd_rule(hw, f_entry);
3570                 if (!status) {
3571                         v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
3572                                                          new_fltr);
3573                         if (!v_list_itr) {
3574                                 status = -ENOENT;
3575                                 goto exit;
3576                         }
3577                         /* reuse VSI list for new rule and increment ref_cnt */
3578                         if (map_info) {
3579                                 v_list_itr->vsi_list_info = map_info;
3580                                 map_info->ref_cnt++;
3581                         } else {
3582                                 v_list_itr->vsi_list_info =
3583                                         ice_create_vsi_list_map(hw, &vsi_handle,
3584                                                                 1, vsi_list_id);
3585                         }
3586                 }
3587         } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
3588                 /* Update existing VSI list to add new VSI ID only if it used
3589                  * by one VLAN rule.
3590                  */
3591                 cur_fltr = &v_list_itr->fltr_info;
3592                 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
3593                                                  new_fltr);
3594         } else {
3595                 /* If VLAN rule exists and VSI list being used by this rule is
3596                  * referenced by more than 1 VLAN rule. Then create a new VSI
3597                  * list appending previous VSI with new VSI and update existing
3598                  * VLAN rule to point to new VSI list ID
3599                  */
3600                 struct ice_fltr_info tmp_fltr;
3601                 u16 vsi_handle_arr[2];
3602                 u16 cur_handle;
3603
3604                 /* Current implementation only supports reusing VSI list with
3605                  * one VSI count. We should never hit below condition
3606                  */
3607                 if (v_list_itr->vsi_count > 1 &&
3608                     v_list_itr->vsi_list_info->ref_cnt > 1) {
3609                         ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
3610                         status = -EIO;
3611                         goto exit;
3612                 }
3613
3614                 cur_handle =
3615                         find_first_bit(v_list_itr->vsi_list_info->vsi_map,
3616                                        ICE_MAX_VSI);
3617
3618                 /* A rule already exists with the new VSI being added */
3619                 if (cur_handle == vsi_handle) {
3620                         status = -EEXIST;
3621                         goto exit;
3622                 }
3623
3624                 vsi_handle_arr[0] = cur_handle;
3625                 vsi_handle_arr[1] = vsi_handle;
3626                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3627                                                   &vsi_list_id, lkup_type);
3628                 if (status)
3629                         goto exit;
3630
3631                 tmp_fltr = v_list_itr->fltr_info;
3632                 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
3633                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3634                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3635                 /* Update the previous switch rule to a new VSI list which
3636                  * includes current VSI that is requested
3637                  */
3638                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3639                 if (status)
3640                         goto exit;
3641
3642                 /* before overriding VSI list map info. decrement ref_cnt of
3643                  * previous VSI list
3644                  */
3645                 v_list_itr->vsi_list_info->ref_cnt--;
3646
3647                 /* now update to newly created list */
3648                 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
3649                 v_list_itr->vsi_list_info =
3650                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3651                                                 vsi_list_id);
3652                 v_list_itr->vsi_count++;
3653         }
3654
3655 exit:
3656         mutex_unlock(rule_lock);
3657         return status;
3658 }
3659
3660 /**
3661  * ice_add_vlan - Add VLAN based filter rule
3662  * @hw: pointer to the hardware structure
3663  * @v_list: list of VLAN entries and forwarding information
3664  */
3665 int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
3666 {
3667         struct ice_fltr_list_entry *v_list_itr;
3668
3669         if (!v_list || !hw)
3670                 return -EINVAL;
3671
3672         list_for_each_entry(v_list_itr, v_list, list_entry) {
3673                 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
3674                         return -EINVAL;
3675                 v_list_itr->fltr_info.flag = ICE_FLTR_TX;
3676                 v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
3677                 if (v_list_itr->status)
3678                         return v_list_itr->status;
3679         }
3680         return 0;
3681 }
3682
3683 /**
3684  * ice_add_eth_mac - Add ethertype and MAC based filter rule
3685  * @hw: pointer to the hardware structure
3686  * @em_list: list of ether type MAC filter, MAC is optional
3687  *
3688  * This function requires the caller to populate the entries in
3689  * the filter list with the necessary fields (including flags to
3690  * indicate Tx or Rx rules).
3691  */
3692 int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3693 {
3694         struct ice_fltr_list_entry *em_list_itr;
3695
3696         if (!em_list || !hw)
3697                 return -EINVAL;
3698
3699         list_for_each_entry(em_list_itr, em_list, list_entry) {
3700                 enum ice_sw_lkup_type l_type =
3701                         em_list_itr->fltr_info.lkup_type;
3702
3703                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3704                     l_type != ICE_SW_LKUP_ETHERTYPE)
3705                         return -EINVAL;
3706
3707                 em_list_itr->status = ice_add_rule_internal(hw, l_type,
3708                                                             em_list_itr);
3709                 if (em_list_itr->status)
3710                         return em_list_itr->status;
3711         }
3712         return 0;
3713 }
3714
3715 /**
3716  * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule
3717  * @hw: pointer to the hardware structure
3718  * @em_list: list of ethertype or ethertype MAC entries
3719  */
3720 int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3721 {
3722         struct ice_fltr_list_entry *em_list_itr, *tmp;
3723
3724         if (!em_list || !hw)
3725                 return -EINVAL;
3726
3727         list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
3728                 enum ice_sw_lkup_type l_type =
3729                         em_list_itr->fltr_info.lkup_type;
3730
3731                 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3732                     l_type != ICE_SW_LKUP_ETHERTYPE)
3733                         return -EINVAL;
3734
3735                 em_list_itr->status = ice_remove_rule_internal(hw, l_type,
3736                                                                em_list_itr);
3737                 if (em_list_itr->status)
3738                         return em_list_itr->status;
3739         }
3740         return 0;
3741 }
3742
3743 /**
3744  * ice_rem_sw_rule_info
3745  * @hw: pointer to the hardware structure
3746  * @rule_head: pointer to the switch list structure that we want to delete
3747  */
3748 static void
3749 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3750 {
3751         if (!list_empty(rule_head)) {
3752                 struct ice_fltr_mgmt_list_entry *entry;
3753                 struct ice_fltr_mgmt_list_entry *tmp;
3754
3755                 list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
3756                         list_del(&entry->list_entry);
3757                         devm_kfree(ice_hw_to_dev(hw), entry);
3758                 }
3759         }
3760 }
3761
3762 /**
3763  * ice_rem_adv_rule_info
3764  * @hw: pointer to the hardware structure
3765  * @rule_head: pointer to the switch list structure that we want to delete
3766  */
3767 static void
3768 ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3769 {
3770         struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
3771         struct ice_adv_fltr_mgmt_list_entry *lst_itr;
3772
3773         if (list_empty(rule_head))
3774                 return;
3775
3776         list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) {
3777                 list_del(&lst_itr->list_entry);
3778                 devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
3779                 devm_kfree(ice_hw_to_dev(hw), lst_itr);
3780         }
3781 }
3782
3783 /**
3784  * ice_cfg_dflt_vsi - change state of VSI to set/clear default
3785  * @pi: pointer to the port_info structure
3786  * @vsi_handle: VSI handle to set as default
3787  * @set: true to add the above mentioned switch rule, false to remove it
3788  * @direction: ICE_FLTR_RX or ICE_FLTR_TX
3789  *
3790  * add filter rule to set/unset given VSI as default VSI for the switch
3791  * (represented by swid)
3792  */
3793 int
3794 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
3795                  u8 direction)
3796 {
3797         struct ice_fltr_list_entry f_list_entry;
3798         struct ice_fltr_info f_info;
3799         struct ice_hw *hw = pi->hw;
3800         u16 hw_vsi_id;
3801         int status;
3802
3803         if (!ice_is_vsi_valid(hw, vsi_handle))
3804                 return -EINVAL;
3805
3806         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3807
3808         memset(&f_info, 0, sizeof(f_info));
3809
3810         f_info.lkup_type = ICE_SW_LKUP_DFLT;
3811         f_info.flag = direction;
3812         f_info.fltr_act = ICE_FWD_TO_VSI;
3813         f_info.fwd_id.hw_vsi_id = hw_vsi_id;
3814         f_info.vsi_handle = vsi_handle;
3815
3816         if (f_info.flag & ICE_FLTR_RX) {
3817                 f_info.src = hw->port_info->lport;
3818                 f_info.src_id = ICE_SRC_ID_LPORT;
3819         } else if (f_info.flag & ICE_FLTR_TX) {
3820                 f_info.src_id = ICE_SRC_ID_VSI;
3821                 f_info.src = hw_vsi_id;
3822         }
3823         f_list_entry.fltr_info = f_info;
3824
3825         if (set)
3826                 status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT,
3827                                                &f_list_entry);
3828         else
3829                 status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT,
3830                                                   &f_list_entry);
3831
3832         return status;
3833 }
3834
3835 /**
3836  * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
3837  * @fm_entry: filter entry to inspect
3838  * @vsi_handle: VSI handle to compare with filter info
3839  */
3840 static bool
3841 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
3842 {
3843         return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
3844                  fm_entry->fltr_info.vsi_handle == vsi_handle) ||
3845                 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
3846                  fm_entry->vsi_list_info &&
3847                  (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
3848 }
3849
3850 /**
3851  * ice_check_if_dflt_vsi - check if VSI is default VSI
3852  * @pi: pointer to the port_info structure
3853  * @vsi_handle: vsi handle to check for in filter list
3854  * @rule_exists: indicates if there are any VSI's in the rule list
3855  *
3856  * checks if the VSI is in a default VSI list, and also indicates
3857  * if the default VSI list is empty
3858  */
3859 bool
3860 ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
3861                       bool *rule_exists)
3862 {
3863         struct ice_fltr_mgmt_list_entry *fm_entry;
3864         struct ice_sw_recipe *recp_list;
3865         struct list_head *rule_head;
3866         struct mutex *rule_lock; /* Lock to protect filter rule list */
3867         bool ret = false;
3868
3869         recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
3870         rule_lock = &recp_list->filt_rule_lock;
3871         rule_head = &recp_list->filt_rules;
3872
3873         mutex_lock(rule_lock);
3874
3875         if (rule_exists && !list_empty(rule_head))
3876                 *rule_exists = true;
3877
3878         list_for_each_entry(fm_entry, rule_head, list_entry) {
3879                 if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
3880                         ret = true;
3881                         break;
3882                 }
3883         }
3884
3885         mutex_unlock(rule_lock);
3886
3887         return ret;
3888 }
3889
3890 /**
3891  * ice_remove_mac - remove a MAC address based filter rule
3892  * @hw: pointer to the hardware structure
3893  * @m_list: list of MAC addresses and forwarding information
3894  *
3895  * This function removes either a MAC filter rule or a specific VSI from a
3896  * VSI list for a multicast MAC address.
3897  *
3898  * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should
3899  * be aware that this call will only work if all the entries passed into m_list
3900  * were added previously. It will not attempt to do a partial remove of entries
3901  * that were found.
3902  */
3903 int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
3904 {
3905         struct ice_fltr_list_entry *list_itr, *tmp;
3906
3907         if (!m_list)
3908                 return -EINVAL;
3909
3910         list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
3911                 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
3912                 u16 vsi_handle;
3913
3914                 if (l_type != ICE_SW_LKUP_MAC)
3915                         return -EINVAL;
3916
3917                 vsi_handle = list_itr->fltr_info.vsi_handle;
3918                 if (!ice_is_vsi_valid(hw, vsi_handle))
3919                         return -EINVAL;
3920
3921                 list_itr->fltr_info.fwd_id.hw_vsi_id =
3922                                         ice_get_hw_vsi_num(hw, vsi_handle);
3923
3924                 list_itr->status = ice_remove_rule_internal(hw,
3925                                                             ICE_SW_LKUP_MAC,
3926                                                             list_itr);
3927                 if (list_itr->status)
3928                         return list_itr->status;
3929         }
3930         return 0;
3931 }
3932
3933 /**
3934  * ice_remove_vlan - Remove VLAN based filter rule
3935  * @hw: pointer to the hardware structure
3936  * @v_list: list of VLAN entries and forwarding information
3937  */
3938 int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
3939 {
3940         struct ice_fltr_list_entry *v_list_itr, *tmp;
3941
3942         if (!v_list || !hw)
3943                 return -EINVAL;
3944
3945         list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
3946                 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
3947
3948                 if (l_type != ICE_SW_LKUP_VLAN)
3949                         return -EINVAL;
3950                 v_list_itr->status = ice_remove_rule_internal(hw,
3951                                                               ICE_SW_LKUP_VLAN,
3952                                                               v_list_itr);
3953                 if (v_list_itr->status)
3954                         return v_list_itr->status;
3955         }
3956         return 0;
3957 }
3958
3959 /**
3960  * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
3961  * @hw: pointer to the hardware structure
3962  * @vsi_handle: VSI handle to remove filters from
3963  * @vsi_list_head: pointer to the list to add entry to
3964  * @fi: pointer to fltr_info of filter entry to copy & add
3965  *
3966  * Helper function, used when creating a list of filters to remove from
3967  * a specific VSI. The entry added to vsi_list_head is a COPY of the
3968  * original filter entry, with the exception of fltr_info.fltr_act and
3969  * fltr_info.fwd_id fields. These are set such that later logic can
3970  * extract which VSI to remove the fltr from, and pass on that information.
3971  */
3972 static int
3973 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
3974                                struct list_head *vsi_list_head,
3975                                struct ice_fltr_info *fi)
3976 {
3977         struct ice_fltr_list_entry *tmp;
3978
3979         /* this memory is freed up in the caller function
3980          * once filters for this VSI are removed
3981          */
3982         tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
3983         if (!tmp)
3984                 return -ENOMEM;
3985
3986         tmp->fltr_info = *fi;
3987
3988         /* Overwrite these fields to indicate which VSI to remove filter from,
3989          * so find and remove logic can extract the information from the
3990          * list entries. Note that original entries will still have proper
3991          * values.
3992          */
3993         tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
3994         tmp->fltr_info.vsi_handle = vsi_handle;
3995         tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3996
3997         list_add(&tmp->list_entry, vsi_list_head);
3998
3999         return 0;
4000 }
4001
4002 /**
4003  * ice_add_to_vsi_fltr_list - Add VSI filters to the list
4004  * @hw: pointer to the hardware structure
4005  * @vsi_handle: VSI handle to remove filters from
4006  * @lkup_list_head: pointer to the list that has certain lookup type filters
4007  * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
4008  *
4009  * Locates all filters in lkup_list_head that are used by the given VSI,
4010  * and adds COPIES of those entries to vsi_list_head (intended to be used
4011  * to remove the listed filters).
4012  * Note that this means all entries in vsi_list_head must be explicitly
4013  * deallocated by the caller when done with list.
4014  */
4015 static int
4016 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
4017                          struct list_head *lkup_list_head,
4018                          struct list_head *vsi_list_head)
4019 {
4020         struct ice_fltr_mgmt_list_entry *fm_entry;
4021         int status = 0;
4022
4023         /* check to make sure VSI ID is valid and within boundary */
4024         if (!ice_is_vsi_valid(hw, vsi_handle))
4025                 return -EINVAL;
4026
4027         list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
4028                 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
4029                         continue;
4030
4031                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4032                                                         vsi_list_head,
4033                                                         &fm_entry->fltr_info);
4034                 if (status)
4035                         return status;
4036         }
4037         return status;
4038 }
4039
4040 /**
4041  * ice_determine_promisc_mask
4042  * @fi: filter info to parse
4043  *
4044  * Helper function to determine which ICE_PROMISC_ mask corresponds
4045  * to given filter into.
4046  */
4047 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
4048 {
4049         u16 vid = fi->l_data.mac_vlan.vlan_id;
4050         u8 *macaddr = fi->l_data.mac.mac_addr;
4051         bool is_tx_fltr = false;
4052         u8 promisc_mask = 0;
4053
4054         if (fi->flag == ICE_FLTR_TX)
4055                 is_tx_fltr = true;
4056
4057         if (is_broadcast_ether_addr(macaddr))
4058                 promisc_mask |= is_tx_fltr ?
4059                         ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
4060         else if (is_multicast_ether_addr(macaddr))
4061                 promisc_mask |= is_tx_fltr ?
4062                         ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
4063         else if (is_unicast_ether_addr(macaddr))
4064                 promisc_mask |= is_tx_fltr ?
4065                         ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
4066         if (vid)
4067                 promisc_mask |= is_tx_fltr ?
4068                         ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
4069
4070         return promisc_mask;
4071 }
4072
4073 /**
4074  * ice_remove_promisc - Remove promisc based filter rules
4075  * @hw: pointer to the hardware structure
4076  * @recp_id: recipe ID for which the rule needs to removed
4077  * @v_list: list of promisc entries
4078  */
4079 static int
4080 ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list)
4081 {
4082         struct ice_fltr_list_entry *v_list_itr, *tmp;
4083
4084         list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
4085                 v_list_itr->status =
4086                         ice_remove_rule_internal(hw, recp_id, v_list_itr);
4087                 if (v_list_itr->status)
4088                         return v_list_itr->status;
4089         }
4090         return 0;
4091 }
4092
4093 /**
4094  * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
4095  * @hw: pointer to the hardware structure
4096  * @vsi_handle: VSI handle to clear mode
4097  * @promisc_mask: mask of promiscuous config bits to clear
4098  * @vid: VLAN ID to clear VLAN promiscuous
4099  */
4100 int
4101 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4102                       u16 vid)
4103 {
4104         struct ice_switch_info *sw = hw->switch_info;
4105         struct ice_fltr_list_entry *fm_entry, *tmp;
4106         struct list_head remove_list_head;
4107         struct ice_fltr_mgmt_list_entry *itr;
4108         struct list_head *rule_head;
4109         struct mutex *rule_lock;        /* Lock to protect filter rule list */
4110         int status = 0;
4111         u8 recipe_id;
4112
4113         if (!ice_is_vsi_valid(hw, vsi_handle))
4114                 return -EINVAL;
4115
4116         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
4117                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4118         else
4119                 recipe_id = ICE_SW_LKUP_PROMISC;
4120
4121         rule_head = &sw->recp_list[recipe_id].filt_rules;
4122         rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
4123
4124         INIT_LIST_HEAD(&remove_list_head);
4125
4126         mutex_lock(rule_lock);
4127         list_for_each_entry(itr, rule_head, list_entry) {
4128                 struct ice_fltr_info *fltr_info;
4129                 u8 fltr_promisc_mask = 0;
4130
4131                 if (!ice_vsi_uses_fltr(itr, vsi_handle))
4132                         continue;
4133                 fltr_info = &itr->fltr_info;
4134
4135                 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
4136                     vid != fltr_info->l_data.mac_vlan.vlan_id)
4137                         continue;
4138
4139                 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
4140
4141                 /* Skip if filter is not completely specified by given mask */
4142                 if (fltr_promisc_mask & ~promisc_mask)
4143                         continue;
4144
4145                 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4146                                                         &remove_list_head,
4147                                                         fltr_info);
4148                 if (status) {
4149                         mutex_unlock(rule_lock);
4150                         goto free_fltr_list;
4151                 }
4152         }
4153         mutex_unlock(rule_lock);
4154
4155         status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
4156
4157 free_fltr_list:
4158         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4159                 list_del(&fm_entry->list_entry);
4160                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4161         }
4162
4163         return status;
4164 }
4165
4166 /**
4167  * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
4168  * @hw: pointer to the hardware structure
4169  * @vsi_handle: VSI handle to configure
4170  * @promisc_mask: mask of promiscuous config bits
4171  * @vid: VLAN ID to set VLAN promiscuous
4172  */
4173 int
4174 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
4175 {
4176         enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
4177         struct ice_fltr_list_entry f_list_entry;
4178         struct ice_fltr_info new_fltr;
4179         bool is_tx_fltr;
4180         int status = 0;
4181         u16 hw_vsi_id;
4182         int pkt_type;
4183         u8 recipe_id;
4184
4185         if (!ice_is_vsi_valid(hw, vsi_handle))
4186                 return -EINVAL;
4187         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4188
4189         memset(&new_fltr, 0, sizeof(new_fltr));
4190
4191         if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
4192                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
4193                 new_fltr.l_data.mac_vlan.vlan_id = vid;
4194                 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4195         } else {
4196                 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
4197                 recipe_id = ICE_SW_LKUP_PROMISC;
4198         }
4199
4200         /* Separate filters must be set for each direction/packet type
4201          * combination, so we will loop over the mask value, store the
4202          * individual type, and clear it out in the input mask as it
4203          * is found.
4204          */
4205         while (promisc_mask) {
4206                 u8 *mac_addr;
4207
4208                 pkt_type = 0;
4209                 is_tx_fltr = false;
4210
4211                 if (promisc_mask & ICE_PROMISC_UCAST_RX) {
4212                         promisc_mask &= ~ICE_PROMISC_UCAST_RX;
4213                         pkt_type = UCAST_FLTR;
4214                 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
4215                         promisc_mask &= ~ICE_PROMISC_UCAST_TX;
4216                         pkt_type = UCAST_FLTR;
4217                         is_tx_fltr = true;
4218                 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
4219                         promisc_mask &= ~ICE_PROMISC_MCAST_RX;
4220                         pkt_type = MCAST_FLTR;
4221                 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
4222                         promisc_mask &= ~ICE_PROMISC_MCAST_TX;
4223                         pkt_type = MCAST_FLTR;
4224                         is_tx_fltr = true;
4225                 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
4226                         promisc_mask &= ~ICE_PROMISC_BCAST_RX;
4227                         pkt_type = BCAST_FLTR;
4228                 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
4229                         promisc_mask &= ~ICE_PROMISC_BCAST_TX;
4230                         pkt_type = BCAST_FLTR;
4231                         is_tx_fltr = true;
4232                 }
4233
4234                 /* Check for VLAN promiscuous flag */
4235                 if (promisc_mask & ICE_PROMISC_VLAN_RX) {
4236                         promisc_mask &= ~ICE_PROMISC_VLAN_RX;
4237                 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
4238                         promisc_mask &= ~ICE_PROMISC_VLAN_TX;
4239                         is_tx_fltr = true;
4240                 }
4241
4242                 /* Set filter DA based on packet type */
4243                 mac_addr = new_fltr.l_data.mac.mac_addr;
4244                 if (pkt_type == BCAST_FLTR) {
4245                         eth_broadcast_addr(mac_addr);
4246                 } else if (pkt_type == MCAST_FLTR ||
4247                            pkt_type == UCAST_FLTR) {
4248                         /* Use the dummy ether header DA */
4249                         ether_addr_copy(mac_addr, dummy_eth_header);
4250                         if (pkt_type == MCAST_FLTR)
4251                                 mac_addr[0] |= 0x1;     /* Set multicast bit */
4252                 }
4253
4254                 /* Need to reset this to zero for all iterations */
4255                 new_fltr.flag = 0;
4256                 if (is_tx_fltr) {
4257                         new_fltr.flag |= ICE_FLTR_TX;
4258                         new_fltr.src = hw_vsi_id;
4259                 } else {
4260                         new_fltr.flag |= ICE_FLTR_RX;
4261                         new_fltr.src = hw->port_info->lport;
4262                 }
4263
4264                 new_fltr.fltr_act = ICE_FWD_TO_VSI;
4265                 new_fltr.vsi_handle = vsi_handle;
4266                 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
4267                 f_list_entry.fltr_info = new_fltr;
4268
4269                 status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
4270                 if (status)
4271                         goto set_promisc_exit;
4272         }
4273
4274 set_promisc_exit:
4275         return status;
4276 }
4277
4278 /**
4279  * ice_set_vlan_vsi_promisc
4280  * @hw: pointer to the hardware structure
4281  * @vsi_handle: VSI handle to configure
4282  * @promisc_mask: mask of promiscuous config bits
4283  * @rm_vlan_promisc: Clear VLANs VSI promisc mode
4284  *
4285  * Configure VSI with all associated VLANs to given promiscuous mode(s)
4286  */
4287 int
4288 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4289                          bool rm_vlan_promisc)
4290 {
4291         struct ice_switch_info *sw = hw->switch_info;
4292         struct ice_fltr_list_entry *list_itr, *tmp;
4293         struct list_head vsi_list_head;
4294         struct list_head *vlan_head;
4295         struct mutex *vlan_lock; /* Lock to protect filter rule list */
4296         u16 vlan_id;
4297         int status;
4298
4299         INIT_LIST_HEAD(&vsi_list_head);
4300         vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
4301         vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
4302         mutex_lock(vlan_lock);
4303         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
4304                                           &vsi_list_head);
4305         mutex_unlock(vlan_lock);
4306         if (status)
4307                 goto free_fltr_list;
4308
4309         list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
4310                 /* Avoid enabling or disabling VLAN zero twice when in double
4311                  * VLAN mode
4312                  */
4313                 if (ice_is_dvm_ena(hw) &&
4314                     list_itr->fltr_info.l_data.vlan.tpid == 0)
4315                         continue;
4316
4317                 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
4318                 if (rm_vlan_promisc)
4319                         status = ice_clear_vsi_promisc(hw, vsi_handle,
4320                                                        promisc_mask, vlan_id);
4321                 else
4322                         status = ice_set_vsi_promisc(hw, vsi_handle,
4323                                                      promisc_mask, vlan_id);
4324                 if (status && status != -EEXIST)
4325                         break;
4326         }
4327
4328 free_fltr_list:
4329         list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
4330                 list_del(&list_itr->list_entry);
4331                 devm_kfree(ice_hw_to_dev(hw), list_itr);
4332         }
4333         return status;
4334 }
4335
4336 /**
4337  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
4338  * @hw: pointer to the hardware structure
4339  * @vsi_handle: VSI handle to remove filters from
4340  * @lkup: switch rule filter lookup type
4341  */
4342 static void
4343 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
4344                          enum ice_sw_lkup_type lkup)
4345 {
4346         struct ice_switch_info *sw = hw->switch_info;
4347         struct ice_fltr_list_entry *fm_entry;
4348         struct list_head remove_list_head;
4349         struct list_head *rule_head;
4350         struct ice_fltr_list_entry *tmp;
4351         struct mutex *rule_lock;        /* Lock to protect filter rule list */
4352         int status;
4353
4354         INIT_LIST_HEAD(&remove_list_head);
4355         rule_lock = &sw->recp_list[lkup].filt_rule_lock;
4356         rule_head = &sw->recp_list[lkup].filt_rules;
4357         mutex_lock(rule_lock);
4358         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
4359                                           &remove_list_head);
4360         mutex_unlock(rule_lock);
4361         if (status)
4362                 goto free_fltr_list;
4363
4364         switch (lkup) {
4365         case ICE_SW_LKUP_MAC:
4366                 ice_remove_mac(hw, &remove_list_head);
4367                 break;
4368         case ICE_SW_LKUP_VLAN:
4369                 ice_remove_vlan(hw, &remove_list_head);
4370                 break;
4371         case ICE_SW_LKUP_PROMISC:
4372         case ICE_SW_LKUP_PROMISC_VLAN:
4373                 ice_remove_promisc(hw, lkup, &remove_list_head);
4374                 break;
4375         case ICE_SW_LKUP_MAC_VLAN:
4376         case ICE_SW_LKUP_ETHERTYPE:
4377         case ICE_SW_LKUP_ETHERTYPE_MAC:
4378         case ICE_SW_LKUP_DFLT:
4379         case ICE_SW_LKUP_LAST:
4380         default:
4381                 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
4382                 break;
4383         }
4384
4385 free_fltr_list:
4386         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4387                 list_del(&fm_entry->list_entry);
4388                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4389         }
4390 }
4391
4392 /**
4393  * ice_remove_vsi_fltr - Remove all filters for a VSI
4394  * @hw: pointer to the hardware structure
4395  * @vsi_handle: VSI handle to remove filters from
4396  */
4397 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
4398 {
4399         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
4400         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
4401         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
4402         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
4403         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
4404         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
4405         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
4406         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
4407 }
4408
4409 /**
4410  * ice_alloc_res_cntr - allocating resource counter
4411  * @hw: pointer to the hardware structure
4412  * @type: type of resource
4413  * @alloc_shared: if set it is shared else dedicated
4414  * @num_items: number of entries requested for FD resource type
4415  * @counter_id: counter index returned by AQ call
4416  */
4417 int
4418 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4419                    u16 *counter_id)
4420 {
4421         DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4422         u16 buf_len = __struct_size(buf);
4423         int status;
4424
4425         buf->num_elems = cpu_to_le16(num_items);
4426         buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
4427                                     alloc_shared);
4428
4429         status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_alloc_res);
4430         if (status)
4431                 return status;
4432
4433         *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
4434         return status;
4435 }
4436
4437 /**
4438  * ice_free_res_cntr - free resource counter
4439  * @hw: pointer to the hardware structure
4440  * @type: type of resource
4441  * @alloc_shared: if set it is shared else dedicated
4442  * @num_items: number of entries to be freed for FD resource type
4443  * @counter_id: counter ID resource which needs to be freed
4444  */
4445 int
4446 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4447                   u16 counter_id)
4448 {
4449         DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4450         u16 buf_len = __struct_size(buf);
4451         int status;
4452
4453         buf->num_elems = cpu_to_le16(num_items);
4454         buf->res_type = cpu_to_le16(FIELD_PREP(ICE_AQC_RES_TYPE_M, type) |
4455                                     alloc_shared);
4456         buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
4457
4458         status = ice_aq_alloc_free_res(hw, buf, buf_len, ice_aqc_opc_free_res);
4459         if (status)
4460                 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
4461
4462         return status;
4463 }
4464
4465 #define ICE_PROTOCOL_ENTRY(id, ...) {           \
4466         .prot_type      = id,                   \
4467         .offs           = {__VA_ARGS__},        \
4468 }
4469
4470 /**
4471  * ice_share_res - set a resource as shared or dedicated
4472  * @hw: hw struct of original owner of resource
4473  * @type: resource type
4474  * @shared: is the resource being set to shared
4475  * @res_id: resource id (descriptor)
4476  */
4477 int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id)
4478 {
4479         DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
4480         u16 buf_len = __struct_size(buf);
4481         u16 res_type;
4482         int status;
4483
4484         buf->num_elems = cpu_to_le16(1);
4485         res_type = FIELD_PREP(ICE_AQC_RES_TYPE_M, type);
4486         if (shared)
4487                 res_type |= ICE_AQC_RES_TYPE_FLAG_SHARED;
4488
4489         buf->res_type = cpu_to_le16(res_type);
4490         buf->elem[0].e.sw_resp = cpu_to_le16(res_id);
4491         status = ice_aq_alloc_free_res(hw, buf, buf_len,
4492                                        ice_aqc_opc_share_res);
4493         if (status)
4494                 ice_debug(hw, ICE_DBG_SW, "Could not set resource type %u id %u to %s\n",
4495                           type, res_id, shared ? "SHARED" : "DEDICATED");
4496
4497         return status;
4498 }
4499
4500 /* This is mapping table entry that maps every word within a given protocol
4501  * structure to the real byte offset as per the specification of that
4502  * protocol header.
4503  * for example dst address is 3 words in ethertype header and corresponding
4504  * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
4505  * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
4506  * matching entry describing its field. This needs to be updated if new
4507  * structure is added to that union.
4508  */
4509 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
4510         ICE_PROTOCOL_ENTRY(ICE_MAC_OFOS, 0, 2, 4, 6, 8, 10, 12),
4511         ICE_PROTOCOL_ENTRY(ICE_MAC_IL, 0, 2, 4, 6, 8, 10, 12),
4512         ICE_PROTOCOL_ENTRY(ICE_ETYPE_OL, 0),
4513         ICE_PROTOCOL_ENTRY(ICE_ETYPE_IL, 0),
4514         ICE_PROTOCOL_ENTRY(ICE_VLAN_OFOS, 2, 0),
4515         ICE_PROTOCOL_ENTRY(ICE_IPV4_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
4516         ICE_PROTOCOL_ENTRY(ICE_IPV4_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18),
4517         ICE_PROTOCOL_ENTRY(ICE_IPV6_OFOS, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
4518                            20, 22, 24, 26, 28, 30, 32, 34, 36, 38),
4519         ICE_PROTOCOL_ENTRY(ICE_IPV6_IL, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,
4520                            22, 24, 26, 28, 30, 32, 34, 36, 38),
4521         ICE_PROTOCOL_ENTRY(ICE_TCP_IL, 0, 2),
4522         ICE_PROTOCOL_ENTRY(ICE_UDP_OF, 0, 2),
4523         ICE_PROTOCOL_ENTRY(ICE_UDP_ILOS, 0, 2),
4524         ICE_PROTOCOL_ENTRY(ICE_VXLAN, 8, 10, 12, 14),
4525         ICE_PROTOCOL_ENTRY(ICE_GENEVE, 8, 10, 12, 14),
4526         ICE_PROTOCOL_ENTRY(ICE_NVGRE, 0, 2, 4, 6),
4527         ICE_PROTOCOL_ENTRY(ICE_GTP, 8, 10, 12, 14, 16, 18, 20, 22),
4528         ICE_PROTOCOL_ENTRY(ICE_GTP_NO_PAY, 8, 10, 12, 14),
4529         ICE_PROTOCOL_ENTRY(ICE_PPPOE, 0, 2, 4, 6),
4530         ICE_PROTOCOL_ENTRY(ICE_L2TPV3, 0, 2, 4, 6, 8, 10),
4531         ICE_PROTOCOL_ENTRY(ICE_VLAN_EX, 2, 0),
4532         ICE_PROTOCOL_ENTRY(ICE_VLAN_IN, 2, 0),
4533         ICE_PROTOCOL_ENTRY(ICE_HW_METADATA,
4534                            ICE_SOURCE_PORT_MDID_OFFSET,
4535                            ICE_PTYPE_MDID_OFFSET,
4536                            ICE_PACKET_LENGTH_MDID_OFFSET,
4537                            ICE_SOURCE_VSI_MDID_OFFSET,
4538                            ICE_PKT_VLAN_MDID_OFFSET,
4539                            ICE_PKT_TUNNEL_MDID_OFFSET,
4540                            ICE_PKT_TCP_MDID_OFFSET,
4541                            ICE_PKT_ERROR_MDID_OFFSET),
4542 };
4543
4544 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
4545         { ICE_MAC_OFOS,         ICE_MAC_OFOS_HW },
4546         { ICE_MAC_IL,           ICE_MAC_IL_HW },
4547         { ICE_ETYPE_OL,         ICE_ETYPE_OL_HW },
4548         { ICE_ETYPE_IL,         ICE_ETYPE_IL_HW },
4549         { ICE_VLAN_OFOS,        ICE_VLAN_OL_HW },
4550         { ICE_IPV4_OFOS,        ICE_IPV4_OFOS_HW },
4551         { ICE_IPV4_IL,          ICE_IPV4_IL_HW },
4552         { ICE_IPV6_OFOS,        ICE_IPV6_OFOS_HW },
4553         { ICE_IPV6_IL,          ICE_IPV6_IL_HW },
4554         { ICE_TCP_IL,           ICE_TCP_IL_HW },
4555         { ICE_UDP_OF,           ICE_UDP_OF_HW },
4556         { ICE_UDP_ILOS,         ICE_UDP_ILOS_HW },
4557         { ICE_VXLAN,            ICE_UDP_OF_HW },
4558         { ICE_GENEVE,           ICE_UDP_OF_HW },
4559         { ICE_NVGRE,            ICE_GRE_OF_HW },
4560         { ICE_GTP,              ICE_UDP_OF_HW },
4561         { ICE_GTP_NO_PAY,       ICE_UDP_ILOS_HW },
4562         { ICE_PPPOE,            ICE_PPPOE_HW },
4563         { ICE_L2TPV3,           ICE_L2TPV3_HW },
4564         { ICE_VLAN_EX,          ICE_VLAN_OF_HW },
4565         { ICE_VLAN_IN,          ICE_VLAN_OL_HW },
4566         { ICE_HW_METADATA,      ICE_META_DATA_ID_HW },
4567 };
4568
4569 /**
4570  * ice_find_recp - find a recipe
4571  * @hw: pointer to the hardware structure
4572  * @lkup_exts: extension sequence to match
4573  * @rinfo: information regarding the rule e.g. priority and action info
4574  *
4575  * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
4576  */
4577 static u16
4578 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
4579               const struct ice_adv_rule_info *rinfo)
4580 {
4581         bool refresh_required = true;
4582         struct ice_sw_recipe *recp;
4583         u8 i;
4584
4585         /* Walk through existing recipes to find a match */
4586         recp = hw->switch_info->recp_list;
4587         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
4588                 /* If recipe was not created for this ID, in SW bookkeeping,
4589                  * check if FW has an entry for this recipe. If the FW has an
4590                  * entry update it in our SW bookkeeping and continue with the
4591                  * matching.
4592                  */
4593                 if (!recp[i].recp_created)
4594                         if (ice_get_recp_frm_fw(hw,
4595                                                 hw->switch_info->recp_list, i,
4596                                                 &refresh_required))
4597                                 continue;
4598
4599                 /* Skip inverse action recipes */
4600                 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
4601                     ICE_AQ_RECIPE_ACT_INV_ACT)
4602                         continue;
4603
4604                 /* if number of words we are looking for match */
4605                 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
4606                         struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
4607                         struct ice_fv_word *be = lkup_exts->fv_words;
4608                         u16 *cr = recp[i].lkup_exts.field_mask;
4609                         u16 *de = lkup_exts->field_mask;
4610                         bool found = true;
4611                         u8 pe, qr;
4612
4613                         /* ar, cr, and qr are related to the recipe words, while
4614                          * be, de, and pe are related to the lookup words
4615                          */
4616                         for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
4617                                 for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
4618                                      qr++) {
4619                                         if (ar[qr].off == be[pe].off &&
4620                                             ar[qr].prot_id == be[pe].prot_id &&
4621                                             cr[qr] == de[pe])
4622                                                 /* Found the "pe"th word in the
4623                                                  * given recipe
4624                                                  */
4625                                                 break;
4626                                 }
4627                                 /* After walking through all the words in the
4628                                  * "i"th recipe if "p"th word was not found then
4629                                  * this recipe is not what we are looking for.
4630                                  * So break out from this loop and try the next
4631                                  * recipe
4632                                  */
4633                                 if (qr >= recp[i].lkup_exts.n_val_words) {
4634                                         found = false;
4635                                         break;
4636                                 }
4637                         }
4638                         /* If for "i"th recipe the found was never set to false
4639                          * then it means we found our match
4640                          * Also tun type and *_pass_l2 of recipe needs to be
4641                          * checked
4642                          */
4643                         if (found && recp[i].tun_type == rinfo->tun_type &&
4644                             recp[i].need_pass_l2 == rinfo->need_pass_l2 &&
4645                             recp[i].allow_pass_l2 == rinfo->allow_pass_l2)
4646                                 return i; /* Return the recipe ID */
4647                 }
4648         }
4649         return ICE_MAX_NUM_RECIPES;
4650 }
4651
4652 /**
4653  * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
4654  *
4655  * As protocol id for outer vlan is different in dvm and svm, if dvm is
4656  * supported protocol array record for outer vlan has to be modified to
4657  * reflect the value proper for DVM.
4658  */
4659 void ice_change_proto_id_to_dvm(void)
4660 {
4661         u8 i;
4662
4663         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4664                 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
4665                     ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
4666                         ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
4667 }
4668
4669 /**
4670  * ice_prot_type_to_id - get protocol ID from protocol type
4671  * @type: protocol type
4672  * @id: pointer to variable that will receive the ID
4673  *
4674  * Returns true if found, false otherwise
4675  */
4676 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
4677 {
4678         u8 i;
4679
4680         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4681                 if (ice_prot_id_tbl[i].type == type) {
4682                         *id = ice_prot_id_tbl[i].protocol_id;
4683                         return true;
4684                 }
4685         return false;
4686 }
4687
4688 /**
4689  * ice_fill_valid_words - count valid words
4690  * @rule: advanced rule with lookup information
4691  * @lkup_exts: byte offset extractions of the words that are valid
4692  *
4693  * calculate valid words in a lookup rule using mask value
4694  */
4695 static u8
4696 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
4697                      struct ice_prot_lkup_ext *lkup_exts)
4698 {
4699         u8 j, word, prot_id, ret_val;
4700
4701         if (!ice_prot_type_to_id(rule->type, &prot_id))
4702                 return 0;
4703
4704         word = lkup_exts->n_val_words;
4705
4706         for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
4707                 if (((u16 *)&rule->m_u)[j] &&
4708                     rule->type < ARRAY_SIZE(ice_prot_ext)) {
4709                         /* No more space to accommodate */
4710                         if (word >= ICE_MAX_CHAIN_WORDS)
4711                                 return 0;
4712                         lkup_exts->fv_words[word].off =
4713                                 ice_prot_ext[rule->type].offs[j];
4714                         lkup_exts->fv_words[word].prot_id =
4715                                 ice_prot_id_tbl[rule->type].protocol_id;
4716                         lkup_exts->field_mask[word] =
4717                                 be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
4718                         word++;
4719                 }
4720
4721         ret_val = word - lkup_exts->n_val_words;
4722         lkup_exts->n_val_words = word;
4723
4724         return ret_val;
4725 }
4726
4727 /**
4728  * ice_create_first_fit_recp_def - Create a recipe grouping
4729  * @hw: pointer to the hardware structure
4730  * @lkup_exts: an array of protocol header extractions
4731  * @rg_list: pointer to a list that stores new recipe groups
4732  * @recp_cnt: pointer to a variable that stores returned number of recipe groups
4733  *
4734  * Using first fit algorithm, take all the words that are still not done
4735  * and start grouping them in 4-word groups. Each group makes up one
4736  * recipe.
4737  */
4738 static int
4739 ice_create_first_fit_recp_def(struct ice_hw *hw,
4740                               struct ice_prot_lkup_ext *lkup_exts,
4741                               struct list_head *rg_list,
4742                               u8 *recp_cnt)
4743 {
4744         struct ice_pref_recipe_group *grp = NULL;
4745         u8 j;
4746
4747         *recp_cnt = 0;
4748
4749         /* Walk through every word in the rule to check if it is not done. If so
4750          * then this word needs to be part of a new recipe.
4751          */
4752         for (j = 0; j < lkup_exts->n_val_words; j++)
4753                 if (!test_bit(j, lkup_exts->done)) {
4754                         if (!grp ||
4755                             grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
4756                                 struct ice_recp_grp_entry *entry;
4757
4758                                 entry = devm_kzalloc(ice_hw_to_dev(hw),
4759                                                      sizeof(*entry),
4760                                                      GFP_KERNEL);
4761                                 if (!entry)
4762                                         return -ENOMEM;
4763                                 list_add(&entry->l_entry, rg_list);
4764                                 grp = &entry->r_group;
4765                                 (*recp_cnt)++;
4766                         }
4767
4768                         grp->pairs[grp->n_val_pairs].prot_id =
4769                                 lkup_exts->fv_words[j].prot_id;
4770                         grp->pairs[grp->n_val_pairs].off =
4771                                 lkup_exts->fv_words[j].off;
4772                         grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
4773                         grp->n_val_pairs++;
4774                 }
4775
4776         return 0;
4777 }
4778
4779 /**
4780  * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
4781  * @hw: pointer to the hardware structure
4782  * @fv_list: field vector with the extraction sequence information
4783  * @rg_list: recipe groupings with protocol-offset pairs
4784  *
4785  * Helper function to fill in the field vector indices for protocol-offset
4786  * pairs. These indexes are then ultimately programmed into a recipe.
4787  */
4788 static int
4789 ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list,
4790                        struct list_head *rg_list)
4791 {
4792         struct ice_sw_fv_list_entry *fv;
4793         struct ice_recp_grp_entry *rg;
4794         struct ice_fv_word *fv_ext;
4795
4796         if (list_empty(fv_list))
4797                 return 0;
4798
4799         fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry,
4800                               list_entry);
4801         fv_ext = fv->fv_ptr->ew;
4802
4803         list_for_each_entry(rg, rg_list, l_entry) {
4804                 u8 i;
4805
4806                 for (i = 0; i < rg->r_group.n_val_pairs; i++) {
4807                         struct ice_fv_word *pr;
4808                         bool found = false;
4809                         u16 mask;
4810                         u8 j;
4811
4812                         pr = &rg->r_group.pairs[i];
4813                         mask = rg->r_group.mask[i];
4814
4815                         for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
4816                                 if (fv_ext[j].prot_id == pr->prot_id &&
4817                                     fv_ext[j].off == pr->off) {
4818                                         found = true;
4819
4820                                         /* Store index of field vector */
4821                                         rg->fv_idx[i] = j;
4822                                         rg->fv_mask[i] = mask;
4823                                         break;
4824                                 }
4825
4826                         /* Protocol/offset could not be found, caller gave an
4827                          * invalid pair
4828                          */
4829                         if (!found)
4830                                 return -EINVAL;
4831                 }
4832         }
4833
4834         return 0;
4835 }
4836
4837 /**
4838  * ice_find_free_recp_res_idx - find free result indexes for recipe
4839  * @hw: pointer to hardware structure
4840  * @profiles: bitmap of profiles that will be associated with the new recipe
4841  * @free_idx: pointer to variable to receive the free index bitmap
4842  *
4843  * The algorithm used here is:
4844  *      1. When creating a new recipe, create a set P which contains all
4845  *         Profiles that will be associated with our new recipe
4846  *
4847  *      2. For each Profile p in set P:
4848  *          a. Add all recipes associated with Profile p into set R
4849  *          b. Optional : PossibleIndexes &= profile[p].possibleIndexes
4850  *              [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
4851  *              i. Or just assume they all have the same possible indexes:
4852  *                      44, 45, 46, 47
4853  *                      i.e., PossibleIndexes = 0x0000F00000000000
4854  *
4855  *      3. For each Recipe r in set R:
4856  *          a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
4857  *          b. FreeIndexes = UsedIndexes ^ PossibleIndexes
4858  *
4859  *      FreeIndexes will contain the bits indicating the indexes free for use,
4860  *      then the code needs to update the recipe[r].used_result_idx_bits to
4861  *      indicate which indexes were selected for use by this recipe.
4862  */
4863 static u16
4864 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
4865                            unsigned long *free_idx)
4866 {
4867         DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
4868         DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
4869         DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
4870         u16 bit;
4871
4872         bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
4873         bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
4874
4875         bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
4876
4877         /* For each profile we are going to associate the recipe with, add the
4878          * recipes that are associated with that profile. This will give us
4879          * the set of recipes that our recipe may collide with. Also, determine
4880          * what possible result indexes are usable given this set of profiles.
4881          */
4882         for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
4883                 bitmap_or(recipes, recipes, profile_to_recipe[bit],
4884                           ICE_MAX_NUM_RECIPES);
4885                 bitmap_and(possible_idx, possible_idx,
4886                            hw->switch_info->prof_res_bm[bit],
4887                            ICE_MAX_FV_WORDS);
4888         }
4889
4890         /* For each recipe that our new recipe may collide with, determine
4891          * which indexes have been used.
4892          */
4893         for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
4894                 bitmap_or(used_idx, used_idx,
4895                           hw->switch_info->recp_list[bit].res_idxs,
4896                           ICE_MAX_FV_WORDS);
4897
4898         bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
4899
4900         /* return number of free indexes */
4901         return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
4902 }
4903
4904 /**
4905  * ice_add_sw_recipe - function to call AQ calls to create switch recipe
4906  * @hw: pointer to hardware structure
4907  * @rm: recipe management list entry
4908  * @profiles: bitmap of profiles that will be associated.
4909  */
4910 static int
4911 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
4912                   unsigned long *profiles)
4913 {
4914         DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
4915         struct ice_aqc_recipe_content *content;
4916         struct ice_aqc_recipe_data_elem *tmp;
4917         struct ice_aqc_recipe_data_elem *buf;
4918         struct ice_recp_grp_entry *entry;
4919         u16 free_res_idx;
4920         u16 recipe_count;
4921         u8 chain_idx;
4922         u8 recps = 0;
4923         int status;
4924
4925         /* When more than one recipe are required, another recipe is needed to
4926          * chain them together. Matching a tunnel metadata ID takes up one of
4927          * the match fields in the chaining recipe reducing the number of
4928          * chained recipes by one.
4929          */
4930          /* check number of free result indices */
4931         bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
4932         free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
4933
4934         ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
4935                   free_res_idx, rm->n_grp_count);
4936
4937         if (rm->n_grp_count > 1) {
4938                 if (rm->n_grp_count > free_res_idx)
4939                         return -ENOSPC;
4940
4941                 rm->n_grp_count++;
4942         }
4943
4944         if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
4945                 return -ENOSPC;
4946
4947         tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
4948         if (!tmp)
4949                 return -ENOMEM;
4950
4951         buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf),
4952                            GFP_KERNEL);
4953         if (!buf) {
4954                 status = -ENOMEM;
4955                 goto err_mem;
4956         }
4957
4958         bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
4959         recipe_count = ICE_MAX_NUM_RECIPES;
4960         status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
4961                                    NULL);
4962         if (status || recipe_count == 0)
4963                 goto err_unroll;
4964
4965         /* Allocate the recipe resources, and configure them according to the
4966          * match fields from protocol headers and extracted field vectors.
4967          */
4968         chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
4969         list_for_each_entry(entry, &rm->rg_list, l_entry) {
4970                 u8 i;
4971
4972                 status = ice_alloc_recipe(hw, &entry->rid);
4973                 if (status)
4974                         goto err_unroll;
4975
4976                 content = &buf[recps].content;
4977
4978                 /* Clear the result index of the located recipe, as this will be
4979                  * updated, if needed, later in the recipe creation process.
4980                  */
4981                 tmp[0].content.result_indx = 0;
4982
4983                 buf[recps] = tmp[0];
4984                 buf[recps].recipe_indx = (u8)entry->rid;
4985                 /* if the recipe is a non-root recipe RID should be programmed
4986                  * as 0 for the rules to be applied correctly.
4987                  */
4988                 content->rid = 0;
4989                 memset(&content->lkup_indx, 0,
4990                        sizeof(content->lkup_indx));
4991
4992                 /* All recipes use look-up index 0 to match switch ID. */
4993                 content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
4994                 content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
4995                 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
4996                  * to be 0
4997                  */
4998                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
4999                         content->lkup_indx[i] = 0x80;
5000                         content->mask[i] = 0;
5001                 }
5002
5003                 for (i = 0; i < entry->r_group.n_val_pairs; i++) {
5004                         content->lkup_indx[i + 1] = entry->fv_idx[i];
5005                         content->mask[i + 1] = cpu_to_le16(entry->fv_mask[i]);
5006                 }
5007
5008                 if (rm->n_grp_count > 1) {
5009                         /* Checks to see if there really is a valid result index
5010                          * that can be used.
5011                          */
5012                         if (chain_idx >= ICE_MAX_FV_WORDS) {
5013                                 ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
5014                                 status = -ENOSPC;
5015                                 goto err_unroll;
5016                         }
5017
5018                         entry->chain_idx = chain_idx;
5019                         content->result_indx =
5020                                 ICE_AQ_RECIPE_RESULT_EN |
5021                                 FIELD_PREP(ICE_AQ_RECIPE_RESULT_DATA_M,
5022                                            chain_idx);
5023                         clear_bit(chain_idx, result_idx_bm);
5024                         chain_idx = find_first_bit(result_idx_bm,
5025                                                    ICE_MAX_FV_WORDS);
5026                 }
5027
5028                 /* fill recipe dependencies */
5029                 bitmap_zero((unsigned long *)buf[recps].recipe_bitmap,
5030                             ICE_MAX_NUM_RECIPES);
5031                 set_bit(buf[recps].recipe_indx,
5032                         (unsigned long *)buf[recps].recipe_bitmap);
5033                 content->act_ctrl_fwd_priority = rm->priority;
5034
5035                 if (rm->need_pass_l2)
5036                         content->act_ctrl |= ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
5037
5038                 if (rm->allow_pass_l2)
5039                         content->act_ctrl |= ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
5040                 recps++;
5041         }
5042
5043         if (rm->n_grp_count == 1) {
5044                 rm->root_rid = buf[0].recipe_indx;
5045                 set_bit(buf[0].recipe_indx, rm->r_bitmap);
5046                 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
5047                 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
5048                         memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
5049                                sizeof(buf[0].recipe_bitmap));
5050                 } else {
5051                         status = -EINVAL;
5052                         goto err_unroll;
5053                 }
5054                 /* Applicable only for ROOT_RECIPE, set the fwd_priority for
5055                  * the recipe which is getting created if specified
5056                  * by user. Usually any advanced switch filter, which results
5057                  * into new extraction sequence, ended up creating a new recipe
5058                  * of type ROOT and usually recipes are associated with profiles
5059                  * Switch rule referreing newly created recipe, needs to have
5060                  * either/or 'fwd' or 'join' priority, otherwise switch rule
5061                  * evaluation will not happen correctly. In other words, if
5062                  * switch rule to be evaluated on priority basis, then recipe
5063                  * needs to have priority, otherwise it will be evaluated last.
5064                  */
5065                 buf[0].content.act_ctrl_fwd_priority = rm->priority;
5066         } else {
5067                 struct ice_recp_grp_entry *last_chain_entry;
5068                 u16 rid, i;
5069
5070                 /* Allocate the last recipe that will chain the outcomes of the
5071                  * other recipes together
5072                  */
5073                 status = ice_alloc_recipe(hw, &rid);
5074                 if (status)
5075                         goto err_unroll;
5076
5077                 content = &buf[recps].content;
5078
5079                 buf[recps].recipe_indx = (u8)rid;
5080                 content->rid = (u8)rid;
5081                 content->rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
5082                 /* the new entry created should also be part of rg_list to
5083                  * make sure we have complete recipe
5084                  */
5085                 last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw),
5086                                                 sizeof(*last_chain_entry),
5087                                                 GFP_KERNEL);
5088                 if (!last_chain_entry) {
5089                         status = -ENOMEM;
5090                         goto err_unroll;
5091                 }
5092                 last_chain_entry->rid = rid;
5093                 memset(&content->lkup_indx, 0, sizeof(content->lkup_indx));
5094                 /* All recipes use look-up index 0 to match switch ID. */
5095                 content->lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
5096                 content->mask[0] = cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
5097                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5098                         content->lkup_indx[i] = ICE_AQ_RECIPE_LKUP_IGNORE;
5099                         content->mask[i] = 0;
5100                 }
5101
5102                 i = 1;
5103                 /* update r_bitmap with the recp that is used for chaining */
5104                 set_bit(rid, rm->r_bitmap);
5105                 /* this is the recipe that chains all the other recipes so it
5106                  * should not have a chaining ID to indicate the same
5107                  */
5108                 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
5109                 list_for_each_entry(entry, &rm->rg_list, l_entry) {
5110                         last_chain_entry->fv_idx[i] = entry->chain_idx;
5111                         content->lkup_indx[i] = entry->chain_idx;
5112                         content->mask[i++] = cpu_to_le16(0xFFFF);
5113                         set_bit(entry->rid, rm->r_bitmap);
5114                 }
5115                 list_add(&last_chain_entry->l_entry, &rm->rg_list);
5116                 if (sizeof(buf[recps].recipe_bitmap) >=
5117                     sizeof(rm->r_bitmap)) {
5118                         memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
5119                                sizeof(buf[recps].recipe_bitmap));
5120                 } else {
5121                         status = -EINVAL;
5122                         goto err_unroll;
5123                 }
5124                 content->act_ctrl_fwd_priority = rm->priority;
5125
5126                 recps++;
5127                 rm->root_rid = (u8)rid;
5128         }
5129         status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5130         if (status)
5131                 goto err_unroll;
5132
5133         status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
5134         ice_release_change_lock(hw);
5135         if (status)
5136                 goto err_unroll;
5137
5138         /* Every recipe that just got created add it to the recipe
5139          * book keeping list
5140          */
5141         list_for_each_entry(entry, &rm->rg_list, l_entry) {
5142                 struct ice_switch_info *sw = hw->switch_info;
5143                 bool is_root, idx_found = false;
5144                 struct ice_sw_recipe *recp;
5145                 u16 idx, buf_idx = 0;
5146
5147                 /* find buffer index for copying some data */
5148                 for (idx = 0; idx < rm->n_grp_count; idx++)
5149                         if (buf[idx].recipe_indx == entry->rid) {
5150                                 buf_idx = idx;
5151                                 idx_found = true;
5152                         }
5153
5154                 if (!idx_found) {
5155                         status = -EIO;
5156                         goto err_unroll;
5157                 }
5158
5159                 recp = &sw->recp_list[entry->rid];
5160                 is_root = (rm->root_rid == entry->rid);
5161                 recp->is_root = is_root;
5162
5163                 recp->root_rid = entry->rid;
5164                 recp->big_recp = (is_root && rm->n_grp_count > 1);
5165
5166                 memcpy(&recp->ext_words, entry->r_group.pairs,
5167                        entry->r_group.n_val_pairs * sizeof(struct ice_fv_word));
5168
5169                 memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
5170                        sizeof(recp->r_bitmap));
5171
5172                 /* Copy non-result fv index values and masks to recipe. This
5173                  * call will also update the result recipe bitmask.
5174                  */
5175                 ice_collect_result_idx(&buf[buf_idx], recp);
5176
5177                 /* for non-root recipes, also copy to the root, this allows
5178                  * easier matching of a complete chained recipe
5179                  */
5180                 if (!is_root)
5181                         ice_collect_result_idx(&buf[buf_idx],
5182                                                &sw->recp_list[rm->root_rid]);
5183
5184                 recp->n_ext_words = entry->r_group.n_val_pairs;
5185                 recp->chain_idx = entry->chain_idx;
5186                 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
5187                 recp->n_grp_count = rm->n_grp_count;
5188                 recp->tun_type = rm->tun_type;
5189                 recp->need_pass_l2 = rm->need_pass_l2;
5190                 recp->allow_pass_l2 = rm->allow_pass_l2;
5191                 recp->recp_created = true;
5192         }
5193         rm->root_buf = buf;
5194         kfree(tmp);
5195         return status;
5196
5197 err_unroll:
5198 err_mem:
5199         kfree(tmp);
5200         devm_kfree(ice_hw_to_dev(hw), buf);
5201         return status;
5202 }
5203
5204 /**
5205  * ice_create_recipe_group - creates recipe group
5206  * @hw: pointer to hardware structure
5207  * @rm: recipe management list entry
5208  * @lkup_exts: lookup elements
5209  */
5210 static int
5211 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
5212                         struct ice_prot_lkup_ext *lkup_exts)
5213 {
5214         u8 recp_count = 0;
5215         int status;
5216
5217         rm->n_grp_count = 0;
5218
5219         /* Create recipes for words that are marked not done by packing them
5220          * as best fit.
5221          */
5222         status = ice_create_first_fit_recp_def(hw, lkup_exts,
5223                                                &rm->rg_list, &recp_count);
5224         if (!status) {
5225                 rm->n_grp_count += recp_count;
5226                 rm->n_ext_words = lkup_exts->n_val_words;
5227                 memcpy(&rm->ext_words, lkup_exts->fv_words,
5228                        sizeof(rm->ext_words));
5229                 memcpy(rm->word_masks, lkup_exts->field_mask,
5230                        sizeof(rm->word_masks));
5231         }
5232
5233         return status;
5234 }
5235
5236 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
5237  * @hw: pointer to hardware structure
5238  * @rinfo: other information regarding the rule e.g. priority and action info
5239  * @bm: pointer to memory for returning the bitmap of field vectors
5240  */
5241 static void
5242 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
5243                          unsigned long *bm)
5244 {
5245         enum ice_prof_type prof_type;
5246
5247         bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
5248
5249         switch (rinfo->tun_type) {
5250         case ICE_NON_TUN:
5251                 prof_type = ICE_PROF_NON_TUN;
5252                 break;
5253         case ICE_ALL_TUNNELS:
5254                 prof_type = ICE_PROF_TUN_ALL;
5255                 break;
5256         case ICE_SW_TUN_GENEVE:
5257         case ICE_SW_TUN_VXLAN:
5258                 prof_type = ICE_PROF_TUN_UDP;
5259                 break;
5260         case ICE_SW_TUN_NVGRE:
5261                 prof_type = ICE_PROF_TUN_GRE;
5262                 break;
5263         case ICE_SW_TUN_GTPU:
5264                 prof_type = ICE_PROF_TUN_GTPU;
5265                 break;
5266         case ICE_SW_TUN_GTPC:
5267                 prof_type = ICE_PROF_TUN_GTPC;
5268                 break;
5269         case ICE_SW_TUN_AND_NON_TUN:
5270         default:
5271                 prof_type = ICE_PROF_ALL;
5272                 break;
5273         }
5274
5275         ice_get_sw_fv_bitmap(hw, prof_type, bm);
5276 }
5277
5278 /**
5279  * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
5280  * @hw: pointer to hardware structure
5281  * @lkups: lookup elements or match criteria for the advanced recipe, one
5282  *  structure per protocol header
5283  * @lkups_cnt: number of protocols
5284  * @rinfo: other information regarding the rule e.g. priority and action info
5285  * @rid: return the recipe ID of the recipe created
5286  */
5287 static int
5288 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5289                    u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
5290 {
5291         DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
5292         DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
5293         struct ice_prot_lkup_ext *lkup_exts;
5294         struct ice_recp_grp_entry *r_entry;
5295         struct ice_sw_fv_list_entry *fvit;
5296         struct ice_recp_grp_entry *r_tmp;
5297         struct ice_sw_fv_list_entry *tmp;
5298         struct ice_sw_recipe *rm;
5299         int status = 0;
5300         u8 i;
5301
5302         if (!lkups_cnt)
5303                 return -EINVAL;
5304
5305         lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
5306         if (!lkup_exts)
5307                 return -ENOMEM;
5308
5309         /* Determine the number of words to be matched and if it exceeds a
5310          * recipe's restrictions
5311          */
5312         for (i = 0; i < lkups_cnt; i++) {
5313                 u16 count;
5314
5315                 if (lkups[i].type >= ICE_PROTOCOL_LAST) {
5316                         status = -EIO;
5317                         goto err_free_lkup_exts;
5318                 }
5319
5320                 count = ice_fill_valid_words(&lkups[i], lkup_exts);
5321                 if (!count) {
5322                         status = -EIO;
5323                         goto err_free_lkup_exts;
5324                 }
5325         }
5326
5327         rm = kzalloc(sizeof(*rm), GFP_KERNEL);
5328         if (!rm) {
5329                 status = -ENOMEM;
5330                 goto err_free_lkup_exts;
5331         }
5332
5333         /* Get field vectors that contain fields extracted from all the protocol
5334          * headers being programmed.
5335          */
5336         INIT_LIST_HEAD(&rm->fv_list);
5337         INIT_LIST_HEAD(&rm->rg_list);
5338
5339         /* Get bitmap of field vectors (profiles) that are compatible with the
5340          * rule request; only these will be searched in the subsequent call to
5341          * ice_get_sw_fv_list.
5342          */
5343         ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
5344
5345         status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
5346         if (status)
5347                 goto err_unroll;
5348
5349         /* Group match words into recipes using preferred recipe grouping
5350          * criteria.
5351          */
5352         status = ice_create_recipe_group(hw, rm, lkup_exts);
5353         if (status)
5354                 goto err_unroll;
5355
5356         /* set the recipe priority if specified */
5357         rm->priority = (u8)rinfo->priority;
5358
5359         rm->need_pass_l2 = rinfo->need_pass_l2;
5360         rm->allow_pass_l2 = rinfo->allow_pass_l2;
5361
5362         /* Find offsets from the field vector. Pick the first one for all the
5363          * recipes.
5364          */
5365         status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
5366         if (status)
5367                 goto err_unroll;
5368
5369         /* get bitmap of all profiles the recipe will be associated with */
5370         bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
5371         list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5372                 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
5373                 set_bit((u16)fvit->profile_id, profiles);
5374         }
5375
5376         /* Look for a recipe which matches our requested fv / mask list */
5377         *rid = ice_find_recp(hw, lkup_exts, rinfo);
5378         if (*rid < ICE_MAX_NUM_RECIPES)
5379                 /* Success if found a recipe that match the existing criteria */
5380                 goto err_unroll;
5381
5382         rm->tun_type = rinfo->tun_type;
5383         /* Recipe we need does not exist, add a recipe */
5384         status = ice_add_sw_recipe(hw, rm, profiles);
5385         if (status)
5386                 goto err_unroll;
5387
5388         /* Associate all the recipes created with all the profiles in the
5389          * common field vector.
5390          */
5391         list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5392                 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
5393                 u16 j;
5394
5395                 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
5396                                                       (u8 *)r_bitmap, NULL);
5397                 if (status)
5398                         goto err_unroll;
5399
5400                 bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
5401                           ICE_MAX_NUM_RECIPES);
5402                 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5403                 if (status)
5404                         goto err_unroll;
5405
5406                 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
5407                                                       (u8 *)r_bitmap,
5408                                                       NULL);
5409                 ice_release_change_lock(hw);
5410
5411                 if (status)
5412                         goto err_unroll;
5413
5414                 /* Update profile to recipe bitmap array */
5415                 bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
5416                             ICE_MAX_NUM_RECIPES);
5417
5418                 /* Update recipe to profile bitmap array */
5419                 for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
5420                         set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
5421         }
5422
5423         *rid = rm->root_rid;
5424         memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
5425                sizeof(*lkup_exts));
5426 err_unroll:
5427         list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) {
5428                 list_del(&r_entry->l_entry);
5429                 devm_kfree(ice_hw_to_dev(hw), r_entry);
5430         }
5431
5432         list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
5433                 list_del(&fvit->list_entry);
5434                 devm_kfree(ice_hw_to_dev(hw), fvit);
5435         }
5436
5437         devm_kfree(ice_hw_to_dev(hw), rm->root_buf);
5438         kfree(rm);
5439
5440 err_free_lkup_exts:
5441         kfree(lkup_exts);
5442
5443         return status;
5444 }
5445
5446 /**
5447  * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt
5448  *
5449  * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added
5450  * @num_vlan: number of VLAN tags
5451  */
5452 static struct ice_dummy_pkt_profile *
5453 ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt,
5454                           u32 num_vlan)
5455 {
5456         struct ice_dummy_pkt_profile *profile;
5457         struct ice_dummy_pkt_offsets *offsets;
5458         u32 buf_len, off, etype_off, i;
5459         u8 *pkt;
5460
5461         if (num_vlan < 1 || num_vlan > 2)
5462                 return ERR_PTR(-EINVAL);
5463
5464         off = num_vlan * VLAN_HLEN;
5465
5466         buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) +
5467                   dummy_pkt->offsets_len;
5468         offsets = kzalloc(buf_len, GFP_KERNEL);
5469         if (!offsets)
5470                 return ERR_PTR(-ENOMEM);
5471
5472         offsets[0] = dummy_pkt->offsets[0];
5473         if (num_vlan == 2) {
5474                 offsets[1] = ice_dummy_qinq_packet_offsets[0];
5475                 offsets[2] = ice_dummy_qinq_packet_offsets[1];
5476         } else if (num_vlan == 1) {
5477                 offsets[1] = ice_dummy_vlan_packet_offsets[0];
5478         }
5479
5480         for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5481                 offsets[i + num_vlan].type = dummy_pkt->offsets[i].type;
5482                 offsets[i + num_vlan].offset =
5483                         dummy_pkt->offsets[i].offset + off;
5484         }
5485         offsets[i + num_vlan] = dummy_pkt->offsets[i];
5486
5487         etype_off = dummy_pkt->offsets[1].offset;
5488
5489         buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) +
5490                   dummy_pkt->pkt_len;
5491         pkt = kzalloc(buf_len, GFP_KERNEL);
5492         if (!pkt) {
5493                 kfree(offsets);
5494                 return ERR_PTR(-ENOMEM);
5495         }
5496
5497         memcpy(pkt, dummy_pkt->pkt, etype_off);
5498         memcpy(pkt + etype_off,
5499                num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet,
5500                off);
5501         memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off,
5502                dummy_pkt->pkt_len - etype_off);
5503
5504         profile = kzalloc(sizeof(*profile), GFP_KERNEL);
5505         if (!profile) {
5506                 kfree(offsets);
5507                 kfree(pkt);
5508                 return ERR_PTR(-ENOMEM);
5509         }
5510
5511         profile->offsets = offsets;
5512         profile->pkt = pkt;
5513         profile->pkt_len = buf_len;
5514         profile->match |= ICE_PKT_KMALLOC;
5515
5516         return profile;
5517 }
5518
5519 /**
5520  * ice_find_dummy_packet - find dummy packet
5521  *
5522  * @lkups: lookup elements or match criteria for the advanced recipe, one
5523  *         structure per protocol header
5524  * @lkups_cnt: number of protocols
5525  * @tun_type: tunnel type
5526  *
5527  * Returns the &ice_dummy_pkt_profile corresponding to these lookup params.
5528  */
5529 static const struct ice_dummy_pkt_profile *
5530 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5531                       enum ice_sw_tunnel_type tun_type)
5532 {
5533         const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles;
5534         u32 match = 0, vlan_count = 0;
5535         u16 i;
5536
5537         switch (tun_type) {
5538         case ICE_SW_TUN_GTPC:
5539                 match |= ICE_PKT_TUN_GTPC;
5540                 break;
5541         case ICE_SW_TUN_GTPU:
5542                 match |= ICE_PKT_TUN_GTPU;
5543                 break;
5544         case ICE_SW_TUN_NVGRE:
5545                 match |= ICE_PKT_TUN_NVGRE;
5546                 break;
5547         case ICE_SW_TUN_GENEVE:
5548         case ICE_SW_TUN_VXLAN:
5549                 match |= ICE_PKT_TUN_UDP;
5550                 break;
5551         default:
5552                 break;
5553         }
5554
5555         for (i = 0; i < lkups_cnt; i++) {
5556                 if (lkups[i].type == ICE_UDP_ILOS)
5557                         match |= ICE_PKT_INNER_UDP;
5558                 else if (lkups[i].type == ICE_TCP_IL)
5559                         match |= ICE_PKT_INNER_TCP;
5560                 else if (lkups[i].type == ICE_IPV6_OFOS)
5561                         match |= ICE_PKT_OUTER_IPV6;
5562                 else if (lkups[i].type == ICE_VLAN_OFOS ||
5563                          lkups[i].type == ICE_VLAN_EX)
5564                         vlan_count++;
5565                 else if (lkups[i].type == ICE_VLAN_IN)
5566                         vlan_count++;
5567                 else if (lkups[i].type == ICE_ETYPE_OL &&
5568                          lkups[i].h_u.ethertype.ethtype_id ==
5569                                 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5570                          lkups[i].m_u.ethertype.ethtype_id ==
5571                                 cpu_to_be16(0xFFFF))
5572                         match |= ICE_PKT_OUTER_IPV6;
5573                 else if (lkups[i].type == ICE_ETYPE_IL &&
5574                          lkups[i].h_u.ethertype.ethtype_id ==
5575                                 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5576                          lkups[i].m_u.ethertype.ethtype_id ==
5577                                 cpu_to_be16(0xFFFF))
5578                         match |= ICE_PKT_INNER_IPV6;
5579                 else if (lkups[i].type == ICE_IPV6_IL)
5580                         match |= ICE_PKT_INNER_IPV6;
5581                 else if (lkups[i].type == ICE_GTP_NO_PAY)
5582                         match |= ICE_PKT_GTP_NOPAY;
5583                 else if (lkups[i].type == ICE_PPPOE) {
5584                         match |= ICE_PKT_PPPOE;
5585                         if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
5586                             htons(PPP_IPV6))
5587                                 match |= ICE_PKT_OUTER_IPV6;
5588                 } else if (lkups[i].type == ICE_L2TPV3)
5589                         match |= ICE_PKT_L2TPV3;
5590         }
5591
5592         while (ret->match && (match & ret->match) != ret->match)
5593                 ret++;
5594
5595         if (vlan_count != 0)
5596                 ret = ice_dummy_packet_add_vlan(ret, vlan_count);
5597
5598         return ret;
5599 }
5600
5601 /**
5602  * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
5603  *
5604  * @lkups: lookup elements or match criteria for the advanced recipe, one
5605  *         structure per protocol header
5606  * @lkups_cnt: number of protocols
5607  * @s_rule: stores rule information from the match criteria
5608  * @profile: dummy packet profile (the template, its size and header offsets)
5609  */
5610 static int
5611 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5612                           struct ice_sw_rule_lkup_rx_tx *s_rule,
5613                           const struct ice_dummy_pkt_profile *profile)
5614 {
5615         u8 *pkt;
5616         u16 i;
5617
5618         /* Start with a packet with a pre-defined/dummy content. Then, fill
5619          * in the header values to be looked up or matched.
5620          */
5621         pkt = s_rule->hdr_data;
5622
5623         memcpy(pkt, profile->pkt, profile->pkt_len);
5624
5625         for (i = 0; i < lkups_cnt; i++) {
5626                 const struct ice_dummy_pkt_offsets *offsets = profile->offsets;
5627                 enum ice_protocol_type type;
5628                 u16 offset = 0, len = 0, j;
5629                 bool found = false;
5630
5631                 /* find the start of this layer; it should be found since this
5632                  * was already checked when search for the dummy packet
5633                  */
5634                 type = lkups[i].type;
5635                 /* metadata isn't present in the packet */
5636                 if (type == ICE_HW_METADATA)
5637                         continue;
5638
5639                 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
5640                         if (type == offsets[j].type) {
5641                                 offset = offsets[j].offset;
5642                                 found = true;
5643                                 break;
5644                         }
5645                 }
5646                 /* this should never happen in a correct calling sequence */
5647                 if (!found)
5648                         return -EINVAL;
5649
5650                 switch (lkups[i].type) {
5651                 case ICE_MAC_OFOS:
5652                 case ICE_MAC_IL:
5653                         len = sizeof(struct ice_ether_hdr);
5654                         break;
5655                 case ICE_ETYPE_OL:
5656                 case ICE_ETYPE_IL:
5657                         len = sizeof(struct ice_ethtype_hdr);
5658                         break;
5659                 case ICE_VLAN_OFOS:
5660                 case ICE_VLAN_EX:
5661                 case ICE_VLAN_IN:
5662                         len = sizeof(struct ice_vlan_hdr);
5663                         break;
5664                 case ICE_IPV4_OFOS:
5665                 case ICE_IPV4_IL:
5666                         len = sizeof(struct ice_ipv4_hdr);
5667                         break;
5668                 case ICE_IPV6_OFOS:
5669                 case ICE_IPV6_IL:
5670                         len = sizeof(struct ice_ipv6_hdr);
5671                         break;
5672                 case ICE_TCP_IL:
5673                 case ICE_UDP_OF:
5674                 case ICE_UDP_ILOS:
5675                         len = sizeof(struct ice_l4_hdr);
5676                         break;
5677                 case ICE_SCTP_IL:
5678                         len = sizeof(struct ice_sctp_hdr);
5679                         break;
5680                 case ICE_NVGRE:
5681                         len = sizeof(struct ice_nvgre_hdr);
5682                         break;
5683                 case ICE_VXLAN:
5684                 case ICE_GENEVE:
5685                         len = sizeof(struct ice_udp_tnl_hdr);
5686                         break;
5687                 case ICE_GTP_NO_PAY:
5688                 case ICE_GTP:
5689                         len = sizeof(struct ice_udp_gtp_hdr);
5690                         break;
5691                 case ICE_PPPOE:
5692                         len = sizeof(struct ice_pppoe_hdr);
5693                         break;
5694                 case ICE_L2TPV3:
5695                         len = sizeof(struct ice_l2tpv3_sess_hdr);
5696                         break;
5697                 default:
5698                         return -EINVAL;
5699                 }
5700
5701                 /* the length should be a word multiple */
5702                 if (len % ICE_BYTES_PER_WORD)
5703                         return -EIO;
5704
5705                 /* We have the offset to the header start, the length, the
5706                  * caller's header values and mask. Use this information to
5707                  * copy the data into the dummy packet appropriately based on
5708                  * the mask. Note that we need to only write the bits as
5709                  * indicated by the mask to make sure we don't improperly write
5710                  * over any significant packet data.
5711                  */
5712                 for (j = 0; j < len / sizeof(u16); j++) {
5713                         u16 *ptr = (u16 *)(pkt + offset);
5714                         u16 mask = lkups[i].m_raw[j];
5715
5716                         if (!mask)
5717                                 continue;
5718
5719                         ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask);
5720                 }
5721         }
5722
5723         s_rule->hdr_len = cpu_to_le16(profile->pkt_len);
5724
5725         return 0;
5726 }
5727
5728 /**
5729  * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
5730  * @hw: pointer to the hardware structure
5731  * @tun_type: tunnel type
5732  * @pkt: dummy packet to fill in
5733  * @offsets: offset info for the dummy packet
5734  */
5735 static int
5736 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
5737                         u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
5738 {
5739         u16 open_port, i;
5740
5741         switch (tun_type) {
5742         case ICE_SW_TUN_VXLAN:
5743                 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
5744                         return -EIO;
5745                 break;
5746         case ICE_SW_TUN_GENEVE:
5747                 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
5748                         return -EIO;
5749                 break;
5750         default:
5751                 /* Nothing needs to be done for this tunnel type */
5752                 return 0;
5753         }
5754
5755         /* Find the outer UDP protocol header and insert the port number */
5756         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5757                 if (offsets[i].type == ICE_UDP_OF) {
5758                         struct ice_l4_hdr *hdr;
5759                         u16 offset;
5760
5761                         offset = offsets[i].offset;
5762                         hdr = (struct ice_l4_hdr *)&pkt[offset];
5763                         hdr->dst_port = cpu_to_be16(open_port);
5764
5765                         return 0;
5766                 }
5767         }
5768
5769         return -EIO;
5770 }
5771
5772 /**
5773  * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
5774  * @hw: pointer to hw structure
5775  * @vlan_type: VLAN tag type
5776  * @pkt: dummy packet to fill in
5777  * @offsets: offset info for the dummy packet
5778  */
5779 static int
5780 ice_fill_adv_packet_vlan(struct ice_hw *hw, u16 vlan_type, u8 *pkt,
5781                          const struct ice_dummy_pkt_offsets *offsets)
5782 {
5783         u16 i;
5784
5785         /* Check if there is something to do */
5786         if (!vlan_type || !ice_is_dvm_ena(hw))
5787                 return 0;
5788
5789         /* Find VLAN header and insert VLAN TPID */
5790         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5791                 if (offsets[i].type == ICE_VLAN_OFOS ||
5792                     offsets[i].type == ICE_VLAN_EX) {
5793                         struct ice_vlan_hdr *hdr;
5794                         u16 offset;
5795
5796                         offset = offsets[i].offset;
5797                         hdr = (struct ice_vlan_hdr *)&pkt[offset];
5798                         hdr->type = cpu_to_be16(vlan_type);
5799
5800                         return 0;
5801                 }
5802         }
5803
5804         return -EIO;
5805 }
5806
5807 static bool ice_rules_equal(const struct ice_adv_rule_info *first,
5808                             const struct ice_adv_rule_info *second)
5809 {
5810         return first->sw_act.flag == second->sw_act.flag &&
5811                first->tun_type == second->tun_type &&
5812                first->vlan_type == second->vlan_type &&
5813                first->src_vsi == second->src_vsi &&
5814                first->need_pass_l2 == second->need_pass_l2 &&
5815                first->allow_pass_l2 == second->allow_pass_l2;
5816 }
5817
5818 /**
5819  * ice_find_adv_rule_entry - Search a rule entry
5820  * @hw: pointer to the hardware structure
5821  * @lkups: lookup elements or match criteria for the advanced recipe, one
5822  *         structure per protocol header
5823  * @lkups_cnt: number of protocols
5824  * @recp_id: recipe ID for which we are finding the rule
5825  * @rinfo: other information regarding the rule e.g. priority and action info
5826  *
5827  * Helper function to search for a given advance rule entry
5828  * Returns pointer to entry storing the rule if found
5829  */
5830 static struct ice_adv_fltr_mgmt_list_entry *
5831 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5832                         u16 lkups_cnt, u16 recp_id,
5833                         struct ice_adv_rule_info *rinfo)
5834 {
5835         struct ice_adv_fltr_mgmt_list_entry *list_itr;
5836         struct ice_switch_info *sw = hw->switch_info;
5837         int i;
5838
5839         list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
5840                             list_entry) {
5841                 bool lkups_matched = true;
5842
5843                 if (lkups_cnt != list_itr->lkups_cnt)
5844                         continue;
5845                 for (i = 0; i < list_itr->lkups_cnt; i++)
5846                         if (memcmp(&list_itr->lkups[i], &lkups[i],
5847                                    sizeof(*lkups))) {
5848                                 lkups_matched = false;
5849                                 break;
5850                         }
5851                 if (ice_rules_equal(rinfo, &list_itr->rule_info) &&
5852                     lkups_matched)
5853                         return list_itr;
5854         }
5855         return NULL;
5856 }
5857
5858 /**
5859  * ice_adv_add_update_vsi_list
5860  * @hw: pointer to the hardware structure
5861  * @m_entry: pointer to current adv filter management list entry
5862  * @cur_fltr: filter information from the book keeping entry
5863  * @new_fltr: filter information with the new VSI to be added
5864  *
5865  * Call AQ command to add or update previously created VSI list with new VSI.
5866  *
5867  * Helper function to do book keeping associated with adding filter information
5868  * The algorithm to do the booking keeping is described below :
5869  * When a VSI needs to subscribe to a given advanced filter
5870  *      if only one VSI has been added till now
5871  *              Allocate a new VSI list and add two VSIs
5872  *              to this list using switch rule command
5873  *              Update the previously created switch rule with the
5874  *              newly created VSI list ID
5875  *      if a VSI list was previously created
5876  *              Add the new VSI to the previously created VSI list set
5877  *              using the update switch rule command
5878  */
5879 static int
5880 ice_adv_add_update_vsi_list(struct ice_hw *hw,
5881                             struct ice_adv_fltr_mgmt_list_entry *m_entry,
5882                             struct ice_adv_rule_info *cur_fltr,
5883                             struct ice_adv_rule_info *new_fltr)
5884 {
5885         u16 vsi_list_id = 0;
5886         int status;
5887
5888         if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
5889             cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
5890             cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
5891                 return -EOPNOTSUPP;
5892
5893         if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
5894              new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
5895             (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
5896              cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
5897                 return -EOPNOTSUPP;
5898
5899         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
5900                  /* Only one entry existed in the mapping and it was not already
5901                   * a part of a VSI list. So, create a VSI list with the old and
5902                   * new VSIs.
5903                   */
5904                 struct ice_fltr_info tmp_fltr;
5905                 u16 vsi_handle_arr[2];
5906
5907                 /* A rule already exists with the new VSI being added */
5908                 if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
5909                     new_fltr->sw_act.fwd_id.hw_vsi_id)
5910                         return -EEXIST;
5911
5912                 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
5913                 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
5914                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
5915                                                   &vsi_list_id,
5916                                                   ICE_SW_LKUP_LAST);
5917                 if (status)
5918                         return status;
5919
5920                 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
5921                 tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
5922                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
5923                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
5924                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
5925                 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
5926
5927                 /* Update the previous switch rule of "forward to VSI" to
5928                  * "fwd to VSI list"
5929                  */
5930                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
5931                 if (status)
5932                         return status;
5933
5934                 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
5935                 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
5936                 m_entry->vsi_list_info =
5937                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
5938                                                 vsi_list_id);
5939         } else {
5940                 u16 vsi_handle = new_fltr->sw_act.vsi_handle;
5941
5942                 if (!m_entry->vsi_list_info)
5943                         return -EIO;
5944
5945                 /* A rule already exists with the new VSI being added */
5946                 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
5947                         return 0;
5948
5949                 /* Update the previously created VSI list set with
5950                  * the new VSI ID passed in
5951                  */
5952                 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
5953
5954                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
5955                                                   vsi_list_id, false,
5956                                                   ice_aqc_opc_update_sw_rules,
5957                                                   ICE_SW_LKUP_LAST);
5958                 /* update VSI list mapping info with new VSI ID */
5959                 if (!status)
5960                         set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
5961         }
5962         if (!status)
5963                 m_entry->vsi_count++;
5964         return status;
5965 }
5966
5967 void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup)
5968 {
5969         lkup->type = ICE_HW_METADATA;
5970         lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID21] |=
5971                 cpu_to_be16(ICE_PKT_TUNNEL_MASK);
5972 }
5973
5974 void ice_rule_add_direction_metadata(struct ice_adv_lkup_elem *lkup)
5975 {
5976         lkup->type = ICE_HW_METADATA;
5977         lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
5978                 cpu_to_be16(ICE_PKT_FROM_NETWORK);
5979 }
5980
5981 void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
5982 {
5983         lkup->type = ICE_HW_METADATA;
5984         lkup->m_u.metadata.flags[ICE_PKT_FLAGS_MDID20] |=
5985                 cpu_to_be16(ICE_PKT_VLAN_MASK);
5986 }
5987
5988 void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup)
5989 {
5990         lkup->type = ICE_HW_METADATA;
5991         lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK);
5992 }
5993
5994 /**
5995  * ice_add_adv_rule - helper function to create an advanced switch rule
5996  * @hw: pointer to the hardware structure
5997  * @lkups: information on the words that needs to be looked up. All words
5998  * together makes one recipe
5999  * @lkups_cnt: num of entries in the lkups array
6000  * @rinfo: other information related to the rule that needs to be programmed
6001  * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
6002  *               ignored is case of error.
6003  *
6004  * This function can program only 1 rule at a time. The lkups is used to
6005  * describe the all the words that forms the "lookup" portion of the recipe.
6006  * These words can span multiple protocols. Callers to this function need to
6007  * pass in a list of protocol headers with lookup information along and mask
6008  * that determines which words are valid from the given protocol header.
6009  * rinfo describes other information related to this rule such as forwarding
6010  * IDs, priority of this rule, etc.
6011  */
6012 int
6013 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6014                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
6015                  struct ice_rule_query_data *added_entry)
6016 {
6017         struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
6018         struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
6019         const struct ice_dummy_pkt_profile *profile;
6020         u16 rid = 0, i, rule_buf_sz, vsi_handle;
6021         struct list_head *rule_head;
6022         struct ice_switch_info *sw;
6023         u16 word_cnt;
6024         u32 act = 0;
6025         int status;
6026         u8 q_rgn;
6027
6028         /* Initialize profile to result index bitmap */
6029         if (!hw->switch_info->prof_res_bm_init) {
6030                 hw->switch_info->prof_res_bm_init = 1;
6031                 ice_init_prof_result_bm(hw);
6032         }
6033
6034         if (!lkups_cnt)
6035                 return -EINVAL;
6036
6037         /* get # of words we need to match */
6038         word_cnt = 0;
6039         for (i = 0; i < lkups_cnt; i++) {
6040                 u16 j;
6041
6042                 for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++)
6043                         if (lkups[i].m_raw[j])
6044                                 word_cnt++;
6045         }
6046
6047         if (!word_cnt)
6048                 return -EINVAL;
6049
6050         if (word_cnt > ICE_MAX_CHAIN_WORDS)
6051                 return -ENOSPC;
6052
6053         /* locate a dummy packet */
6054         profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type);
6055         if (IS_ERR(profile))
6056                 return PTR_ERR(profile);
6057
6058         if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6059               rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
6060               rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6061               rinfo->sw_act.fltr_act == ICE_DROP_PACKET ||
6062               rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
6063               rinfo->sw_act.fltr_act == ICE_NOP)) {
6064                 status = -EIO;
6065                 goto free_pkt_profile;
6066         }
6067
6068         vsi_handle = rinfo->sw_act.vsi_handle;
6069         if (!ice_is_vsi_valid(hw, vsi_handle)) {
6070                 status =  -EINVAL;
6071                 goto free_pkt_profile;
6072         }
6073
6074         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6075             rinfo->sw_act.fltr_act == ICE_MIRROR_PACKET ||
6076             rinfo->sw_act.fltr_act == ICE_NOP) {
6077                 rinfo->sw_act.fwd_id.hw_vsi_id =
6078                         ice_get_hw_vsi_num(hw, vsi_handle);
6079         }
6080
6081         if (rinfo->src_vsi)
6082                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, rinfo->src_vsi);
6083         else
6084                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
6085
6086         status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
6087         if (status)
6088                 goto free_pkt_profile;
6089         m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6090         if (m_entry) {
6091                 /* we have to add VSI to VSI_LIST and increment vsi_count.
6092                  * Also Update VSI list so that we can change forwarding rule
6093                  * if the rule already exists, we will check if it exists with
6094                  * same vsi_id, if not then add it to the VSI list if it already
6095                  * exists if not then create a VSI list and add the existing VSI
6096                  * ID and the new VSI ID to the list
6097                  * We will add that VSI to the list
6098                  */
6099                 status = ice_adv_add_update_vsi_list(hw, m_entry,
6100                                                      &m_entry->rule_info,
6101                                                      rinfo);
6102                 if (added_entry) {
6103                         added_entry->rid = rid;
6104                         added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
6105                         added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6106                 }
6107                 goto free_pkt_profile;
6108         }
6109         rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len);
6110         s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6111         if (!s_rule) {
6112                 status = -ENOMEM;
6113                 goto free_pkt_profile;
6114         }
6115
6116         if (rinfo->sw_act.fltr_act != ICE_MIRROR_PACKET) {
6117                 if (!rinfo->flags_info.act_valid) {
6118                         act |= ICE_SINGLE_ACT_LAN_ENABLE;
6119                         act |= ICE_SINGLE_ACT_LB_ENABLE;
6120                 } else {
6121                         act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
6122                                                         ICE_SINGLE_ACT_LB_ENABLE);
6123                 }
6124         }
6125
6126         switch (rinfo->sw_act.fltr_act) {
6127         case ICE_FWD_TO_VSI:
6128                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6129                                   rinfo->sw_act.fwd_id.hw_vsi_id);
6130                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
6131                 break;
6132         case ICE_FWD_TO_Q:
6133                 act |= ICE_SINGLE_ACT_TO_Q;
6134                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
6135                                   rinfo->sw_act.fwd_id.q_id);
6136                 break;
6137         case ICE_FWD_TO_QGRP:
6138                 q_rgn = rinfo->sw_act.qgrp_size > 0 ?
6139                         (u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
6140                 act |= ICE_SINGLE_ACT_TO_Q;
6141                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_INDEX_M,
6142                                   rinfo->sw_act.fwd_id.q_id);
6143                 act |= FIELD_PREP(ICE_SINGLE_ACT_Q_REGION_M, q_rgn);
6144                 break;
6145         case ICE_DROP_PACKET:
6146                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
6147                        ICE_SINGLE_ACT_VALID_BIT;
6148                 break;
6149         case ICE_MIRROR_PACKET:
6150                 act |= ICE_SINGLE_ACT_OTHER_ACTS;
6151                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6152                                   rinfo->sw_act.fwd_id.hw_vsi_id);
6153                 break;
6154         case ICE_NOP:
6155                 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M,
6156                                   rinfo->sw_act.fwd_id.hw_vsi_id);
6157                 act &= ~ICE_SINGLE_ACT_VALID_BIT;
6158                 break;
6159         default:
6160                 status = -EIO;
6161                 goto err_ice_add_adv_rule;
6162         }
6163
6164         /* If there is no matching criteria for direction there
6165          * is only one difference between Rx and Tx:
6166          * - get switch id base on VSI number from source field (Tx)
6167          * - get switch id base on port number (Rx)
6168          *
6169          * If matching on direction metadata is chose rule direction is
6170          * extracted from type value set here.
6171          */
6172         if (rinfo->sw_act.flag & ICE_FLTR_TX) {
6173                 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
6174                 s_rule->src = cpu_to_le16(rinfo->sw_act.src);
6175         } else {
6176                 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
6177                 s_rule->src = cpu_to_le16(hw->port_info->lport);
6178         }
6179
6180         s_rule->recipe_id = cpu_to_le16(rid);
6181         s_rule->act = cpu_to_le32(act);
6182
6183         status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile);
6184         if (status)
6185                 goto err_ice_add_adv_rule;
6186
6187         status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, s_rule->hdr_data,
6188                                          profile->offsets);
6189         if (status)
6190                 goto err_ice_add_adv_rule;
6191
6192         status = ice_fill_adv_packet_vlan(hw, rinfo->vlan_type,
6193                                           s_rule->hdr_data,
6194                                           profile->offsets);
6195         if (status)
6196                 goto err_ice_add_adv_rule;
6197
6198         status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6199                                  rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
6200                                  NULL);
6201         if (status)
6202                 goto err_ice_add_adv_rule;
6203         adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
6204                                 sizeof(struct ice_adv_fltr_mgmt_list_entry),
6205                                 GFP_KERNEL);
6206         if (!adv_fltr) {
6207                 status = -ENOMEM;
6208                 goto err_ice_add_adv_rule;
6209         }
6210
6211         adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
6212                                        lkups_cnt * sizeof(*lkups), GFP_KERNEL);
6213         if (!adv_fltr->lkups) {
6214                 status = -ENOMEM;
6215                 goto err_ice_add_adv_rule;
6216         }
6217
6218         adv_fltr->lkups_cnt = lkups_cnt;
6219         adv_fltr->rule_info = *rinfo;
6220         adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index);
6221         sw = hw->switch_info;
6222         sw->recp_list[rid].adv_rule = true;
6223         rule_head = &sw->recp_list[rid].filt_rules;
6224
6225         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6226                 adv_fltr->vsi_count = 1;
6227
6228         /* Add rule entry to book keeping list */
6229         list_add(&adv_fltr->list_entry, rule_head);
6230         if (added_entry) {
6231                 added_entry->rid = rid;
6232                 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
6233                 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6234         }
6235 err_ice_add_adv_rule:
6236         if (status && adv_fltr) {
6237                 devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
6238                 devm_kfree(ice_hw_to_dev(hw), adv_fltr);
6239         }
6240
6241         kfree(s_rule);
6242
6243 free_pkt_profile:
6244         if (profile->match & ICE_PKT_KMALLOC) {
6245                 kfree(profile->offsets);
6246                 kfree(profile->pkt);
6247                 kfree(profile);
6248         }
6249
6250         return status;
6251 }
6252
6253 /**
6254  * ice_replay_vsi_fltr - Replay filters for requested VSI
6255  * @hw: pointer to the hardware structure
6256  * @vsi_handle: driver VSI handle
6257  * @recp_id: Recipe ID for which rules need to be replayed
6258  * @list_head: list for which filters need to be replayed
6259  *
6260  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
6261  * It is required to pass valid VSI handle.
6262  */
6263 static int
6264 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
6265                     struct list_head *list_head)
6266 {
6267         struct ice_fltr_mgmt_list_entry *itr;
6268         int status = 0;
6269         u16 hw_vsi_id;
6270
6271         if (list_empty(list_head))
6272                 return status;
6273         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6274
6275         list_for_each_entry(itr, list_head, list_entry) {
6276                 struct ice_fltr_list_entry f_entry;
6277
6278                 f_entry.fltr_info = itr->fltr_info;
6279                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
6280                     itr->fltr_info.vsi_handle == vsi_handle) {
6281                         /* update the src in case it is VSI num */
6282                         if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6283                                 f_entry.fltr_info.src = hw_vsi_id;
6284                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
6285                         if (status)
6286                                 goto end;
6287                         continue;
6288                 }
6289                 if (!itr->vsi_list_info ||
6290                     !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
6291                         continue;
6292                 /* Clearing it so that the logic can add it back */
6293                 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
6294                 f_entry.fltr_info.vsi_handle = vsi_handle;
6295                 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
6296                 /* update the src in case it is VSI num */
6297                 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6298                         f_entry.fltr_info.src = hw_vsi_id;
6299                 if (recp_id == ICE_SW_LKUP_VLAN)
6300                         status = ice_add_vlan_internal(hw, &f_entry);
6301                 else
6302                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
6303                 if (status)
6304                         goto end;
6305         }
6306 end:
6307         return status;
6308 }
6309
6310 /**
6311  * ice_adv_rem_update_vsi_list
6312  * @hw: pointer to the hardware structure
6313  * @vsi_handle: VSI handle of the VSI to remove
6314  * @fm_list: filter management entry for which the VSI list management needs to
6315  *           be done
6316  */
6317 static int
6318 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
6319                             struct ice_adv_fltr_mgmt_list_entry *fm_list)
6320 {
6321         struct ice_vsi_list_map_info *vsi_list_info;
6322         enum ice_sw_lkup_type lkup_type;
6323         u16 vsi_list_id;
6324         int status;
6325
6326         if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
6327             fm_list->vsi_count == 0)
6328                 return -EINVAL;
6329
6330         /* A rule with the VSI being removed does not exist */
6331         if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
6332                 return -ENOENT;
6333
6334         lkup_type = ICE_SW_LKUP_LAST;
6335         vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
6336         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
6337                                           ice_aqc_opc_update_sw_rules,
6338                                           lkup_type);
6339         if (status)
6340                 return status;
6341
6342         fm_list->vsi_count--;
6343         clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
6344         vsi_list_info = fm_list->vsi_list_info;
6345         if (fm_list->vsi_count == 1) {
6346                 struct ice_fltr_info tmp_fltr;
6347                 u16 rem_vsi_handle;
6348
6349                 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
6350                                                 ICE_MAX_VSI);
6351                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
6352                         return -EIO;
6353
6354                 /* Make sure VSI list is empty before removing it below */
6355                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
6356                                                   vsi_list_id, true,
6357                                                   ice_aqc_opc_update_sw_rules,
6358                                                   lkup_type);
6359                 if (status)
6360                         return status;
6361
6362                 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6363                 tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
6364                 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
6365                 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
6366                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
6367                 tmp_fltr.fwd_id.hw_vsi_id =
6368                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
6369                 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
6370                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
6371                 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
6372
6373                 /* Update the previous switch rule of "MAC forward to VSI" to
6374                  * "MAC fwd to VSI list"
6375                  */
6376                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6377                 if (status) {
6378                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
6379                                   tmp_fltr.fwd_id.hw_vsi_id, status);
6380                         return status;
6381                 }
6382                 fm_list->vsi_list_info->ref_cnt--;
6383
6384                 /* Remove the VSI list since it is no longer used */
6385                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
6386                 if (status) {
6387                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
6388                                   vsi_list_id, status);
6389                         return status;
6390                 }
6391
6392                 list_del(&vsi_list_info->list_entry);
6393                 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
6394                 fm_list->vsi_list_info = NULL;
6395         }
6396
6397         return status;
6398 }
6399
6400 /**
6401  * ice_rem_adv_rule - removes existing advanced switch rule
6402  * @hw: pointer to the hardware structure
6403  * @lkups: information on the words that needs to be looked up. All words
6404  *         together makes one recipe
6405  * @lkups_cnt: num of entries in the lkups array
6406  * @rinfo: Its the pointer to the rule information for the rule
6407  *
6408  * This function can be used to remove 1 rule at a time. The lkups is
6409  * used to describe all the words that forms the "lookup" portion of the
6410  * rule. These words can span multiple protocols. Callers to this function
6411  * need to pass in a list of protocol headers with lookup information along
6412  * and mask that determines which words are valid from the given protocol
6413  * header. rinfo describes other information related to this rule such as
6414  * forwarding IDs, priority of this rule, etc.
6415  */
6416 static int
6417 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6418                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
6419 {
6420         struct ice_adv_fltr_mgmt_list_entry *list_elem;
6421         struct ice_prot_lkup_ext lkup_exts;
6422         bool remove_rule = false;
6423         struct mutex *rule_lock; /* Lock to protect filter rule list */
6424         u16 i, rid, vsi_handle;
6425         int status = 0;
6426
6427         memset(&lkup_exts, 0, sizeof(lkup_exts));
6428         for (i = 0; i < lkups_cnt; i++) {
6429                 u16 count;
6430
6431                 if (lkups[i].type >= ICE_PROTOCOL_LAST)
6432                         return -EIO;
6433
6434                 count = ice_fill_valid_words(&lkups[i], &lkup_exts);
6435                 if (!count)
6436                         return -EIO;
6437         }
6438
6439         rid = ice_find_recp(hw, &lkup_exts, rinfo);
6440         /* If did not find a recipe that match the existing criteria */
6441         if (rid == ICE_MAX_NUM_RECIPES)
6442                 return -EINVAL;
6443
6444         rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
6445         list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6446         /* the rule is already removed */
6447         if (!list_elem)
6448                 return 0;
6449         mutex_lock(rule_lock);
6450         if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
6451                 remove_rule = true;
6452         } else if (list_elem->vsi_count > 1) {
6453                 remove_rule = false;
6454                 vsi_handle = rinfo->sw_act.vsi_handle;
6455                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6456         } else {
6457                 vsi_handle = rinfo->sw_act.vsi_handle;
6458                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6459                 if (status) {
6460                         mutex_unlock(rule_lock);
6461                         return status;
6462                 }
6463                 if (list_elem->vsi_count == 0)
6464                         remove_rule = true;
6465         }
6466         mutex_unlock(rule_lock);
6467         if (remove_rule) {
6468                 struct ice_sw_rule_lkup_rx_tx *s_rule;
6469                 u16 rule_buf_sz;
6470
6471                 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule);
6472                 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6473                 if (!s_rule)
6474                         return -ENOMEM;
6475                 s_rule->act = 0;
6476                 s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id);
6477                 s_rule->hdr_len = 0;
6478                 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6479                                          rule_buf_sz, 1,
6480                                          ice_aqc_opc_remove_sw_rules, NULL);
6481                 if (!status || status == -ENOENT) {
6482                         struct ice_switch_info *sw = hw->switch_info;
6483
6484                         mutex_lock(rule_lock);
6485                         list_del(&list_elem->list_entry);
6486                         devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
6487                         devm_kfree(ice_hw_to_dev(hw), list_elem);
6488                         mutex_unlock(rule_lock);
6489                         if (list_empty(&sw->recp_list[rid].filt_rules))
6490                                 sw->recp_list[rid].adv_rule = false;
6491                 }
6492                 kfree(s_rule);
6493         }
6494         return status;
6495 }
6496
6497 /**
6498  * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
6499  * @hw: pointer to the hardware structure
6500  * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
6501  *
6502  * This function is used to remove 1 rule at a time. The removal is based on
6503  * the remove_entry parameter. This function will remove rule for a given
6504  * vsi_handle with a given rule_id which is passed as parameter in remove_entry
6505  */
6506 int
6507 ice_rem_adv_rule_by_id(struct ice_hw *hw,
6508                        struct ice_rule_query_data *remove_entry)
6509 {
6510         struct ice_adv_fltr_mgmt_list_entry *list_itr;
6511         struct list_head *list_head;
6512         struct ice_adv_rule_info rinfo;
6513         struct ice_switch_info *sw;
6514
6515         sw = hw->switch_info;
6516         if (!sw->recp_list[remove_entry->rid].recp_created)
6517                 return -EINVAL;
6518         list_head = &sw->recp_list[remove_entry->rid].filt_rules;
6519         list_for_each_entry(list_itr, list_head, list_entry) {
6520                 if (list_itr->rule_info.fltr_rule_id ==
6521                     remove_entry->rule_id) {
6522                         rinfo = list_itr->rule_info;
6523                         rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
6524                         return ice_rem_adv_rule(hw, list_itr->lkups,
6525                                                 list_itr->lkups_cnt, &rinfo);
6526                 }
6527         }
6528         /* either list is empty or unable to find rule */
6529         return -ENOENT;
6530 }
6531
6532 /**
6533  * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
6534  * @hw: pointer to the hardware structure
6535  * @vsi_handle: driver VSI handle
6536  * @list_head: list for which filters need to be replayed
6537  *
6538  * Replay the advanced rule for the given VSI.
6539  */
6540 static int
6541 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
6542                         struct list_head *list_head)
6543 {
6544         struct ice_rule_query_data added_entry = { 0 };
6545         struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
6546         int status = 0;
6547
6548         if (list_empty(list_head))
6549                 return status;
6550         list_for_each_entry(adv_fltr, list_head, list_entry) {
6551                 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
6552                 u16 lk_cnt = adv_fltr->lkups_cnt;
6553
6554                 if (vsi_handle != rinfo->sw_act.vsi_handle)
6555                         continue;
6556                 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
6557                                           &added_entry);
6558                 if (status)
6559                         break;
6560         }
6561         return status;
6562 }
6563
6564 /**
6565  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
6566  * @hw: pointer to the hardware structure
6567  * @vsi_handle: driver VSI handle
6568  *
6569  * Replays filters for requested VSI via vsi_handle.
6570  */
6571 int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
6572 {
6573         struct ice_switch_info *sw = hw->switch_info;
6574         int status;
6575         u8 i;
6576
6577         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6578                 struct list_head *head;
6579
6580                 head = &sw->recp_list[i].filt_replay_rules;
6581                 if (!sw->recp_list[i].adv_rule)
6582                         status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
6583                 else
6584                         status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
6585                 if (status)
6586                         return status;
6587         }
6588         return status;
6589 }
6590
6591 /**
6592  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
6593  * @hw: pointer to the HW struct
6594  *
6595  * Deletes the filter replay rules.
6596  */
6597 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
6598 {
6599         struct ice_switch_info *sw = hw->switch_info;
6600         u8 i;
6601
6602         if (!sw)
6603                 return;
6604
6605         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6606                 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
6607                         struct list_head *l_head;
6608
6609                         l_head = &sw->recp_list[i].filt_replay_rules;
6610                         if (!sw->recp_list[i].adv_rule)
6611                                 ice_rem_sw_rule_info(hw, l_head);
6612                         else
6613                                 ice_rem_adv_rule_info(hw, l_head);
6614                 }
6615         }
6616 }