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