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