Merge branches 'clk-baikal', 'clk-broadcom', 'clk-vc5' and 'clk-versaclock' into...
[platform/kernel/linux-starfive.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                 /* Avoid enabling or disabling VLAN zero twice when in double
4449                  * VLAN mode
4450                  */
4451                 if (ice_is_dvm_ena(hw) &&
4452                     list_itr->fltr_info.l_data.vlan.tpid == 0)
4453                         continue;
4454
4455                 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
4456                 if (rm_vlan_promisc)
4457                         status = ice_clear_vsi_promisc(hw, vsi_handle,
4458                                                        promisc_mask, vlan_id);
4459                 else
4460                         status = ice_set_vsi_promisc(hw, vsi_handle,
4461                                                      promisc_mask, vlan_id);
4462                 if (status && status != -EEXIST)
4463                         break;
4464         }
4465
4466 free_fltr_list:
4467         list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
4468                 list_del(&list_itr->list_entry);
4469                 devm_kfree(ice_hw_to_dev(hw), list_itr);
4470         }
4471         return status;
4472 }
4473
4474 /**
4475  * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
4476  * @hw: pointer to the hardware structure
4477  * @vsi_handle: VSI handle to remove filters from
4478  * @lkup: switch rule filter lookup type
4479  */
4480 static void
4481 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
4482                          enum ice_sw_lkup_type lkup)
4483 {
4484         struct ice_switch_info *sw = hw->switch_info;
4485         struct ice_fltr_list_entry *fm_entry;
4486         struct list_head remove_list_head;
4487         struct list_head *rule_head;
4488         struct ice_fltr_list_entry *tmp;
4489         struct mutex *rule_lock;        /* Lock to protect filter rule list */
4490         int status;
4491
4492         INIT_LIST_HEAD(&remove_list_head);
4493         rule_lock = &sw->recp_list[lkup].filt_rule_lock;
4494         rule_head = &sw->recp_list[lkup].filt_rules;
4495         mutex_lock(rule_lock);
4496         status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
4497                                           &remove_list_head);
4498         mutex_unlock(rule_lock);
4499         if (status)
4500                 goto free_fltr_list;
4501
4502         switch (lkup) {
4503         case ICE_SW_LKUP_MAC:
4504                 ice_remove_mac(hw, &remove_list_head);
4505                 break;
4506         case ICE_SW_LKUP_VLAN:
4507                 ice_remove_vlan(hw, &remove_list_head);
4508                 break;
4509         case ICE_SW_LKUP_PROMISC:
4510         case ICE_SW_LKUP_PROMISC_VLAN:
4511                 ice_remove_promisc(hw, lkup, &remove_list_head);
4512                 break;
4513         case ICE_SW_LKUP_MAC_VLAN:
4514         case ICE_SW_LKUP_ETHERTYPE:
4515         case ICE_SW_LKUP_ETHERTYPE_MAC:
4516         case ICE_SW_LKUP_DFLT:
4517         case ICE_SW_LKUP_LAST:
4518         default:
4519                 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
4520                 break;
4521         }
4522
4523 free_fltr_list:
4524         list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4525                 list_del(&fm_entry->list_entry);
4526                 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4527         }
4528 }
4529
4530 /**
4531  * ice_remove_vsi_fltr - Remove all filters for a VSI
4532  * @hw: pointer to the hardware structure
4533  * @vsi_handle: VSI handle to remove filters from
4534  */
4535 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
4536 {
4537         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
4538         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
4539         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
4540         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
4541         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
4542         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
4543         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
4544         ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
4545 }
4546
4547 /**
4548  * ice_alloc_res_cntr - allocating resource counter
4549  * @hw: pointer to the hardware structure
4550  * @type: type of resource
4551  * @alloc_shared: if set it is shared else dedicated
4552  * @num_items: number of entries requested for FD resource type
4553  * @counter_id: counter index returned by AQ call
4554  */
4555 int
4556 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4557                    u16 *counter_id)
4558 {
4559         struct ice_aqc_alloc_free_res_elem *buf;
4560         u16 buf_len;
4561         int status;
4562
4563         /* Allocate resource */
4564         buf_len = struct_size(buf, elem, 1);
4565         buf = kzalloc(buf_len, GFP_KERNEL);
4566         if (!buf)
4567                 return -ENOMEM;
4568
4569         buf->num_elems = cpu_to_le16(num_items);
4570         buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
4571                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
4572
4573         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
4574                                        ice_aqc_opc_alloc_res, NULL);
4575         if (status)
4576                 goto exit;
4577
4578         *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
4579
4580 exit:
4581         kfree(buf);
4582         return status;
4583 }
4584
4585 /**
4586  * ice_free_res_cntr - free resource counter
4587  * @hw: pointer to the hardware structure
4588  * @type: type of resource
4589  * @alloc_shared: if set it is shared else dedicated
4590  * @num_items: number of entries to be freed for FD resource type
4591  * @counter_id: counter ID resource which needs to be freed
4592  */
4593 int
4594 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4595                   u16 counter_id)
4596 {
4597         struct ice_aqc_alloc_free_res_elem *buf;
4598         u16 buf_len;
4599         int status;
4600
4601         /* Free resource */
4602         buf_len = struct_size(buf, elem, 1);
4603         buf = kzalloc(buf_len, GFP_KERNEL);
4604         if (!buf)
4605                 return -ENOMEM;
4606
4607         buf->num_elems = cpu_to_le16(num_items);
4608         buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
4609                                       ICE_AQC_RES_TYPE_M) | alloc_shared);
4610         buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
4611
4612         status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
4613                                        ice_aqc_opc_free_res, NULL);
4614         if (status)
4615                 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
4616
4617         kfree(buf);
4618         return status;
4619 }
4620
4621 /* This is mapping table entry that maps every word within a given protocol
4622  * structure to the real byte offset as per the specification of that
4623  * protocol header.
4624  * for example dst address is 3 words in ethertype header and corresponding
4625  * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
4626  * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
4627  * matching entry describing its field. This needs to be updated if new
4628  * structure is added to that union.
4629  */
4630 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
4631         { ICE_MAC_OFOS,         { 0, 2, 4, 6, 8, 10, 12 } },
4632         { ICE_MAC_IL,           { 0, 2, 4, 6, 8, 10, 12 } },
4633         { ICE_ETYPE_OL,         { 0 } },
4634         { ICE_ETYPE_IL,         { 0 } },
4635         { ICE_VLAN_OFOS,        { 2, 0 } },
4636         { ICE_IPV4_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
4637         { ICE_IPV4_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
4638         { ICE_IPV6_OFOS,        { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
4639                                  26, 28, 30, 32, 34, 36, 38 } },
4640         { ICE_IPV6_IL,          { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
4641                                  26, 28, 30, 32, 34, 36, 38 } },
4642         { ICE_TCP_IL,           { 0, 2 } },
4643         { ICE_UDP_OF,           { 0, 2 } },
4644         { ICE_UDP_ILOS,         { 0, 2 } },
4645         { ICE_VXLAN,            { 8, 10, 12, 14 } },
4646         { ICE_GENEVE,           { 8, 10, 12, 14 } },
4647         { ICE_NVGRE,            { 0, 2, 4, 6 } },
4648         { ICE_GTP,              { 8, 10, 12, 14, 16, 18, 20, 22 } },
4649         { ICE_GTP_NO_PAY,       { 8, 10, 12, 14 } },
4650         { ICE_PPPOE,            { 0, 2, 4, 6 } },
4651         { ICE_VLAN_EX,          { 2, 0 } },
4652         { ICE_VLAN_IN,          { 2, 0 } },
4653 };
4654
4655 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
4656         { ICE_MAC_OFOS,         ICE_MAC_OFOS_HW },
4657         { ICE_MAC_IL,           ICE_MAC_IL_HW },
4658         { ICE_ETYPE_OL,         ICE_ETYPE_OL_HW },
4659         { ICE_ETYPE_IL,         ICE_ETYPE_IL_HW },
4660         { ICE_VLAN_OFOS,        ICE_VLAN_OL_HW },
4661         { ICE_IPV4_OFOS,        ICE_IPV4_OFOS_HW },
4662         { ICE_IPV4_IL,          ICE_IPV4_IL_HW },
4663         { ICE_IPV6_OFOS,        ICE_IPV6_OFOS_HW },
4664         { ICE_IPV6_IL,          ICE_IPV6_IL_HW },
4665         { ICE_TCP_IL,           ICE_TCP_IL_HW },
4666         { ICE_UDP_OF,           ICE_UDP_OF_HW },
4667         { ICE_UDP_ILOS,         ICE_UDP_ILOS_HW },
4668         { ICE_VXLAN,            ICE_UDP_OF_HW },
4669         { ICE_GENEVE,           ICE_UDP_OF_HW },
4670         { ICE_NVGRE,            ICE_GRE_OF_HW },
4671         { ICE_GTP,              ICE_UDP_OF_HW },
4672         { ICE_GTP_NO_PAY,       ICE_UDP_ILOS_HW },
4673         { ICE_PPPOE,            ICE_PPPOE_HW },
4674         { ICE_VLAN_EX,          ICE_VLAN_OF_HW },
4675         { ICE_VLAN_IN,          ICE_VLAN_OL_HW },
4676 };
4677
4678 /**
4679  * ice_find_recp - find a recipe
4680  * @hw: pointer to the hardware structure
4681  * @lkup_exts: extension sequence to match
4682  * @tun_type: type of recipe tunnel
4683  *
4684  * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
4685  */
4686 static u16
4687 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
4688               enum ice_sw_tunnel_type tun_type)
4689 {
4690         bool refresh_required = true;
4691         struct ice_sw_recipe *recp;
4692         u8 i;
4693
4694         /* Walk through existing recipes to find a match */
4695         recp = hw->switch_info->recp_list;
4696         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
4697                 /* If recipe was not created for this ID, in SW bookkeeping,
4698                  * check if FW has an entry for this recipe. If the FW has an
4699                  * entry update it in our SW bookkeeping and continue with the
4700                  * matching.
4701                  */
4702                 if (!recp[i].recp_created)
4703                         if (ice_get_recp_frm_fw(hw,
4704                                                 hw->switch_info->recp_list, i,
4705                                                 &refresh_required))
4706                                 continue;
4707
4708                 /* Skip inverse action recipes */
4709                 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
4710                     ICE_AQ_RECIPE_ACT_INV_ACT)
4711                         continue;
4712
4713                 /* if number of words we are looking for match */
4714                 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
4715                         struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
4716                         struct ice_fv_word *be = lkup_exts->fv_words;
4717                         u16 *cr = recp[i].lkup_exts.field_mask;
4718                         u16 *de = lkup_exts->field_mask;
4719                         bool found = true;
4720                         u8 pe, qr;
4721
4722                         /* ar, cr, and qr are related to the recipe words, while
4723                          * be, de, and pe are related to the lookup words
4724                          */
4725                         for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
4726                                 for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
4727                                      qr++) {
4728                                         if (ar[qr].off == be[pe].off &&
4729                                             ar[qr].prot_id == be[pe].prot_id &&
4730                                             cr[qr] == de[pe])
4731                                                 /* Found the "pe"th word in the
4732                                                  * given recipe
4733                                                  */
4734                                                 break;
4735                                 }
4736                                 /* After walking through all the words in the
4737                                  * "i"th recipe if "p"th word was not found then
4738                                  * this recipe is not what we are looking for.
4739                                  * So break out from this loop and try the next
4740                                  * recipe
4741                                  */
4742                                 if (qr >= recp[i].lkup_exts.n_val_words) {
4743                                         found = false;
4744                                         break;
4745                                 }
4746                         }
4747                         /* If for "i"th recipe the found was never set to false
4748                          * then it means we found our match
4749                          * Also tun type of recipe needs to be checked
4750                          */
4751                         if (found && recp[i].tun_type == tun_type)
4752                                 return i; /* Return the recipe ID */
4753                 }
4754         }
4755         return ICE_MAX_NUM_RECIPES;
4756 }
4757
4758 /**
4759  * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
4760  *
4761  * As protocol id for outer vlan is different in dvm and svm, if dvm is
4762  * supported protocol array record for outer vlan has to be modified to
4763  * reflect the value proper for DVM.
4764  */
4765 void ice_change_proto_id_to_dvm(void)
4766 {
4767         u8 i;
4768
4769         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4770                 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
4771                     ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
4772                         ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
4773 }
4774
4775 /**
4776  * ice_prot_type_to_id - get protocol ID from protocol type
4777  * @type: protocol type
4778  * @id: pointer to variable that will receive the ID
4779  *
4780  * Returns true if found, false otherwise
4781  */
4782 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
4783 {
4784         u8 i;
4785
4786         for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4787                 if (ice_prot_id_tbl[i].type == type) {
4788                         *id = ice_prot_id_tbl[i].protocol_id;
4789                         return true;
4790                 }
4791         return false;
4792 }
4793
4794 /**
4795  * ice_fill_valid_words - count valid words
4796  * @rule: advanced rule with lookup information
4797  * @lkup_exts: byte offset extractions of the words that are valid
4798  *
4799  * calculate valid words in a lookup rule using mask value
4800  */
4801 static u8
4802 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
4803                      struct ice_prot_lkup_ext *lkup_exts)
4804 {
4805         u8 j, word, prot_id, ret_val;
4806
4807         if (!ice_prot_type_to_id(rule->type, &prot_id))
4808                 return 0;
4809
4810         word = lkup_exts->n_val_words;
4811
4812         for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
4813                 if (((u16 *)&rule->m_u)[j] &&
4814                     rule->type < ARRAY_SIZE(ice_prot_ext)) {
4815                         /* No more space to accommodate */
4816                         if (word >= ICE_MAX_CHAIN_WORDS)
4817                                 return 0;
4818                         lkup_exts->fv_words[word].off =
4819                                 ice_prot_ext[rule->type].offs[j];
4820                         lkup_exts->fv_words[word].prot_id =
4821                                 ice_prot_id_tbl[rule->type].protocol_id;
4822                         lkup_exts->field_mask[word] =
4823                                 be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
4824                         word++;
4825                 }
4826
4827         ret_val = word - lkup_exts->n_val_words;
4828         lkup_exts->n_val_words = word;
4829
4830         return ret_val;
4831 }
4832
4833 /**
4834  * ice_create_first_fit_recp_def - Create a recipe grouping
4835  * @hw: pointer to the hardware structure
4836  * @lkup_exts: an array of protocol header extractions
4837  * @rg_list: pointer to a list that stores new recipe groups
4838  * @recp_cnt: pointer to a variable that stores returned number of recipe groups
4839  *
4840  * Using first fit algorithm, take all the words that are still not done
4841  * and start grouping them in 4-word groups. Each group makes up one
4842  * recipe.
4843  */
4844 static int
4845 ice_create_first_fit_recp_def(struct ice_hw *hw,
4846                               struct ice_prot_lkup_ext *lkup_exts,
4847                               struct list_head *rg_list,
4848                               u8 *recp_cnt)
4849 {
4850         struct ice_pref_recipe_group *grp = NULL;
4851         u8 j;
4852
4853         *recp_cnt = 0;
4854
4855         /* Walk through every word in the rule to check if it is not done. If so
4856          * then this word needs to be part of a new recipe.
4857          */
4858         for (j = 0; j < lkup_exts->n_val_words; j++)
4859                 if (!test_bit(j, lkup_exts->done)) {
4860                         if (!grp ||
4861                             grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
4862                                 struct ice_recp_grp_entry *entry;
4863
4864                                 entry = devm_kzalloc(ice_hw_to_dev(hw),
4865                                                      sizeof(*entry),
4866                                                      GFP_KERNEL);
4867                                 if (!entry)
4868                                         return -ENOMEM;
4869                                 list_add(&entry->l_entry, rg_list);
4870                                 grp = &entry->r_group;
4871                                 (*recp_cnt)++;
4872                         }
4873
4874                         grp->pairs[grp->n_val_pairs].prot_id =
4875                                 lkup_exts->fv_words[j].prot_id;
4876                         grp->pairs[grp->n_val_pairs].off =
4877                                 lkup_exts->fv_words[j].off;
4878                         grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
4879                         grp->n_val_pairs++;
4880                 }
4881
4882         return 0;
4883 }
4884
4885 /**
4886  * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
4887  * @hw: pointer to the hardware structure
4888  * @fv_list: field vector with the extraction sequence information
4889  * @rg_list: recipe groupings with protocol-offset pairs
4890  *
4891  * Helper function to fill in the field vector indices for protocol-offset
4892  * pairs. These indexes are then ultimately programmed into a recipe.
4893  */
4894 static int
4895 ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list,
4896                        struct list_head *rg_list)
4897 {
4898         struct ice_sw_fv_list_entry *fv;
4899         struct ice_recp_grp_entry *rg;
4900         struct ice_fv_word *fv_ext;
4901
4902         if (list_empty(fv_list))
4903                 return 0;
4904
4905         fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry,
4906                               list_entry);
4907         fv_ext = fv->fv_ptr->ew;
4908
4909         list_for_each_entry(rg, rg_list, l_entry) {
4910                 u8 i;
4911
4912                 for (i = 0; i < rg->r_group.n_val_pairs; i++) {
4913                         struct ice_fv_word *pr;
4914                         bool found = false;
4915                         u16 mask;
4916                         u8 j;
4917
4918                         pr = &rg->r_group.pairs[i];
4919                         mask = rg->r_group.mask[i];
4920
4921                         for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
4922                                 if (fv_ext[j].prot_id == pr->prot_id &&
4923                                     fv_ext[j].off == pr->off) {
4924                                         found = true;
4925
4926                                         /* Store index of field vector */
4927                                         rg->fv_idx[i] = j;
4928                                         rg->fv_mask[i] = mask;
4929                                         break;
4930                                 }
4931
4932                         /* Protocol/offset could not be found, caller gave an
4933                          * invalid pair
4934                          */
4935                         if (!found)
4936                                 return -EINVAL;
4937                 }
4938         }
4939
4940         return 0;
4941 }
4942
4943 /**
4944  * ice_find_free_recp_res_idx - find free result indexes for recipe
4945  * @hw: pointer to hardware structure
4946  * @profiles: bitmap of profiles that will be associated with the new recipe
4947  * @free_idx: pointer to variable to receive the free index bitmap
4948  *
4949  * The algorithm used here is:
4950  *      1. When creating a new recipe, create a set P which contains all
4951  *         Profiles that will be associated with our new recipe
4952  *
4953  *      2. For each Profile p in set P:
4954  *          a. Add all recipes associated with Profile p into set R
4955  *          b. Optional : PossibleIndexes &= profile[p].possibleIndexes
4956  *              [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
4957  *              i. Or just assume they all have the same possible indexes:
4958  *                      44, 45, 46, 47
4959  *                      i.e., PossibleIndexes = 0x0000F00000000000
4960  *
4961  *      3. For each Recipe r in set R:
4962  *          a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
4963  *          b. FreeIndexes = UsedIndexes ^ PossibleIndexes
4964  *
4965  *      FreeIndexes will contain the bits indicating the indexes free for use,
4966  *      then the code needs to update the recipe[r].used_result_idx_bits to
4967  *      indicate which indexes were selected for use by this recipe.
4968  */
4969 static u16
4970 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
4971                            unsigned long *free_idx)
4972 {
4973         DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
4974         DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
4975         DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
4976         u16 bit;
4977
4978         bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
4979         bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
4980
4981         bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
4982
4983         /* For each profile we are going to associate the recipe with, add the
4984          * recipes that are associated with that profile. This will give us
4985          * the set of recipes that our recipe may collide with. Also, determine
4986          * what possible result indexes are usable given this set of profiles.
4987          */
4988         for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
4989                 bitmap_or(recipes, recipes, profile_to_recipe[bit],
4990                           ICE_MAX_NUM_RECIPES);
4991                 bitmap_and(possible_idx, possible_idx,
4992                            hw->switch_info->prof_res_bm[bit],
4993                            ICE_MAX_FV_WORDS);
4994         }
4995
4996         /* For each recipe that our new recipe may collide with, determine
4997          * which indexes have been used.
4998          */
4999         for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
5000                 bitmap_or(used_idx, used_idx,
5001                           hw->switch_info->recp_list[bit].res_idxs,
5002                           ICE_MAX_FV_WORDS);
5003
5004         bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
5005
5006         /* return number of free indexes */
5007         return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
5008 }
5009
5010 /**
5011  * ice_add_sw_recipe - function to call AQ calls to create switch recipe
5012  * @hw: pointer to hardware structure
5013  * @rm: recipe management list entry
5014  * @profiles: bitmap of profiles that will be associated.
5015  */
5016 static int
5017 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
5018                   unsigned long *profiles)
5019 {
5020         DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
5021         struct ice_aqc_recipe_data_elem *tmp;
5022         struct ice_aqc_recipe_data_elem *buf;
5023         struct ice_recp_grp_entry *entry;
5024         u16 free_res_idx;
5025         u16 recipe_count;
5026         u8 chain_idx;
5027         u8 recps = 0;
5028         int status;
5029
5030         /* When more than one recipe are required, another recipe is needed to
5031          * chain them together. Matching a tunnel metadata ID takes up one of
5032          * the match fields in the chaining recipe reducing the number of
5033          * chained recipes by one.
5034          */
5035          /* check number of free result indices */
5036         bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
5037         free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
5038
5039         ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
5040                   free_res_idx, rm->n_grp_count);
5041
5042         if (rm->n_grp_count > 1) {
5043                 if (rm->n_grp_count > free_res_idx)
5044                         return -ENOSPC;
5045
5046                 rm->n_grp_count++;
5047         }
5048
5049         if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
5050                 return -ENOSPC;
5051
5052         tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
5053         if (!tmp)
5054                 return -ENOMEM;
5055
5056         buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf),
5057                            GFP_KERNEL);
5058         if (!buf) {
5059                 status = -ENOMEM;
5060                 goto err_mem;
5061         }
5062
5063         bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
5064         recipe_count = ICE_MAX_NUM_RECIPES;
5065         status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
5066                                    NULL);
5067         if (status || recipe_count == 0)
5068                 goto err_unroll;
5069
5070         /* Allocate the recipe resources, and configure them according to the
5071          * match fields from protocol headers and extracted field vectors.
5072          */
5073         chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
5074         list_for_each_entry(entry, &rm->rg_list, l_entry) {
5075                 u8 i;
5076
5077                 status = ice_alloc_recipe(hw, &entry->rid);
5078                 if (status)
5079                         goto err_unroll;
5080
5081                 /* Clear the result index of the located recipe, as this will be
5082                  * updated, if needed, later in the recipe creation process.
5083                  */
5084                 tmp[0].content.result_indx = 0;
5085
5086                 buf[recps] = tmp[0];
5087                 buf[recps].recipe_indx = (u8)entry->rid;
5088                 /* if the recipe is a non-root recipe RID should be programmed
5089                  * as 0 for the rules to be applied correctly.
5090                  */
5091                 buf[recps].content.rid = 0;
5092                 memset(&buf[recps].content.lkup_indx, 0,
5093                        sizeof(buf[recps].content.lkup_indx));
5094
5095                 /* All recipes use look-up index 0 to match switch ID. */
5096                 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
5097                 buf[recps].content.mask[0] =
5098                         cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
5099                 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
5100                  * to be 0
5101                  */
5102                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5103                         buf[recps].content.lkup_indx[i] = 0x80;
5104                         buf[recps].content.mask[i] = 0;
5105                 }
5106
5107                 for (i = 0; i < entry->r_group.n_val_pairs; i++) {
5108                         buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
5109                         buf[recps].content.mask[i + 1] =
5110                                 cpu_to_le16(entry->fv_mask[i]);
5111                 }
5112
5113                 if (rm->n_grp_count > 1) {
5114                         /* Checks to see if there really is a valid result index
5115                          * that can be used.
5116                          */
5117                         if (chain_idx >= ICE_MAX_FV_WORDS) {
5118                                 ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
5119                                 status = -ENOSPC;
5120                                 goto err_unroll;
5121                         }
5122
5123                         entry->chain_idx = chain_idx;
5124                         buf[recps].content.result_indx =
5125                                 ICE_AQ_RECIPE_RESULT_EN |
5126                                 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
5127                                  ICE_AQ_RECIPE_RESULT_DATA_M);
5128                         clear_bit(chain_idx, result_idx_bm);
5129                         chain_idx = find_first_bit(result_idx_bm,
5130                                                    ICE_MAX_FV_WORDS);
5131                 }
5132
5133                 /* fill recipe dependencies */
5134                 bitmap_zero((unsigned long *)buf[recps].recipe_bitmap,
5135                             ICE_MAX_NUM_RECIPES);
5136                 set_bit(buf[recps].recipe_indx,
5137                         (unsigned long *)buf[recps].recipe_bitmap);
5138                 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
5139                 recps++;
5140         }
5141
5142         if (rm->n_grp_count == 1) {
5143                 rm->root_rid = buf[0].recipe_indx;
5144                 set_bit(buf[0].recipe_indx, rm->r_bitmap);
5145                 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
5146                 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
5147                         memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
5148                                sizeof(buf[0].recipe_bitmap));
5149                 } else {
5150                         status = -EINVAL;
5151                         goto err_unroll;
5152                 }
5153                 /* Applicable only for ROOT_RECIPE, set the fwd_priority for
5154                  * the recipe which is getting created if specified
5155                  * by user. Usually any advanced switch filter, which results
5156                  * into new extraction sequence, ended up creating a new recipe
5157                  * of type ROOT and usually recipes are associated with profiles
5158                  * Switch rule referreing newly created recipe, needs to have
5159                  * either/or 'fwd' or 'join' priority, otherwise switch rule
5160                  * evaluation will not happen correctly. In other words, if
5161                  * switch rule to be evaluated on priority basis, then recipe
5162                  * needs to have priority, otherwise it will be evaluated last.
5163                  */
5164                 buf[0].content.act_ctrl_fwd_priority = rm->priority;
5165         } else {
5166                 struct ice_recp_grp_entry *last_chain_entry;
5167                 u16 rid, i;
5168
5169                 /* Allocate the last recipe that will chain the outcomes of the
5170                  * other recipes together
5171                  */
5172                 status = ice_alloc_recipe(hw, &rid);
5173                 if (status)
5174                         goto err_unroll;
5175
5176                 buf[recps].recipe_indx = (u8)rid;
5177                 buf[recps].content.rid = (u8)rid;
5178                 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
5179                 /* the new entry created should also be part of rg_list to
5180                  * make sure we have complete recipe
5181                  */
5182                 last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw),
5183                                                 sizeof(*last_chain_entry),
5184                                                 GFP_KERNEL);
5185                 if (!last_chain_entry) {
5186                         status = -ENOMEM;
5187                         goto err_unroll;
5188                 }
5189                 last_chain_entry->rid = rid;
5190                 memset(&buf[recps].content.lkup_indx, 0,
5191                        sizeof(buf[recps].content.lkup_indx));
5192                 /* All recipes use look-up index 0 to match switch ID. */
5193                 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
5194                 buf[recps].content.mask[0] =
5195                         cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
5196                 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5197                         buf[recps].content.lkup_indx[i] =
5198                                 ICE_AQ_RECIPE_LKUP_IGNORE;
5199                         buf[recps].content.mask[i] = 0;
5200                 }
5201
5202                 i = 1;
5203                 /* update r_bitmap with the recp that is used for chaining */
5204                 set_bit(rid, rm->r_bitmap);
5205                 /* this is the recipe that chains all the other recipes so it
5206                  * should not have a chaining ID to indicate the same
5207                  */
5208                 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
5209                 list_for_each_entry(entry, &rm->rg_list, l_entry) {
5210                         last_chain_entry->fv_idx[i] = entry->chain_idx;
5211                         buf[recps].content.lkup_indx[i] = entry->chain_idx;
5212                         buf[recps].content.mask[i++] = cpu_to_le16(0xFFFF);
5213                         set_bit(entry->rid, rm->r_bitmap);
5214                 }
5215                 list_add(&last_chain_entry->l_entry, &rm->rg_list);
5216                 if (sizeof(buf[recps].recipe_bitmap) >=
5217                     sizeof(rm->r_bitmap)) {
5218                         memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
5219                                sizeof(buf[recps].recipe_bitmap));
5220                 } else {
5221                         status = -EINVAL;
5222                         goto err_unroll;
5223                 }
5224                 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
5225
5226                 recps++;
5227                 rm->root_rid = (u8)rid;
5228         }
5229         status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5230         if (status)
5231                 goto err_unroll;
5232
5233         status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
5234         ice_release_change_lock(hw);
5235         if (status)
5236                 goto err_unroll;
5237
5238         /* Every recipe that just got created add it to the recipe
5239          * book keeping list
5240          */
5241         list_for_each_entry(entry, &rm->rg_list, l_entry) {
5242                 struct ice_switch_info *sw = hw->switch_info;
5243                 bool is_root, idx_found = false;
5244                 struct ice_sw_recipe *recp;
5245                 u16 idx, buf_idx = 0;
5246
5247                 /* find buffer index for copying some data */
5248                 for (idx = 0; idx < rm->n_grp_count; idx++)
5249                         if (buf[idx].recipe_indx == entry->rid) {
5250                                 buf_idx = idx;
5251                                 idx_found = true;
5252                         }
5253
5254                 if (!idx_found) {
5255                         status = -EIO;
5256                         goto err_unroll;
5257                 }
5258
5259                 recp = &sw->recp_list[entry->rid];
5260                 is_root = (rm->root_rid == entry->rid);
5261                 recp->is_root = is_root;
5262
5263                 recp->root_rid = entry->rid;
5264                 recp->big_recp = (is_root && rm->n_grp_count > 1);
5265
5266                 memcpy(&recp->ext_words, entry->r_group.pairs,
5267                        entry->r_group.n_val_pairs * sizeof(struct ice_fv_word));
5268
5269                 memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
5270                        sizeof(recp->r_bitmap));
5271
5272                 /* Copy non-result fv index values and masks to recipe. This
5273                  * call will also update the result recipe bitmask.
5274                  */
5275                 ice_collect_result_idx(&buf[buf_idx], recp);
5276
5277                 /* for non-root recipes, also copy to the root, this allows
5278                  * easier matching of a complete chained recipe
5279                  */
5280                 if (!is_root)
5281                         ice_collect_result_idx(&buf[buf_idx],
5282                                                &sw->recp_list[rm->root_rid]);
5283
5284                 recp->n_ext_words = entry->r_group.n_val_pairs;
5285                 recp->chain_idx = entry->chain_idx;
5286                 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
5287                 recp->n_grp_count = rm->n_grp_count;
5288                 recp->tun_type = rm->tun_type;
5289                 recp->recp_created = true;
5290         }
5291         rm->root_buf = buf;
5292         kfree(tmp);
5293         return status;
5294
5295 err_unroll:
5296 err_mem:
5297         kfree(tmp);
5298         devm_kfree(ice_hw_to_dev(hw), buf);
5299         return status;
5300 }
5301
5302 /**
5303  * ice_create_recipe_group - creates recipe group
5304  * @hw: pointer to hardware structure
5305  * @rm: recipe management list entry
5306  * @lkup_exts: lookup elements
5307  */
5308 static int
5309 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
5310                         struct ice_prot_lkup_ext *lkup_exts)
5311 {
5312         u8 recp_count = 0;
5313         int status;
5314
5315         rm->n_grp_count = 0;
5316
5317         /* Create recipes for words that are marked not done by packing them
5318          * as best fit.
5319          */
5320         status = ice_create_first_fit_recp_def(hw, lkup_exts,
5321                                                &rm->rg_list, &recp_count);
5322         if (!status) {
5323                 rm->n_grp_count += recp_count;
5324                 rm->n_ext_words = lkup_exts->n_val_words;
5325                 memcpy(&rm->ext_words, lkup_exts->fv_words,
5326                        sizeof(rm->ext_words));
5327                 memcpy(rm->word_masks, lkup_exts->field_mask,
5328                        sizeof(rm->word_masks));
5329         }
5330
5331         return status;
5332 }
5333
5334 /**
5335  * ice_tun_type_match_word - determine if tun type needs a match mask
5336  * @tun_type: tunnel type
5337  * @mask: mask to be used for the tunnel
5338  */
5339 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
5340 {
5341         switch (tun_type) {
5342         case ICE_SW_TUN_GENEVE:
5343         case ICE_SW_TUN_VXLAN:
5344         case ICE_SW_TUN_NVGRE:
5345         case ICE_SW_TUN_GTPU:
5346         case ICE_SW_TUN_GTPC:
5347                 *mask = ICE_TUN_FLAG_MASK;
5348                 return true;
5349
5350         default:
5351                 *mask = 0;
5352                 return false;
5353         }
5354 }
5355
5356 /**
5357  * ice_add_special_words - Add words that are not protocols, such as metadata
5358  * @rinfo: other information regarding the rule e.g. priority and action info
5359  * @lkup_exts: lookup word structure
5360  * @dvm_ena: is double VLAN mode enabled
5361  */
5362 static int
5363 ice_add_special_words(struct ice_adv_rule_info *rinfo,
5364                       struct ice_prot_lkup_ext *lkup_exts, bool dvm_ena)
5365 {
5366         u16 mask;
5367
5368         /* If this is a tunneled packet, then add recipe index to match the
5369          * tunnel bit in the packet metadata flags.
5370          */
5371         if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
5372                 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
5373                         u8 word = lkup_exts->n_val_words++;
5374
5375                         lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
5376                         lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
5377                         lkup_exts->field_mask[word] = mask;
5378                 } else {
5379                         return -ENOSPC;
5380                 }
5381         }
5382
5383         if (rinfo->vlan_type != 0 && dvm_ena) {
5384                 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
5385                         u8 word = lkup_exts->n_val_words++;
5386
5387                         lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
5388                         lkup_exts->fv_words[word].off = ICE_VLAN_FLAG_MDID_OFF;
5389                         lkup_exts->field_mask[word] =
5390                                         ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK;
5391                 } else {
5392                         return -ENOSPC;
5393                 }
5394         }
5395
5396         return 0;
5397 }
5398
5399 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
5400  * @hw: pointer to hardware structure
5401  * @rinfo: other information regarding the rule e.g. priority and action info
5402  * @bm: pointer to memory for returning the bitmap of field vectors
5403  */
5404 static void
5405 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
5406                          unsigned long *bm)
5407 {
5408         enum ice_prof_type prof_type;
5409
5410         bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
5411
5412         switch (rinfo->tun_type) {
5413         case ICE_NON_TUN:
5414                 prof_type = ICE_PROF_NON_TUN;
5415                 break;
5416         case ICE_ALL_TUNNELS:
5417                 prof_type = ICE_PROF_TUN_ALL;
5418                 break;
5419         case ICE_SW_TUN_GENEVE:
5420         case ICE_SW_TUN_VXLAN:
5421                 prof_type = ICE_PROF_TUN_UDP;
5422                 break;
5423         case ICE_SW_TUN_NVGRE:
5424                 prof_type = ICE_PROF_TUN_GRE;
5425                 break;
5426         case ICE_SW_TUN_GTPU:
5427                 prof_type = ICE_PROF_TUN_GTPU;
5428                 break;
5429         case ICE_SW_TUN_GTPC:
5430                 prof_type = ICE_PROF_TUN_GTPC;
5431                 break;
5432         case ICE_SW_TUN_AND_NON_TUN:
5433         default:
5434                 prof_type = ICE_PROF_ALL;
5435                 break;
5436         }
5437
5438         ice_get_sw_fv_bitmap(hw, prof_type, bm);
5439 }
5440
5441 /**
5442  * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
5443  * @hw: pointer to hardware structure
5444  * @lkups: lookup elements or match criteria for the advanced recipe, one
5445  *  structure per protocol header
5446  * @lkups_cnt: number of protocols
5447  * @rinfo: other information regarding the rule e.g. priority and action info
5448  * @rid: return the recipe ID of the recipe created
5449  */
5450 static int
5451 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5452                    u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
5453 {
5454         DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
5455         DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
5456         struct ice_prot_lkup_ext *lkup_exts;
5457         struct ice_recp_grp_entry *r_entry;
5458         struct ice_sw_fv_list_entry *fvit;
5459         struct ice_recp_grp_entry *r_tmp;
5460         struct ice_sw_fv_list_entry *tmp;
5461         struct ice_sw_recipe *rm;
5462         int status = 0;
5463         u8 i;
5464
5465         if (!lkups_cnt)
5466                 return -EINVAL;
5467
5468         lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
5469         if (!lkup_exts)
5470                 return -ENOMEM;
5471
5472         /* Determine the number of words to be matched and if it exceeds a
5473          * recipe's restrictions
5474          */
5475         for (i = 0; i < lkups_cnt; i++) {
5476                 u16 count;
5477
5478                 if (lkups[i].type >= ICE_PROTOCOL_LAST) {
5479                         status = -EIO;
5480                         goto err_free_lkup_exts;
5481                 }
5482
5483                 count = ice_fill_valid_words(&lkups[i], lkup_exts);
5484                 if (!count) {
5485                         status = -EIO;
5486                         goto err_free_lkup_exts;
5487                 }
5488         }
5489
5490         rm = kzalloc(sizeof(*rm), GFP_KERNEL);
5491         if (!rm) {
5492                 status = -ENOMEM;
5493                 goto err_free_lkup_exts;
5494         }
5495
5496         /* Get field vectors that contain fields extracted from all the protocol
5497          * headers being programmed.
5498          */
5499         INIT_LIST_HEAD(&rm->fv_list);
5500         INIT_LIST_HEAD(&rm->rg_list);
5501
5502         /* Get bitmap of field vectors (profiles) that are compatible with the
5503          * rule request; only these will be searched in the subsequent call to
5504          * ice_get_sw_fv_list.
5505          */
5506         ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
5507
5508         status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
5509         if (status)
5510                 goto err_unroll;
5511
5512         /* Create any special protocol/offset pairs, such as looking at tunnel
5513          * bits by extracting metadata
5514          */
5515         status = ice_add_special_words(rinfo, lkup_exts, ice_is_dvm_ena(hw));
5516         if (status)
5517                 goto err_free_lkup_exts;
5518
5519         /* Group match words into recipes using preferred recipe grouping
5520          * criteria.
5521          */
5522         status = ice_create_recipe_group(hw, rm, lkup_exts);
5523         if (status)
5524                 goto err_unroll;
5525
5526         /* set the recipe priority if specified */
5527         rm->priority = (u8)rinfo->priority;
5528
5529         /* Find offsets from the field vector. Pick the first one for all the
5530          * recipes.
5531          */
5532         status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
5533         if (status)
5534                 goto err_unroll;
5535
5536         /* get bitmap of all profiles the recipe will be associated with */
5537         bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
5538         list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5539                 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
5540                 set_bit((u16)fvit->profile_id, profiles);
5541         }
5542
5543         /* Look for a recipe which matches our requested fv / mask list */
5544         *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type);
5545         if (*rid < ICE_MAX_NUM_RECIPES)
5546                 /* Success if found a recipe that match the existing criteria */
5547                 goto err_unroll;
5548
5549         rm->tun_type = rinfo->tun_type;
5550         /* Recipe we need does not exist, add a recipe */
5551         status = ice_add_sw_recipe(hw, rm, profiles);
5552         if (status)
5553                 goto err_unroll;
5554
5555         /* Associate all the recipes created with all the profiles in the
5556          * common field vector.
5557          */
5558         list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5559                 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
5560                 u16 j;
5561
5562                 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
5563                                                       (u8 *)r_bitmap, NULL);
5564                 if (status)
5565                         goto err_unroll;
5566
5567                 bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
5568                           ICE_MAX_NUM_RECIPES);
5569                 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5570                 if (status)
5571                         goto err_unroll;
5572
5573                 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
5574                                                       (u8 *)r_bitmap,
5575                                                       NULL);
5576                 ice_release_change_lock(hw);
5577
5578                 if (status)
5579                         goto err_unroll;
5580
5581                 /* Update profile to recipe bitmap array */
5582                 bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
5583                             ICE_MAX_NUM_RECIPES);
5584
5585                 /* Update recipe to profile bitmap array */
5586                 for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
5587                         set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
5588         }
5589
5590         *rid = rm->root_rid;
5591         memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
5592                sizeof(*lkup_exts));
5593 err_unroll:
5594         list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) {
5595                 list_del(&r_entry->l_entry);
5596                 devm_kfree(ice_hw_to_dev(hw), r_entry);
5597         }
5598
5599         list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
5600                 list_del(&fvit->list_entry);
5601                 devm_kfree(ice_hw_to_dev(hw), fvit);
5602         }
5603
5604         if (rm->root_buf)
5605                 devm_kfree(ice_hw_to_dev(hw), rm->root_buf);
5606
5607         kfree(rm);
5608
5609 err_free_lkup_exts:
5610         kfree(lkup_exts);
5611
5612         return status;
5613 }
5614
5615 /**
5616  * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt
5617  *
5618  * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added
5619  * @num_vlan: number of VLAN tags
5620  */
5621 static struct ice_dummy_pkt_profile *
5622 ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt,
5623                           u32 num_vlan)
5624 {
5625         struct ice_dummy_pkt_profile *profile;
5626         struct ice_dummy_pkt_offsets *offsets;
5627         u32 buf_len, off, etype_off, i;
5628         u8 *pkt;
5629
5630         if (num_vlan < 1 || num_vlan > 2)
5631                 return ERR_PTR(-EINVAL);
5632
5633         off = num_vlan * VLAN_HLEN;
5634
5635         buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) +
5636                   dummy_pkt->offsets_len;
5637         offsets = kzalloc(buf_len, GFP_KERNEL);
5638         if (!offsets)
5639                 return ERR_PTR(-ENOMEM);
5640
5641         offsets[0] = dummy_pkt->offsets[0];
5642         if (num_vlan == 2) {
5643                 offsets[1] = ice_dummy_qinq_packet_offsets[0];
5644                 offsets[2] = ice_dummy_qinq_packet_offsets[1];
5645         } else if (num_vlan == 1) {
5646                 offsets[1] = ice_dummy_vlan_packet_offsets[0];
5647         }
5648
5649         for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5650                 offsets[i + num_vlan].type = dummy_pkt->offsets[i].type;
5651                 offsets[i + num_vlan].offset =
5652                         dummy_pkt->offsets[i].offset + off;
5653         }
5654         offsets[i + num_vlan] = dummy_pkt->offsets[i];
5655
5656         etype_off = dummy_pkt->offsets[1].offset;
5657
5658         buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) +
5659                   dummy_pkt->pkt_len;
5660         pkt = kzalloc(buf_len, GFP_KERNEL);
5661         if (!pkt) {
5662                 kfree(offsets);
5663                 return ERR_PTR(-ENOMEM);
5664         }
5665
5666         memcpy(pkt, dummy_pkt->pkt, etype_off);
5667         memcpy(pkt + etype_off,
5668                num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet,
5669                off);
5670         memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off,
5671                dummy_pkt->pkt_len - etype_off);
5672
5673         profile = kzalloc(sizeof(*profile), GFP_KERNEL);
5674         if (!profile) {
5675                 kfree(offsets);
5676                 kfree(pkt);
5677                 return ERR_PTR(-ENOMEM);
5678         }
5679
5680         profile->offsets = offsets;
5681         profile->pkt = pkt;
5682         profile->pkt_len = buf_len;
5683         profile->match |= ICE_PKT_KMALLOC;
5684
5685         return profile;
5686 }
5687
5688 /**
5689  * ice_find_dummy_packet - find dummy packet
5690  *
5691  * @lkups: lookup elements or match criteria for the advanced recipe, one
5692  *         structure per protocol header
5693  * @lkups_cnt: number of protocols
5694  * @tun_type: tunnel type
5695  *
5696  * Returns the &ice_dummy_pkt_profile corresponding to these lookup params.
5697  */
5698 static const struct ice_dummy_pkt_profile *
5699 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5700                       enum ice_sw_tunnel_type tun_type)
5701 {
5702         const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles;
5703         u32 match = 0, vlan_count = 0;
5704         u16 i;
5705
5706         switch (tun_type) {
5707         case ICE_SW_TUN_GTPC:
5708                 match |= ICE_PKT_TUN_GTPC;
5709                 break;
5710         case ICE_SW_TUN_GTPU:
5711                 match |= ICE_PKT_TUN_GTPU;
5712                 break;
5713         case ICE_SW_TUN_NVGRE:
5714                 match |= ICE_PKT_TUN_NVGRE;
5715                 break;
5716         case ICE_SW_TUN_GENEVE:
5717         case ICE_SW_TUN_VXLAN:
5718                 match |= ICE_PKT_TUN_UDP;
5719                 break;
5720         default:
5721                 break;
5722         }
5723
5724         for (i = 0; i < lkups_cnt; i++) {
5725                 if (lkups[i].type == ICE_UDP_ILOS)
5726                         match |= ICE_PKT_INNER_UDP;
5727                 else if (lkups[i].type == ICE_TCP_IL)
5728                         match |= ICE_PKT_INNER_TCP;
5729                 else if (lkups[i].type == ICE_IPV6_OFOS)
5730                         match |= ICE_PKT_OUTER_IPV6;
5731                 else if (lkups[i].type == ICE_VLAN_OFOS ||
5732                          lkups[i].type == ICE_VLAN_EX)
5733                         vlan_count++;
5734                 else if (lkups[i].type == ICE_VLAN_IN)
5735                         vlan_count++;
5736                 else if (lkups[i].type == ICE_ETYPE_OL &&
5737                          lkups[i].h_u.ethertype.ethtype_id ==
5738                                 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5739                          lkups[i].m_u.ethertype.ethtype_id ==
5740                                 cpu_to_be16(0xFFFF))
5741                         match |= ICE_PKT_OUTER_IPV6;
5742                 else if (lkups[i].type == ICE_ETYPE_IL &&
5743                          lkups[i].h_u.ethertype.ethtype_id ==
5744                                 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5745                          lkups[i].m_u.ethertype.ethtype_id ==
5746                                 cpu_to_be16(0xFFFF))
5747                         match |= ICE_PKT_INNER_IPV6;
5748                 else if (lkups[i].type == ICE_IPV6_IL)
5749                         match |= ICE_PKT_INNER_IPV6;
5750                 else if (lkups[i].type == ICE_GTP_NO_PAY)
5751                         match |= ICE_PKT_GTP_NOPAY;
5752                 else if (lkups[i].type == ICE_PPPOE) {
5753                         match |= ICE_PKT_PPPOE;
5754                         if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
5755                             htons(PPP_IPV6))
5756                                 match |= ICE_PKT_OUTER_IPV6;
5757                 }
5758         }
5759
5760         while (ret->match && (match & ret->match) != ret->match)
5761                 ret++;
5762
5763         if (vlan_count != 0)
5764                 ret = ice_dummy_packet_add_vlan(ret, vlan_count);
5765
5766         return ret;
5767 }
5768
5769 /**
5770  * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
5771  *
5772  * @lkups: lookup elements or match criteria for the advanced recipe, one
5773  *         structure per protocol header
5774  * @lkups_cnt: number of protocols
5775  * @s_rule: stores rule information from the match criteria
5776  * @profile: dummy packet profile (the template, its size and header offsets)
5777  */
5778 static int
5779 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5780                           struct ice_sw_rule_lkup_rx_tx *s_rule,
5781                           const struct ice_dummy_pkt_profile *profile)
5782 {
5783         u8 *pkt;
5784         u16 i;
5785
5786         /* Start with a packet with a pre-defined/dummy content. Then, fill
5787          * in the header values to be looked up or matched.
5788          */
5789         pkt = s_rule->hdr_data;
5790
5791         memcpy(pkt, profile->pkt, profile->pkt_len);
5792
5793         for (i = 0; i < lkups_cnt; i++) {
5794                 const struct ice_dummy_pkt_offsets *offsets = profile->offsets;
5795                 enum ice_protocol_type type;
5796                 u16 offset = 0, len = 0, j;
5797                 bool found = false;
5798
5799                 /* find the start of this layer; it should be found since this
5800                  * was already checked when search for the dummy packet
5801                  */
5802                 type = lkups[i].type;
5803                 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
5804                         if (type == offsets[j].type) {
5805                                 offset = offsets[j].offset;
5806                                 found = true;
5807                                 break;
5808                         }
5809                 }
5810                 /* this should never happen in a correct calling sequence */
5811                 if (!found)
5812                         return -EINVAL;
5813
5814                 switch (lkups[i].type) {
5815                 case ICE_MAC_OFOS:
5816                 case ICE_MAC_IL:
5817                         len = sizeof(struct ice_ether_hdr);
5818                         break;
5819                 case ICE_ETYPE_OL:
5820                 case ICE_ETYPE_IL:
5821                         len = sizeof(struct ice_ethtype_hdr);
5822                         break;
5823                 case ICE_VLAN_OFOS:
5824                 case ICE_VLAN_EX:
5825                 case ICE_VLAN_IN:
5826                         len = sizeof(struct ice_vlan_hdr);
5827                         break;
5828                 case ICE_IPV4_OFOS:
5829                 case ICE_IPV4_IL:
5830                         len = sizeof(struct ice_ipv4_hdr);
5831                         break;
5832                 case ICE_IPV6_OFOS:
5833                 case ICE_IPV6_IL:
5834                         len = sizeof(struct ice_ipv6_hdr);
5835                         break;
5836                 case ICE_TCP_IL:
5837                 case ICE_UDP_OF:
5838                 case ICE_UDP_ILOS:
5839                         len = sizeof(struct ice_l4_hdr);
5840                         break;
5841                 case ICE_SCTP_IL:
5842                         len = sizeof(struct ice_sctp_hdr);
5843                         break;
5844                 case ICE_NVGRE:
5845                         len = sizeof(struct ice_nvgre_hdr);
5846                         break;
5847                 case ICE_VXLAN:
5848                 case ICE_GENEVE:
5849                         len = sizeof(struct ice_udp_tnl_hdr);
5850                         break;
5851                 case ICE_GTP_NO_PAY:
5852                 case ICE_GTP:
5853                         len = sizeof(struct ice_udp_gtp_hdr);
5854                         break;
5855                 case ICE_PPPOE:
5856                         len = sizeof(struct ice_pppoe_hdr);
5857                         break;
5858                 default:
5859                         return -EINVAL;
5860                 }
5861
5862                 /* the length should be a word multiple */
5863                 if (len % ICE_BYTES_PER_WORD)
5864                         return -EIO;
5865
5866                 /* We have the offset to the header start, the length, the
5867                  * caller's header values and mask. Use this information to
5868                  * copy the data into the dummy packet appropriately based on
5869                  * the mask. Note that we need to only write the bits as
5870                  * indicated by the mask to make sure we don't improperly write
5871                  * over any significant packet data.
5872                  */
5873                 for (j = 0; j < len / sizeof(u16); j++) {
5874                         u16 *ptr = (u16 *)(pkt + offset);
5875                         u16 mask = lkups[i].m_raw[j];
5876
5877                         if (!mask)
5878                                 continue;
5879
5880                         ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask);
5881                 }
5882         }
5883
5884         s_rule->hdr_len = cpu_to_le16(profile->pkt_len);
5885
5886         return 0;
5887 }
5888
5889 /**
5890  * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
5891  * @hw: pointer to the hardware structure
5892  * @tun_type: tunnel type
5893  * @pkt: dummy packet to fill in
5894  * @offsets: offset info for the dummy packet
5895  */
5896 static int
5897 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
5898                         u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
5899 {
5900         u16 open_port, i;
5901
5902         switch (tun_type) {
5903         case ICE_SW_TUN_VXLAN:
5904                 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
5905                         return -EIO;
5906                 break;
5907         case ICE_SW_TUN_GENEVE:
5908                 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
5909                         return -EIO;
5910                 break;
5911         default:
5912                 /* Nothing needs to be done for this tunnel type */
5913                 return 0;
5914         }
5915
5916         /* Find the outer UDP protocol header and insert the port number */
5917         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5918                 if (offsets[i].type == ICE_UDP_OF) {
5919                         struct ice_l4_hdr *hdr;
5920                         u16 offset;
5921
5922                         offset = offsets[i].offset;
5923                         hdr = (struct ice_l4_hdr *)&pkt[offset];
5924                         hdr->dst_port = cpu_to_be16(open_port);
5925
5926                         return 0;
5927                 }
5928         }
5929
5930         return -EIO;
5931 }
5932
5933 /**
5934  * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
5935  * @vlan_type: VLAN tag type
5936  * @pkt: dummy packet to fill in
5937  * @offsets: offset info for the dummy packet
5938  */
5939 static int
5940 ice_fill_adv_packet_vlan(u16 vlan_type, u8 *pkt,
5941                          const struct ice_dummy_pkt_offsets *offsets)
5942 {
5943         u16 i;
5944
5945         /* Find VLAN header and insert VLAN TPID */
5946         for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5947                 if (offsets[i].type == ICE_VLAN_OFOS ||
5948                     offsets[i].type == ICE_VLAN_EX) {
5949                         struct ice_vlan_hdr *hdr;
5950                         u16 offset;
5951
5952                         offset = offsets[i].offset;
5953                         hdr = (struct ice_vlan_hdr *)&pkt[offset];
5954                         hdr->type = cpu_to_be16(vlan_type);
5955
5956                         return 0;
5957                 }
5958         }
5959
5960         return -EIO;
5961 }
5962
5963 /**
5964  * ice_find_adv_rule_entry - Search a rule entry
5965  * @hw: pointer to the hardware structure
5966  * @lkups: lookup elements or match criteria for the advanced recipe, one
5967  *         structure per protocol header
5968  * @lkups_cnt: number of protocols
5969  * @recp_id: recipe ID for which we are finding the rule
5970  * @rinfo: other information regarding the rule e.g. priority and action info
5971  *
5972  * Helper function to search for a given advance rule entry
5973  * Returns pointer to entry storing the rule if found
5974  */
5975 static struct ice_adv_fltr_mgmt_list_entry *
5976 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5977                         u16 lkups_cnt, u16 recp_id,
5978                         struct ice_adv_rule_info *rinfo)
5979 {
5980         struct ice_adv_fltr_mgmt_list_entry *list_itr;
5981         struct ice_switch_info *sw = hw->switch_info;
5982         int i;
5983
5984         list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
5985                             list_entry) {
5986                 bool lkups_matched = true;
5987
5988                 if (lkups_cnt != list_itr->lkups_cnt)
5989                         continue;
5990                 for (i = 0; i < list_itr->lkups_cnt; i++)
5991                         if (memcmp(&list_itr->lkups[i], &lkups[i],
5992                                    sizeof(*lkups))) {
5993                                 lkups_matched = false;
5994                                 break;
5995                         }
5996                 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
5997                     rinfo->tun_type == list_itr->rule_info.tun_type &&
5998                     rinfo->vlan_type == list_itr->rule_info.vlan_type &&
5999                     lkups_matched)
6000                         return list_itr;
6001         }
6002         return NULL;
6003 }
6004
6005 /**
6006  * ice_adv_add_update_vsi_list
6007  * @hw: pointer to the hardware structure
6008  * @m_entry: pointer to current adv filter management list entry
6009  * @cur_fltr: filter information from the book keeping entry
6010  * @new_fltr: filter information with the new VSI to be added
6011  *
6012  * Call AQ command to add or update previously created VSI list with new VSI.
6013  *
6014  * Helper function to do book keeping associated with adding filter information
6015  * The algorithm to do the booking keeping is described below :
6016  * When a VSI needs to subscribe to a given advanced filter
6017  *      if only one VSI has been added till now
6018  *              Allocate a new VSI list and add two VSIs
6019  *              to this list using switch rule command
6020  *              Update the previously created switch rule with the
6021  *              newly created VSI list ID
6022  *      if a VSI list was previously created
6023  *              Add the new VSI to the previously created VSI list set
6024  *              using the update switch rule command
6025  */
6026 static int
6027 ice_adv_add_update_vsi_list(struct ice_hw *hw,
6028                             struct ice_adv_fltr_mgmt_list_entry *m_entry,
6029                             struct ice_adv_rule_info *cur_fltr,
6030                             struct ice_adv_rule_info *new_fltr)
6031 {
6032         u16 vsi_list_id = 0;
6033         int status;
6034
6035         if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
6036             cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6037             cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
6038                 return -EOPNOTSUPP;
6039
6040         if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
6041              new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
6042             (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6043              cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
6044                 return -EOPNOTSUPP;
6045
6046         if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
6047                  /* Only one entry existed in the mapping and it was not already
6048                   * a part of a VSI list. So, create a VSI list with the old and
6049                   * new VSIs.
6050                   */
6051                 struct ice_fltr_info tmp_fltr;
6052                 u16 vsi_handle_arr[2];
6053
6054                 /* A rule already exists with the new VSI being added */
6055                 if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
6056                     new_fltr->sw_act.fwd_id.hw_vsi_id)
6057                         return -EEXIST;
6058
6059                 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
6060                 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
6061                 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
6062                                                   &vsi_list_id,
6063                                                   ICE_SW_LKUP_LAST);
6064                 if (status)
6065                         return status;
6066
6067                 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6068                 tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
6069                 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
6070                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
6071                 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
6072                 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
6073
6074                 /* Update the previous switch rule of "forward to VSI" to
6075                  * "fwd to VSI list"
6076                  */
6077                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6078                 if (status)
6079                         return status;
6080
6081                 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
6082                 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
6083                 m_entry->vsi_list_info =
6084                         ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
6085                                                 vsi_list_id);
6086         } else {
6087                 u16 vsi_handle = new_fltr->sw_act.vsi_handle;
6088
6089                 if (!m_entry->vsi_list_info)
6090                         return -EIO;
6091
6092                 /* A rule already exists with the new VSI being added */
6093                 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
6094                         return 0;
6095
6096                 /* Update the previously created VSI list set with
6097                  * the new VSI ID passed in
6098                  */
6099                 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
6100
6101                 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
6102                                                   vsi_list_id, false,
6103                                                   ice_aqc_opc_update_sw_rules,
6104                                                   ICE_SW_LKUP_LAST);
6105                 /* update VSI list mapping info with new VSI ID */
6106                 if (!status)
6107                         set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
6108         }
6109         if (!status)
6110                 m_entry->vsi_count++;
6111         return status;
6112 }
6113
6114 /**
6115  * ice_add_adv_rule - helper function to create an advanced switch rule
6116  * @hw: pointer to the hardware structure
6117  * @lkups: information on the words that needs to be looked up. All words
6118  * together makes one recipe
6119  * @lkups_cnt: num of entries in the lkups array
6120  * @rinfo: other information related to the rule that needs to be programmed
6121  * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
6122  *               ignored is case of error.
6123  *
6124  * This function can program only 1 rule at a time. The lkups is used to
6125  * describe the all the words that forms the "lookup" portion of the recipe.
6126  * These words can span multiple protocols. Callers to this function need to
6127  * pass in a list of protocol headers with lookup information along and mask
6128  * that determines which words are valid from the given protocol header.
6129  * rinfo describes other information related to this rule such as forwarding
6130  * IDs, priority of this rule, etc.
6131  */
6132 int
6133 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6134                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
6135                  struct ice_rule_query_data *added_entry)
6136 {
6137         struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
6138         struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
6139         const struct ice_dummy_pkt_profile *profile;
6140         u16 rid = 0, i, rule_buf_sz, vsi_handle;
6141         struct list_head *rule_head;
6142         struct ice_switch_info *sw;
6143         u16 word_cnt;
6144         u32 act = 0;
6145         int status;
6146         u8 q_rgn;
6147
6148         /* Initialize profile to result index bitmap */
6149         if (!hw->switch_info->prof_res_bm_init) {
6150                 hw->switch_info->prof_res_bm_init = 1;
6151                 ice_init_prof_result_bm(hw);
6152         }
6153
6154         if (!lkups_cnt)
6155                 return -EINVAL;
6156
6157         /* get # of words we need to match */
6158         word_cnt = 0;
6159         for (i = 0; i < lkups_cnt; i++) {
6160                 u16 j;
6161
6162                 for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++)
6163                         if (lkups[i].m_raw[j])
6164                                 word_cnt++;
6165         }
6166
6167         if (!word_cnt)
6168                 return -EINVAL;
6169
6170         if (word_cnt > ICE_MAX_CHAIN_WORDS)
6171                 return -ENOSPC;
6172
6173         /* locate a dummy packet */
6174         profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type);
6175         if (IS_ERR(profile))
6176                 return PTR_ERR(profile);
6177
6178         if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6179               rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
6180               rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6181               rinfo->sw_act.fltr_act == ICE_DROP_PACKET)) {
6182                 status = -EIO;
6183                 goto free_pkt_profile;
6184         }
6185
6186         vsi_handle = rinfo->sw_act.vsi_handle;
6187         if (!ice_is_vsi_valid(hw, vsi_handle)) {
6188                 status =  -EINVAL;
6189                 goto free_pkt_profile;
6190         }
6191
6192         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6193                 rinfo->sw_act.fwd_id.hw_vsi_id =
6194                         ice_get_hw_vsi_num(hw, vsi_handle);
6195         if (rinfo->sw_act.flag & ICE_FLTR_TX)
6196                 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
6197
6198         status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
6199         if (status)
6200                 goto free_pkt_profile;
6201         m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6202         if (m_entry) {
6203                 /* we have to add VSI to VSI_LIST and increment vsi_count.
6204                  * Also Update VSI list so that we can change forwarding rule
6205                  * if the rule already exists, we will check if it exists with
6206                  * same vsi_id, if not then add it to the VSI list if it already
6207                  * exists if not then create a VSI list and add the existing VSI
6208                  * ID and the new VSI ID to the list
6209                  * We will add that VSI to the list
6210                  */
6211                 status = ice_adv_add_update_vsi_list(hw, m_entry,
6212                                                      &m_entry->rule_info,
6213                                                      rinfo);
6214                 if (added_entry) {
6215                         added_entry->rid = rid;
6216                         added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
6217                         added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6218                 }
6219                 goto free_pkt_profile;
6220         }
6221         rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len);
6222         s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6223         if (!s_rule) {
6224                 status = -ENOMEM;
6225                 goto free_pkt_profile;
6226         }
6227         if (!rinfo->flags_info.act_valid) {
6228                 act |= ICE_SINGLE_ACT_LAN_ENABLE;
6229                 act |= ICE_SINGLE_ACT_LB_ENABLE;
6230         } else {
6231                 act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
6232                                                 ICE_SINGLE_ACT_LB_ENABLE);
6233         }
6234
6235         switch (rinfo->sw_act.fltr_act) {
6236         case ICE_FWD_TO_VSI:
6237                 act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
6238                         ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
6239                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
6240                 break;
6241         case ICE_FWD_TO_Q:
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                 break;
6246         case ICE_FWD_TO_QGRP:
6247                 q_rgn = rinfo->sw_act.qgrp_size > 0 ?
6248                         (u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
6249                 act |= ICE_SINGLE_ACT_TO_Q;
6250                 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
6251                        ICE_SINGLE_ACT_Q_INDEX_M;
6252                 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
6253                        ICE_SINGLE_ACT_Q_REGION_M;
6254                 break;
6255         case ICE_DROP_PACKET:
6256                 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
6257                        ICE_SINGLE_ACT_VALID_BIT;
6258                 break;
6259         default:
6260                 status = -EIO;
6261                 goto err_ice_add_adv_rule;
6262         }
6263
6264         /* set the rule LOOKUP type based on caller specified 'Rx'
6265          * instead of hardcoding it to be either LOOKUP_TX/RX
6266          *
6267          * for 'Rx' set the source to be the port number
6268          * for 'Tx' set the source to be the source HW VSI number (determined
6269          * by caller)
6270          */
6271         if (rinfo->rx) {
6272                 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
6273                 s_rule->src = cpu_to_le16(hw->port_info->lport);
6274         } else {
6275                 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
6276                 s_rule->src = cpu_to_le16(rinfo->sw_act.src);
6277         }
6278
6279         s_rule->recipe_id = cpu_to_le16(rid);
6280         s_rule->act = cpu_to_le32(act);
6281
6282         status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile);
6283         if (status)
6284                 goto err_ice_add_adv_rule;
6285
6286         if (rinfo->tun_type != ICE_NON_TUN &&
6287             rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
6288                 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
6289                                                  s_rule->hdr_data,
6290                                                  profile->offsets);
6291                 if (status)
6292                         goto err_ice_add_adv_rule;
6293         }
6294
6295         if (rinfo->vlan_type != 0 && ice_is_dvm_ena(hw)) {
6296                 status = ice_fill_adv_packet_vlan(rinfo->vlan_type,
6297                                                   s_rule->hdr_data,
6298                                                   profile->offsets);
6299                 if (status)
6300                         goto err_ice_add_adv_rule;
6301         }
6302
6303         status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6304                                  rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
6305                                  NULL);
6306         if (status)
6307                 goto err_ice_add_adv_rule;
6308         adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
6309                                 sizeof(struct ice_adv_fltr_mgmt_list_entry),
6310                                 GFP_KERNEL);
6311         if (!adv_fltr) {
6312                 status = -ENOMEM;
6313                 goto err_ice_add_adv_rule;
6314         }
6315
6316         adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
6317                                        lkups_cnt * sizeof(*lkups), GFP_KERNEL);
6318         if (!adv_fltr->lkups) {
6319                 status = -ENOMEM;
6320                 goto err_ice_add_adv_rule;
6321         }
6322
6323         adv_fltr->lkups_cnt = lkups_cnt;
6324         adv_fltr->rule_info = *rinfo;
6325         adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index);
6326         sw = hw->switch_info;
6327         sw->recp_list[rid].adv_rule = true;
6328         rule_head = &sw->recp_list[rid].filt_rules;
6329
6330         if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6331                 adv_fltr->vsi_count = 1;
6332
6333         /* Add rule entry to book keeping list */
6334         list_add(&adv_fltr->list_entry, rule_head);
6335         if (added_entry) {
6336                 added_entry->rid = rid;
6337                 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
6338                 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6339         }
6340 err_ice_add_adv_rule:
6341         if (status && adv_fltr) {
6342                 devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
6343                 devm_kfree(ice_hw_to_dev(hw), adv_fltr);
6344         }
6345
6346         kfree(s_rule);
6347
6348 free_pkt_profile:
6349         if (profile->match & ICE_PKT_KMALLOC) {
6350                 kfree(profile->offsets);
6351                 kfree(profile->pkt);
6352                 kfree(profile);
6353         }
6354
6355         return status;
6356 }
6357
6358 /**
6359  * ice_replay_vsi_fltr - Replay filters for requested VSI
6360  * @hw: pointer to the hardware structure
6361  * @vsi_handle: driver VSI handle
6362  * @recp_id: Recipe ID for which rules need to be replayed
6363  * @list_head: list for which filters need to be replayed
6364  *
6365  * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
6366  * It is required to pass valid VSI handle.
6367  */
6368 static int
6369 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
6370                     struct list_head *list_head)
6371 {
6372         struct ice_fltr_mgmt_list_entry *itr;
6373         int status = 0;
6374         u16 hw_vsi_id;
6375
6376         if (list_empty(list_head))
6377                 return status;
6378         hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6379
6380         list_for_each_entry(itr, list_head, list_entry) {
6381                 struct ice_fltr_list_entry f_entry;
6382
6383                 f_entry.fltr_info = itr->fltr_info;
6384                 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
6385                     itr->fltr_info.vsi_handle == vsi_handle) {
6386                         /* update the src in case it is VSI num */
6387                         if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6388                                 f_entry.fltr_info.src = hw_vsi_id;
6389                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
6390                         if (status)
6391                                 goto end;
6392                         continue;
6393                 }
6394                 if (!itr->vsi_list_info ||
6395                     !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
6396                         continue;
6397                 /* Clearing it so that the logic can add it back */
6398                 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
6399                 f_entry.fltr_info.vsi_handle = vsi_handle;
6400                 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
6401                 /* update the src in case it is VSI num */
6402                 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6403                         f_entry.fltr_info.src = hw_vsi_id;
6404                 if (recp_id == ICE_SW_LKUP_VLAN)
6405                         status = ice_add_vlan_internal(hw, &f_entry);
6406                 else
6407                         status = ice_add_rule_internal(hw, recp_id, &f_entry);
6408                 if (status)
6409                         goto end;
6410         }
6411 end:
6412         return status;
6413 }
6414
6415 /**
6416  * ice_adv_rem_update_vsi_list
6417  * @hw: pointer to the hardware structure
6418  * @vsi_handle: VSI handle of the VSI to remove
6419  * @fm_list: filter management entry for which the VSI list management needs to
6420  *           be done
6421  */
6422 static int
6423 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
6424                             struct ice_adv_fltr_mgmt_list_entry *fm_list)
6425 {
6426         struct ice_vsi_list_map_info *vsi_list_info;
6427         enum ice_sw_lkup_type lkup_type;
6428         u16 vsi_list_id;
6429         int status;
6430
6431         if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
6432             fm_list->vsi_count == 0)
6433                 return -EINVAL;
6434
6435         /* A rule with the VSI being removed does not exist */
6436         if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
6437                 return -ENOENT;
6438
6439         lkup_type = ICE_SW_LKUP_LAST;
6440         vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
6441         status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
6442                                           ice_aqc_opc_update_sw_rules,
6443                                           lkup_type);
6444         if (status)
6445                 return status;
6446
6447         fm_list->vsi_count--;
6448         clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
6449         vsi_list_info = fm_list->vsi_list_info;
6450         if (fm_list->vsi_count == 1) {
6451                 struct ice_fltr_info tmp_fltr;
6452                 u16 rem_vsi_handle;
6453
6454                 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
6455                                                 ICE_MAX_VSI);
6456                 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
6457                         return -EIO;
6458
6459                 /* Make sure VSI list is empty before removing it below */
6460                 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
6461                                                   vsi_list_id, true,
6462                                                   ice_aqc_opc_update_sw_rules,
6463                                                   lkup_type);
6464                 if (status)
6465                         return status;
6466
6467                 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6468                 tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
6469                 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
6470                 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
6471                 tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
6472                 tmp_fltr.fwd_id.hw_vsi_id =
6473                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
6474                 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
6475                         ice_get_hw_vsi_num(hw, rem_vsi_handle);
6476                 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
6477
6478                 /* Update the previous switch rule of "MAC forward to VSI" to
6479                  * "MAC fwd to VSI list"
6480                  */
6481                 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6482                 if (status) {
6483                         ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
6484                                   tmp_fltr.fwd_id.hw_vsi_id, status);
6485                         return status;
6486                 }
6487                 fm_list->vsi_list_info->ref_cnt--;
6488
6489                 /* Remove the VSI list since it is no longer used */
6490                 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
6491                 if (status) {
6492                         ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
6493                                   vsi_list_id, status);
6494                         return status;
6495                 }
6496
6497                 list_del(&vsi_list_info->list_entry);
6498                 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
6499                 fm_list->vsi_list_info = NULL;
6500         }
6501
6502         return status;
6503 }
6504
6505 /**
6506  * ice_rem_adv_rule - removes existing advanced switch rule
6507  * @hw: pointer to the hardware structure
6508  * @lkups: information on the words that needs to be looked up. All words
6509  *         together makes one recipe
6510  * @lkups_cnt: num of entries in the lkups array
6511  * @rinfo: Its the pointer to the rule information for the rule
6512  *
6513  * This function can be used to remove 1 rule at a time. The lkups is
6514  * used to describe all the words that forms the "lookup" portion of the
6515  * rule. These words can span multiple protocols. Callers to this function
6516  * need to pass in a list of protocol headers with lookup information along
6517  * and mask that determines which words are valid from the given protocol
6518  * header. rinfo describes other information related to this rule such as
6519  * forwarding IDs, priority of this rule, etc.
6520  */
6521 static int
6522 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6523                  u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
6524 {
6525         struct ice_adv_fltr_mgmt_list_entry *list_elem;
6526         struct ice_prot_lkup_ext lkup_exts;
6527         bool remove_rule = false;
6528         struct mutex *rule_lock; /* Lock to protect filter rule list */
6529         u16 i, rid, vsi_handle;
6530         int status = 0;
6531
6532         memset(&lkup_exts, 0, sizeof(lkup_exts));
6533         for (i = 0; i < lkups_cnt; i++) {
6534                 u16 count;
6535
6536                 if (lkups[i].type >= ICE_PROTOCOL_LAST)
6537                         return -EIO;
6538
6539                 count = ice_fill_valid_words(&lkups[i], &lkup_exts);
6540                 if (!count)
6541                         return -EIO;
6542         }
6543
6544         /* Create any special protocol/offset pairs, such as looking at tunnel
6545          * bits by extracting metadata
6546          */
6547         status = ice_add_special_words(rinfo, &lkup_exts, ice_is_dvm_ena(hw));
6548         if (status)
6549                 return status;
6550
6551         rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type);
6552         /* If did not find a recipe that match the existing criteria */
6553         if (rid == ICE_MAX_NUM_RECIPES)
6554                 return -EINVAL;
6555
6556         rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
6557         list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6558         /* the rule is already removed */
6559         if (!list_elem)
6560                 return 0;
6561         mutex_lock(rule_lock);
6562         if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
6563                 remove_rule = true;
6564         } else if (list_elem->vsi_count > 1) {
6565                 remove_rule = false;
6566                 vsi_handle = rinfo->sw_act.vsi_handle;
6567                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6568         } else {
6569                 vsi_handle = rinfo->sw_act.vsi_handle;
6570                 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6571                 if (status) {
6572                         mutex_unlock(rule_lock);
6573                         return status;
6574                 }
6575                 if (list_elem->vsi_count == 0)
6576                         remove_rule = true;
6577         }
6578         mutex_unlock(rule_lock);
6579         if (remove_rule) {
6580                 struct ice_sw_rule_lkup_rx_tx *s_rule;
6581                 u16 rule_buf_sz;
6582
6583                 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule);
6584                 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6585                 if (!s_rule)
6586                         return -ENOMEM;
6587                 s_rule->act = 0;
6588                 s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id);
6589                 s_rule->hdr_len = 0;
6590                 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6591                                          rule_buf_sz, 1,
6592                                          ice_aqc_opc_remove_sw_rules, NULL);
6593                 if (!status || status == -ENOENT) {
6594                         struct ice_switch_info *sw = hw->switch_info;
6595
6596                         mutex_lock(rule_lock);
6597                         list_del(&list_elem->list_entry);
6598                         devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
6599                         devm_kfree(ice_hw_to_dev(hw), list_elem);
6600                         mutex_unlock(rule_lock);
6601                         if (list_empty(&sw->recp_list[rid].filt_rules))
6602                                 sw->recp_list[rid].adv_rule = false;
6603                 }
6604                 kfree(s_rule);
6605         }
6606         return status;
6607 }
6608
6609 /**
6610  * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
6611  * @hw: pointer to the hardware structure
6612  * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
6613  *
6614  * This function is used to remove 1 rule at a time. The removal is based on
6615  * the remove_entry parameter. This function will remove rule for a given
6616  * vsi_handle with a given rule_id which is passed as parameter in remove_entry
6617  */
6618 int
6619 ice_rem_adv_rule_by_id(struct ice_hw *hw,
6620                        struct ice_rule_query_data *remove_entry)
6621 {
6622         struct ice_adv_fltr_mgmt_list_entry *list_itr;
6623         struct list_head *list_head;
6624         struct ice_adv_rule_info rinfo;
6625         struct ice_switch_info *sw;
6626
6627         sw = hw->switch_info;
6628         if (!sw->recp_list[remove_entry->rid].recp_created)
6629                 return -EINVAL;
6630         list_head = &sw->recp_list[remove_entry->rid].filt_rules;
6631         list_for_each_entry(list_itr, list_head, list_entry) {
6632                 if (list_itr->rule_info.fltr_rule_id ==
6633                     remove_entry->rule_id) {
6634                         rinfo = list_itr->rule_info;
6635                         rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
6636                         return ice_rem_adv_rule(hw, list_itr->lkups,
6637                                                 list_itr->lkups_cnt, &rinfo);
6638                 }
6639         }
6640         /* either list is empty or unable to find rule */
6641         return -ENOENT;
6642 }
6643
6644 /**
6645  * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a
6646  *                            given VSI handle
6647  * @hw: pointer to the hardware structure
6648  * @vsi_handle: VSI handle for which we are supposed to remove all the rules.
6649  *
6650  * This function is used to remove all the rules for a given VSI and as soon
6651  * as removing a rule fails, it will return immediately with the error code,
6652  * else it will return success.
6653  */
6654 int ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
6655 {
6656         struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
6657         struct ice_vsi_list_map_info *map_info;
6658         struct ice_adv_rule_info rinfo;
6659         struct list_head *list_head;
6660         struct ice_switch_info *sw;
6661         int status;
6662         u8 rid;
6663
6664         sw = hw->switch_info;
6665         for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
6666                 if (!sw->recp_list[rid].recp_created)
6667                         continue;
6668                 if (!sw->recp_list[rid].adv_rule)
6669                         continue;
6670
6671                 list_head = &sw->recp_list[rid].filt_rules;
6672                 list_for_each_entry_safe(list_itr, tmp_entry, list_head,
6673                                          list_entry) {
6674                         rinfo = list_itr->rule_info;
6675
6676                         if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
6677                                 map_info = list_itr->vsi_list_info;
6678                                 if (!map_info)
6679                                         continue;
6680
6681                                 if (!test_bit(vsi_handle, map_info->vsi_map))
6682                                         continue;
6683                         } else if (rinfo.sw_act.vsi_handle != vsi_handle) {
6684                                 continue;
6685                         }
6686
6687                         rinfo.sw_act.vsi_handle = vsi_handle;
6688                         status = ice_rem_adv_rule(hw, list_itr->lkups,
6689                                                   list_itr->lkups_cnt, &rinfo);
6690                         if (status)
6691                                 return status;
6692                 }
6693         }
6694         return 0;
6695 }
6696
6697 /**
6698  * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
6699  * @hw: pointer to the hardware structure
6700  * @vsi_handle: driver VSI handle
6701  * @list_head: list for which filters need to be replayed
6702  *
6703  * Replay the advanced rule for the given VSI.
6704  */
6705 static int
6706 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
6707                         struct list_head *list_head)
6708 {
6709         struct ice_rule_query_data added_entry = { 0 };
6710         struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
6711         int status = 0;
6712
6713         if (list_empty(list_head))
6714                 return status;
6715         list_for_each_entry(adv_fltr, list_head, list_entry) {
6716                 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
6717                 u16 lk_cnt = adv_fltr->lkups_cnt;
6718
6719                 if (vsi_handle != rinfo->sw_act.vsi_handle)
6720                         continue;
6721                 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
6722                                           &added_entry);
6723                 if (status)
6724                         break;
6725         }
6726         return status;
6727 }
6728
6729 /**
6730  * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
6731  * @hw: pointer to the hardware structure
6732  * @vsi_handle: driver VSI handle
6733  *
6734  * Replays filters for requested VSI via vsi_handle.
6735  */
6736 int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
6737 {
6738         struct ice_switch_info *sw = hw->switch_info;
6739         int status;
6740         u8 i;
6741
6742         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6743                 struct list_head *head;
6744
6745                 head = &sw->recp_list[i].filt_replay_rules;
6746                 if (!sw->recp_list[i].adv_rule)
6747                         status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
6748                 else
6749                         status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
6750                 if (status)
6751                         return status;
6752         }
6753         return status;
6754 }
6755
6756 /**
6757  * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
6758  * @hw: pointer to the HW struct
6759  *
6760  * Deletes the filter replay rules.
6761  */
6762 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
6763 {
6764         struct ice_switch_info *sw = hw->switch_info;
6765         u8 i;
6766
6767         if (!sw)
6768                 return;
6769
6770         for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6771                 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
6772                         struct list_head *l_head;
6773
6774                         l_head = &sw->recp_list[i].filt_replay_rules;
6775                         if (!sw->recp_list[i].adv_rule)
6776                                 ice_rem_sw_rule_info(hw, l_head);
6777                         else
6778                                 ice_rem_adv_rule_info(hw, l_head);
6779                 }
6780         }
6781 }