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