Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2001-2023 Intel Corporation
3 : : */
4 : :
5 : : #include "ice_common.h"
6 : : #include "ice_switch.h"
7 : : #include "ice_flex_type.h"
8 : : #include "ice_flow.h"
9 : :
10 : : #define ICE_ETH_DA_OFFSET 0
11 : : #define ICE_ETH_ETHTYPE_OFFSET 12
12 : : #define ICE_ETH_VLAN_TCI_OFFSET 14
13 : : #define ICE_MAX_VLAN_ID 0xFFF
14 : : #define ICE_IPV6_ETHER_ID 0x86DD
15 : : #define ICE_IPV4_NVGRE_PROTO_ID 0x002F
16 : : #define ICE_PPP_IPV6_PROTO_ID 0x0057
17 : : #define ICE_TCP_PROTO_ID 0x06
18 : : #define ICE_GTPU_PROFILE 24
19 : : #define ICE_MPLS_ETHER_ID 0x8847
20 : : #define ICE_ETH_P_8021Q 0x8100
21 : :
22 : : /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem
23 : : * struct to configure any switch filter rules.
24 : : * {DA (6 bytes), SA(6 bytes),
25 : : * Ether type (2 bytes for header without VLAN tag) OR
26 : : * VLAN tag (4 bytes for header with VLAN tag) }
27 : : *
28 : : * Word on Hardcoded values
29 : : * byte 0 = 0x2: to identify it as locally administered DA MAC
30 : : * byte 6 = 0x2: to identify it as locally administered SA MAC
31 : : * byte 12 = 0x81 & byte 13 = 0x00:
32 : : * In case of VLAN filter first two bytes defines ether type (0x8100)
33 : : * and remaining two bytes are placeholder for programming a given VLAN ID
34 : : * In case of Ether type filter it is treated as header without VLAN tag
35 : : * and byte 12 and 13 is used to program a given Ether type instead
36 : : */
37 : : static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
38 : : 0x2, 0, 0, 0, 0, 0,
39 : : 0x81, 0, 0, 0};
40 : :
41 : : struct ice_dummy_pkt_offsets {
42 : : enum ice_protocol_type type;
43 : : u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
44 : : };
45 : :
46 : : static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = {
47 : : { ICE_MAC_OFOS, 0 },
48 : : { ICE_ETYPE_OL, 12 },
49 : : { ICE_IPV4_OFOS, 14 },
50 : : { ICE_NVGRE, 34 },
51 : : { ICE_MAC_IL, 42 },
52 : : { ICE_ETYPE_IL, 54 },
53 : : { ICE_IPV4_IL, 56 },
54 : : { ICE_TCP_IL, 76 },
55 : : { ICE_PROTOCOL_LAST, 0 },
56 : : };
57 : :
58 : : static const u8 dummy_gre_tcp_packet[] = {
59 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
60 : : 0x00, 0x00, 0x00, 0x00,
61 : : 0x00, 0x00, 0x00, 0x00,
62 : :
63 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
64 : :
65 : : 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
66 : : 0x00, 0x00, 0x00, 0x00,
67 : : 0x00, 0x2F, 0x00, 0x00,
68 : : 0x00, 0x00, 0x00, 0x00,
69 : : 0x00, 0x00, 0x00, 0x00,
70 : :
71 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
72 : : 0x00, 0x00, 0x00, 0x00,
73 : :
74 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
75 : : 0x00, 0x00, 0x00, 0x00,
76 : : 0x00, 0x00, 0x00, 0x00,
77 : :
78 : : 0x08, 0x00, /* ICE_ETYPE_IL 54 */
79 : :
80 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
81 : : 0x00, 0x00, 0x00, 0x00,
82 : : 0x00, 0x06, 0x00, 0x00,
83 : : 0x00, 0x00, 0x00, 0x00,
84 : : 0x00, 0x00, 0x00, 0x00,
85 : :
86 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */
87 : : 0x00, 0x00, 0x00, 0x00,
88 : : 0x00, 0x00, 0x00, 0x00,
89 : : 0x50, 0x02, 0x20, 0x00,
90 : : 0x00, 0x00, 0x00, 0x00
91 : : };
92 : :
93 : : static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = {
94 : : { ICE_MAC_OFOS, 0 },
95 : : { ICE_ETYPE_OL, 12 },
96 : : { ICE_IPV4_OFOS, 14 },
97 : : { ICE_NVGRE, 34 },
98 : : { ICE_MAC_IL, 42 },
99 : : { ICE_ETYPE_IL, 54 },
100 : : { ICE_IPV4_IL, 56 },
101 : : { ICE_UDP_ILOS, 76 },
102 : : { ICE_PROTOCOL_LAST, 0 },
103 : : };
104 : :
105 : : static const u8 dummy_gre_udp_packet[] = {
106 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
107 : : 0x00, 0x00, 0x00, 0x00,
108 : : 0x00, 0x00, 0x00, 0x00,
109 : :
110 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
111 : :
112 : : 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
113 : : 0x00, 0x00, 0x00, 0x00,
114 : : 0x00, 0x2F, 0x00, 0x00,
115 : : 0x00, 0x00, 0x00, 0x00,
116 : : 0x00, 0x00, 0x00, 0x00,
117 : :
118 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
119 : : 0x00, 0x00, 0x00, 0x00,
120 : :
121 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
122 : : 0x00, 0x00, 0x00, 0x00,
123 : : 0x00, 0x00, 0x00, 0x00,
124 : :
125 : : 0x08, 0x00, /* ICE_ETYPE_IL 54 */
126 : :
127 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
128 : : 0x00, 0x00, 0x00, 0x00,
129 : : 0x00, 0x11, 0x00, 0x00,
130 : : 0x00, 0x00, 0x00, 0x00,
131 : : 0x00, 0x00, 0x00, 0x00,
132 : :
133 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */
134 : : 0x00, 0x08, 0x00, 0x00,
135 : : };
136 : :
137 : : static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
138 : : { ICE_MAC_OFOS, 0 },
139 : : { ICE_ETYPE_OL, 12 },
140 : : { ICE_IPV4_OFOS, 14 },
141 : : { ICE_UDP_OF, 34 },
142 : : { ICE_VXLAN, 42 },
143 : : { ICE_GENEVE, 42 },
144 : : { ICE_VXLAN_GPE, 42 },
145 : : { ICE_MAC_IL, 50 },
146 : : { ICE_ETYPE_IL, 62 },
147 : : { ICE_IPV4_IL, 64 },
148 : : { ICE_TCP_IL, 84 },
149 : : { ICE_PROTOCOL_LAST, 0 },
150 : : };
151 : :
152 : : static const u8 dummy_udp_tun_tcp_packet[] = {
153 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
154 : : 0x00, 0x00, 0x00, 0x00,
155 : : 0x00, 0x00, 0x00, 0x00,
156 : :
157 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
158 : :
159 : : 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
160 : : 0x00, 0x01, 0x00, 0x00,
161 : : 0x40, 0x11, 0x00, 0x00,
162 : : 0x00, 0x00, 0x00, 0x00,
163 : : 0x00, 0x00, 0x00, 0x00,
164 : :
165 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
166 : : 0x00, 0x46, 0x00, 0x00,
167 : :
168 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
169 : : 0x00, 0x00, 0x00, 0x00,
170 : :
171 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
172 : : 0x00, 0x00, 0x00, 0x00,
173 : : 0x00, 0x00, 0x00, 0x00,
174 : :
175 : : 0x08, 0x00, /* ICE_ETYPE_IL 62*/
176 : :
177 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
178 : : 0x00, 0x01, 0x00, 0x00,
179 : : 0x40, 0x06, 0x00, 0x00,
180 : : 0x00, 0x00, 0x00, 0x00,
181 : : 0x00, 0x00, 0x00, 0x00,
182 : :
183 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
184 : : 0x00, 0x00, 0x00, 0x00,
185 : : 0x00, 0x00, 0x00, 0x00,
186 : : 0x50, 0x02, 0x20, 0x00,
187 : : 0x00, 0x00, 0x00, 0x00
188 : : };
189 : :
190 : : static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
191 : : { ICE_MAC_OFOS, 0 },
192 : : { ICE_ETYPE_OL, 12 },
193 : : { ICE_IPV4_OFOS, 14 },
194 : : { ICE_UDP_OF, 34 },
195 : : { ICE_VXLAN, 42 },
196 : : { ICE_GENEVE, 42 },
197 : : { ICE_VXLAN_GPE, 42 },
198 : : { ICE_MAC_IL, 50 },
199 : : { ICE_ETYPE_IL, 62 },
200 : : { ICE_IPV4_IL, 64 },
201 : : { ICE_UDP_ILOS, 84 },
202 : : { ICE_PROTOCOL_LAST, 0 },
203 : : };
204 : :
205 : : static const u8 dummy_udp_tun_udp_packet[] = {
206 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
207 : : 0x00, 0x00, 0x00, 0x00,
208 : : 0x00, 0x00, 0x00, 0x00,
209 : :
210 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
211 : :
212 : : 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
213 : : 0x00, 0x01, 0x00, 0x00,
214 : : 0x00, 0x11, 0x00, 0x00,
215 : : 0x00, 0x00, 0x00, 0x00,
216 : : 0x00, 0x00, 0x00, 0x00,
217 : :
218 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
219 : : 0x00, 0x3a, 0x00, 0x00,
220 : :
221 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
222 : : 0x00, 0x00, 0x00, 0x00,
223 : :
224 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
225 : : 0x00, 0x00, 0x00, 0x00,
226 : : 0x00, 0x00, 0x00, 0x00,
227 : :
228 : : 0x08, 0x00, /* ICE_ETYPE_IL 62 */
229 : :
230 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
231 : : 0x00, 0x01, 0x00, 0x00,
232 : : 0x00, 0x11, 0x00, 0x00,
233 : : 0x00, 0x00, 0x00, 0x00,
234 : : 0x00, 0x00, 0x00, 0x00,
235 : :
236 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
237 : : 0x00, 0x08, 0x00, 0x00,
238 : : };
239 : :
240 : : static const struct ice_dummy_pkt_offsets
241 : : dummy_gre_ipv6_tcp_packet_offsets[] = {
242 : : { ICE_MAC_OFOS, 0 },
243 : : { ICE_ETYPE_OL, 12 },
244 : : { ICE_IPV4_OFOS, 14 },
245 : : { ICE_NVGRE, 34 },
246 : : { ICE_MAC_IL, 42 },
247 : : { ICE_ETYPE_IL, 54 },
248 : : { ICE_IPV6_IL, 56 },
249 : : { ICE_TCP_IL, 96 },
250 : : { ICE_PROTOCOL_LAST, 0 },
251 : : };
252 : :
253 : : static const u8 dummy_gre_ipv6_tcp_packet[] = {
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, 0x66, /* ICE_IPV4_OFOS 14 */
261 : : 0x00, 0x00, 0x00, 0x00,
262 : : 0x00, 0x2F, 0x00, 0x00,
263 : : 0x00, 0x00, 0x00, 0x00,
264 : : 0x00, 0x00, 0x00, 0x00,
265 : :
266 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
267 : : 0x00, 0x00, 0x00, 0x00,
268 : :
269 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
270 : : 0x00, 0x00, 0x00, 0x00,
271 : : 0x00, 0x00, 0x00, 0x00,
272 : :
273 : : 0x86, 0xdd, /* ICE_ETYPE_IL 54 */
274 : :
275 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
276 : : 0x00, 0x08, 0x06, 0x40,
277 : : 0x00, 0x00, 0x00, 0x00,
278 : : 0x00, 0x00, 0x00, 0x00,
279 : : 0x00, 0x00, 0x00, 0x00,
280 : : 0x00, 0x00, 0x00, 0x00,
281 : : 0x00, 0x00, 0x00, 0x00,
282 : : 0x00, 0x00, 0x00, 0x00,
283 : : 0x00, 0x00, 0x00, 0x00,
284 : : 0x00, 0x00, 0x00, 0x00,
285 : :
286 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */
287 : : 0x00, 0x00, 0x00, 0x00,
288 : : 0x00, 0x00, 0x00, 0x00,
289 : : 0x50, 0x02, 0x20, 0x00,
290 : : 0x00, 0x00, 0x00, 0x00
291 : : };
292 : :
293 : : static const struct ice_dummy_pkt_offsets
294 : : dummy_gre_ipv6_udp_packet_offsets[] = {
295 : : { ICE_MAC_OFOS, 0 },
296 : : { ICE_ETYPE_OL, 12 },
297 : : { ICE_IPV4_OFOS, 14 },
298 : : { ICE_NVGRE, 34 },
299 : : { ICE_MAC_IL, 42 },
300 : : { ICE_ETYPE_IL, 54 },
301 : : { ICE_IPV6_IL, 56 },
302 : : { ICE_UDP_ILOS, 96 },
303 : : { ICE_PROTOCOL_LAST, 0 },
304 : : };
305 : :
306 : : static const u8 dummy_gre_ipv6_udp_packet[] = {
307 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
308 : : 0x00, 0x00, 0x00, 0x00,
309 : : 0x00, 0x00, 0x00, 0x00,
310 : :
311 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
312 : :
313 : : 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
314 : : 0x00, 0x00, 0x00, 0x00,
315 : : 0x00, 0x2F, 0x00, 0x00,
316 : : 0x00, 0x00, 0x00, 0x00,
317 : : 0x00, 0x00, 0x00, 0x00,
318 : :
319 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
320 : : 0x00, 0x00, 0x00, 0x00,
321 : :
322 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
323 : : 0x00, 0x00, 0x00, 0x00,
324 : : 0x00, 0x00, 0x00, 0x00,
325 : :
326 : : 0x86, 0xdd, /* ICE_ETYPE_IL 54 */
327 : :
328 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
329 : : 0x00, 0x08, 0x11, 0x40,
330 : : 0x00, 0x00, 0x00, 0x00,
331 : : 0x00, 0x00, 0x00, 0x00,
332 : : 0x00, 0x00, 0x00, 0x00,
333 : : 0x00, 0x00, 0x00, 0x00,
334 : : 0x00, 0x00, 0x00, 0x00,
335 : : 0x00, 0x00, 0x00, 0x00,
336 : : 0x00, 0x00, 0x00, 0x00,
337 : : 0x00, 0x00, 0x00, 0x00,
338 : :
339 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */
340 : : 0x00, 0x08, 0x00, 0x00,
341 : : };
342 : :
343 : : static const struct ice_dummy_pkt_offsets
344 : : dummy_udp_tun_ipv6_tcp_packet_offsets[] = {
345 : : { ICE_MAC_OFOS, 0 },
346 : : { ICE_ETYPE_OL, 12 },
347 : : { ICE_IPV4_OFOS, 14 },
348 : : { ICE_UDP_OF, 34 },
349 : : { ICE_VXLAN, 42 },
350 : : { ICE_GENEVE, 42 },
351 : : { ICE_VXLAN_GPE, 42 },
352 : : { ICE_MAC_IL, 50 },
353 : : { ICE_ETYPE_IL, 62 },
354 : : { ICE_IPV6_IL, 64 },
355 : : { ICE_TCP_IL, 104 },
356 : : { ICE_PROTOCOL_LAST, 0 },
357 : : };
358 : :
359 : : static const u8 dummy_udp_tun_ipv6_tcp_packet[] = {
360 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
361 : : 0x00, 0x00, 0x00, 0x00,
362 : : 0x00, 0x00, 0x00, 0x00,
363 : :
364 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
365 : :
366 : : 0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */
367 : : 0x00, 0x01, 0x00, 0x00,
368 : : 0x40, 0x11, 0x00, 0x00,
369 : : 0x00, 0x00, 0x00, 0x00,
370 : : 0x00, 0x00, 0x00, 0x00,
371 : :
372 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
373 : : 0x00, 0x5a, 0x00, 0x00,
374 : :
375 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
376 : : 0x00, 0x00, 0x00, 0x00,
377 : :
378 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
379 : : 0x00, 0x00, 0x00, 0x00,
380 : : 0x00, 0x00, 0x00, 0x00,
381 : :
382 : : 0x86, 0xdd, /* ICE_ETYPE_IL 62 */
383 : :
384 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
385 : : 0x00, 0x08, 0x06, 0x40,
386 : : 0x00, 0x00, 0x00, 0x00,
387 : : 0x00, 0x00, 0x00, 0x00,
388 : : 0x00, 0x00, 0x00, 0x00,
389 : : 0x00, 0x00, 0x00, 0x00,
390 : : 0x00, 0x00, 0x00, 0x00,
391 : : 0x00, 0x00, 0x00, 0x00,
392 : : 0x00, 0x00, 0x00, 0x00,
393 : : 0x00, 0x00, 0x00, 0x00,
394 : :
395 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */
396 : : 0x00, 0x00, 0x00, 0x00,
397 : : 0x00, 0x00, 0x00, 0x00,
398 : : 0x50, 0x02, 0x20, 0x00,
399 : : 0x00, 0x00, 0x00, 0x00
400 : : };
401 : :
402 : : static const struct ice_dummy_pkt_offsets
403 : : dummy_udp_tun_ipv6_udp_packet_offsets[] = {
404 : : { ICE_MAC_OFOS, 0 },
405 : : { ICE_ETYPE_OL, 12 },
406 : : { ICE_IPV4_OFOS, 14 },
407 : : { ICE_UDP_OF, 34 },
408 : : { ICE_VXLAN, 42 },
409 : : { ICE_GENEVE, 42 },
410 : : { ICE_VXLAN_GPE, 42 },
411 : : { ICE_MAC_IL, 50 },
412 : : { ICE_ETYPE_IL, 62 },
413 : : { ICE_IPV6_IL, 64 },
414 : : { ICE_UDP_ILOS, 104 },
415 : : { ICE_PROTOCOL_LAST, 0 },
416 : : };
417 : :
418 : : static const u8 dummy_udp_tun_ipv6_udp_packet[] = {
419 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
420 : : 0x00, 0x00, 0x00, 0x00,
421 : : 0x00, 0x00, 0x00, 0x00,
422 : :
423 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
424 : :
425 : : 0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */
426 : : 0x00, 0x01, 0x00, 0x00,
427 : : 0x00, 0x11, 0x00, 0x00,
428 : : 0x00, 0x00, 0x00, 0x00,
429 : : 0x00, 0x00, 0x00, 0x00,
430 : :
431 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
432 : : 0x00, 0x4e, 0x00, 0x00,
433 : :
434 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
435 : : 0x00, 0x00, 0x00, 0x00,
436 : :
437 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
438 : : 0x00, 0x00, 0x00, 0x00,
439 : : 0x00, 0x00, 0x00, 0x00,
440 : :
441 : : 0x86, 0xdd, /* ICE_ETYPE_IL 62 */
442 : :
443 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
444 : : 0x00, 0x08, 0x11, 0x40,
445 : : 0x00, 0x00, 0x00, 0x00,
446 : : 0x00, 0x00, 0x00, 0x00,
447 : : 0x00, 0x00, 0x00, 0x00,
448 : : 0x00, 0x00, 0x00, 0x00,
449 : : 0x00, 0x00, 0x00, 0x00,
450 : : 0x00, 0x00, 0x00, 0x00,
451 : : 0x00, 0x00, 0x00, 0x00,
452 : : 0x00, 0x00, 0x00, 0x00,
453 : :
454 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */
455 : : 0x00, 0x08, 0x00, 0x00,
456 : : };
457 : :
458 : : /* offset info for MAC + IPv4 + UDP dummy packet */
459 : : static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
460 : : { ICE_MAC_OFOS, 0 },
461 : : { ICE_ETYPE_OL, 12 },
462 : : { ICE_IPV4_OFOS, 14 },
463 : : { ICE_UDP_ILOS, 34 },
464 : : { ICE_PROTOCOL_LAST, 0 },
465 : : };
466 : :
467 : : /* Dummy packet for MAC + IPv4 + UDP */
468 : : static const u8 dummy_udp_packet[] = {
469 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
470 : : 0x00, 0x00, 0x00, 0x00,
471 : : 0x00, 0x00, 0x00, 0x00,
472 : :
473 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
474 : :
475 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
476 : : 0x00, 0x01, 0x00, 0x00,
477 : : 0x00, 0x11, 0x00, 0x00,
478 : : 0x00, 0x00, 0x00, 0x00,
479 : : 0x00, 0x00, 0x00, 0x00,
480 : :
481 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
482 : : 0x00, 0x08, 0x00, 0x00,
483 : :
484 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
485 : : };
486 : :
487 : : /* offset info for MAC + VLAN + IPv4 + UDP dummy packet */
488 : : static const struct ice_dummy_pkt_offsets dummy_vlan_udp_packet_offsets[] = {
489 : : { ICE_MAC_OFOS, 0 },
490 : : { ICE_VLAN_OFOS, 12 },
491 : : { ICE_ETYPE_OL, 16 },
492 : : { ICE_IPV4_OFOS, 18 },
493 : : { ICE_UDP_ILOS, 38 },
494 : : { ICE_PROTOCOL_LAST, 0 },
495 : : };
496 : :
497 : : /* C-tag (801.1Q), IPv4:UDP dummy packet */
498 : : static const u8 dummy_vlan_udp_packet[] = {
499 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
500 : : 0x00, 0x00, 0x00, 0x00,
501 : : 0x00, 0x00, 0x00, 0x00,
502 : :
503 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
504 : :
505 : : 0x08, 0x00, /* ICE_ETYPE_OL 16 */
506 : :
507 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 18 */
508 : : 0x00, 0x01, 0x00, 0x00,
509 : : 0x00, 0x11, 0x00, 0x00,
510 : : 0x00, 0x00, 0x00, 0x00,
511 : : 0x00, 0x00, 0x00, 0x00,
512 : :
513 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 38 */
514 : : 0x00, 0x08, 0x00, 0x00,
515 : :
516 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
517 : : };
518 : :
519 : : /* offset info for MAC + IPv4 + TCP dummy packet */
520 : : static const struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = {
521 : : { ICE_MAC_OFOS, 0 },
522 : : { ICE_ETYPE_OL, 12 },
523 : : { ICE_IPV4_OFOS, 14 },
524 : : { ICE_TCP_IL, 34 },
525 : : { ICE_PROTOCOL_LAST, 0 },
526 : : };
527 : :
528 : : /* Dummy packet for MAC + IPv4 + TCP */
529 : : static const u8 dummy_tcp_packet[] = {
530 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
531 : : 0x00, 0x00, 0x00, 0x00,
532 : : 0x00, 0x00, 0x00, 0x00,
533 : :
534 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
535 : :
536 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
537 : : 0x00, 0x01, 0x00, 0x00,
538 : : 0x00, 0x06, 0x00, 0x00,
539 : : 0x00, 0x00, 0x00, 0x00,
540 : : 0x00, 0x00, 0x00, 0x00,
541 : :
542 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
543 : : 0x00, 0x00, 0x00, 0x00,
544 : : 0x00, 0x00, 0x00, 0x00,
545 : : 0x50, 0x00, 0x00, 0x00,
546 : : 0x00, 0x00, 0x00, 0x00,
547 : :
548 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
549 : : };
550 : :
551 : : /* offset info for MAC + VLAN (C-tag, 802.1Q) + IPv4 + TCP dummy packet */
552 : : static const struct ice_dummy_pkt_offsets dummy_vlan_tcp_packet_offsets[] = {
553 : : { ICE_MAC_OFOS, 0 },
554 : : { ICE_VLAN_OFOS, 12 },
555 : : { ICE_ETYPE_OL, 16 },
556 : : { ICE_IPV4_OFOS, 18 },
557 : : { ICE_TCP_IL, 38 },
558 : : { ICE_PROTOCOL_LAST, 0 },
559 : : };
560 : :
561 : : /* C-tag (801.1Q), IPv4:TCP dummy packet */
562 : : static const u8 dummy_vlan_tcp_packet[] = {
563 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
564 : : 0x00, 0x00, 0x00, 0x00,
565 : : 0x00, 0x00, 0x00, 0x00,
566 : :
567 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
568 : :
569 : : 0x08, 0x00, /* ICE_ETYPE_OL 16 */
570 : :
571 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 18 */
572 : : 0x00, 0x01, 0x00, 0x00,
573 : : 0x00, 0x06, 0x00, 0x00,
574 : : 0x00, 0x00, 0x00, 0x00,
575 : : 0x00, 0x00, 0x00, 0x00,
576 : :
577 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 38 */
578 : : 0x00, 0x00, 0x00, 0x00,
579 : : 0x00, 0x00, 0x00, 0x00,
580 : : 0x50, 0x00, 0x00, 0x00,
581 : : 0x00, 0x00, 0x00, 0x00,
582 : :
583 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
584 : : };
585 : :
586 : : static const struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = {
587 : : { ICE_MAC_OFOS, 0 },
588 : : { ICE_ETYPE_OL, 12 },
589 : : { ICE_IPV6_OFOS, 14 },
590 : : { ICE_TCP_IL, 54 },
591 : : { ICE_PROTOCOL_LAST, 0 },
592 : : };
593 : :
594 : : static const u8 dummy_tcp_ipv6_packet[] = {
595 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
596 : : 0x00, 0x00, 0x00, 0x00,
597 : : 0x00, 0x00, 0x00, 0x00,
598 : :
599 : : 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
600 : :
601 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
602 : : 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
603 : : 0x00, 0x00, 0x00, 0x00,
604 : : 0x00, 0x00, 0x00, 0x00,
605 : : 0x00, 0x00, 0x00, 0x00,
606 : : 0x00, 0x00, 0x00, 0x00,
607 : : 0x00, 0x00, 0x00, 0x00,
608 : : 0x00, 0x00, 0x00, 0x00,
609 : : 0x00, 0x00, 0x00, 0x00,
610 : : 0x00, 0x00, 0x00, 0x00,
611 : :
612 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
613 : : 0x00, 0x00, 0x00, 0x00,
614 : : 0x00, 0x00, 0x00, 0x00,
615 : : 0x50, 0x00, 0x00, 0x00,
616 : : 0x00, 0x00, 0x00, 0x00,
617 : :
618 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
619 : : };
620 : :
621 : : /* C-tag (802.1Q): IPv6 + TCP */
622 : : static const struct ice_dummy_pkt_offsets
623 : : dummy_vlan_tcp_ipv6_packet_offsets[] = {
624 : : { ICE_MAC_OFOS, 0 },
625 : : { ICE_VLAN_OFOS, 12 },
626 : : { ICE_ETYPE_OL, 16 },
627 : : { ICE_IPV6_OFOS, 18 },
628 : : { ICE_TCP_IL, 58 },
629 : : { ICE_PROTOCOL_LAST, 0 },
630 : : };
631 : :
632 : : /* C-tag (802.1Q), IPv6 + TCP dummy packet */
633 : : static const u8 dummy_vlan_tcp_ipv6_packet[] = {
634 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
635 : : 0x00, 0x00, 0x00, 0x00,
636 : : 0x00, 0x00, 0x00, 0x00,
637 : :
638 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
639 : :
640 : : 0x86, 0xDD, /* ICE_ETYPE_OL 16 */
641 : :
642 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
643 : : 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
644 : : 0x00, 0x00, 0x00, 0x00,
645 : : 0x00, 0x00, 0x00, 0x00,
646 : : 0x00, 0x00, 0x00, 0x00,
647 : : 0x00, 0x00, 0x00, 0x00,
648 : : 0x00, 0x00, 0x00, 0x00,
649 : : 0x00, 0x00, 0x00, 0x00,
650 : : 0x00, 0x00, 0x00, 0x00,
651 : : 0x00, 0x00, 0x00, 0x00,
652 : :
653 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 58 */
654 : : 0x00, 0x00, 0x00, 0x00,
655 : : 0x00, 0x00, 0x00, 0x00,
656 : : 0x50, 0x00, 0x00, 0x00,
657 : : 0x00, 0x00, 0x00, 0x00,
658 : :
659 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
660 : : };
661 : :
662 : : /* IPv6 + UDP */
663 : : static const struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = {
664 : : { ICE_MAC_OFOS, 0 },
665 : : { ICE_ETYPE_OL, 12 },
666 : : { ICE_IPV6_OFOS, 14 },
667 : : { ICE_UDP_ILOS, 54 },
668 : : { ICE_PROTOCOL_LAST, 0 },
669 : : };
670 : :
671 : : /* IPv6 + UDP dummy packet */
672 : : static const u8 dummy_udp_ipv6_packet[] = {
673 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
674 : : 0x00, 0x00, 0x00, 0x00,
675 : : 0x00, 0x00, 0x00, 0x00,
676 : :
677 : : 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
678 : :
679 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
680 : : 0x00, 0x10, 0x11, 0x00, /* Next header UDP */
681 : : 0x00, 0x00, 0x00, 0x00,
682 : : 0x00, 0x00, 0x00, 0x00,
683 : : 0x00, 0x00, 0x00, 0x00,
684 : : 0x00, 0x00, 0x00, 0x00,
685 : : 0x00, 0x00, 0x00, 0x00,
686 : : 0x00, 0x00, 0x00, 0x00,
687 : : 0x00, 0x00, 0x00, 0x00,
688 : : 0x00, 0x00, 0x00, 0x00,
689 : :
690 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
691 : : 0x00, 0x10, 0x00, 0x00,
692 : :
693 : : 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
694 : : 0x00, 0x00, 0x00, 0x00,
695 : :
696 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
697 : : };
698 : :
699 : : /* C-tag (802.1Q): IPv6 + UDP */
700 : : static const struct ice_dummy_pkt_offsets
701 : : dummy_vlan_udp_ipv6_packet_offsets[] = {
702 : : { ICE_MAC_OFOS, 0 },
703 : : { ICE_VLAN_OFOS, 12 },
704 : : { ICE_ETYPE_OL, 16 },
705 : : { ICE_IPV6_OFOS, 18 },
706 : : { ICE_UDP_ILOS, 58 },
707 : : { ICE_PROTOCOL_LAST, 0 },
708 : : };
709 : :
710 : : /* C-tag (802.1Q), IPv6 + UDP dummy packet */
711 : : static const u8 dummy_vlan_udp_ipv6_packet[] = {
712 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
713 : : 0x00, 0x00, 0x00, 0x00,
714 : : 0x00, 0x00, 0x00, 0x00,
715 : :
716 : : 0x81, 0x00, 0x00, 0x00,/* ICE_VLAN_OFOS 12 */
717 : :
718 : : 0x86, 0xDD, /* ICE_ETYPE_OL 16 */
719 : :
720 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
721 : : 0x00, 0x08, 0x11, 0x00, /* Next header UDP */
722 : : 0x00, 0x00, 0x00, 0x00,
723 : : 0x00, 0x00, 0x00, 0x00,
724 : : 0x00, 0x00, 0x00, 0x00,
725 : : 0x00, 0x00, 0x00, 0x00,
726 : : 0x00, 0x00, 0x00, 0x00,
727 : : 0x00, 0x00, 0x00, 0x00,
728 : : 0x00, 0x00, 0x00, 0x00,
729 : : 0x00, 0x00, 0x00, 0x00,
730 : :
731 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 58 */
732 : : 0x00, 0x08, 0x00, 0x00,
733 : :
734 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
735 : : };
736 : :
737 : : /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
738 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = {
739 : : { ICE_MAC_OFOS, 0 },
740 : : { ICE_IPV4_OFOS, 14 },
741 : : { ICE_UDP_OF, 34 },
742 : : { ICE_GTP, 42 },
743 : : { ICE_IPV4_IL, 62 },
744 : : { ICE_TCP_IL, 82 },
745 : : { ICE_PROTOCOL_LAST, 0 },
746 : : };
747 : :
748 : : static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = {
749 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
750 : : 0x00, 0x00, 0x00, 0x00,
751 : : 0x00, 0x00, 0x00, 0x00,
752 : : 0x08, 0x00,
753 : :
754 : : 0x45, 0x00, 0x00, 0x58, /* IP 14 */
755 : : 0x00, 0x00, 0x00, 0x00,
756 : : 0x00, 0x11, 0x00, 0x00,
757 : : 0x00, 0x00, 0x00, 0x00,
758 : : 0x00, 0x00, 0x00, 0x00,
759 : :
760 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
761 : : 0x00, 0x44, 0x00, 0x00,
762 : :
763 : : 0x34, 0xff, 0x00, 0x34, /* GTP-U Header 42 */
764 : : 0x00, 0x00, 0x00, 0x00,
765 : : 0x00, 0x00, 0x00, 0x85,
766 : :
767 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
768 : : 0x00, 0x00, 0x00, 0x00,
769 : :
770 : : 0x45, 0x00, 0x00, 0x28, /* IP 62 */
771 : : 0x00, 0x00, 0x00, 0x00,
772 : : 0x00, 0x06, 0x00, 0x00,
773 : : 0x00, 0x00, 0x00, 0x00,
774 : : 0x00, 0x00, 0x00, 0x00,
775 : :
776 : : 0x00, 0x00, 0x00, 0x00, /* TCP 82 */
777 : : 0x00, 0x00, 0x00, 0x00,
778 : : 0x00, 0x00, 0x00, 0x00,
779 : : 0x50, 0x00, 0x00, 0x00,
780 : : 0x00, 0x00, 0x00, 0x00,
781 : :
782 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
783 : : };
784 : :
785 : : /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
786 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = {
787 : : { ICE_MAC_OFOS, 0 },
788 : : { ICE_IPV4_OFOS, 14 },
789 : : { ICE_UDP_OF, 34 },
790 : : { ICE_GTP, 42 },
791 : : { ICE_IPV4_IL, 62 },
792 : : { ICE_UDP_ILOS, 82 },
793 : : { ICE_PROTOCOL_LAST, 0 },
794 : : };
795 : :
796 : : static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = {
797 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
798 : : 0x00, 0x00, 0x00, 0x00,
799 : : 0x00, 0x00, 0x00, 0x00,
800 : : 0x08, 0x00,
801 : :
802 : : 0x45, 0x00, 0x00, 0x4c, /* IP 14 */
803 : : 0x00, 0x00, 0x00, 0x00,
804 : : 0x00, 0x11, 0x00, 0x00,
805 : : 0x00, 0x00, 0x00, 0x00,
806 : : 0x00, 0x00, 0x00, 0x00,
807 : :
808 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
809 : : 0x00, 0x38, 0x00, 0x00,
810 : :
811 : : 0x34, 0xff, 0x00, 0x28, /* GTP-U Header 42 */
812 : : 0x00, 0x00, 0x00, 0x00,
813 : : 0x00, 0x00, 0x00, 0x85,
814 : :
815 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
816 : : 0x00, 0x00, 0x00, 0x00,
817 : :
818 : : 0x45, 0x00, 0x00, 0x1c, /* IP 62 */
819 : : 0x00, 0x00, 0x00, 0x00,
820 : : 0x00, 0x11, 0x00, 0x00,
821 : : 0x00, 0x00, 0x00, 0x00,
822 : : 0x00, 0x00, 0x00, 0x00,
823 : :
824 : : 0x00, 0x00, 0x00, 0x00, /* UDP 82 */
825 : : 0x00, 0x08, 0x00, 0x00,
826 : :
827 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
828 : : };
829 : :
830 : : /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
831 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = {
832 : : { ICE_MAC_OFOS, 0 },
833 : : { ICE_IPV4_OFOS, 14 },
834 : : { ICE_UDP_OF, 34 },
835 : : { ICE_GTP, 42 },
836 : : { ICE_IPV6_IL, 62 },
837 : : { ICE_TCP_IL, 102 },
838 : : { ICE_PROTOCOL_LAST, 0 },
839 : : };
840 : :
841 : : static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = {
842 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
843 : : 0x00, 0x00, 0x00, 0x00,
844 : : 0x00, 0x00, 0x00, 0x00,
845 : : 0x08, 0x00,
846 : :
847 : : 0x45, 0x00, 0x00, 0x6c, /* IP 14 */
848 : : 0x00, 0x00, 0x00, 0x00,
849 : : 0x00, 0x11, 0x00, 0x00,
850 : : 0x00, 0x00, 0x00, 0x00,
851 : : 0x00, 0x00, 0x00, 0x00,
852 : :
853 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
854 : : 0x00, 0x58, 0x00, 0x00,
855 : :
856 : : 0x34, 0xff, 0x00, 0x48, /* GTP-U Header 42 */
857 : : 0x00, 0x00, 0x00, 0x00,
858 : : 0x00, 0x00, 0x00, 0x85,
859 : :
860 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
861 : : 0x00, 0x00, 0x00, 0x00,
862 : :
863 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
864 : : 0x00, 0x14, 0x06, 0x00,
865 : : 0x00, 0x00, 0x00, 0x00,
866 : : 0x00, 0x00, 0x00, 0x00,
867 : : 0x00, 0x00, 0x00, 0x00,
868 : : 0x00, 0x00, 0x00, 0x00,
869 : : 0x00, 0x00, 0x00, 0x00,
870 : : 0x00, 0x00, 0x00, 0x00,
871 : : 0x00, 0x00, 0x00, 0x00,
872 : : 0x00, 0x00, 0x00, 0x00,
873 : :
874 : : 0x00, 0x00, 0x00, 0x00, /* TCP 102 */
875 : : 0x00, 0x00, 0x00, 0x00,
876 : : 0x00, 0x00, 0x00, 0x00,
877 : : 0x50, 0x00, 0x00, 0x00,
878 : : 0x00, 0x00, 0x00, 0x00,
879 : :
880 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
881 : : };
882 : :
883 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_udp_packet_offsets[] = {
884 : : { ICE_MAC_OFOS, 0 },
885 : : { ICE_IPV4_OFOS, 14 },
886 : : { ICE_UDP_OF, 34 },
887 : : { ICE_GTP, 42 },
888 : : { ICE_IPV6_IL, 62 },
889 : : { ICE_UDP_ILOS, 102 },
890 : : { ICE_PROTOCOL_LAST, 0 },
891 : : };
892 : :
893 : : static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = {
894 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
895 : : 0x00, 0x00, 0x00, 0x00,
896 : : 0x00, 0x00, 0x00, 0x00,
897 : : 0x08, 0x00,
898 : :
899 : : 0x45, 0x00, 0x00, 0x60, /* IP 14 */
900 : : 0x00, 0x00, 0x00, 0x00,
901 : : 0x00, 0x11, 0x00, 0x00,
902 : : 0x00, 0x00, 0x00, 0x00,
903 : : 0x00, 0x00, 0x00, 0x00,
904 : :
905 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
906 : : 0x00, 0x4c, 0x00, 0x00,
907 : :
908 : : 0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 42 */
909 : : 0x00, 0x00, 0x00, 0x00,
910 : : 0x00, 0x00, 0x00, 0x85,
911 : :
912 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
913 : : 0x00, 0x00, 0x00, 0x00,
914 : :
915 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
916 : : 0x00, 0x08, 0x11, 0x00,
917 : : 0x00, 0x00, 0x00, 0x00,
918 : : 0x00, 0x00, 0x00, 0x00,
919 : : 0x00, 0x00, 0x00, 0x00,
920 : : 0x00, 0x00, 0x00, 0x00,
921 : : 0x00, 0x00, 0x00, 0x00,
922 : : 0x00, 0x00, 0x00, 0x00,
923 : : 0x00, 0x00, 0x00, 0x00,
924 : : 0x00, 0x00, 0x00, 0x00,
925 : :
926 : : 0x00, 0x00, 0x00, 0x00, /* UDP 102 */
927 : : 0x00, 0x08, 0x00, 0x00,
928 : :
929 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
930 : : };
931 : :
932 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = {
933 : : { ICE_MAC_OFOS, 0 },
934 : : { ICE_IPV6_OFOS, 14 },
935 : : { ICE_UDP_OF, 54 },
936 : : { ICE_GTP, 62 },
937 : : { ICE_IPV4_IL, 82 },
938 : : { ICE_TCP_IL, 102 },
939 : : { ICE_PROTOCOL_LAST, 0 },
940 : : };
941 : :
942 : : static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = {
943 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
944 : : 0x00, 0x00, 0x00, 0x00,
945 : : 0x00, 0x00, 0x00, 0x00,
946 : : 0x86, 0xdd,
947 : :
948 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
949 : : 0x00, 0x44, 0x11, 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 : : 0x00, 0x00, 0x00, 0x00,
958 : :
959 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
960 : : 0x00, 0x44, 0x00, 0x00,
961 : :
962 : : 0x34, 0xff, 0x00, 0x34, /* GTP-U Header 62 */
963 : : 0x00, 0x00, 0x00, 0x00,
964 : : 0x00, 0x00, 0x00, 0x85,
965 : :
966 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
967 : : 0x00, 0x00, 0x00, 0x00,
968 : :
969 : : 0x45, 0x00, 0x00, 0x28, /* IP 82 */
970 : : 0x00, 0x00, 0x00, 0x00,
971 : : 0x00, 0x06, 0x00, 0x00,
972 : : 0x00, 0x00, 0x00, 0x00,
973 : : 0x00, 0x00, 0x00, 0x00,
974 : :
975 : : 0x00, 0x00, 0x00, 0x00, /* TCP 102 */
976 : : 0x00, 0x00, 0x00, 0x00,
977 : : 0x00, 0x00, 0x00, 0x00,
978 : : 0x50, 0x00, 0x00, 0x00,
979 : : 0x00, 0x00, 0x00, 0x00,
980 : :
981 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
982 : : };
983 : :
984 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_udp_packet_offsets[] = {
985 : : { ICE_MAC_OFOS, 0 },
986 : : { ICE_IPV6_OFOS, 14 },
987 : : { ICE_UDP_OF, 54 },
988 : : { ICE_GTP, 62 },
989 : : { ICE_IPV4_IL, 82 },
990 : : { ICE_UDP_ILOS, 102 },
991 : : { ICE_PROTOCOL_LAST, 0 },
992 : : };
993 : :
994 : : static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = {
995 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
996 : : 0x00, 0x00, 0x00, 0x00,
997 : : 0x00, 0x00, 0x00, 0x00,
998 : : 0x86, 0xdd,
999 : :
1000 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1001 : : 0x00, 0x38, 0x11, 0x00,
1002 : : 0x00, 0x00, 0x00, 0x00,
1003 : : 0x00, 0x00, 0x00, 0x00,
1004 : : 0x00, 0x00, 0x00, 0x00,
1005 : : 0x00, 0x00, 0x00, 0x00,
1006 : : 0x00, 0x00, 0x00, 0x00,
1007 : : 0x00, 0x00, 0x00, 0x00,
1008 : : 0x00, 0x00, 0x00, 0x00,
1009 : : 0x00, 0x00, 0x00, 0x00,
1010 : :
1011 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1012 : : 0x00, 0x38, 0x00, 0x00,
1013 : :
1014 : : 0x34, 0xff, 0x00, 0x28, /* GTP-U Header 62 */
1015 : : 0x00, 0x00, 0x00, 0x00,
1016 : : 0x00, 0x00, 0x00, 0x85,
1017 : :
1018 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1019 : : 0x00, 0x00, 0x00, 0x00,
1020 : :
1021 : : 0x45, 0x00, 0x00, 0x1c, /* IP 82 */
1022 : : 0x00, 0x00, 0x00, 0x00,
1023 : : 0x00, 0x11, 0x00, 0x00,
1024 : : 0x00, 0x00, 0x00, 0x00,
1025 : : 0x00, 0x00, 0x00, 0x00,
1026 : :
1027 : : 0x00, 0x00, 0x00, 0x00, /* UDP 102 */
1028 : : 0x00, 0x08, 0x00, 0x00,
1029 : :
1030 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1031 : : };
1032 : :
1033 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = {
1034 : : { ICE_MAC_OFOS, 0 },
1035 : : { ICE_IPV6_OFOS, 14 },
1036 : : { ICE_UDP_OF, 54 },
1037 : : { ICE_GTP, 62 },
1038 : : { ICE_IPV6_IL, 82 },
1039 : : { ICE_TCP_IL, 122 },
1040 : : { ICE_PROTOCOL_LAST, 0 },
1041 : : };
1042 : :
1043 : : static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = {
1044 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
1045 : : 0x00, 0x00, 0x00, 0x00,
1046 : : 0x00, 0x00, 0x00, 0x00,
1047 : : 0x86, 0xdd,
1048 : :
1049 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1050 : : 0x00, 0x58, 0x11, 0x00,
1051 : : 0x00, 0x00, 0x00, 0x00,
1052 : : 0x00, 0x00, 0x00, 0x00,
1053 : : 0x00, 0x00, 0x00, 0x00,
1054 : : 0x00, 0x00, 0x00, 0x00,
1055 : : 0x00, 0x00, 0x00, 0x00,
1056 : : 0x00, 0x00, 0x00, 0x00,
1057 : : 0x00, 0x00, 0x00, 0x00,
1058 : : 0x00, 0x00, 0x00, 0x00,
1059 : :
1060 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1061 : : 0x00, 0x58, 0x00, 0x00,
1062 : :
1063 : : 0x34, 0xff, 0x00, 0x48, /* GTP-U Header 62 */
1064 : : 0x00, 0x00, 0x00, 0x00,
1065 : : 0x00, 0x00, 0x00, 0x85,
1066 : :
1067 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1068 : : 0x00, 0x00, 0x00, 0x00,
1069 : :
1070 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
1071 : : 0x00, 0x14, 0x06, 0x00,
1072 : : 0x00, 0x00, 0x00, 0x00,
1073 : : 0x00, 0x00, 0x00, 0x00,
1074 : : 0x00, 0x00, 0x00, 0x00,
1075 : : 0x00, 0x00, 0x00, 0x00,
1076 : : 0x00, 0x00, 0x00, 0x00,
1077 : : 0x00, 0x00, 0x00, 0x00,
1078 : : 0x00, 0x00, 0x00, 0x00,
1079 : : 0x00, 0x00, 0x00, 0x00,
1080 : :
1081 : : 0x00, 0x00, 0x00, 0x00, /* TCP 122 */
1082 : : 0x00, 0x00, 0x00, 0x00,
1083 : : 0x00, 0x00, 0x00, 0x00,
1084 : : 0x50, 0x00, 0x00, 0x00,
1085 : : 0x00, 0x00, 0x00, 0x00,
1086 : :
1087 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1088 : : };
1089 : :
1090 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_udp_packet_offsets[] = {
1091 : : { ICE_MAC_OFOS, 0 },
1092 : : { ICE_IPV6_OFOS, 14 },
1093 : : { ICE_UDP_OF, 54 },
1094 : : { ICE_GTP, 62 },
1095 : : { ICE_IPV6_IL, 82 },
1096 : : { ICE_UDP_ILOS, 122 },
1097 : : { ICE_PROTOCOL_LAST, 0 },
1098 : : };
1099 : :
1100 : : static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = {
1101 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
1102 : : 0x00, 0x00, 0x00, 0x00,
1103 : : 0x00, 0x00, 0x00, 0x00,
1104 : : 0x86, 0xdd,
1105 : :
1106 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1107 : : 0x00, 0x4c, 0x11, 0x00,
1108 : : 0x00, 0x00, 0x00, 0x00,
1109 : : 0x00, 0x00, 0x00, 0x00,
1110 : : 0x00, 0x00, 0x00, 0x00,
1111 : : 0x00, 0x00, 0x00, 0x00,
1112 : : 0x00, 0x00, 0x00, 0x00,
1113 : : 0x00, 0x00, 0x00, 0x00,
1114 : : 0x00, 0x00, 0x00, 0x00,
1115 : : 0x00, 0x00, 0x00, 0x00,
1116 : :
1117 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1118 : : 0x00, 0x4c, 0x00, 0x00,
1119 : :
1120 : : 0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 62 */
1121 : : 0x00, 0x00, 0x00, 0x00,
1122 : : 0x00, 0x00, 0x00, 0x85,
1123 : :
1124 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1125 : : 0x00, 0x00, 0x00, 0x00,
1126 : :
1127 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
1128 : : 0x00, 0x08, 0x11, 0x00,
1129 : : 0x00, 0x00, 0x00, 0x00,
1130 : : 0x00, 0x00, 0x00, 0x00,
1131 : : 0x00, 0x00, 0x00, 0x00,
1132 : : 0x00, 0x00, 0x00, 0x00,
1133 : : 0x00, 0x00, 0x00, 0x00,
1134 : : 0x00, 0x00, 0x00, 0x00,
1135 : : 0x00, 0x00, 0x00, 0x00,
1136 : : 0x00, 0x00, 0x00, 0x00,
1137 : :
1138 : : 0x00, 0x00, 0x00, 0x00, /* UDP 122 */
1139 : : 0x00, 0x08, 0x00, 0x00,
1140 : :
1141 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1142 : : };
1143 : :
1144 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_packet_offsets[] = {
1145 : : { ICE_MAC_OFOS, 0 },
1146 : : { ICE_IPV4_OFOS, 14 },
1147 : : { ICE_UDP_OF, 34 },
1148 : : { ICE_GTP, 42 },
1149 : : { ICE_IPV4_IL, 62 },
1150 : : { ICE_PROTOCOL_LAST, 0 },
1151 : : };
1152 : :
1153 : : static const u8 dummy_ipv4_gtpu_ipv4_packet[] = {
1154 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1155 : : 0x00, 0x00, 0x00, 0x00,
1156 : : 0x00, 0x00, 0x00, 0x00,
1157 : : 0x08, 0x00,
1158 : :
1159 : : 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
1160 : : 0x00, 0x00, 0x40, 0x00,
1161 : : 0x40, 0x11, 0x00, 0x00,
1162 : : 0x00, 0x00, 0x00, 0x00,
1163 : : 0x00, 0x00, 0x00, 0x00,
1164 : :
1165 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
1166 : : 0x00, 0x00, 0x00, 0x00,
1167 : :
1168 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
1169 : : 0x00, 0x00, 0x00, 0x00,
1170 : : 0x00, 0x00, 0x00, 0x85,
1171 : :
1172 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1173 : : 0x00, 0x00, 0x00, 0x00,
1174 : :
1175 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
1176 : : 0x00, 0x00, 0x40, 0x00,
1177 : : 0x40, 0x00, 0x00, 0x00,
1178 : : 0x00, 0x00, 0x00, 0x00,
1179 : : 0x00, 0x00, 0x00, 0x00,
1180 : : 0x00, 0x00,
1181 : : };
1182 : :
1183 : : static const
1184 : : struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_packet_offsets[] = {
1185 : : { ICE_MAC_OFOS, 0 },
1186 : : { ICE_IPV4_OFOS, 14 },
1187 : : { ICE_UDP_OF, 34 },
1188 : : { ICE_GTP, 42 },
1189 : : { ICE_IPV6_IL, 62 },
1190 : : { ICE_PROTOCOL_LAST, 0 },
1191 : : };
1192 : :
1193 : : static const u8 dummy_ipv4_gtpu_ipv6_packet[] = {
1194 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1195 : : 0x00, 0x00, 0x00, 0x00,
1196 : : 0x00, 0x00, 0x00, 0x00,
1197 : : 0x08, 0x00,
1198 : :
1199 : : 0x45, 0x00, 0x00, 0x58, /* ICE_IPV4_OFOS 14 */
1200 : : 0x00, 0x00, 0x40, 0x00,
1201 : : 0x40, 0x11, 0x00, 0x00,
1202 : : 0x00, 0x00, 0x00, 0x00,
1203 : : 0x00, 0x00, 0x00, 0x00,
1204 : :
1205 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
1206 : : 0x00, 0x00, 0x00, 0x00,
1207 : :
1208 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
1209 : : 0x00, 0x00, 0x00, 0x00,
1210 : : 0x00, 0x00, 0x00, 0x85,
1211 : :
1212 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1213 : : 0x00, 0x00, 0x00, 0x00,
1214 : :
1215 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 62 */
1216 : : 0x00, 0x00, 0x3b, 0x00,
1217 : : 0x00, 0x00, 0x00, 0x00,
1218 : : 0x00, 0x00, 0x00, 0x00,
1219 : : 0x00, 0x00, 0x00, 0x00,
1220 : : 0x00, 0x00, 0x00, 0x00,
1221 : : 0x00, 0x00, 0x00, 0x00,
1222 : : 0x00, 0x00, 0x00, 0x00,
1223 : : 0x00, 0x00, 0x00, 0x00,
1224 : : 0x00, 0x00, 0x00, 0x00,
1225 : :
1226 : : 0x00, 0x00,
1227 : : };
1228 : :
1229 : : static const
1230 : : struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_packet_offsets[] = {
1231 : : { ICE_MAC_OFOS, 0 },
1232 : : { ICE_IPV6_OFOS, 14 },
1233 : : { ICE_UDP_OF, 54 },
1234 : : { ICE_GTP, 62 },
1235 : : { ICE_IPV4_IL, 82 },
1236 : : { ICE_PROTOCOL_LAST, 0 },
1237 : : };
1238 : :
1239 : : static const u8 dummy_ipv6_gtpu_ipv4_packet[] = {
1240 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1241 : : 0x00, 0x00, 0x00, 0x00,
1242 : : 0x00, 0x00, 0x00, 0x00,
1243 : : 0x86, 0xdd,
1244 : :
1245 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1246 : : 0x00, 0x58, 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 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1257 : : 0x00, 0x00, 0x00, 0x00,
1258 : :
1259 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 62 */
1260 : : 0x00, 0x00, 0x00, 0x00,
1261 : : 0x00, 0x00, 0x00, 0x85,
1262 : :
1263 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1264 : : 0x00, 0x00, 0x00, 0x00,
1265 : :
1266 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 82 */
1267 : : 0x00, 0x00, 0x40, 0x00,
1268 : : 0x40, 0x00, 0x00, 0x00,
1269 : : 0x00, 0x00, 0x00, 0x00,
1270 : : 0x00, 0x00, 0x00, 0x00,
1271 : :
1272 : : 0x00, 0x00,
1273 : : };
1274 : :
1275 : : static const
1276 : : struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_packet_offsets[] = {
1277 : : { ICE_MAC_OFOS, 0 },
1278 : : { ICE_IPV6_OFOS, 14 },
1279 : : { ICE_UDP_OF, 54 },
1280 : : { ICE_GTP, 62 },
1281 : : { ICE_IPV6_IL, 82 },
1282 : : { ICE_PROTOCOL_LAST, 0 },
1283 : : };
1284 : :
1285 : : static const u8 dummy_ipv6_gtpu_ipv6_packet[] = {
1286 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1287 : : 0x00, 0x00, 0x00, 0x00,
1288 : : 0x00, 0x00, 0x00, 0x00,
1289 : : 0x86, 0xdd,
1290 : :
1291 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1292 : : 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1293 : : 0x00, 0x00, 0x00, 0x00,
1294 : : 0x00, 0x00, 0x00, 0x00,
1295 : : 0x00, 0x00, 0x00, 0x00,
1296 : : 0x00, 0x00, 0x00, 0x00,
1297 : : 0x00, 0x00, 0x00, 0x00,
1298 : : 0x00, 0x00, 0x00, 0x00,
1299 : : 0x00, 0x00, 0x00, 0x00,
1300 : : 0x00, 0x00, 0x00, 0x00,
1301 : :
1302 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1303 : : 0x00, 0x00, 0x00, 0x00,
1304 : :
1305 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 62 */
1306 : : 0x00, 0x00, 0x00, 0x00,
1307 : : 0x00, 0x00, 0x00, 0x85,
1308 : :
1309 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1310 : : 0x00, 0x00, 0x00, 0x00,
1311 : :
1312 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFIL 82 */
1313 : : 0x00, 0x00, 0x3b, 0x00,
1314 : : 0x00, 0x00, 0x00, 0x00,
1315 : : 0x00, 0x00, 0x00, 0x00,
1316 : : 0x00, 0x00, 0x00, 0x00,
1317 : : 0x00, 0x00, 0x00, 0x00,
1318 : : 0x00, 0x00, 0x00, 0x00,
1319 : : 0x00, 0x00, 0x00, 0x00,
1320 : : 0x00, 0x00, 0x00, 0x00,
1321 : : 0x00, 0x00, 0x00, 0x00,
1322 : :
1323 : : 0x00, 0x00,
1324 : : };
1325 : :
1326 : : static const
1327 : : struct ice_dummy_pkt_offsets dummy_ipv4_gtp_no_pay_packet_offsets[] = {
1328 : : { ICE_MAC_OFOS, 0 },
1329 : : { ICE_IPV4_OFOS, 14 },
1330 : : { ICE_UDP_OF, 34 },
1331 : : { ICE_GTP_NO_PAY, 42 },
1332 : : { ICE_PROTOCOL_LAST, 0 },
1333 : : };
1334 : :
1335 : : static const
1336 : : struct ice_dummy_pkt_offsets dummy_ipv6_gtp_no_pay_packet_offsets[] = {
1337 : : { ICE_MAC_OFOS, 0 },
1338 : : { ICE_IPV6_OFOS, 14 },
1339 : : { ICE_UDP_OF, 54 },
1340 : : { ICE_GTP_NO_PAY, 62 },
1341 : : { ICE_PROTOCOL_LAST, 0 },
1342 : : };
1343 : :
1344 : : static const u8 dummy_ipv6_gtp_packet[] = {
1345 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1346 : : 0x00, 0x00, 0x00, 0x00,
1347 : : 0x00, 0x00, 0x00, 0x00,
1348 : : 0x86, 0xdd,
1349 : :
1350 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1351 : : 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1352 : : 0x00, 0x00, 0x00, 0x00,
1353 : : 0x00, 0x00, 0x00, 0x00,
1354 : : 0x00, 0x00, 0x00, 0x00,
1355 : : 0x00, 0x00, 0x00, 0x00,
1356 : : 0x00, 0x00, 0x00, 0x00,
1357 : : 0x00, 0x00, 0x00, 0x00,
1358 : : 0x00, 0x00, 0x00, 0x00,
1359 : : 0x00, 0x00, 0x00, 0x00,
1360 : :
1361 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1362 : : 0x00, 0x00, 0x00, 0x00,
1363 : :
1364 : : 0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */
1365 : : 0x00, 0x00, 0x00, 0x00,
1366 : :
1367 : : 0x00, 0x00,
1368 : : };
1369 : :
1370 : : static const struct ice_dummy_pkt_offsets dummy_qinq_ipv4_packet_offsets[] = {
1371 : : { ICE_MAC_OFOS, 0 },
1372 : : { ICE_VLAN_EX, 12 },
1373 : : { ICE_VLAN_IN, 16 },
1374 : : { ICE_ETYPE_OL, 20 },
1375 : : { ICE_IPV4_OFOS, 22 },
1376 : : { ICE_PROTOCOL_LAST, 0 },
1377 : : };
1378 : :
1379 : : static const u8 dummy_qinq_ipv4_pkt[] = {
1380 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1381 : : 0x00, 0x00, 0x00, 0x00,
1382 : : 0x00, 0x00, 0x00, 0x00,
1383 : :
1384 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1385 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1386 : : 0x08, 0x00, /* ICE_ETYPE_OL 20 */
1387 : :
1388 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_OFOS 22 */
1389 : : 0x00, 0x01, 0x00, 0x00,
1390 : : 0x00, 0x00, 0x00, 0x00,
1391 : : 0x00, 0x00, 0x00, 0x00,
1392 : : 0x00, 0x00, 0x00, 0x00,
1393 : :
1394 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1395 : : };
1396 : :
1397 : : static const
1398 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv4_udp_packet_offsets[] = {
1399 : : { ICE_MAC_OFOS, 0 },
1400 : : { ICE_VLAN_EX, 12 },
1401 : : { ICE_VLAN_IN, 16 },
1402 : : { ICE_ETYPE_OL, 20 },
1403 : : { ICE_IPV4_OFOS, 22 },
1404 : : { ICE_UDP_ILOS, 42 },
1405 : : { ICE_PROTOCOL_LAST, 0 },
1406 : : };
1407 : :
1408 : : static const u8 dummy_qinq_ipv4_udp_pkt[] = {
1409 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1410 : : 0x00, 0x00, 0x00, 0x00,
1411 : : 0x00, 0x00, 0x00, 0x00,
1412 : :
1413 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1414 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1415 : : 0x08, 0x00, /* ICE_ETYPE_OL 20 */
1416 : :
1417 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
1418 : : 0x00, 0x01, 0x00, 0x00,
1419 : : 0x00, 0x11, 0x00, 0x00,
1420 : : 0x00, 0x00, 0x00, 0x00,
1421 : : 0x00, 0x00, 0x00, 0x00,
1422 : :
1423 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
1424 : : 0x00, 0x08, 0x00, 0x00,
1425 : :
1426 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1427 : : };
1428 : :
1429 : : static const
1430 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv4_tcp_packet_offsets[] = {
1431 : : { ICE_MAC_OFOS, 0 },
1432 : : { ICE_VLAN_EX, 12 },
1433 : : { ICE_VLAN_IN, 16 },
1434 : : { ICE_ETYPE_OL, 20 },
1435 : : { ICE_IPV4_OFOS, 22 },
1436 : : { ICE_TCP_IL, 42 },
1437 : : { ICE_PROTOCOL_LAST, 0 },
1438 : : };
1439 : :
1440 : : static const u8 dummy_qinq_ipv4_tcp_pkt[] = {
1441 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1442 : : 0x00, 0x00, 0x00, 0x00,
1443 : : 0x00, 0x00, 0x00, 0x00,
1444 : :
1445 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1446 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1447 : : 0x08, 0x00, /* ICE_ETYPE_OL 20 */
1448 : :
1449 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */
1450 : : 0x00, 0x01, 0x00, 0x00,
1451 : : 0x00, 0x06, 0x00, 0x00,
1452 : : 0x00, 0x00, 0x00, 0x00,
1453 : : 0x00, 0x00, 0x00, 0x00,
1454 : :
1455 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */
1456 : : 0x00, 0x00, 0x00, 0x00,
1457 : : 0x00, 0x00, 0x00, 0x00,
1458 : : 0x50, 0x00, 0x00, 0x00,
1459 : : 0x00, 0x00, 0x00, 0x00,
1460 : :
1461 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1462 : : };
1463 : :
1464 : : static const struct ice_dummy_pkt_offsets dummy_qinq_ipv6_packet_offsets[] = {
1465 : : { ICE_MAC_OFOS, 0 },
1466 : : { ICE_VLAN_EX, 12 },
1467 : : { ICE_VLAN_IN, 16 },
1468 : : { ICE_ETYPE_OL, 20 },
1469 : : { ICE_IPV6_OFOS, 22 },
1470 : : { ICE_PROTOCOL_LAST, 0 },
1471 : : };
1472 : :
1473 : : static const u8 dummy_qinq_ipv6_pkt[] = {
1474 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1475 : : 0x00, 0x00, 0x00, 0x00,
1476 : : 0x00, 0x00, 0x00, 0x00,
1477 : :
1478 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1479 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1480 : : 0x86, 0xDD, /* ICE_ETYPE_OL 20 */
1481 : :
1482 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1483 : : 0x00, 0x00, 0x3b, 0x00,
1484 : : 0x00, 0x00, 0x00, 0x00,
1485 : : 0x00, 0x00, 0x00, 0x00,
1486 : : 0x00, 0x00, 0x00, 0x00,
1487 : : 0x00, 0x00, 0x00, 0x00,
1488 : : 0x00, 0x00, 0x00, 0x00,
1489 : : 0x00, 0x00, 0x00, 0x00,
1490 : : 0x00, 0x00, 0x00, 0x00,
1491 : : 0x00, 0x00, 0x00, 0x00,
1492 : :
1493 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1494 : : };
1495 : :
1496 : : static const
1497 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv6_udp_packet_offsets[] = {
1498 : : { ICE_MAC_OFOS, 0 },
1499 : : { ICE_VLAN_EX, 12 },
1500 : : { ICE_VLAN_IN, 16 },
1501 : : { ICE_ETYPE_OL, 20 },
1502 : : { ICE_IPV6_OFOS, 22 },
1503 : : { ICE_UDP_ILOS, 62 },
1504 : : { ICE_PROTOCOL_LAST, 0 },
1505 : : };
1506 : :
1507 : : static const u8 dummy_qinq_ipv6_udp_pkt[] = {
1508 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1509 : : 0x00, 0x00, 0x00, 0x00,
1510 : : 0x00, 0x00, 0x00, 0x00,
1511 : :
1512 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1513 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1514 : : 0x86, 0xDD, /* ICE_ETYPE_OL 20 */
1515 : :
1516 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1517 : : 0x00, 0x08, 0x11, 0x00, /* Next header UDP */
1518 : : 0x00, 0x00, 0x00, 0x00,
1519 : : 0x00, 0x00, 0x00, 0x00,
1520 : : 0x00, 0x00, 0x00, 0x00,
1521 : : 0x00, 0x00, 0x00, 0x00,
1522 : : 0x00, 0x00, 0x00, 0x00,
1523 : : 0x00, 0x00, 0x00, 0x00,
1524 : : 0x00, 0x00, 0x00, 0x00,
1525 : : 0x00, 0x00, 0x00, 0x00,
1526 : :
1527 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
1528 : : 0x00, 0x08, 0x00, 0x00,
1529 : :
1530 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1531 : : };
1532 : :
1533 : : static const
1534 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv6_tcp_packet_offsets[] = {
1535 : : { ICE_MAC_OFOS, 0 },
1536 : : { ICE_VLAN_EX, 12 },
1537 : : { ICE_VLAN_IN, 16 },
1538 : : { ICE_ETYPE_OL, 20 },
1539 : : { ICE_IPV6_OFOS, 22 },
1540 : : { ICE_TCP_IL, 62 },
1541 : : { ICE_PROTOCOL_LAST, 0 },
1542 : : };
1543 : :
1544 : : static const u8 dummy_qinq_ipv6_tcp_pkt[] = {
1545 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1546 : : 0x00, 0x00, 0x00, 0x00,
1547 : : 0x00, 0x00, 0x00, 0x00,
1548 : :
1549 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1550 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1551 : : 0x86, 0xDD, /* ICE_ETYPE_OL 20 */
1552 : :
1553 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1554 : : 0x00, 0x14, 0x06, 0x00, /* Next header TCP */
1555 : : 0x00, 0x00, 0x00, 0x00,
1556 : : 0x00, 0x00, 0x00, 0x00,
1557 : : 0x00, 0x00, 0x00, 0x00,
1558 : : 0x00, 0x00, 0x00, 0x00,
1559 : : 0x00, 0x00, 0x00, 0x00,
1560 : : 0x00, 0x00, 0x00, 0x00,
1561 : : 0x00, 0x00, 0x00, 0x00,
1562 : : 0x00, 0x00, 0x00, 0x00,
1563 : :
1564 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */
1565 : : 0x00, 0x00, 0x00, 0x00,
1566 : : 0x00, 0x00, 0x00, 0x00,
1567 : : 0x50, 0x00, 0x00, 0x00,
1568 : : 0x00, 0x00, 0x00, 0x00,
1569 : :
1570 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1571 : : };
1572 : :
1573 : : /* offset info for MAC + MPLS dummy packet */
1574 : : static const struct ice_dummy_pkt_offsets dummy_mpls_packet_offsets[] = {
1575 : : { ICE_MAC_OFOS, 0 },
1576 : : { ICE_ETYPE_OL, 12 },
1577 : : { ICE_PROTOCOL_LAST, 0 },
1578 : : };
1579 : :
1580 : : /* Dummy packet for MAC + MPLS */
1581 : : static const u8 dummy_mpls_packet[] = {
1582 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1583 : : 0x00, 0x00, 0x00, 0x00,
1584 : : 0x00, 0x00, 0x00, 0x00,
1585 : :
1586 : : 0x88, 0x47, /* ICE_ETYPE_OL 12 */
1587 : : 0x00, 0x00, 0x01, 0x00,
1588 : :
1589 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1590 : : };
1591 : :
1592 : : static const struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = {
1593 : : { ICE_MAC_OFOS, 0 },
1594 : : { ICE_IPV4_OFOS, 14 },
1595 : : { ICE_UDP_OF, 34 },
1596 : : { ICE_GTP, 42 },
1597 : : { ICE_PROTOCOL_LAST, 0 },
1598 : : };
1599 : :
1600 : : static const u8 dummy_udp_gtp_packet[] = {
1601 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1602 : : 0x00, 0x00, 0x00, 0x00,
1603 : : 0x00, 0x00, 0x00, 0x00,
1604 : : 0x08, 0x00,
1605 : :
1606 : : 0x45, 0x00, 0x00, 0x30, /* ICE_IPV4_OFOS 14 */
1607 : : 0x00, 0x00, 0x00, 0x00,
1608 : : 0x00, 0x11, 0x00, 0x00,
1609 : : 0x00, 0x00, 0x00, 0x00,
1610 : : 0x00, 0x00, 0x00, 0x00,
1611 : :
1612 : : 0x00, 0x00, 0x08, 0x68, /* ICE_UDP_OF 34 */
1613 : : 0x00, 0x1c, 0x00, 0x00,
1614 : :
1615 : : 0x34, 0xff, 0x00, 0x0c, /* ICE_GTP 42 */
1616 : : 0x00, 0x00, 0x00, 0x00,
1617 : : 0x00, 0x00, 0x00, 0x85,
1618 : :
1619 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1620 : : 0x00, 0x00, 0x00, 0x00,
1621 : : };
1622 : :
1623 : : static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_offsets[] = {
1624 : : { ICE_MAC_OFOS, 0 },
1625 : : { ICE_VLAN_OFOS, 12 },
1626 : : { ICE_ETYPE_OL, 16 },
1627 : : { ICE_PPPOE, 18 },
1628 : : { ICE_PROTOCOL_LAST, 0 },
1629 : : };
1630 : :
1631 : : static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv4_offsets[] = {
1632 : : { ICE_MAC_OFOS, 0 },
1633 : : { ICE_VLAN_OFOS, 12 },
1634 : : { ICE_ETYPE_OL, 16 },
1635 : : { ICE_PPPOE, 18 },
1636 : : { ICE_IPV4_OFOS, 26 },
1637 : : { ICE_PROTOCOL_LAST, 0 },
1638 : : };
1639 : :
1640 : : static const u8 dummy_pppoe_ipv4_packet[] = {
1641 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1642 : : 0x00, 0x00, 0x00, 0x00,
1643 : : 0x00, 0x00, 0x00, 0x00,
1644 : :
1645 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1646 : :
1647 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1648 : :
1649 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1650 : : 0x00, 0x16,
1651 : :
1652 : : 0x00, 0x21, /* PPP Link Layer 24 */
1653 : :
1654 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 26 */
1655 : : 0x00, 0x00, 0x00, 0x00,
1656 : : 0x00, 0x00, 0x00, 0x00,
1657 : : 0x00, 0x00, 0x00, 0x00,
1658 : : 0x00, 0x00, 0x00, 0x00,
1659 : :
1660 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1661 : : };
1662 : :
1663 : : static const
1664 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_tcp_packet_offsets[] = {
1665 : : { ICE_MAC_OFOS, 0 },
1666 : : { ICE_VLAN_OFOS, 12 },
1667 : : { ICE_ETYPE_OL, 16 },
1668 : : { ICE_PPPOE, 18 },
1669 : : { ICE_IPV4_OFOS, 26 },
1670 : : { ICE_TCP_IL, 46 },
1671 : : { ICE_PROTOCOL_LAST, 0 },
1672 : : };
1673 : :
1674 : : static const u8 dummy_pppoe_ipv4_tcp_packet[] = {
1675 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1676 : : 0x00, 0x00, 0x00, 0x00,
1677 : : 0x00, 0x00, 0x00, 0x00,
1678 : :
1679 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1680 : :
1681 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1682 : :
1683 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1684 : : 0x00, 0x16,
1685 : :
1686 : : 0x00, 0x21, /* PPP Link Layer 24 */
1687 : :
1688 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 26 */
1689 : : 0x00, 0x01, 0x00, 0x00,
1690 : : 0x00, 0x06, 0x00, 0x00,
1691 : : 0x00, 0x00, 0x00, 0x00,
1692 : : 0x00, 0x00, 0x00, 0x00,
1693 : :
1694 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 46 */
1695 : : 0x00, 0x00, 0x00, 0x00,
1696 : : 0x00, 0x00, 0x00, 0x00,
1697 : : 0x50, 0x00, 0x00, 0x00,
1698 : : 0x00, 0x00, 0x00, 0x00,
1699 : :
1700 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1701 : : };
1702 : :
1703 : : static const
1704 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_udp_packet_offsets[] = {
1705 : : { ICE_MAC_OFOS, 0 },
1706 : : { ICE_VLAN_OFOS, 12 },
1707 : : { ICE_ETYPE_OL, 16 },
1708 : : { ICE_PPPOE, 18 },
1709 : : { ICE_IPV4_OFOS, 26 },
1710 : : { ICE_UDP_ILOS, 46 },
1711 : : { ICE_PROTOCOL_LAST, 0 },
1712 : : };
1713 : :
1714 : : static const u8 dummy_pppoe_ipv4_udp_packet[] = {
1715 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1716 : : 0x00, 0x00, 0x00, 0x00,
1717 : : 0x00, 0x00, 0x00, 0x00,
1718 : :
1719 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1720 : :
1721 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1722 : :
1723 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1724 : : 0x00, 0x16,
1725 : :
1726 : : 0x00, 0x21, /* PPP Link Layer 24 */
1727 : :
1728 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 26 */
1729 : : 0x00, 0x01, 0x00, 0x00,
1730 : : 0x00, 0x11, 0x00, 0x00,
1731 : : 0x00, 0x00, 0x00, 0x00,
1732 : : 0x00, 0x00, 0x00, 0x00,
1733 : :
1734 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 46 */
1735 : : 0x00, 0x08, 0x00, 0x00,
1736 : :
1737 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1738 : : };
1739 : :
1740 : : static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_offsets[] = {
1741 : : { ICE_MAC_OFOS, 0 },
1742 : : { ICE_VLAN_OFOS, 12 },
1743 : : { ICE_ETYPE_OL, 16 },
1744 : : { ICE_PPPOE, 18 },
1745 : : { ICE_IPV6_OFOS, 26 },
1746 : : { ICE_PROTOCOL_LAST, 0 },
1747 : : };
1748 : :
1749 : : static const u8 dummy_pppoe_ipv6_packet[] = {
1750 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1751 : : 0x00, 0x00, 0x00, 0x00,
1752 : : 0x00, 0x00, 0x00, 0x00,
1753 : :
1754 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1755 : :
1756 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1757 : :
1758 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1759 : : 0x00, 0x2a,
1760 : :
1761 : : 0x00, 0x57, /* PPP Link Layer 24 */
1762 : :
1763 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1764 : : 0x00, 0x00, 0x3b, 0x00,
1765 : : 0x00, 0x00, 0x00, 0x00,
1766 : : 0x00, 0x00, 0x00, 0x00,
1767 : : 0x00, 0x00, 0x00, 0x00,
1768 : : 0x00, 0x00, 0x00, 0x00,
1769 : : 0x00, 0x00, 0x00, 0x00,
1770 : : 0x00, 0x00, 0x00, 0x00,
1771 : : 0x00, 0x00, 0x00, 0x00,
1772 : : 0x00, 0x00, 0x00, 0x00,
1773 : :
1774 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1775 : : };
1776 : :
1777 : : static const
1778 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv6_tcp_packet_offsets[] = {
1779 : : { ICE_MAC_OFOS, 0 },
1780 : : { ICE_VLAN_OFOS, 12 },
1781 : : { ICE_ETYPE_OL, 16 },
1782 : : { ICE_PPPOE, 18 },
1783 : : { ICE_IPV6_OFOS, 26 },
1784 : : { ICE_TCP_IL, 66 },
1785 : : { ICE_PROTOCOL_LAST, 0 },
1786 : : };
1787 : :
1788 : : static const u8 dummy_pppoe_ipv6_tcp_packet[] = {
1789 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1790 : : 0x00, 0x00, 0x00, 0x00,
1791 : : 0x00, 0x00, 0x00, 0x00,
1792 : :
1793 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1794 : :
1795 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1796 : :
1797 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1798 : : 0x00, 0x2a,
1799 : :
1800 : : 0x00, 0x57, /* PPP Link Layer 24 */
1801 : :
1802 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1803 : : 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
1804 : : 0x00, 0x00, 0x00, 0x00,
1805 : : 0x00, 0x00, 0x00, 0x00,
1806 : : 0x00, 0x00, 0x00, 0x00,
1807 : : 0x00, 0x00, 0x00, 0x00,
1808 : : 0x00, 0x00, 0x00, 0x00,
1809 : : 0x00, 0x00, 0x00, 0x00,
1810 : : 0x00, 0x00, 0x00, 0x00,
1811 : : 0x00, 0x00, 0x00, 0x00,
1812 : :
1813 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 66 */
1814 : : 0x00, 0x00, 0x00, 0x00,
1815 : : 0x00, 0x00, 0x00, 0x00,
1816 : : 0x50, 0x00, 0x00, 0x00,
1817 : : 0x00, 0x00, 0x00, 0x00,
1818 : :
1819 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1820 : : };
1821 : :
1822 : : static const
1823 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv6_udp_packet_offsets[] = {
1824 : : { ICE_MAC_OFOS, 0 },
1825 : : { ICE_VLAN_OFOS, 12 },
1826 : : { ICE_ETYPE_OL, 16 },
1827 : : { ICE_PPPOE, 18 },
1828 : : { ICE_IPV6_OFOS, 26 },
1829 : : { ICE_UDP_ILOS, 66 },
1830 : : { ICE_PROTOCOL_LAST, 0 },
1831 : : };
1832 : :
1833 : : static const u8 dummy_pppoe_ipv6_udp_packet[] = {
1834 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1835 : : 0x00, 0x00, 0x00, 0x00,
1836 : : 0x00, 0x00, 0x00, 0x00,
1837 : :
1838 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1839 : :
1840 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1841 : :
1842 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1843 : : 0x00, 0x2a,
1844 : :
1845 : : 0x00, 0x57, /* PPP Link Layer 24 */
1846 : :
1847 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1848 : : 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
1849 : : 0x00, 0x00, 0x00, 0x00,
1850 : : 0x00, 0x00, 0x00, 0x00,
1851 : : 0x00, 0x00, 0x00, 0x00,
1852 : : 0x00, 0x00, 0x00, 0x00,
1853 : : 0x00, 0x00, 0x00, 0x00,
1854 : : 0x00, 0x00, 0x00, 0x00,
1855 : : 0x00, 0x00, 0x00, 0x00,
1856 : : 0x00, 0x00, 0x00, 0x00,
1857 : :
1858 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 66 */
1859 : : 0x00, 0x08, 0x00, 0x00,
1860 : :
1861 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1862 : : };
1863 : :
1864 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_esp_packet_offsets[] = {
1865 : : { ICE_MAC_OFOS, 0 },
1866 : : { ICE_IPV4_OFOS, 14 },
1867 : : { ICE_ESP, 34 },
1868 : : { ICE_PROTOCOL_LAST, 0 },
1869 : : };
1870 : :
1871 : : static const u8 dummy_ipv4_esp_pkt[] = {
1872 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1873 : : 0x00, 0x00, 0x00, 0x00,
1874 : : 0x00, 0x00, 0x00, 0x00,
1875 : : 0x08, 0x00,
1876 : :
1877 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 14 */
1878 : : 0x00, 0x00, 0x40, 0x00,
1879 : : 0x40, 0x32, 0x00, 0x00,
1880 : : 0x00, 0x00, 0x00, 0x00,
1881 : : 0x00, 0x00, 0x00, 0x00,
1882 : :
1883 : : 0x00, 0x00, 0x00, 0x00, /* ICE_ESP 34 */
1884 : : 0x00, 0x00, 0x00, 0x00,
1885 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1886 : : };
1887 : :
1888 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_esp_packet_offsets[] = {
1889 : : { ICE_MAC_OFOS, 0 },
1890 : : { ICE_IPV6_OFOS, 14 },
1891 : : { ICE_ESP, 54 },
1892 : : { ICE_PROTOCOL_LAST, 0 },
1893 : : };
1894 : :
1895 : : static const u8 dummy_ipv6_esp_pkt[] = {
1896 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1897 : : 0x00, 0x00, 0x00, 0x00,
1898 : : 0x00, 0x00, 0x00, 0x00,
1899 : : 0x86, 0xDD,
1900 : :
1901 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1902 : : 0x00, 0x08, 0x32, 0x00, /* Next header ESP */
1903 : : 0x00, 0x00, 0x00, 0x00,
1904 : : 0x00, 0x00, 0x00, 0x00,
1905 : : 0x00, 0x00, 0x00, 0x00,
1906 : : 0x00, 0x00, 0x00, 0x00,
1907 : : 0x00, 0x00, 0x00, 0x00,
1908 : : 0x00, 0x00, 0x00, 0x00,
1909 : : 0x00, 0x00, 0x00, 0x00,
1910 : : 0x00, 0x00, 0x00, 0x00,
1911 : :
1912 : : 0x00, 0x00, 0x00, 0x00, /* ICE_ESP 54 */
1913 : : 0x00, 0x00, 0x00, 0x00,
1914 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1915 : : };
1916 : :
1917 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_ah_packet_offsets[] = {
1918 : : { ICE_MAC_OFOS, 0 },
1919 : : { ICE_IPV4_OFOS, 14 },
1920 : : { ICE_AH, 34 },
1921 : : { ICE_PROTOCOL_LAST, 0 },
1922 : : };
1923 : :
1924 : : static const u8 dummy_ipv4_ah_pkt[] = {
1925 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1926 : : 0x00, 0x00, 0x00, 0x00,
1927 : : 0x00, 0x00, 0x00, 0x00,
1928 : : 0x08, 0x00,
1929 : :
1930 : : 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1931 : : 0x00, 0x00, 0x40, 0x00,
1932 : : 0x40, 0x33, 0x00, 0x00,
1933 : : 0x00, 0x00, 0x00, 0x00,
1934 : : 0x00, 0x00, 0x00, 0x00,
1935 : :
1936 : : 0x00, 0x00, 0x00, 0x00, /* ICE_AH 34 */
1937 : : 0x00, 0x00, 0x00, 0x00,
1938 : : 0x00, 0x00, 0x00, 0x00,
1939 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1940 : : };
1941 : :
1942 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_ah_packet_offsets[] = {
1943 : : { ICE_MAC_OFOS, 0 },
1944 : : { ICE_IPV6_OFOS, 14 },
1945 : : { ICE_AH, 54 },
1946 : : { ICE_PROTOCOL_LAST, 0 },
1947 : : };
1948 : :
1949 : : static const u8 dummy_ipv6_ah_pkt[] = {
1950 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1951 : : 0x00, 0x00, 0x00, 0x00,
1952 : : 0x00, 0x00, 0x00, 0x00,
1953 : : 0x86, 0xDD,
1954 : :
1955 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1956 : : 0x00, 0x0c, 0x33, 0x00, /* Next header AH */
1957 : : 0x00, 0x00, 0x00, 0x00,
1958 : : 0x00, 0x00, 0x00, 0x00,
1959 : : 0x00, 0x00, 0x00, 0x00,
1960 : : 0x00, 0x00, 0x00, 0x00,
1961 : : 0x00, 0x00, 0x00, 0x00,
1962 : : 0x00, 0x00, 0x00, 0x00,
1963 : : 0x00, 0x00, 0x00, 0x00,
1964 : : 0x00, 0x00, 0x00, 0x00,
1965 : :
1966 : : 0x00, 0x00, 0x00, 0x00, /* ICE_AH 54 */
1967 : : 0x00, 0x00, 0x00, 0x00,
1968 : : 0x00, 0x00, 0x00, 0x00,
1969 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1970 : : };
1971 : :
1972 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_nat_packet_offsets[] = {
1973 : : { ICE_MAC_OFOS, 0 },
1974 : : { ICE_IPV4_OFOS, 14 },
1975 : : { ICE_UDP_ILOS, 34 },
1976 : : { ICE_NAT_T, 42 },
1977 : : { ICE_PROTOCOL_LAST, 0 },
1978 : : };
1979 : :
1980 : : static const u8 dummy_ipv4_nat_pkt[] = {
1981 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1982 : : 0x00, 0x00, 0x00, 0x00,
1983 : : 0x00, 0x00, 0x00, 0x00,
1984 : : 0x08, 0x00,
1985 : :
1986 : : 0x45, 0x00, 0x00, 0x24, /* ICE_IPV4_IL 14 */
1987 : : 0x00, 0x00, 0x40, 0x00,
1988 : : 0x40, 0x11, 0x00, 0x00,
1989 : : 0x00, 0x00, 0x00, 0x00,
1990 : : 0x00, 0x00, 0x00, 0x00,
1991 : :
1992 : : 0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 34 */
1993 : : 0x00, 0x00, 0x00, 0x00,
1994 : :
1995 : : 0x00, 0x00, 0x00, 0x00,
1996 : : 0x00, 0x00, 0x00, 0x00,
1997 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1998 : : };
1999 : :
2000 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_nat_packet_offsets[] = {
2001 : : { ICE_MAC_OFOS, 0 },
2002 : : { ICE_IPV6_OFOS, 14 },
2003 : : { ICE_UDP_ILOS, 54 },
2004 : : { ICE_NAT_T, 62 },
2005 : : { ICE_PROTOCOL_LAST, 0 },
2006 : : };
2007 : :
2008 : : static const u8 dummy_ipv6_nat_pkt[] = {
2009 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2010 : : 0x00, 0x00, 0x00, 0x00,
2011 : : 0x00, 0x00, 0x00, 0x00,
2012 : : 0x86, 0xDD,
2013 : :
2014 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
2015 : : 0x00, 0x10, 0x11, 0x00, /* Next header NAT_T */
2016 : : 0x00, 0x00, 0x00, 0x00,
2017 : : 0x00, 0x00, 0x00, 0x00,
2018 : : 0x00, 0x00, 0x00, 0x00,
2019 : : 0x00, 0x00, 0x00, 0x00,
2020 : : 0x00, 0x00, 0x00, 0x00,
2021 : : 0x00, 0x00, 0x00, 0x00,
2022 : : 0x00, 0x00, 0x00, 0x00,
2023 : : 0x00, 0x00, 0x00, 0x00,
2024 : :
2025 : : 0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 54 */
2026 : : 0x00, 0x00, 0x00, 0x00,
2027 : :
2028 : : 0x00, 0x00, 0x00, 0x00,
2029 : : 0x00, 0x00, 0x00, 0x00,
2030 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2031 : :
2032 : : };
2033 : :
2034 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_l2tpv3_packet_offsets[] = {
2035 : : { ICE_MAC_OFOS, 0 },
2036 : : { ICE_IPV4_OFOS, 14 },
2037 : : { ICE_L2TPV3, 34 },
2038 : : { ICE_PROTOCOL_LAST, 0 },
2039 : : };
2040 : :
2041 : : static const u8 dummy_ipv4_l2tpv3_pkt[] = {
2042 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2043 : : 0x00, 0x00, 0x00, 0x00,
2044 : : 0x00, 0x00, 0x00, 0x00,
2045 : : 0x08, 0x00,
2046 : :
2047 : : 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
2048 : : 0x00, 0x00, 0x40, 0x00,
2049 : : 0x40, 0x73, 0x00, 0x00,
2050 : : 0x00, 0x00, 0x00, 0x00,
2051 : : 0x00, 0x00, 0x00, 0x00,
2052 : :
2053 : : 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
2054 : : 0x00, 0x00, 0x00, 0x00,
2055 : : 0x00, 0x00, 0x00, 0x00,
2056 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2057 : : };
2058 : :
2059 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_l2tpv3_packet_offsets[] = {
2060 : : { ICE_MAC_OFOS, 0 },
2061 : : { ICE_IPV6_OFOS, 14 },
2062 : : { ICE_L2TPV3, 54 },
2063 : : { ICE_PROTOCOL_LAST, 0 },
2064 : : };
2065 : :
2066 : : static const u8 dummy_ipv6_l2tpv3_pkt[] = {
2067 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2068 : : 0x00, 0x00, 0x00, 0x00,
2069 : : 0x00, 0x00, 0x00, 0x00,
2070 : : 0x86, 0xDD,
2071 : :
2072 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
2073 : : 0x00, 0x0c, 0x73, 0x40,
2074 : : 0x00, 0x00, 0x00, 0x00,
2075 : : 0x00, 0x00, 0x00, 0x00,
2076 : : 0x00, 0x00, 0x00, 0x00,
2077 : : 0x00, 0x00, 0x00, 0x00,
2078 : : 0x00, 0x00, 0x00, 0x00,
2079 : : 0x00, 0x00, 0x00, 0x00,
2080 : : 0x00, 0x00, 0x00, 0x00,
2081 : : 0x00, 0x00, 0x00, 0x00,
2082 : :
2083 : : 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
2084 : : 0x00, 0x00, 0x00, 0x00,
2085 : : 0x00, 0x00, 0x00, 0x00,
2086 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2087 : : };
2088 : :
2089 : : static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = {
2090 : : { ICE_MAC_OFOS, 0 },
2091 : : { ICE_VLAN_EX, 12 },
2092 : : { ICE_VLAN_IN, 16 },
2093 : : { ICE_ETYPE_OL, 20 },
2094 : : { ICE_PPPOE, 22 },
2095 : : { ICE_PROTOCOL_LAST, 0 },
2096 : : };
2097 : :
2098 : : static const
2099 : : struct ice_dummy_pkt_offsets dummy_qinq_pppoe_ipv4_packet_offsets[] = {
2100 : : { ICE_MAC_OFOS, 0 },
2101 : : { ICE_VLAN_EX, 12 },
2102 : : { ICE_VLAN_IN, 16 },
2103 : : { ICE_ETYPE_OL, 20 },
2104 : : { ICE_PPPOE, 22 },
2105 : : { ICE_IPV4_OFOS, 30 },
2106 : : { ICE_PROTOCOL_LAST, 0 },
2107 : : };
2108 : :
2109 : : static const u8 dummy_qinq_pppoe_ipv4_pkt[] = {
2110 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2111 : : 0x00, 0x00, 0x00, 0x00,
2112 : : 0x00, 0x00, 0x00, 0x00,
2113 : :
2114 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
2115 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
2116 : : 0x88, 0x64, /* ICE_ETYPE_OL 20 */
2117 : :
2118 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
2119 : : 0x00, 0x16,
2120 : :
2121 : : 0x00, 0x21, /* PPP Link Layer 28 */
2122 : :
2123 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_OFOS 30 */
2124 : : 0x00, 0x00, 0x00, 0x00,
2125 : : 0x00, 0x00, 0x00, 0x00,
2126 : : 0x00, 0x00, 0x00, 0x00,
2127 : : 0x00, 0x00, 0x00, 0x00,
2128 : :
2129 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
2130 : : };
2131 : :
2132 : : static const
2133 : : struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_ipv6_offsets[] = {
2134 : : { ICE_MAC_OFOS, 0 },
2135 : : { ICE_VLAN_EX, 12 },
2136 : : { ICE_VLAN_IN, 16 },
2137 : : { ICE_ETYPE_OL, 20 },
2138 : : { ICE_PPPOE, 22 },
2139 : : { ICE_IPV6_OFOS, 30 },
2140 : : { ICE_PROTOCOL_LAST, 0 },
2141 : : };
2142 : :
2143 : : static const u8 dummy_qinq_pppoe_ipv6_packet[] = {
2144 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2145 : : 0x00, 0x00, 0x00, 0x00,
2146 : : 0x00, 0x00, 0x00, 0x00,
2147 : :
2148 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
2149 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
2150 : : 0x88, 0x64, /* ICE_ETYPE_OL 20 */
2151 : :
2152 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
2153 : : 0x00, 0x2a,
2154 : :
2155 : : 0x00, 0x57, /* PPP Link Layer 28*/
2156 : :
2157 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 30 */
2158 : : 0x00, 0x00, 0x3b, 0x00,
2159 : : 0x00, 0x00, 0x00, 0x00,
2160 : : 0x00, 0x00, 0x00, 0x00,
2161 : : 0x00, 0x00, 0x00, 0x00,
2162 : : 0x00, 0x00, 0x00, 0x00,
2163 : : 0x00, 0x00, 0x00, 0x00,
2164 : : 0x00, 0x00, 0x00, 0x00,
2165 : : 0x00, 0x00, 0x00, 0x00,
2166 : : 0x00, 0x00, 0x00, 0x00,
2167 : :
2168 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2169 : : };
2170 : :
2171 : : /* this is a recipe to profile association bitmap */
2172 : : static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES],
2173 : : ICE_MAX_NUM_PROFILES);
2174 : :
2175 : : /* this is a profile to recipe association bitmap */
2176 : : static ice_declare_bitmap(profile_to_recipe[ICE_MAX_NUM_PROFILES],
2177 : : ICE_MAX_NUM_RECIPES);
2178 : :
2179 : : static void ice_get_recp_to_prof_map(struct ice_hw *hw);
2180 : :
2181 : : /**
2182 : : * ice_collect_result_idx - copy result index values
2183 : : * @buf: buffer that contains the result index
2184 : : * @recp: the recipe struct to copy data into
2185 : : */
2186 : : static void ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
2187 : : struct ice_sw_recipe *recp)
2188 : : {
2189 [ # # ]: 0 : if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2190 : 0 : ice_set_bit(buf->content.result_indx &
2191 : 0 : ~ICE_AQ_RECIPE_RESULT_EN, recp->res_idxs);
2192 : : }
2193 : :
2194 : : static struct ice_prof_type_entry ice_prof_type_tbl[ICE_GTPU_PROFILE] = {
2195 : : { ICE_PROFID_IPV4_GTPU_IPV4_OTHER, ICE_SW_TUN_IPV4_GTPU_IPV4},
2196 : : { ICE_PROFID_IPV4_GTPU_IPV4_UDP, ICE_SW_TUN_IPV4_GTPU_IPV4_UDP},
2197 : : { ICE_PROFID_IPV4_GTPU_IPV4_TCP, ICE_SW_TUN_IPV4_GTPU_IPV4_TCP},
2198 : : { ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, ICE_SW_TUN_IPV4_GTPU_EH_IPV4},
2199 : : { ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP},
2200 : : { ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP},
2201 : : { ICE_PROFID_IPV4_GTPU_IPV6_OTHER, ICE_SW_TUN_IPV4_GTPU_IPV6},
2202 : : { ICE_PROFID_IPV4_GTPU_IPV6_UDP, ICE_SW_TUN_IPV4_GTPU_IPV6_UDP},
2203 : : { ICE_PROFID_IPV4_GTPU_IPV6_TCP, ICE_SW_TUN_IPV4_GTPU_IPV6_TCP},
2204 : : { ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, ICE_SW_TUN_IPV4_GTPU_EH_IPV6},
2205 : : { ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP},
2206 : : { ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP},
2207 : : { ICE_PROFID_IPV6_GTPU_IPV4_OTHER, ICE_SW_TUN_IPV6_GTPU_IPV4},
2208 : : { ICE_PROFID_IPV6_GTPU_IPV4_UDP, ICE_SW_TUN_IPV6_GTPU_IPV4_UDP},
2209 : : { ICE_PROFID_IPV6_GTPU_IPV4_TCP, ICE_SW_TUN_IPV6_GTPU_IPV4_TCP},
2210 : : { ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, ICE_SW_TUN_IPV6_GTPU_EH_IPV4},
2211 : : { ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP},
2212 : : { ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP},
2213 : : { ICE_PROFID_IPV6_GTPU_IPV6_OTHER, ICE_SW_TUN_IPV6_GTPU_IPV6},
2214 : : { ICE_PROFID_IPV6_GTPU_IPV6_UDP, ICE_SW_TUN_IPV6_GTPU_IPV6_UDP},
2215 : : { ICE_PROFID_IPV6_GTPU_IPV6_TCP, ICE_SW_TUN_IPV6_GTPU_IPV6_TCP},
2216 : : { ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, ICE_SW_TUN_IPV6_GTPU_EH_IPV6},
2217 : : { ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP},
2218 : : { ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP},
2219 : : };
2220 : :
2221 : : /**
2222 : : * ice_get_tun_type_for_recipe - get tunnel type for the recipe
2223 : : * @rid: recipe ID that we are populating
2224 : : */
2225 : 0 : static enum ice_sw_tunnel_type ice_get_tun_type_for_recipe(u8 rid, bool vlan)
2226 : : {
2227 : 0 : u8 vxlan_profile[12] = {10, 11, 12, 16, 17, 18, 22, 23, 24, 25, 26, 27};
2228 : 0 : u8 gre_profile[12] = {13, 14, 15, 19, 20, 21, 28, 29, 30, 31, 32, 33};
2229 : 0 : u8 pppoe_profile[7] = {34, 35, 36, 37, 38, 39, 40};
2230 : 0 : u8 non_tun_profile[6] = {4, 5, 6, 7, 8, 9};
2231 : : enum ice_sw_tunnel_type tun_type;
2232 : : u16 i, j, k, profile_num = 0;
2233 : : bool non_tun_valid = false;
2234 : : bool pppoe_valid = false;
2235 : : bool vxlan_valid = false;
2236 : : bool gre_valid = false;
2237 : : bool gtp_valid = false;
2238 : : bool flag_valid = false;
2239 : :
2240 [ # # ]: 0 : for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) {
2241 [ # # ]: 0 : if (!ice_is_bit_set(recipe_to_profile[rid], j))
2242 : 0 : continue;
2243 : : else
2244 : 0 : profile_num++;
2245 : :
2246 [ # # ]: 0 : for (i = 0; i < 12; i++) {
2247 [ # # ]: 0 : if (gre_profile[i] == j)
2248 : : gre_valid = true;
2249 : : }
2250 : :
2251 [ # # ]: 0 : for (i = 0; i < 12; i++) {
2252 [ # # ]: 0 : if (vxlan_profile[i] == j)
2253 : : vxlan_valid = true;
2254 : : }
2255 : :
2256 [ # # ]: 0 : for (i = 0; i < 7; i++) {
2257 [ # # ]: 0 : if (pppoe_profile[i] == j)
2258 : : pppoe_valid = true;
2259 : : }
2260 : :
2261 [ # # ]: 0 : for (i = 0; i < 6; i++) {
2262 [ # # ]: 0 : if (non_tun_profile[i] == j)
2263 : : non_tun_valid = true;
2264 : : }
2265 : :
2266 [ # # ]: 0 : if (j >= ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER &&
2267 : : j <= ICE_PROFID_IPV6_GTPU_IPV6_TCP)
2268 : : gtp_valid = true;
2269 : :
2270 : 0 : if ((j >= ICE_PROFID_IPV4_ESP &&
2271 : 0 : j <= ICE_PROFID_IPV6_PFCP_SESSION) ||
2272 [ # # ]: 0 : (j >= ICE_PROFID_IPV4_GTPC_TEID &&
2273 : : j <= ICE_PROFID_IPV6_GTPU_TEID))
2274 : : flag_valid = true;
2275 : : }
2276 : :
2277 [ # # ]: 0 : if (!non_tun_valid && vxlan_valid)
2278 : : tun_type = ICE_SW_TUN_VXLAN;
2279 [ # # ]: 0 : else if (!non_tun_valid && gre_valid)
2280 : : tun_type = ICE_SW_TUN_NVGRE;
2281 [ # # ]: 0 : else if (!non_tun_valid && pppoe_valid)
2282 : : tun_type = ICE_SW_TUN_PPPOE;
2283 [ # # ]: 0 : else if (!non_tun_valid && gtp_valid)
2284 : : tun_type = ICE_SW_TUN_GTP;
2285 [ # # ]: 0 : else if (non_tun_valid &&
2286 [ # # ]: 0 : (vxlan_valid || gre_valid || gtp_valid || pppoe_valid))
2287 : : tun_type = ICE_SW_TUN_AND_NON_TUN;
2288 [ # # ]: 0 : else if (non_tun_valid && !vxlan_valid && !gre_valid && !gtp_valid &&
2289 : : !pppoe_valid)
2290 : : tun_type = ICE_NON_TUN;
2291 : : else
2292 : : tun_type = ICE_NON_TUN;
2293 : :
2294 [ # # ]: 0 : if (profile_num > 1 && tun_type == ICE_SW_TUN_PPPOE) {
2295 [ # # ]: 0 : i = ice_is_bit_set(recipe_to_profile[rid],
2296 : : ICE_PROFID_PPPOE_IPV4_OTHER);
2297 : : j = ice_is_bit_set(recipe_to_profile[rid],
2298 : : ICE_PROFID_PPPOE_IPV6_OTHER);
2299 [ # # ]: 0 : if (i && !j)
2300 : : tun_type = ICE_SW_TUN_PPPOE_IPV4;
2301 [ # # ]: 0 : else if (!i && j)
2302 : : tun_type = ICE_SW_TUN_PPPOE_IPV6;
2303 : : }
2304 : :
2305 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_GTP) {
2306 [ # # ]: 0 : for (k = 0; k < ARRAY_SIZE(ice_prof_type_tbl); k++)
2307 : 0 : if (ice_is_bit_set(recipe_to_profile[rid],
2308 [ # # ]: 0 : ice_prof_type_tbl[k].prof_id)) {
2309 : 0 : tun_type = ice_prof_type_tbl[k].type;
2310 : 0 : break;
2311 : : }
2312 : : }
2313 : :
2314 [ # # # # ]: 0 : if (profile_num == 1 && (flag_valid || non_tun_valid || pppoe_valid)) {
2315 [ # # ]: 0 : for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) {
2316 [ # # ]: 0 : if (ice_is_bit_set(recipe_to_profile[rid], j)) {
2317 [ # # # # : 0 : switch (j) {
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
2318 : 0 : case ICE_PROFID_IPV4_TCP:
2319 : : tun_type = ICE_SW_IPV4_TCP;
2320 : 0 : break;
2321 : 0 : case ICE_PROFID_IPV4_UDP:
2322 : : tun_type = ICE_SW_IPV4_UDP;
2323 : 0 : break;
2324 : 0 : case ICE_PROFID_IPV6_TCP:
2325 : : tun_type = ICE_SW_IPV6_TCP;
2326 : 0 : break;
2327 : 0 : case ICE_PROFID_IPV6_UDP:
2328 : : tun_type = ICE_SW_IPV6_UDP;
2329 : 0 : break;
2330 : 0 : case ICE_PROFID_PPPOE_PAY:
2331 : : tun_type = ICE_SW_TUN_PPPOE_PAY;
2332 : 0 : break;
2333 : 0 : case ICE_PROFID_PPPOE_IPV4_TCP:
2334 : : tun_type = ICE_SW_TUN_PPPOE_IPV4_TCP;
2335 : 0 : break;
2336 : 0 : case ICE_PROFID_PPPOE_IPV4_UDP:
2337 : : tun_type = ICE_SW_TUN_PPPOE_IPV4_UDP;
2338 : 0 : break;
2339 : 0 : case ICE_PROFID_PPPOE_IPV4_OTHER:
2340 : : tun_type = ICE_SW_TUN_PPPOE_IPV4;
2341 : 0 : break;
2342 : 0 : case ICE_PROFID_PPPOE_IPV6_TCP:
2343 : : tun_type = ICE_SW_TUN_PPPOE_IPV6_TCP;
2344 : 0 : break;
2345 : 0 : case ICE_PROFID_PPPOE_IPV6_UDP:
2346 : : tun_type = ICE_SW_TUN_PPPOE_IPV6_UDP;
2347 : 0 : break;
2348 : 0 : case ICE_PROFID_PPPOE_IPV6_OTHER:
2349 : : tun_type = ICE_SW_TUN_PPPOE_IPV6;
2350 : 0 : break;
2351 : 0 : case ICE_PROFID_IPV4_ESP:
2352 : : tun_type = ICE_SW_TUN_IPV4_ESP;
2353 : 0 : break;
2354 : 0 : case ICE_PROFID_IPV6_ESP:
2355 : : tun_type = ICE_SW_TUN_IPV6_ESP;
2356 : 0 : break;
2357 : 0 : case ICE_PROFID_IPV4_AH:
2358 : : tun_type = ICE_SW_TUN_IPV4_AH;
2359 : 0 : break;
2360 : 0 : case ICE_PROFID_IPV6_AH:
2361 : : tun_type = ICE_SW_TUN_IPV6_AH;
2362 : 0 : break;
2363 : 0 : case ICE_PROFID_IPV4_NAT_T:
2364 : : tun_type = ICE_SW_TUN_IPV4_NAT_T;
2365 : 0 : break;
2366 : 0 : case ICE_PROFID_IPV6_NAT_T:
2367 : : tun_type = ICE_SW_TUN_IPV6_NAT_T;
2368 : 0 : break;
2369 : 0 : case ICE_PROFID_IPV4_PFCP_NODE:
2370 : : tun_type =
2371 : : ICE_SW_TUN_PROFID_IPV4_PFCP_NODE;
2372 : 0 : break;
2373 : 0 : case ICE_PROFID_IPV6_PFCP_NODE:
2374 : : tun_type =
2375 : : ICE_SW_TUN_PROFID_IPV6_PFCP_NODE;
2376 : 0 : break;
2377 : 0 : case ICE_PROFID_IPV4_PFCP_SESSION:
2378 : : tun_type =
2379 : : ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION;
2380 : 0 : break;
2381 : 0 : case ICE_PROFID_IPV6_PFCP_SESSION:
2382 : : tun_type =
2383 : : ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION;
2384 : 0 : break;
2385 : 0 : case ICE_PROFID_MAC_IPV4_L2TPV3:
2386 : : tun_type = ICE_SW_TUN_IPV4_L2TPV3;
2387 : 0 : break;
2388 : 0 : case ICE_PROFID_MAC_IPV6_L2TPV3:
2389 : : tun_type = ICE_SW_TUN_IPV6_L2TPV3;
2390 : 0 : break;
2391 : 0 : case ICE_PROFID_IPV4_GTPU_TEID:
2392 : : tun_type = ICE_SW_TUN_IPV4_GTPU_NO_PAY;
2393 : 0 : break;
2394 : 0 : case ICE_PROFID_IPV6_GTPU_TEID:
2395 : : tun_type = ICE_SW_TUN_IPV6_GTPU_NO_PAY;
2396 : 0 : break;
2397 : : default:
2398 : : break;
2399 : : }
2400 : :
2401 : 0 : return tun_type;
2402 : : }
2403 : : }
2404 : : }
2405 : :
2406 [ # # ]: 0 : if (vlan && tun_type == ICE_SW_TUN_PPPOE)
2407 : : tun_type = ICE_SW_TUN_PPPOE_QINQ;
2408 [ # # ]: 0 : else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV6)
2409 : : tun_type = ICE_SW_TUN_PPPOE_IPV6_QINQ;
2410 [ # # ]: 0 : else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV4)
2411 : : tun_type = ICE_SW_TUN_PPPOE_IPV4_QINQ;
2412 [ # # ]: 0 : else if (vlan && tun_type == ICE_SW_TUN_PPPOE_PAY)
2413 : : tun_type = ICE_SW_TUN_PPPOE_PAY_QINQ;
2414 [ # # ]: 0 : else if (vlan && tun_type == ICE_SW_TUN_AND_NON_TUN)
2415 : : tun_type = ICE_SW_TUN_AND_NON_TUN_QINQ;
2416 [ # # ]: 0 : else if (vlan && tun_type == ICE_NON_TUN)
2417 : : tun_type = ICE_NON_TUN_QINQ;
2418 : :
2419 : : return tun_type;
2420 : : }
2421 : :
2422 : : /**
2423 : : * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries
2424 : : * @hw: pointer to hardware structure
2425 : : * @recps: struct that we need to populate
2426 : : * @rid: recipe ID that we are populating
2427 : : * @refresh_required: true if we should get recipe to profile mapping from FW
2428 : : *
2429 : : * This function is used to populate all the necessary entries into our
2430 : : * bookkeeping so that we have a current list of all the recipes that are
2431 : : * programmed in the firmware.
2432 : : */
2433 : : static enum ice_status
2434 : 0 : ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2435 : : bool *refresh_required)
2436 : : {
2437 : : ice_declare_bitmap(result_bm, ICE_MAX_FV_WORDS);
2438 : : struct ice_aqc_recipe_data_elem *tmp;
2439 : 0 : u16 num_recps = ICE_MAX_NUM_RECIPES;
2440 : : struct ice_prot_lkup_ext *lkup_exts;
2441 : : enum ice_status status;
2442 : : u8 fv_word_idx = 0;
2443 : : bool vlan = false;
2444 : : u16 sub_recps;
2445 : :
2446 : : ice_zero_bitmap(result_bm, ICE_MAX_FV_WORDS);
2447 : :
2448 : : /* we need a buffer big enough to accommodate all the recipes */
2449 : 0 : tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
2450 : : ICE_MAX_NUM_RECIPES, sizeof(*tmp));
2451 [ # # ]: 0 : if (!tmp)
2452 : : return ICE_ERR_NO_MEMORY;
2453 : :
2454 : 0 : tmp[0].recipe_indx = rid;
2455 : 0 : status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2456 : : /* non-zero status meaning recipe doesn't exist */
2457 [ # # ]: 0 : if (status)
2458 : 0 : goto err_unroll;
2459 : :
2460 : : /* Get recipe to profile map so that we can get the fv from lkups that
2461 : : * we read for a recipe from FW. Since we want to minimize the number of
2462 : : * times we make this FW call, just make one call and cache the copy
2463 : : * until a new recipe is added. This operation is only required the
2464 : : * first time to get the changes from FW. Then to search existing
2465 : : * entries we don't need to update the cache again until another recipe
2466 : : * gets added.
2467 : : */
2468 [ # # ]: 0 : if (*refresh_required) {
2469 : 0 : ice_get_recp_to_prof_map(hw);
2470 : 0 : *refresh_required = false;
2471 : : }
2472 : :
2473 : : /* Start populating all the entries for recps[rid] based on lkups from
2474 : : * firmware. Note that we are only creating the root recipe in our
2475 : : * database.
2476 : : */
2477 : 0 : lkup_exts = &recps[rid].lkup_exts;
2478 : :
2479 [ # # ]: 0 : for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2480 : 0 : struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2481 : : struct ice_recp_grp_entry *rg_entry;
2482 : 0 : u8 i, prof, idx, prot = 0;
2483 : : bool is_root;
2484 : 0 : u16 off = 0;
2485 : :
2486 : : rg_entry = (struct ice_recp_grp_entry *)
2487 : 0 : ice_malloc(hw, sizeof(*rg_entry));
2488 [ # # ]: 0 : if (!rg_entry) {
2489 : : status = ICE_ERR_NO_MEMORY;
2490 : 0 : goto err_unroll;
2491 : : }
2492 : :
2493 : 0 : idx = root_bufs.recipe_indx;
2494 : 0 : is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2495 : :
2496 : : /* Mark all result indices in this chain */
2497 [ # # ]: 0 : if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2498 : 0 : ice_set_bit(root_bufs.content.result_indx &
2499 : : ~ICE_AQ_RECIPE_RESULT_EN, result_bm);
2500 : :
2501 : : /* get the first profile that is associated with rid */
2502 : 0 : prof = (u8)ice_find_first_bit(recipe_to_profile[idx],
2503 : : ICE_MAX_NUM_PROFILES);
2504 [ # # ]: 0 : for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2505 : 0 : u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2506 : :
2507 : 0 : rg_entry->fv_idx[i] = lkup_indx;
2508 : 0 : rg_entry->fv_mask[i] =
2509 : 0 : LE16_TO_CPU(root_bufs.content.mask[i + 1]);
2510 : :
2511 : : /* If the recipe is a chained recipe then all its
2512 : : * child recipe's result will have a result index.
2513 : : * To fill fv_words we should not use those result
2514 : : * index, we only need the protocol ids and offsets.
2515 : : * We will skip all the fv_idx which stores result
2516 : : * index in them. We also need to skip any fv_idx which
2517 : : * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2518 : : * valid offset value.
2519 : : */
2520 [ # # ]: 0 : if (ice_is_bit_set(hw->switch_info->prof_res_bm[prof],
2521 [ # # ]: 0 : rg_entry->fv_idx[i]) ||
2522 [ # # ]: 0 : rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2523 : : rg_entry->fv_idx[i] == 0)
2524 : 0 : continue;
2525 : :
2526 : 0 : ice_find_prot_off(hw, ICE_BLK_SW, prof,
2527 : : rg_entry->fv_idx[i], &prot, &off);
2528 : 0 : lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2529 : 0 : lkup_exts->fv_words[fv_word_idx].off = off;
2530 : 0 : lkup_exts->field_mask[fv_word_idx] =
2531 : 0 : rg_entry->fv_mask[i];
2532 [ # # # # ]: 0 : if (prot == ICE_META_DATA_ID_HW &&
2533 : : off == ICE_TUN_FLAG_MDID_OFF(1))
2534 : : vlan = true;
2535 : 0 : fv_word_idx++;
2536 : : }
2537 : : /* populate rg_list with the data from the child entry of this
2538 : : * recipe
2539 : : */
2540 [ # # ]: 0 : LIST_ADD(&rg_entry->l_entry, &recps[rid].rg_list);
2541 : :
2542 : : /* Propagate some data to the recipe database */
2543 : 0 : recps[idx].is_root = !!is_root;
2544 : 0 : recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2545 [ # # ]: 0 : ice_zero_bitmap(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2546 [ # # ]: 0 : if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2547 : 0 : recps[idx].chain_idx = root_bufs.content.result_indx &
2548 : : ~ICE_AQ_RECIPE_RESULT_EN;
2549 : : ice_set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2550 : : } else {
2551 : 0 : recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2552 : : }
2553 : :
2554 [ # # ]: 0 : if (!is_root)
2555 : 0 : continue;
2556 : :
2557 : : /* Only do the following for root recipes entries */
2558 [ # # ]: 0 : ice_memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2559 : : sizeof(recps[idx].r_bitmap), ICE_NONDMA_TO_NONDMA);
2560 : 0 : recps[idx].root_rid = root_bufs.content.rid &
2561 : : ~ICE_AQ_RECIPE_ID_IS_ROOT;
2562 : 0 : recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2563 : : }
2564 : :
2565 : : /* Complete initialization of the root recipe entry */
2566 : 0 : lkup_exts->n_val_words = fv_word_idx;
2567 : 0 : recps[rid].big_recp = (num_recps > 1);
2568 : 0 : recps[rid].n_grp_count = (u8)num_recps;
2569 : 0 : recps[rid].tun_type = ice_get_tun_type_for_recipe(rid, vlan);
2570 : 0 : recps[rid].root_buf = (struct ice_aqc_recipe_data_elem *)
2571 : 0 : ice_memdup(hw, tmp, recps[rid].n_grp_count *
2572 : : sizeof(*recps[rid].root_buf), ICE_NONDMA_TO_NONDMA);
2573 [ # # ]: 0 : if (!recps[rid].root_buf)
2574 : 0 : goto err_unroll;
2575 : :
2576 : : /* Copy result indexes */
2577 : 0 : ice_cp_bitmap(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2578 : 0 : recps[rid].recp_created = true;
2579 : :
2580 : 0 : err_unroll:
2581 : 0 : ice_free(hw, tmp);
2582 : 0 : return status;
2583 : : }
2584 : :
2585 : : /**
2586 : : * ice_get_recp_to_prof_map - updates recipe to profile mapping
2587 : : * @hw: pointer to hardware structure
2588 : : *
2589 : : * This function is used to populate recipe_to_profile matrix where index to
2590 : : * this array is the recipe ID and the element is the mapping of which profiles
2591 : : * is this recipe mapped to.
2592 : : */
2593 : 0 : static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2594 : : {
2595 : : ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2596 : : u16 i;
2597 : :
2598 [ # # ]: 0 : for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2599 : : u16 j;
2600 : :
2601 : 0 : ice_zero_bitmap(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2602 : : ice_zero_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2603 [ # # ]: 0 : if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
2604 : 0 : continue;
2605 : 0 : ice_cp_bitmap(profile_to_recipe[i], r_bitmap,
2606 : : ICE_MAX_NUM_RECIPES);
2607 [ # # ]: 0 : ice_for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2608 : 0 : ice_set_bit(i, recipe_to_profile[j]);
2609 : : }
2610 : 0 : }
2611 : :
2612 : : static bool
2613 : : ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle);
2614 : :
2615 : : /**
2616 : : * ice_init_def_sw_recp - initialize the recipe book keeping tables
2617 : : * @hw: pointer to the HW struct
2618 : : * @recp_list: pointer to sw recipe list
2619 : : *
2620 : : * Allocate memory for the entire recipe table and initialize the structures/
2621 : : * entries corresponding to basic recipes.
2622 : : */
2623 : : enum ice_status
2624 : 0 : ice_init_def_sw_recp(struct ice_hw *hw, struct ice_sw_recipe **recp_list)
2625 : : {
2626 : : struct ice_sw_recipe *recps;
2627 : : u8 i;
2628 : :
2629 : : recps = (struct ice_sw_recipe *)
2630 : 0 : ice_calloc(hw, ICE_MAX_NUM_RECIPES, sizeof(*recps));
2631 [ # # ]: 0 : if (!recps)
2632 : : return ICE_ERR_NO_MEMORY;
2633 : :
2634 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
2635 : 0 : recps[i].root_rid = i;
2636 : 0 : INIT_LIST_HEAD(&recps[i].filt_rules);
2637 : 0 : INIT_LIST_HEAD(&recps[i].filt_replay_rules);
2638 : 0 : INIT_LIST_HEAD(&recps[i].rg_list);
2639 : : ice_init_lock(&recps[i].filt_rule_lock);
2640 : : }
2641 : :
2642 : 0 : *recp_list = recps;
2643 : :
2644 : 0 : return ICE_SUCCESS;
2645 : : }
2646 : :
2647 : : /**
2648 : : * ice_aq_get_sw_cfg - get switch configuration
2649 : : * @hw: pointer to the hardware structure
2650 : : * @buf: pointer to the result buffer
2651 : : * @buf_size: length of the buffer available for response
2652 : : * @req_desc: pointer to requested descriptor
2653 : : * @num_elems: pointer to number of elements
2654 : : * @cd: pointer to command details structure or NULL
2655 : : *
2656 : : * Get switch configuration (0x0200) to be placed in buf.
2657 : : * This admin command returns information such as initial VSI/port number
2658 : : * and switch ID it belongs to.
2659 : : *
2660 : : * NOTE: *req_desc is both an input/output parameter.
2661 : : * The caller of this function first calls this function with *request_desc set
2662 : : * to 0. If the response from f/w has *req_desc set to 0, all the switch
2663 : : * configuration information has been returned; if non-zero (meaning not all
2664 : : * the information was returned), the caller should call this function again
2665 : : * with *req_desc set to the previous value returned by f/w to get the
2666 : : * next block of switch configuration information.
2667 : : *
2668 : : * *num_elems is output only parameter. This reflects the number of elements
2669 : : * in response buffer. The caller of this function to use *num_elems while
2670 : : * parsing the response buffer.
2671 : : */
2672 : : static enum ice_status
2673 : 0 : ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
2674 : : u16 buf_size, u16 *req_desc, u16 *num_elems,
2675 : : struct ice_sq_cd *cd)
2676 : : {
2677 : : struct ice_aqc_get_sw_cfg *cmd;
2678 : : struct ice_aq_desc desc;
2679 : : enum ice_status status;
2680 : :
2681 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
2682 : : cmd = &desc.params.get_sw_conf;
2683 : 0 : cmd->element = CPU_TO_LE16(*req_desc);
2684 : :
2685 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
2686 [ # # ]: 0 : if (!status) {
2687 : 0 : *req_desc = LE16_TO_CPU(cmd->element);
2688 : 0 : *num_elems = LE16_TO_CPU(cmd->num_elems);
2689 : : }
2690 : :
2691 : 0 : return status;
2692 : : }
2693 : :
2694 : : /**
2695 : : * ice_alloc_rss_global_lut - allocate a RSS global LUT
2696 : : * @hw: pointer to the HW struct
2697 : : * @shared_res: true to allocate as a shared resource and false to allocate as a dedicated resource
2698 : : * @global_lut_id: output parameter for the RSS global LUT's ID
2699 : : */
2700 : 0 : enum ice_status ice_alloc_rss_global_lut(struct ice_hw *hw, bool shared_res, u16 *global_lut_id)
2701 : : {
2702 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2703 : : enum ice_status status;
2704 : : u16 buf_len;
2705 : :
2706 : : buf_len = ice_struct_size(sw_buf, elem, 1);
2707 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2708 [ # # ]: 0 : if (!sw_buf)
2709 : : return ICE_ERR_NO_MEMORY;
2710 : :
2711 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
2712 [ # # ]: 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH |
2713 : : (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2714 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2715 : :
2716 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, ice_aqc_opc_alloc_res, NULL);
2717 [ # # ]: 0 : if (status) {
2718 [ # # # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Failed to allocate %s RSS global LUT, status %d\n",
2719 : : shared_res ? "shared" : "dedicated", status);
2720 : 0 : goto ice_alloc_global_lut_exit;
2721 : : }
2722 : :
2723 : 0 : *global_lut_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
2724 : :
2725 : 0 : ice_alloc_global_lut_exit:
2726 : 0 : ice_free(hw, sw_buf);
2727 : 0 : return status;
2728 : : }
2729 : :
2730 : : /**
2731 : : * ice_free_sw_marker_lg - free a switch marker large action
2732 : : * @hw: pointer to the HW struct
2733 : : * @marker_lg_id: ID of the marker large action to free
2734 : : * @sw_marker: sw marker to tag the Rx descriptor with
2735 : : */
2736 : : static enum ice_status
2737 : 0 : ice_free_sw_marker_lg(struct ice_hw *hw, u16 marker_lg_id, u32 sw_marker)
2738 : : {
2739 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2740 : : u16 buf_len, num_elems = 1;
2741 : : enum ice_status status;
2742 : :
2743 : : buf_len = ice_struct_size(sw_buf, elem, num_elems);
2744 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2745 [ # # ]: 0 : if (!sw_buf)
2746 : : return ICE_ERR_NO_MEMORY;
2747 : :
2748 : 0 : sw_buf->num_elems = CPU_TO_LE16(num_elems);
2749 [ # # ]: 0 : if (sw_marker == (sw_marker & 0xFFFF))
2750 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_1);
2751 : : else
2752 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_2);
2753 : :
2754 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(marker_lg_id);
2755 : :
2756 : 0 : status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len,
2757 : : ice_aqc_opc_free_res, NULL);
2758 [ # # ]: 0 : if (status)
2759 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Failed to free sw marker lg %d, status %d\n",
2760 : : marker_lg_id, status);
2761 : :
2762 : 0 : ice_free(hw, sw_buf);
2763 : 0 : return status;
2764 : : }
2765 : :
2766 : : /**
2767 : : * ice_free_rss_global_lut - free a RSS global LUT
2768 : : * @hw: pointer to the HW struct
2769 : : * @global_lut_id: ID of the RSS global LUT to free
2770 : : */
2771 : 0 : enum ice_status ice_free_rss_global_lut(struct ice_hw *hw, u16 global_lut_id)
2772 : : {
2773 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2774 : : u16 buf_len, num_elems = 1;
2775 : : enum ice_status status;
2776 : :
2777 : : buf_len = ice_struct_size(sw_buf, elem, num_elems);
2778 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2779 [ # # ]: 0 : if (!sw_buf)
2780 : : return ICE_ERR_NO_MEMORY;
2781 : :
2782 : 0 : sw_buf->num_elems = CPU_TO_LE16(num_elems);
2783 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH);
2784 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(global_lut_id);
2785 : :
2786 : 0 : status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len, ice_aqc_opc_free_res, NULL);
2787 [ # # ]: 0 : if (status)
2788 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Failed to free RSS global LUT %d, status %d\n",
2789 : : global_lut_id, status);
2790 : :
2791 : 0 : ice_free(hw, sw_buf);
2792 : 0 : return status;
2793 : : }
2794 : :
2795 : : /**
2796 : : * ice_alloc_sw - allocate resources specific to switch
2797 : : * @hw: pointer to the HW struct
2798 : : * @ena_stats: true to turn on VEB stats
2799 : : * @shared_res: true for shared resource, false for dedicated resource
2800 : : * @sw_id: switch ID returned
2801 : : * @counter_id: VEB counter ID returned
2802 : : *
2803 : : * allocates switch resources (SWID and VEB counter) (0x0208)
2804 : : */
2805 : : enum ice_status
2806 : 0 : ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id,
2807 : : u16 *counter_id)
2808 : : {
2809 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2810 : : struct ice_aqc_res_elem *sw_ele;
2811 : : enum ice_status status;
2812 : : u16 buf_len;
2813 : :
2814 : : buf_len = ice_struct_size(sw_buf, elem, 1);
2815 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2816 [ # # ]: 0 : if (!sw_buf)
2817 : : return ICE_ERR_NO_MEMORY;
2818 : :
2819 : : /* Prepare buffer for switch ID.
2820 : : * The number of resource entries in buffer is passed as 1 since only a
2821 : : * single switch/VEB instance is allocated, and hence a single sw_id
2822 : : * is requested.
2823 : : */
2824 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
2825 [ # # ]: 0 : sw_buf->res_type =
2826 : : CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID |
2827 : : (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2828 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2829 : :
2830 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2831 : : ice_aqc_opc_alloc_res, NULL);
2832 : :
2833 [ # # ]: 0 : if (status)
2834 : 0 : goto ice_alloc_sw_exit;
2835 : :
2836 : : sw_ele = &sw_buf->elem[0];
2837 : 0 : *sw_id = LE16_TO_CPU(sw_ele->e.sw_resp);
2838 : :
2839 [ # # ]: 0 : if (ena_stats) {
2840 : : /* Prepare buffer for VEB Counter */
2841 : : enum ice_adminq_opc opc = ice_aqc_opc_alloc_res;
2842 : : struct ice_aqc_alloc_free_res_elem *counter_buf;
2843 : : struct ice_aqc_res_elem *counter_ele;
2844 : :
2845 : : counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2846 : 0 : ice_malloc(hw, buf_len);
2847 [ # # ]: 0 : if (!counter_buf) {
2848 : : status = ICE_ERR_NO_MEMORY;
2849 : 0 : goto ice_alloc_sw_exit;
2850 : : }
2851 : :
2852 : : /* The number of resource entries in buffer is passed as 1 since
2853 : : * only a single switch/VEB instance is allocated, and hence a
2854 : : * single VEB counter is requested.
2855 : : */
2856 : 0 : counter_buf->num_elems = CPU_TO_LE16(1);
2857 : 0 : counter_buf->res_type =
2858 : : CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER |
2859 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED);
2860 : 0 : status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2861 : : opc, NULL);
2862 : :
2863 [ # # ]: 0 : if (status) {
2864 : 0 : ice_free(hw, counter_buf);
2865 : 0 : goto ice_alloc_sw_exit;
2866 : : }
2867 : : counter_ele = &counter_buf->elem[0];
2868 : 0 : *counter_id = LE16_TO_CPU(counter_ele->e.sw_resp);
2869 : 0 : ice_free(hw, counter_buf);
2870 : : }
2871 : :
2872 : 0 : ice_alloc_sw_exit:
2873 : 0 : ice_free(hw, sw_buf);
2874 : 0 : return status;
2875 : : }
2876 : :
2877 : : /**
2878 : : * ice_free_sw - free resources specific to switch
2879 : : * @hw: pointer to the HW struct
2880 : : * @sw_id: switch ID returned
2881 : : * @counter_id: VEB counter ID returned
2882 : : *
2883 : : * free switch resources (SWID and VEB counter) (0x0209)
2884 : : *
2885 : : * NOTE: This function frees multiple resources. It continues
2886 : : * releasing other resources even after it encounters error.
2887 : : * The error code returned is the last error it encountered.
2888 : : */
2889 : 0 : enum ice_status ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id)
2890 : : {
2891 : : struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf;
2892 : : enum ice_status status, ret_status;
2893 : : u16 buf_len;
2894 : :
2895 : : buf_len = ice_struct_size(sw_buf, elem, 1);
2896 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2897 [ # # ]: 0 : if (!sw_buf)
2898 : : return ICE_ERR_NO_MEMORY;
2899 : :
2900 : : /* Prepare buffer to free for switch ID res.
2901 : : * The number of resource entries in buffer is passed as 1 since only a
2902 : : * single switch/VEB instance is freed, and hence a single sw_id
2903 : : * is released.
2904 : : */
2905 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
2906 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID);
2907 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id);
2908 : :
2909 : 0 : ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2910 : : ice_aqc_opc_free_res, NULL);
2911 : :
2912 [ # # ]: 0 : if (ret_status)
2913 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
2914 : :
2915 : : /* Prepare buffer to free for VEB Counter resource */
2916 : : counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2917 : 0 : ice_malloc(hw, buf_len);
2918 [ # # ]: 0 : if (!counter_buf) {
2919 : 0 : ice_free(hw, sw_buf);
2920 : 0 : return ICE_ERR_NO_MEMORY;
2921 : : }
2922 : :
2923 : : /* The number of resource entries in buffer is passed as 1 since only a
2924 : : * single switch/VEB instance is freed, and hence a single VEB counter
2925 : : * is released
2926 : : */
2927 : 0 : counter_buf->num_elems = CPU_TO_LE16(1);
2928 : 0 : counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER);
2929 : 0 : counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
2930 : :
2931 : 0 : status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2932 : : ice_aqc_opc_free_res, NULL);
2933 [ # # ]: 0 : if (status) {
2934 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "VEB counter resource could not be freed\n");
2935 : : ret_status = status;
2936 : : }
2937 : :
2938 : 0 : ice_free(hw, counter_buf);
2939 : 0 : ice_free(hw, sw_buf);
2940 : 0 : return ret_status;
2941 : : }
2942 : :
2943 : : /**
2944 : : * ice_aq_add_vsi
2945 : : * @hw: pointer to the HW struct
2946 : : * @vsi_ctx: pointer to a VSI context struct
2947 : : * @cd: pointer to command details structure or NULL
2948 : : *
2949 : : * Add a VSI context to the hardware (0x0210)
2950 : : */
2951 : : enum ice_status
2952 : 0 : ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2953 : : struct ice_sq_cd *cd)
2954 : : {
2955 : : struct ice_aqc_add_update_free_vsi_resp *res;
2956 : : struct ice_aqc_add_get_update_free_vsi *cmd;
2957 : : struct ice_aq_desc desc;
2958 : : enum ice_status status;
2959 : :
2960 : : cmd = &desc.params.vsi_cmd;
2961 : : res = &desc.params.add_update_free_vsi_res;
2962 : :
2963 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
2964 : :
2965 [ # # ]: 0 : if (!vsi_ctx->alloc_from_pool)
2966 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num |
2967 : : ICE_AQ_VSI_IS_VALID);
2968 : :
2969 : 0 : cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
2970 : :
2971 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2972 : :
2973 : 0 : status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2974 : : sizeof(vsi_ctx->info), cd);
2975 : :
2976 [ # # ]: 0 : if (!status) {
2977 : 0 : vsi_ctx->vsi_num = LE16_TO_CPU(res->vsi_num) & ICE_AQ_VSI_NUM_M;
2978 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(res->vsi_used);
2979 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(res->vsi_free);
2980 : : }
2981 : :
2982 : 0 : return status;
2983 : : }
2984 : :
2985 : : /**
2986 : : * ice_aq_free_vsi
2987 : : * @hw: pointer to the HW struct
2988 : : * @vsi_ctx: pointer to a VSI context struct
2989 : : * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
2990 : : * @cd: pointer to command details structure or NULL
2991 : : *
2992 : : * Free VSI context info from hardware (0x0213)
2993 : : */
2994 : : enum ice_status
2995 : 0 : ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2996 : : bool keep_vsi_alloc, struct ice_sq_cd *cd)
2997 : : {
2998 : : struct ice_aqc_add_update_free_vsi_resp *resp;
2999 : : struct ice_aqc_add_get_update_free_vsi *cmd;
3000 : : struct ice_aq_desc desc;
3001 : : enum ice_status status;
3002 : :
3003 : : cmd = &desc.params.vsi_cmd;
3004 : : resp = &desc.params.add_update_free_vsi_res;
3005 : :
3006 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
3007 : :
3008 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
3009 [ # # ]: 0 : if (keep_vsi_alloc)
3010 : 0 : cmd->cmd_flags = CPU_TO_LE16(ICE_AQ_VSI_KEEP_ALLOC);
3011 : :
3012 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3013 [ # # ]: 0 : if (!status) {
3014 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
3015 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
3016 : : }
3017 : :
3018 : 0 : return status;
3019 : : }
3020 : :
3021 : : /**
3022 : : * ice_aq_update_vsi
3023 : : * @hw: pointer to the HW struct
3024 : : * @vsi_ctx: pointer to a VSI context struct
3025 : : * @cd: pointer to command details structure or NULL
3026 : : *
3027 : : * Update VSI context in the hardware (0x0211)
3028 : : */
3029 : : enum ice_status
3030 : 0 : ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
3031 : : struct ice_sq_cd *cd)
3032 : : {
3033 : : struct ice_aqc_add_update_free_vsi_resp *resp;
3034 : : struct ice_aqc_add_get_update_free_vsi *cmd;
3035 : : struct ice_aq_desc desc;
3036 : : enum ice_status status;
3037 : :
3038 : : cmd = &desc.params.vsi_cmd;
3039 : : resp = &desc.params.add_update_free_vsi_res;
3040 : :
3041 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
3042 : :
3043 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
3044 : :
3045 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3046 : :
3047 : 0 : status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
3048 : : sizeof(vsi_ctx->info), cd);
3049 : :
3050 [ # # ]: 0 : if (!status) {
3051 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
3052 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
3053 : : }
3054 : :
3055 : 0 : return status;
3056 : : }
3057 : :
3058 : : /**
3059 : : * ice_is_vsi_valid - check whether the VSI is valid or not
3060 : : * @hw: pointer to the HW struct
3061 : : * @vsi_handle: VSI handle
3062 : : *
3063 : : * check whether the VSI is valid or not
3064 : : */
3065 : 0 : bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
3066 : : {
3067 [ # # # # ]: 0 : return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
3068 : : }
3069 : :
3070 : : /**
3071 : : * ice_get_hw_vsi_num - return the HW VSI number
3072 : : * @hw: pointer to the HW struct
3073 : : * @vsi_handle: VSI handle
3074 : : *
3075 : : * return the HW VSI number
3076 : : * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
3077 : : */
3078 : 0 : u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
3079 : : {
3080 : 0 : return hw->vsi_ctx[vsi_handle]->vsi_num;
3081 : : }
3082 : :
3083 : : /**
3084 : : * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
3085 : : * @hw: pointer to the HW struct
3086 : : * @vsi_handle: VSI handle
3087 : : *
3088 : : * return the VSI context entry for a given VSI handle
3089 : : */
3090 : 0 : struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
3091 : : {
3092 [ # # ]: 0 : return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
3093 : : }
3094 : :
3095 : : /**
3096 : : * ice_save_vsi_ctx - save the VSI context for a given VSI handle
3097 : : * @hw: pointer to the HW struct
3098 : : * @vsi_handle: VSI handle
3099 : : * @vsi: VSI context pointer
3100 : : *
3101 : : * save the VSI context entry for a given VSI handle
3102 : : */
3103 : : static void
3104 : : ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
3105 : : {
3106 : 0 : hw->vsi_ctx[vsi_handle] = vsi;
3107 : 0 : }
3108 : :
3109 : : /**
3110 : : * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
3111 : : * @hw: pointer to the HW struct
3112 : : * @vsi_handle: VSI handle
3113 : : */
3114 : 0 : static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
3115 : : {
3116 : : struct ice_vsi_ctx *vsi;
3117 : : u8 i;
3118 : :
3119 : 0 : vsi = ice_get_vsi_ctx(hw, vsi_handle);
3120 [ # # ]: 0 : if (!vsi)
3121 : : return;
3122 [ # # ]: 0 : ice_for_each_traffic_class(i) {
3123 [ # # ]: 0 : if (vsi->lan_q_ctx[i]) {
3124 : 0 : ice_free(hw, vsi->lan_q_ctx[i]);
3125 : 0 : vsi->lan_q_ctx[i] = NULL;
3126 : : }
3127 : : }
3128 : : }
3129 : :
3130 : : /**
3131 : : * ice_clear_vsi_ctx - clear the VSI context entry
3132 : : * @hw: pointer to the HW struct
3133 : : * @vsi_handle: VSI handle
3134 : : *
3135 : : * clear the VSI context entry
3136 : : */
3137 : 0 : static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
3138 : : {
3139 : : struct ice_vsi_ctx *vsi;
3140 : :
3141 : 0 : vsi = ice_get_vsi_ctx(hw, vsi_handle);
3142 [ # # ]: 0 : if (vsi) {
3143 : 0 : ice_clear_vsi_q_ctx(hw, vsi_handle);
3144 : 0 : ice_free(hw, vsi);
3145 : 0 : hw->vsi_ctx[vsi_handle] = NULL;
3146 : : }
3147 : 0 : }
3148 : :
3149 : : /**
3150 : : * ice_clear_all_vsi_ctx - clear all the VSI context entries
3151 : : * @hw: pointer to the HW struct
3152 : : */
3153 : 0 : void ice_clear_all_vsi_ctx(struct ice_hw *hw)
3154 : : {
3155 : : u16 i;
3156 : :
3157 [ # # ]: 0 : for (i = 0; i < ICE_MAX_VSI; i++)
3158 : 0 : ice_clear_vsi_ctx(hw, i);
3159 : 0 : }
3160 : :
3161 : : /**
3162 : : * ice_add_vsi - add VSI context to the hardware and VSI handle list
3163 : : * @hw: pointer to the HW struct
3164 : : * @vsi_handle: unique VSI handle provided by drivers
3165 : : * @vsi_ctx: pointer to a VSI context struct
3166 : : * @cd: pointer to command details structure or NULL
3167 : : *
3168 : : * Add a VSI context to the hardware also add it into the VSI handle list.
3169 : : * If this function gets called after reset for existing VSIs then update
3170 : : * with the new HW VSI number in the corresponding VSI handle list entry.
3171 : : */
3172 : : enum ice_status
3173 : 0 : ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
3174 : : struct ice_sq_cd *cd)
3175 : : {
3176 : : struct ice_vsi_ctx *tmp_vsi_ctx;
3177 : : enum ice_status status;
3178 : :
3179 [ # # ]: 0 : if (vsi_handle >= ICE_MAX_VSI)
3180 : : return ICE_ERR_PARAM;
3181 : 0 : status = ice_aq_add_vsi(hw, vsi_ctx, cd);
3182 [ # # ]: 0 : if (status)
3183 : : return status;
3184 : 0 : tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
3185 [ # # ]: 0 : if (!tmp_vsi_ctx) {
3186 : : /* Create a new VSI context */
3187 : : tmp_vsi_ctx = (struct ice_vsi_ctx *)
3188 : 0 : ice_malloc(hw, sizeof(*tmp_vsi_ctx));
3189 [ # # ]: 0 : if (!tmp_vsi_ctx) {
3190 : 0 : ice_aq_free_vsi(hw, vsi_ctx, false, cd);
3191 : 0 : return ICE_ERR_NO_MEMORY;
3192 : : }
3193 : 0 : *tmp_vsi_ctx = *vsi_ctx;
3194 : :
3195 : : ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
3196 : : } else {
3197 : : /* update with new HW VSI num */
3198 : 0 : tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
3199 : : }
3200 : :
3201 : : return ICE_SUCCESS;
3202 : : }
3203 : :
3204 : : /**
3205 : : * ice_free_vsi- free VSI context from hardware and VSI handle list
3206 : : * @hw: pointer to the HW struct
3207 : : * @vsi_handle: unique VSI handle
3208 : : * @vsi_ctx: pointer to a VSI context struct
3209 : : * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
3210 : : * @cd: pointer to command details structure or NULL
3211 : : *
3212 : : * Free VSI context info from hardware as well as from VSI handle list
3213 : : */
3214 : : enum ice_status
3215 : 0 : ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
3216 : : bool keep_vsi_alloc, struct ice_sq_cd *cd)
3217 : : {
3218 : : enum ice_status status;
3219 : :
3220 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
3221 : : return ICE_ERR_PARAM;
3222 : 0 : vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
3223 : 0 : status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
3224 [ # # ]: 0 : if (!status)
3225 : 0 : ice_clear_vsi_ctx(hw, vsi_handle);
3226 : : return status;
3227 : : }
3228 : :
3229 : : /**
3230 : : * ice_update_vsi
3231 : : * @hw: pointer to the HW struct
3232 : : * @vsi_handle: unique VSI handle
3233 : : * @vsi_ctx: pointer to a VSI context struct
3234 : : * @cd: pointer to command details structure or NULL
3235 : : *
3236 : : * Update VSI context in the hardware
3237 : : */
3238 : : enum ice_status
3239 : 0 : ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
3240 : : struct ice_sq_cd *cd)
3241 : : {
3242 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
3243 : : return ICE_ERR_PARAM;
3244 : 0 : vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
3245 : 0 : return ice_aq_update_vsi(hw, vsi_ctx, cd);
3246 : : }
3247 : :
3248 : : /**
3249 : : * ice_aq_get_vsi_params
3250 : : * @hw: pointer to the HW struct
3251 : : * @vsi_ctx: pointer to a VSI context struct
3252 : : * @cd: pointer to command details structure or NULL
3253 : : *
3254 : : * Get VSI context info from hardware (0x0212)
3255 : : */
3256 : : enum ice_status
3257 : 0 : ice_aq_get_vsi_params(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
3258 : : struct ice_sq_cd *cd)
3259 : : {
3260 : : struct ice_aqc_add_get_update_free_vsi *cmd;
3261 : : struct ice_aqc_get_vsi_resp *resp;
3262 : : struct ice_aq_desc desc;
3263 : : enum ice_status status;
3264 : :
3265 : : cmd = &desc.params.vsi_cmd;
3266 : : resp = &desc.params.get_vsi_resp;
3267 : :
3268 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_vsi_params);
3269 : :
3270 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
3271 : :
3272 : 0 : status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
3273 : : sizeof(vsi_ctx->info), cd);
3274 [ # # ]: 0 : if (!status) {
3275 : 0 : vsi_ctx->vsi_num = LE16_TO_CPU(resp->vsi_num) &
3276 : : ICE_AQ_VSI_NUM_M;
3277 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
3278 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
3279 : : }
3280 : :
3281 : 0 : return status;
3282 : : }
3283 : :
3284 : : /**
3285 : : * ice_aq_add_update_mir_rule - add/update a mirror rule
3286 : : * @hw: pointer to the HW struct
3287 : : * @rule_type: Rule Type
3288 : : * @dest_vsi: VSI number to which packets will be mirrored
3289 : : * @count: length of the list
3290 : : * @mr_buf: buffer for list of mirrored VSI numbers
3291 : : * @cd: pointer to command details structure or NULL
3292 : : * @rule_id: Rule ID
3293 : : *
3294 : : * Add/Update Mirror Rule (0x260).
3295 : : */
3296 : : enum ice_status
3297 : 0 : ice_aq_add_update_mir_rule(struct ice_hw *hw, u16 rule_type, u16 dest_vsi,
3298 : : u16 count, struct ice_mir_rule_buf *mr_buf,
3299 : : struct ice_sq_cd *cd, u16 *rule_id)
3300 : : {
3301 : : struct ice_aqc_add_update_mir_rule *cmd;
3302 : : struct ice_aq_desc desc;
3303 : : enum ice_status status;
3304 : : __le16 *mr_list = NULL;
3305 : : u16 buf_size = 0;
3306 : :
3307 [ # # # ]: 0 : switch (rule_type) {
3308 : 0 : case ICE_AQC_RULE_TYPE_VPORT_INGRESS:
3309 : : case ICE_AQC_RULE_TYPE_VPORT_EGRESS:
3310 : : /* Make sure count and mr_buf are set for these rule_types */
3311 [ # # ]: 0 : if (!(count && mr_buf))
3312 : : return ICE_ERR_PARAM;
3313 : :
3314 : 0 : buf_size = count * sizeof(__le16);
3315 : 0 : mr_list = (_FORCE_ __le16 *)ice_malloc(hw, buf_size);
3316 [ # # ]: 0 : if (!mr_list)
3317 : : return ICE_ERR_NO_MEMORY;
3318 : : break;
3319 : 0 : case ICE_AQC_RULE_TYPE_PPORT_INGRESS:
3320 : : case ICE_AQC_RULE_TYPE_PPORT_EGRESS:
3321 : : /* Make sure count and mr_buf are not set for these
3322 : : * rule_types
3323 : : */
3324 [ # # ]: 0 : if (count || mr_buf)
3325 : : return ICE_ERR_PARAM;
3326 : : break;
3327 : 0 : default:
3328 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Error due to unsupported rule_type %u\n", rule_type);
3329 : : return ICE_ERR_OUT_OF_RANGE;
3330 : : }
3331 : :
3332 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_update_mir_rule);
3333 : :
3334 : : /* Pre-process 'mr_buf' items for add/update of virtual port
3335 : : * ingress/egress mirroring (but not physical port ingress/egress
3336 : : * mirroring)
3337 : : */
3338 [ # # ]: 0 : if (mr_buf) {
3339 : : int i;
3340 : :
3341 [ # # ]: 0 : for (i = 0; i < count; i++) {
3342 : : u16 id;
3343 : :
3344 : 0 : id = mr_buf[i].vsi_idx & ICE_AQC_RULE_MIRRORED_VSI_M;
3345 : :
3346 : : /* Validate specified VSI number, make sure it is less
3347 : : * than ICE_MAX_VSI, if not return with error.
3348 : : */
3349 [ # # ]: 0 : if (id >= ICE_MAX_VSI) {
3350 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Error VSI index (%u) out-of-range\n",
3351 : : id);
3352 : 0 : ice_free(hw, mr_list);
3353 : 0 : return ICE_ERR_OUT_OF_RANGE;
3354 : : }
3355 : :
3356 : : /* add VSI to mirror rule */
3357 [ # # ]: 0 : if (mr_buf[i].add)
3358 : 0 : mr_list[i] =
3359 : : CPU_TO_LE16(id | ICE_AQC_RULE_ACT_M);
3360 : : else /* remove VSI from mirror rule */
3361 : 0 : mr_list[i] = CPU_TO_LE16(id);
3362 : : }
3363 : :
3364 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3365 : : }
3366 : :
3367 : : cmd = &desc.params.add_update_rule;
3368 [ # # ]: 0 : if ((*rule_id) != ICE_INVAL_MIRROR_RULE_ID)
3369 : 0 : cmd->rule_id = CPU_TO_LE16(((*rule_id) & ICE_AQC_RULE_ID_M) |
3370 : : ICE_AQC_RULE_ID_VALID_M);
3371 : 0 : cmd->rule_type = CPU_TO_LE16(rule_type & ICE_AQC_RULE_TYPE_M);
3372 : 0 : cmd->num_entries = CPU_TO_LE16(count);
3373 : 0 : cmd->dest = CPU_TO_LE16(dest_vsi);
3374 : :
3375 : 0 : status = ice_aq_send_cmd(hw, &desc, mr_list, buf_size, cd);
3376 [ # # ]: 0 : if (!status)
3377 : 0 : *rule_id = LE16_TO_CPU(cmd->rule_id) & ICE_AQC_RULE_ID_M;
3378 : :
3379 : 0 : ice_free(hw, mr_list);
3380 : :
3381 : 0 : return status;
3382 : : }
3383 : :
3384 : : /**
3385 : : * ice_aq_delete_mir_rule - delete a mirror rule
3386 : : * @hw: pointer to the HW struct
3387 : : * @rule_id: Mirror rule ID (to be deleted)
3388 : : * @keep_allocd: if set, the VSI stays part of the PF allocated res,
3389 : : * otherwise it is returned to the shared pool
3390 : : * @cd: pointer to command details structure or NULL
3391 : : *
3392 : : * Delete Mirror Rule (0x261).
3393 : : */
3394 : : enum ice_status
3395 : 0 : ice_aq_delete_mir_rule(struct ice_hw *hw, u16 rule_id, bool keep_allocd,
3396 : : struct ice_sq_cd *cd)
3397 : : {
3398 : : struct ice_aqc_delete_mir_rule *cmd;
3399 : : struct ice_aq_desc desc;
3400 : :
3401 : : /* rule_id should be in the range 0...63 */
3402 [ # # ]: 0 : if (rule_id >= ICE_MAX_NUM_MIRROR_RULES)
3403 : : return ICE_ERR_OUT_OF_RANGE;
3404 : :
3405 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_del_mir_rule);
3406 : :
3407 : : cmd = &desc.params.del_rule;
3408 : 0 : rule_id |= ICE_AQC_RULE_ID_VALID_M;
3409 : 0 : cmd->rule_id = CPU_TO_LE16(rule_id);
3410 : :
3411 [ # # ]: 0 : if (keep_allocd)
3412 : 0 : cmd->flags = CPU_TO_LE16(ICE_AQC_FLAG_KEEP_ALLOCD_M);
3413 : :
3414 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3415 : : }
3416 : :
3417 : : /**
3418 : : * ice_aq_alloc_free_vsi_list
3419 : : * @hw: pointer to the HW struct
3420 : : * @vsi_list_id: VSI list ID returned or used for lookup
3421 : : * @lkup_type: switch rule filter lookup type
3422 : : * @opc: switch rules population command type - pass in the command opcode
3423 : : *
3424 : : * allocates or free a VSI list resource
3425 : : */
3426 : : static enum ice_status
3427 : 0 : ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
3428 : : enum ice_sw_lkup_type lkup_type,
3429 : : enum ice_adminq_opc opc)
3430 : : {
3431 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
3432 : : struct ice_aqc_res_elem *vsi_ele;
3433 : : enum ice_status status;
3434 : : u16 buf_len;
3435 : :
3436 : : buf_len = ice_struct_size(sw_buf, elem, 1);
3437 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3438 [ # # ]: 0 : if (!sw_buf)
3439 : : return ICE_ERR_NO_MEMORY;
3440 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
3441 : :
3442 : 0 : if (lkup_type == ICE_SW_LKUP_MAC ||
3443 : 0 : lkup_type == ICE_SW_LKUP_MAC_VLAN ||
3444 : 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3445 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3446 : 0 : lkup_type == ICE_SW_LKUP_PROMISC ||
3447 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3448 : 0 : lkup_type == ICE_SW_LKUP_DFLT ||
3449 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_LAST) {
3450 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
3451 [ # # ]: 0 : } else if (lkup_type == ICE_SW_LKUP_VLAN) {
3452 : 0 : sw_buf->res_type =
3453 : : CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
3454 : : } else {
3455 : : status = ICE_ERR_PARAM;
3456 : 0 : goto ice_aq_alloc_free_vsi_list_exit;
3457 : : }
3458 : :
3459 [ # # ]: 0 : if (opc == ice_aqc_opc_free_res)
3460 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(*vsi_list_id);
3461 : :
3462 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
3463 [ # # ]: 0 : if (status)
3464 : 0 : goto ice_aq_alloc_free_vsi_list_exit;
3465 : :
3466 [ # # ]: 0 : if (opc == ice_aqc_opc_alloc_res) {
3467 : : vsi_ele = &sw_buf->elem[0];
3468 : 0 : *vsi_list_id = LE16_TO_CPU(vsi_ele->e.sw_resp);
3469 : : }
3470 : :
3471 : 0 : ice_aq_alloc_free_vsi_list_exit:
3472 : 0 : ice_free(hw, sw_buf);
3473 : 0 : return status;
3474 : : }
3475 : :
3476 : : /**
3477 : : * ice_aq_set_storm_ctrl - Sets storm control configuration
3478 : : * @hw: pointer to the HW struct
3479 : : * @bcast_thresh: represents the upper threshold for broadcast storm control
3480 : : * @mcast_thresh: represents the upper threshold for multicast storm control
3481 : : * @ctl_bitmask: storm control knobs
3482 : : *
3483 : : * Sets the storm control configuration (0x0280)
3484 : : */
3485 : : enum ice_status
3486 : 0 : ice_aq_set_storm_ctrl(struct ice_hw *hw, u32 bcast_thresh, u32 mcast_thresh,
3487 : : u32 ctl_bitmask)
3488 : : {
3489 : : struct ice_aqc_storm_cfg *cmd;
3490 : : struct ice_aq_desc desc;
3491 : :
3492 : : cmd = &desc.params.storm_conf;
3493 : :
3494 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_storm_cfg);
3495 : :
3496 : 0 : cmd->bcast_thresh_size = CPU_TO_LE32(bcast_thresh & ICE_AQ_THRESHOLD_M);
3497 : 0 : cmd->mcast_thresh_size = CPU_TO_LE32(mcast_thresh & ICE_AQ_THRESHOLD_M);
3498 : 0 : cmd->storm_ctrl_ctrl = CPU_TO_LE32(ctl_bitmask);
3499 : :
3500 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3501 : : }
3502 : :
3503 : : /**
3504 : : * ice_aq_get_storm_ctrl - gets storm control configuration
3505 : : * @hw: pointer to the HW struct
3506 : : * @bcast_thresh: represents the upper threshold for broadcast storm control
3507 : : * @mcast_thresh: represents the upper threshold for multicast storm control
3508 : : * @ctl_bitmask: storm control knobs
3509 : : *
3510 : : * Gets the storm control configuration (0x0281)
3511 : : */
3512 : : enum ice_status
3513 : 0 : ice_aq_get_storm_ctrl(struct ice_hw *hw, u32 *bcast_thresh, u32 *mcast_thresh,
3514 : : u32 *ctl_bitmask)
3515 : : {
3516 : : enum ice_status status;
3517 : : struct ice_aq_desc desc;
3518 : :
3519 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_storm_cfg);
3520 : :
3521 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3522 [ # # ]: 0 : if (!status) {
3523 : : struct ice_aqc_storm_cfg *resp = &desc.params.storm_conf;
3524 : :
3525 [ # # ]: 0 : if (bcast_thresh)
3526 : 0 : *bcast_thresh = LE32_TO_CPU(resp->bcast_thresh_size) &
3527 : : ICE_AQ_THRESHOLD_M;
3528 [ # # ]: 0 : if (mcast_thresh)
3529 : 0 : *mcast_thresh = LE32_TO_CPU(resp->mcast_thresh_size) &
3530 : : ICE_AQ_THRESHOLD_M;
3531 [ # # ]: 0 : if (ctl_bitmask)
3532 : 0 : *ctl_bitmask = LE32_TO_CPU(resp->storm_ctrl_ctrl);
3533 : : }
3534 : :
3535 : 0 : return status;
3536 : : }
3537 : :
3538 : : /**
3539 : : * ice_aq_sw_rules - add/update/remove switch rules
3540 : : * @hw: pointer to the HW struct
3541 : : * @rule_list: pointer to switch rule population list
3542 : : * @rule_list_sz: total size of the rule list in bytes
3543 : : * @num_rules: number of switch rules in the rule_list
3544 : : * @opc: switch rules population command type - pass in the command opcode
3545 : : * @cd: pointer to command details structure or NULL
3546 : : *
3547 : : * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
3548 : : */
3549 : : static enum ice_status
3550 : 0 : ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
3551 : : u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
3552 : : {
3553 : : struct ice_aq_desc desc;
3554 : : enum ice_status status;
3555 : :
3556 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3557 : :
3558 : 0 : if (opc != ice_aqc_opc_add_sw_rules &&
3559 [ # # ]: 0 : opc != ice_aqc_opc_update_sw_rules &&
3560 : : opc != ice_aqc_opc_remove_sw_rules)
3561 : : return ICE_ERR_PARAM;
3562 : :
3563 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, opc);
3564 : :
3565 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3566 : 0 : desc.params.sw_rules.num_rules_fltr_entry_index =
3567 : : CPU_TO_LE16(num_rules);
3568 : 0 : status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
3569 [ # # ]: 0 : if (opc != ice_aqc_opc_add_sw_rules &&
3570 [ # # ]: 0 : hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
3571 : : status = ICE_ERR_DOES_NOT_EXIST;
3572 : :
3573 : : return status;
3574 : : }
3575 : :
3576 : : /**
3577 : : * ice_aq_add_recipe - add switch recipe
3578 : : * @hw: pointer to the HW struct
3579 : : * @s_recipe_list: pointer to switch rule population list
3580 : : * @num_recipes: number of switch recipes in the list
3581 : : * @cd: pointer to command details structure or NULL
3582 : : *
3583 : : * Add(0x0290)
3584 : : */
3585 : : enum ice_status
3586 : 0 : ice_aq_add_recipe(struct ice_hw *hw,
3587 : : struct ice_aqc_recipe_data_elem *s_recipe_list,
3588 : : u16 num_recipes, struct ice_sq_cd *cd)
3589 : : {
3590 : : struct ice_aqc_add_get_recipe *cmd;
3591 : : struct ice_aq_desc desc;
3592 : : u16 buf_size;
3593 : :
3594 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3595 : : cmd = &desc.params.add_get_recipe;
3596 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
3597 : :
3598 : 0 : cmd->num_sub_recipes = CPU_TO_LE16(num_recipes);
3599 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3600 : :
3601 : 0 : buf_size = num_recipes * sizeof(*s_recipe_list);
3602 : :
3603 : 0 : return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3604 : : }
3605 : :
3606 : : /**
3607 : : * ice_aq_get_recipe - get switch recipe
3608 : : * @hw: pointer to the HW struct
3609 : : * @s_recipe_list: pointer to switch rule population list
3610 : : * @num_recipes: pointer to the number of recipes (input and output)
3611 : : * @recipe_root: root recipe number of recipe(s) to retrieve
3612 : : * @cd: pointer to command details structure or NULL
3613 : : *
3614 : : * Get(0x0292)
3615 : : *
3616 : : * On input, *num_recipes should equal the number of entries in s_recipe_list.
3617 : : * On output, *num_recipes will equal the number of entries returned in
3618 : : * s_recipe_list.
3619 : : *
3620 : : * The caller must supply enough space in s_recipe_list to hold all possible
3621 : : * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
3622 : : */
3623 : : enum ice_status
3624 : 0 : ice_aq_get_recipe(struct ice_hw *hw,
3625 : : struct ice_aqc_recipe_data_elem *s_recipe_list,
3626 : : u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
3627 : : {
3628 : : struct ice_aqc_add_get_recipe *cmd;
3629 : : struct ice_aq_desc desc;
3630 : : enum ice_status status;
3631 : : u16 buf_size;
3632 : :
3633 [ # # ]: 0 : if (*num_recipes != ICE_MAX_NUM_RECIPES)
3634 : : return ICE_ERR_PARAM;
3635 : :
3636 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3637 : : cmd = &desc.params.add_get_recipe;
3638 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
3639 : :
3640 : 0 : cmd->return_index = CPU_TO_LE16(recipe_root);
3641 : 0 : cmd->num_sub_recipes = 0;
3642 : :
3643 : 0 : buf_size = *num_recipes * sizeof(*s_recipe_list);
3644 : :
3645 : 0 : status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3646 : 0 : *num_recipes = LE16_TO_CPU(cmd->num_sub_recipes);
3647 : :
3648 : 0 : return status;
3649 : : }
3650 : :
3651 : : /**
3652 : : * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
3653 : : * @hw: pointer to the HW struct
3654 : : * @params: parameters used to update the default recipe
3655 : : *
3656 : : * This function only supports updating default recipes and it only supports
3657 : : * updating a single recipe based on the lkup_idx at a time.
3658 : : *
3659 : : * This is done as a read-modify-write operation. First, get the current recipe
3660 : : * contents based on the recipe's ID. Then modify the field vector index and
3661 : : * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
3662 : : * the pre-existing recipe with the modifications.
3663 : : */
3664 : : enum ice_status
3665 : 0 : ice_update_recipe_lkup_idx(struct ice_hw *hw,
3666 : : struct ice_update_recipe_lkup_idx_params *params)
3667 : : {
3668 : : struct ice_aqc_recipe_data_elem *rcp_list;
3669 : 0 : u16 num_recps = ICE_MAX_NUM_RECIPES;
3670 : : enum ice_status status;
3671 : :
3672 : 0 : rcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));
3673 [ # # ]: 0 : if (!rcp_list)
3674 : : return ICE_ERR_NO_MEMORY;
3675 : :
3676 : : /* read current recipe list from firmware */
3677 : 0 : rcp_list->recipe_indx = params->rid;
3678 : 0 : status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
3679 [ # # ]: 0 : if (status) {
3680 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
3681 : : params->rid, status);
3682 : 0 : goto error_out;
3683 : : }
3684 : :
3685 : : /* only modify existing recipe's lkup_idx and mask if valid, while
3686 : : * leaving all other fields the same, then update the recipe firmware
3687 : : */
3688 : 0 : rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
3689 [ # # ]: 0 : if (params->mask_valid)
3690 : 0 : rcp_list->content.mask[params->lkup_idx] =
3691 : 0 : CPU_TO_LE16(params->mask);
3692 : :
3693 [ # # ]: 0 : if (params->ignore_valid)
3694 : 0 : rcp_list->content.lkup_indx[params->lkup_idx] |=
3695 : : ICE_AQ_RECIPE_LKUP_IGNORE;
3696 : :
3697 : 0 : status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
3698 [ # # ]: 0 : if (status)
3699 [ # # # # ]: 0 : 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",
3700 : : params->rid, params->lkup_idx, params->fv_idx,
3701 : : params->mask, params->mask_valid ? "true" : "false",
3702 : : status);
3703 : :
3704 : 0 : error_out:
3705 : 0 : ice_free(hw, rcp_list);
3706 : 0 : return status;
3707 : : }
3708 : :
3709 : : /**
3710 : : * ice_aq_map_recipe_to_profile - Map recipe to packet profile
3711 : : * @hw: pointer to the HW struct
3712 : : * @profile_id: package profile ID to associate the recipe with
3713 : : * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3714 : : * @cd: pointer to command details structure or NULL
3715 : : * Recipe to profile association (0x0291)
3716 : : */
3717 : : enum ice_status
3718 : 0 : ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3719 : : struct ice_sq_cd *cd)
3720 : : {
3721 : : struct ice_aqc_recipe_to_profile *cmd;
3722 : : struct ice_aq_desc desc;
3723 : :
3724 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3725 : : cmd = &desc.params.recipe_to_profile;
3726 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
3727 [ # # ]: 0 : cmd->profile_id = CPU_TO_LE16(profile_id);
3728 : : /* Set the recipe ID bit in the bitmask to let the device know which
3729 : : * profile we are associating the recipe to
3730 : : */
3731 : : ice_memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc),
3732 : : ICE_NONDMA_TO_NONDMA);
3733 : :
3734 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3735 : : }
3736 : :
3737 : : /**
3738 : : * ice_aq_get_recipe_to_profile - Map recipe to packet profile
3739 : : * @hw: pointer to the HW struct
3740 : : * @profile_id: package profile ID to associate the recipe with
3741 : : * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3742 : : * @cd: pointer to command details structure or NULL
3743 : : * Associate profile ID with given recipe (0x0293)
3744 : : */
3745 : : enum ice_status
3746 : 0 : ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3747 : : struct ice_sq_cd *cd)
3748 : : {
3749 : : struct ice_aqc_recipe_to_profile *cmd;
3750 : : struct ice_aq_desc desc;
3751 : : enum ice_status status;
3752 : :
3753 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3754 : : cmd = &desc.params.recipe_to_profile;
3755 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
3756 : 0 : cmd->profile_id = CPU_TO_LE16(profile_id);
3757 : :
3758 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3759 [ # # ]: 0 : if (!status)
3760 : : ice_memcpy(r_bitmap, cmd->recipe_assoc,
3761 : : sizeof(cmd->recipe_assoc), ICE_NONDMA_TO_NONDMA);
3762 : :
3763 : 0 : return status;
3764 : : }
3765 : :
3766 : : /**
3767 : : * ice_alloc_recipe - add recipe resource
3768 : : * @hw: pointer to the hardware structure
3769 : : * @rid: recipe ID returned as response to AQ call
3770 : : */
3771 : 0 : enum ice_status ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
3772 : : {
3773 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
3774 : : enum ice_status status;
3775 : : u16 buf_len;
3776 : :
3777 : : buf_len = ice_struct_size(sw_buf, elem, 1);
3778 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3779 [ # # ]: 0 : if (!sw_buf)
3780 : : return ICE_ERR_NO_MEMORY;
3781 : :
3782 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
3783 : 0 : sw_buf->res_type = CPU_TO_LE16((ICE_AQC_RES_TYPE_RECIPE <<
3784 : : ICE_AQC_RES_TYPE_S) |
3785 : : ICE_AQC_RES_TYPE_FLAG_SHARED);
3786 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
3787 : : ice_aqc_opc_alloc_res, NULL);
3788 [ # # ]: 0 : if (!status)
3789 : 0 : *rid = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
3790 : 0 : ice_free(hw, sw_buf);
3791 : :
3792 : 0 : return status;
3793 : : }
3794 : :
3795 : : /* ice_init_port_info - Initialize port_info with switch configuration data
3796 : : * @pi: pointer to port_info
3797 : : * @vsi_port_num: VSI number or port number
3798 : : * @type: Type of switch element (port or VSI)
3799 : : * @swid: switch ID of the switch the element is attached to
3800 : : * @pf_vf_num: PF or VF number
3801 : : * @is_vf: true if the element is a VF, false otherwise
3802 : : */
3803 : : static void
3804 : 0 : ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
3805 : : u16 swid, u16 pf_vf_num, bool is_vf)
3806 : : {
3807 [ # # ]: 0 : switch (type) {
3808 : 0 : case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3809 : 0 : pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
3810 : 0 : pi->sw_id = swid;
3811 : 0 : pi->pf_vf_num = pf_vf_num;
3812 : 0 : pi->is_vf = is_vf;
3813 : 0 : break;
3814 : 0 : default:
3815 [ # # ]: 0 : ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
3816 : : break;
3817 : : }
3818 : 0 : }
3819 : :
3820 : : /* ice_get_initial_sw_cfg - Get initial port and default VSI data
3821 : : * @hw: pointer to the hardware structure
3822 : : */
3823 : 0 : enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw)
3824 : : {
3825 : : struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
3826 : : enum ice_status status;
3827 : : u8 num_total_ports;
3828 : 0 : u16 req_desc = 0;
3829 : : u16 num_elems;
3830 : : u8 j = 0;
3831 : : u16 i;
3832 : :
3833 : : num_total_ports = 1;
3834 : :
3835 : : rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *)
3836 : 0 : ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN);
3837 : :
3838 [ # # ]: 0 : if (!rbuf)
3839 : : return ICE_ERR_NO_MEMORY;
3840 : :
3841 : : /* Multiple calls to ice_aq_get_sw_cfg may be required
3842 : : * to get all the switch configuration information. The need
3843 : : * for additional calls is indicated by ice_aq_get_sw_cfg
3844 : : * writing a non-zero value in req_desc
3845 : : */
3846 : : do {
3847 : : struct ice_aqc_get_sw_cfg_resp_elem *ele;
3848 : :
3849 : 0 : status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
3850 : : &req_desc, &num_elems, NULL);
3851 : :
3852 [ # # ]: 0 : if (status)
3853 : : break;
3854 : :
3855 [ # # ]: 0 : for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
3856 : : u16 pf_vf_num, swid, vsi_port_num;
3857 : : bool is_vf = false;
3858 : : u8 res_type;
3859 : :
3860 : 0 : vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) &
3861 : : ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
3862 : :
3863 : 0 : pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) &
3864 : : ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
3865 : :
3866 : 0 : swid = LE16_TO_CPU(ele->swid);
3867 : :
3868 [ # # ]: 0 : if (LE16_TO_CPU(ele->pf_vf_num) &
3869 : : ICE_AQC_GET_SW_CONF_RESP_IS_VF)
3870 : : is_vf = true;
3871 : :
3872 : 0 : res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >>
3873 : : ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
3874 : :
3875 [ # # # ]: 0 : switch (res_type) {
3876 : 0 : case ICE_AQC_GET_SW_CONF_RESP_VSI:
3877 [ # # # # ]: 0 : if (hw->dcf_enabled && !is_vf)
3878 : 0 : hw->pf_id = pf_vf_num;
3879 : : break;
3880 : 0 : case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3881 : : case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT:
3882 [ # # ]: 0 : if (j == num_total_ports) {
3883 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "more ports than expected\n");
3884 : : status = ICE_ERR_CFG;
3885 : 0 : goto out;
3886 : : }
3887 : 0 : ice_init_port_info(hw->port_info,
3888 : : vsi_port_num, res_type, swid,
3889 : : pf_vf_num, is_vf);
3890 : 0 : j++;
3891 : 0 : break;
3892 : : default:
3893 : : break;
3894 : : }
3895 : : }
3896 [ # # ]: 0 : } while (req_desc && !status);
3897 : :
3898 : 0 : out:
3899 : 0 : ice_free(hw, rbuf);
3900 : 0 : return status;
3901 : : }
3902 : :
3903 : : /**
3904 : : * ice_fill_sw_info - Helper function to populate lb_en and lan_en
3905 : : * @hw: pointer to the hardware structure
3906 : : * @fi: filter info structure to fill/update
3907 : : *
3908 : : * This helper function populates the lb_en and lan_en elements of the provided
3909 : : * ice_fltr_info struct using the switch's type and characteristics of the
3910 : : * switch rule being configured.
3911 : : */
3912 : 0 : static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
3913 : : {
3914 : 0 : if ((fi->flag & ICE_FLTR_RX) &&
3915 : : (fi->fltr_act == ICE_FWD_TO_VSI ||
3916 : : fi->fltr_act == ICE_FWD_TO_VSI_LIST) &&
3917 : : fi->lkup_type == ICE_SW_LKUP_LAST)
3918 : : fi->lan_en = true;
3919 : 0 : fi->lb_en = false;
3920 : 0 : fi->lan_en = false;
3921 [ # # ]: 0 : if ((fi->flag & ICE_FLTR_TX) &&
3922 [ # # ]: 0 : (fi->fltr_act == ICE_FWD_TO_VSI ||
3923 : : fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
3924 : : fi->fltr_act == ICE_FWD_TO_Q ||
3925 : : fi->fltr_act == ICE_FWD_TO_QGRP)) {
3926 : : /* Setting LB for prune actions will result in replicated
3927 : : * packets to the internal switch that will be dropped.
3928 : : */
3929 [ # # ]: 0 : if (fi->lkup_type != ICE_SW_LKUP_VLAN)
3930 : 0 : fi->lb_en = true;
3931 : :
3932 : : /* Set lan_en to TRUE if
3933 : : * 1. The switch is a VEB AND
3934 : : * 2
3935 : : * 2.1 The lookup is a directional lookup like ethertype,
3936 : : * promiscuous, ethertype-MAC, promiscuous-VLAN
3937 : : * and default-port OR
3938 : : * 2.2 The lookup is VLAN, OR
3939 : : * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
3940 : : * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
3941 : : *
3942 : : * OR
3943 : : *
3944 : : * The switch is a VEPA.
3945 : : *
3946 : : * In all other cases, the LAN enable has to be set to false.
3947 : : */
3948 [ # # ]: 0 : if (hw->evb_veb) {
3949 [ # # ]: 0 : if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3950 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_PROMISC ||
3951 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3952 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3953 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_DFLT ||
3954 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_VLAN ||
3955 : 0 : (fi->lkup_type == ICE_SW_LKUP_MAC &&
3956 [ # # # # ]: 0 : !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) ||
3957 : 0 : (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
3958 [ # # ]: 0 : !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)))
3959 : 0 : fi->lan_en = true;
3960 : : } else {
3961 : 0 : fi->lan_en = true;
3962 : : }
3963 : : }
3964 : 0 : }
3965 : :
3966 : : /**
3967 : : * ice_fill_sw_rule - Helper function to fill switch rule structure
3968 : : * @hw: pointer to the hardware structure
3969 : : * @f_info: entry containing packet forwarding information
3970 : : * @s_rule: switch rule structure to be filled in based on mac_entry
3971 : : * @opc: switch rules population command type - pass in the command opcode
3972 : : */
3973 : : static void
3974 : 0 : ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
3975 : : struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc)
3976 : : {
3977 : : u16 vlan_id = ICE_MAX_VLAN_ID + 1;
3978 : : u16 vlan_tpid = ICE_ETH_P_8021Q;
3979 : : void *daddr = NULL;
3980 : : u16 eth_hdr_sz;
3981 : : u8 *eth_hdr;
3982 : : u32 act = 0;
3983 : : __be16 *off;
3984 : : u8 q_rgn;
3985 : :
3986 [ # # ]: 0 : if (opc == ice_aqc_opc_remove_sw_rules) {
3987 : 0 : s_rule->pdata.lkup_tx_rx.act = 0;
3988 : 0 : s_rule->pdata.lkup_tx_rx.index =
3989 : 0 : CPU_TO_LE16(f_info->fltr_rule_id);
3990 : 0 : s_rule->pdata.lkup_tx_rx.hdr_len = 0;
3991 : 0 : return;
3992 : : }
3993 : :
3994 : : eth_hdr_sz = sizeof(dummy_eth_header);
3995 [ # # ]: 0 : eth_hdr = s_rule->pdata.lkup_tx_rx.hdr;
3996 : :
3997 : : /* initialize the ether header with a dummy header */
3998 : : ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA);
3999 : 0 : ice_fill_sw_info(hw, f_info);
4000 : :
4001 [ # # # # : 0 : switch (f_info->fltr_act) {
# # ]
4002 : 0 : case ICE_FWD_TO_VSI:
4003 : 0 : act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
4004 : : ICE_SINGLE_ACT_VSI_ID_M;
4005 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
4006 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING |
4007 : : ICE_SINGLE_ACT_VALID_BIT;
4008 : : break;
4009 : 0 : case ICE_FWD_TO_VSI_LIST:
4010 : : act |= ICE_SINGLE_ACT_VSI_LIST;
4011 : 0 : act |= (f_info->fwd_id.vsi_list_id <<
4012 : 0 : ICE_SINGLE_ACT_VSI_LIST_ID_S) &
4013 : : ICE_SINGLE_ACT_VSI_LIST_ID_M;
4014 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
4015 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING |
4016 : : ICE_SINGLE_ACT_VALID_BIT;
4017 : : break;
4018 : 0 : case ICE_FWD_TO_Q:
4019 : : act |= ICE_SINGLE_ACT_TO_Q;
4020 : 0 : act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
4021 : : ICE_SINGLE_ACT_Q_INDEX_M;
4022 : 0 : break;
4023 : : case ICE_DROP_PACKET:
4024 : : act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
4025 : : ICE_SINGLE_ACT_VALID_BIT;
4026 : : break;
4027 : 0 : case ICE_FWD_TO_QGRP:
4028 [ # # ]: 0 : q_rgn = f_info->qgrp_size > 0 ?
4029 : 0 : (u8)ice_ilog2(f_info->qgrp_size) : 0;
4030 : : act |= ICE_SINGLE_ACT_TO_Q;
4031 : 0 : act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
4032 : : ICE_SINGLE_ACT_Q_INDEX_M;
4033 : 0 : act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
4034 : : ICE_SINGLE_ACT_Q_REGION_M;
4035 : 0 : break;
4036 : : default:
4037 : : return;
4038 : : }
4039 : :
4040 [ # # ]: 0 : if (f_info->lb_en)
4041 : 0 : act |= ICE_SINGLE_ACT_LB_ENABLE;
4042 [ # # ]: 0 : if (f_info->lan_en)
4043 : 0 : act |= ICE_SINGLE_ACT_LAN_ENABLE;
4044 : :
4045 [ # # # # : 0 : switch (f_info->lkup_type) {
# # # # ]
4046 : 0 : case ICE_SW_LKUP_MAC:
4047 : 0 : daddr = f_info->l_data.mac.mac_addr;
4048 : 0 : break;
4049 : 0 : case ICE_SW_LKUP_VLAN:
4050 : 0 : vlan_id = f_info->l_data.vlan.vlan_id;
4051 [ # # ]: 0 : if (f_info->l_data.vlan.tpid_valid)
4052 : 0 : vlan_tpid = f_info->l_data.vlan.tpid;
4053 [ # # ]: 0 : if (f_info->fltr_act == ICE_FWD_TO_VSI ||
4054 : : f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
4055 : : act |= ICE_SINGLE_ACT_PRUNE;
4056 : 0 : act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
4057 : : }
4058 : : break;
4059 : 0 : case ICE_SW_LKUP_ETHERTYPE_MAC:
4060 : 0 : daddr = f_info->l_data.ethertype_mac.mac_addr;
4061 : : /* fall-through */
4062 : 0 : case ICE_SW_LKUP_ETHERTYPE:
4063 : : off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
4064 [ # # ]: 0 : *off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype);
4065 : 0 : break;
4066 : 0 : case ICE_SW_LKUP_MAC_VLAN:
4067 : 0 : daddr = f_info->l_data.mac_vlan.mac_addr;
4068 : 0 : vlan_id = f_info->l_data.mac_vlan.vlan_id;
4069 : 0 : break;
4070 : 0 : case ICE_SW_LKUP_PROMISC_VLAN:
4071 : 0 : vlan_id = f_info->l_data.mac_vlan.vlan_id;
4072 : : /* fall-through */
4073 : 0 : case ICE_SW_LKUP_PROMISC:
4074 : 0 : daddr = f_info->l_data.mac_vlan.mac_addr;
4075 : 0 : break;
4076 : : default:
4077 : : break;
4078 : : }
4079 : :
4080 : 0 : s_rule->type = (f_info->flag & ICE_FLTR_RX) ?
4081 : 0 : CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) :
4082 : : CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
4083 : :
4084 : : /* Recipe set depending on lookup type */
4085 : 0 : s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(f_info->lkup_type);
4086 : 0 : s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(f_info->src);
4087 : 0 : s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
4088 : :
4089 [ # # ]: 0 : if (daddr)
4090 : : ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN,
4091 : : ICE_NONDMA_TO_NONDMA);
4092 : :
4093 [ # # ]: 0 : if (!(vlan_id > ICE_MAX_VLAN_ID)) {
4094 : : off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
4095 [ # # ]: 0 : *off = CPU_TO_BE16(vlan_id);
4096 : : off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
4097 [ # # ]: 0 : *off = CPU_TO_BE16(vlan_tpid);
4098 : : }
4099 : :
4100 : : /* Create the switch rule with the final dummy Ethernet header */
4101 [ # # ]: 0 : if (opc != ice_aqc_opc_update_sw_rules)
4102 : 0 : s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(eth_hdr_sz);
4103 : : }
4104 : :
4105 : : /**
4106 : : * ice_add_marker_act
4107 : : * @hw: pointer to the hardware structure
4108 : : * @m_ent: the management entry for which sw marker needs to be added
4109 : : * @sw_marker: sw marker to tag the Rx descriptor with
4110 : : * @l_id: large action resource ID
4111 : : *
4112 : : * Create a large action to hold software marker and update the switch rule
4113 : : * entry pointed by m_ent with newly created large action
4114 : : */
4115 : : static enum ice_status
4116 : 0 : ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
4117 : : u16 sw_marker, u16 l_id)
4118 : : {
4119 : : struct ice_aqc_sw_rules_elem *lg_act, *rx_tx;
4120 : : /* For software marker we need 3 large actions
4121 : : * 1. FWD action: FWD TO VSI or VSI LIST
4122 : : * 2. GENERIC VALUE action to hold the profile ID
4123 : : * 3. GENERIC VALUE action to hold the software marker ID
4124 : : */
4125 : : const u16 num_lg_acts = 3;
4126 : : enum ice_status status;
4127 : : u16 lg_act_size;
4128 : : u16 rules_size;
4129 : : u32 act;
4130 : : u16 id;
4131 : :
4132 [ # # ]: 0 : if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
4133 : : return ICE_ERR_PARAM;
4134 : :
4135 : : /* Create two back-to-back switch rules and submit them to the HW using
4136 : : * one memory buffer:
4137 : : * 1. Large Action
4138 : : * 2. Look up Tx Rx
4139 : : */
4140 : : lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts);
4141 : : rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
4142 : 0 : lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
4143 [ # # ]: 0 : if (!lg_act)
4144 : : return ICE_ERR_NO_MEMORY;
4145 : :
4146 : 0 : rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
4147 : :
4148 : : /* Fill in the first switch rule i.e. large action */
4149 : 0 : lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
4150 : 0 : lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
4151 : 0 : lg_act->pdata.lg_act.size = CPU_TO_LE16(num_lg_acts);
4152 : :
4153 : : /* First action VSI forwarding or VSI list forwarding depending on how
4154 : : * many VSIs
4155 : : */
4156 [ # # ]: 0 : id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
4157 : 0 : m_ent->fltr_info.fwd_id.hw_vsi_id;
4158 : :
4159 : : act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
4160 : 0 : act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
4161 [ # # ]: 0 : if (m_ent->vsi_count > 1)
4162 : 0 : act |= ICE_LG_ACT_VSI_LIST;
4163 : 0 : lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
4164 : :
4165 : : /* Second action descriptor type */
4166 : : act = ICE_LG_ACT_GENERIC;
4167 : :
4168 : : act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
4169 : 0 : lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
4170 : :
4171 : : act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
4172 : : ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
4173 : :
4174 : : /* Third action Marker value */
4175 : : act |= ICE_LG_ACT_GENERIC;
4176 : 0 : act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
4177 : : ICE_LG_ACT_GENERIC_VALUE_M;
4178 : :
4179 : 0 : lg_act->pdata.lg_act.act[2] = CPU_TO_LE32(act);
4180 : :
4181 : : /* call the fill switch rule to fill the lookup Tx Rx structure */
4182 : 0 : ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
4183 : : ice_aqc_opc_update_sw_rules);
4184 : :
4185 : : /* Update the action to point to the large action ID */
4186 : 0 : rx_tx->pdata.lkup_tx_rx.act =
4187 : 0 : CPU_TO_LE32(ICE_SINGLE_ACT_PTR |
4188 : : ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
4189 : : ICE_SINGLE_ACT_PTR_VAL_M));
4190 : :
4191 : : /* Use the filter rule ID of the previously created rule with single
4192 : : * act. Once the update happens, hardware will treat this as large
4193 : : * action
4194 : : */
4195 : 0 : rx_tx->pdata.lkup_tx_rx.index =
4196 : 0 : CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id);
4197 : :
4198 : 0 : status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
4199 : : ice_aqc_opc_update_sw_rules, NULL);
4200 [ # # ]: 0 : if (!status) {
4201 : 0 : m_ent->lg_act_idx = l_id;
4202 : 0 : m_ent->sw_marker_id = sw_marker;
4203 : : }
4204 : :
4205 : 0 : ice_free(hw, lg_act);
4206 : 0 : return status;
4207 : : }
4208 : :
4209 : : /**
4210 : : * ice_add_counter_act - add/update filter rule with counter action
4211 : : * @hw: pointer to the hardware structure
4212 : : * @m_ent: the management entry for which counter needs to be added
4213 : : * @counter_id: VLAN counter ID returned as part of allocate resource
4214 : : * @l_id: large action resource ID
4215 : : */
4216 : : static enum ice_status
4217 : 0 : ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
4218 : : u16 counter_id, u16 l_id)
4219 : : {
4220 : : struct ice_aqc_sw_rules_elem *lg_act;
4221 : : struct ice_aqc_sw_rules_elem *rx_tx;
4222 : : enum ice_status status;
4223 : : /* 2 actions will be added while adding a large action counter */
4224 : : const int num_acts = 2;
4225 : : u16 lg_act_size;
4226 : : u16 rules_size;
4227 : : u16 f_rule_id;
4228 : : u32 act;
4229 : : u16 id;
4230 : :
4231 [ # # ]: 0 : if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
4232 : : return ICE_ERR_PARAM;
4233 : :
4234 : : /* Create two back-to-back switch rules and submit them to the HW using
4235 : : * one memory buffer:
4236 : : * 1. Large Action
4237 : : * 2. Look up Tx Rx
4238 : : */
4239 : : lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_acts);
4240 : : rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
4241 : 0 : lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
4242 [ # # ]: 0 : if (!lg_act)
4243 : : return ICE_ERR_NO_MEMORY;
4244 : :
4245 : 0 : rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
4246 : :
4247 : : /* Fill in the first switch rule i.e. large action */
4248 : 0 : lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
4249 : 0 : lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
4250 : 0 : lg_act->pdata.lg_act.size = CPU_TO_LE16(num_acts);
4251 : :
4252 : : /* First action VSI forwarding or VSI list forwarding depending on how
4253 : : * many VSIs
4254 : : */
4255 [ # # ]: 0 : id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
4256 : 0 : m_ent->fltr_info.fwd_id.hw_vsi_id;
4257 : :
4258 : : act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
4259 : 0 : act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
4260 : : ICE_LG_ACT_VSI_LIST_ID_M;
4261 [ # # ]: 0 : if (m_ent->vsi_count > 1)
4262 : 0 : act |= ICE_LG_ACT_VSI_LIST;
4263 : 0 : lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
4264 : :
4265 : : /* Second action counter ID */
4266 : : act = ICE_LG_ACT_STAT_COUNT;
4267 : 0 : act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) &
4268 : : ICE_LG_ACT_STAT_COUNT_M;
4269 : 0 : lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
4270 : :
4271 : : /* call the fill switch rule to fill the lookup Tx Rx structure */
4272 : 0 : ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
4273 : : ice_aqc_opc_update_sw_rules);
4274 : :
4275 : : act = ICE_SINGLE_ACT_PTR;
4276 : 0 : act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M;
4277 : 0 : rx_tx->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
4278 : :
4279 : : /* Use the filter rule ID of the previously created rule with single
4280 : : * act. Once the update happens, hardware will treat this as large
4281 : : * action
4282 : : */
4283 : 0 : f_rule_id = m_ent->fltr_info.fltr_rule_id;
4284 : 0 : rx_tx->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_rule_id);
4285 : :
4286 : 0 : status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
4287 : : ice_aqc_opc_update_sw_rules, NULL);
4288 [ # # ]: 0 : if (!status) {
4289 : 0 : m_ent->lg_act_idx = l_id;
4290 : 0 : m_ent->counter_index = (u8)counter_id;
4291 : : }
4292 : :
4293 : 0 : ice_free(hw, lg_act);
4294 : 0 : return status;
4295 : : }
4296 : :
4297 : : /**
4298 : : * ice_create_vsi_list_map
4299 : : * @hw: pointer to the hardware structure
4300 : : * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
4301 : : * @num_vsi: number of VSI handles in the array
4302 : : * @vsi_list_id: VSI list ID generated as part of allocate resource
4303 : : *
4304 : : * Helper function to create a new entry of VSI list ID to VSI mapping
4305 : : * using the given VSI list ID
4306 : : */
4307 : : static struct ice_vsi_list_map_info *
4308 : 0 : ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4309 : : u16 vsi_list_id)
4310 : : {
4311 : 0 : struct ice_switch_info *sw = hw->switch_info;
4312 : : struct ice_vsi_list_map_info *v_map;
4313 : : int i;
4314 : :
4315 : 0 : v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map));
4316 [ # # ]: 0 : if (!v_map)
4317 : : return NULL;
4318 : :
4319 : 0 : v_map->vsi_list_id = vsi_list_id;
4320 : 0 : v_map->ref_cnt = 1;
4321 [ # # ]: 0 : for (i = 0; i < num_vsi; i++)
4322 : 0 : ice_set_bit(vsi_handle_arr[i], v_map->vsi_map);
4323 : :
4324 [ # # ]: 0 : LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head);
4325 : 0 : return v_map;
4326 : : }
4327 : :
4328 : : /**
4329 : : * ice_update_vsi_list_rule
4330 : : * @hw: pointer to the hardware structure
4331 : : * @vsi_handle_arr: array of VSI handles to form a VSI list
4332 : : * @num_vsi: number of VSI handles in the array
4333 : : * @vsi_list_id: VSI list ID generated as part of allocate resource
4334 : : * @remove: Boolean value to indicate if this is a remove action
4335 : : * @opc: switch rules population command type - pass in the command opcode
4336 : : * @lkup_type: lookup type of the filter
4337 : : *
4338 : : * Call AQ command to add a new switch rule or update existing switch rule
4339 : : * using the given VSI list ID
4340 : : */
4341 : : static enum ice_status
4342 : 0 : ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4343 : : u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
4344 : : enum ice_sw_lkup_type lkup_type)
4345 : : {
4346 : : struct ice_aqc_sw_rules_elem *s_rule;
4347 : : enum ice_status status;
4348 : : u16 s_rule_size;
4349 : : u16 rule_type;
4350 : : int i;
4351 : :
4352 [ # # ]: 0 : if (!num_vsi)
4353 : : return ICE_ERR_PARAM;
4354 : :
4355 : 0 : if (lkup_type == ICE_SW_LKUP_MAC ||
4356 : 0 : lkup_type == ICE_SW_LKUP_MAC_VLAN ||
4357 : 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE ||
4358 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
4359 : 0 : lkup_type == ICE_SW_LKUP_PROMISC ||
4360 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
4361 : 0 : lkup_type == ICE_SW_LKUP_DFLT ||
4362 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_LAST)
4363 [ # # ]: 0 : rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
4364 : : ICE_AQC_SW_RULES_T_VSI_LIST_SET;
4365 [ # # ]: 0 : else if (lkup_type == ICE_SW_LKUP_VLAN)
4366 [ # # ]: 0 : rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
4367 : : ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
4368 : : else
4369 : : return ICE_ERR_PARAM;
4370 : :
4371 : 0 : s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi);
4372 : 0 : s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size);
4373 [ # # ]: 0 : if (!s_rule)
4374 : : return ICE_ERR_NO_MEMORY;
4375 [ # # ]: 0 : for (i = 0; i < num_vsi; i++) {
4376 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
4377 : : status = ICE_ERR_PARAM;
4378 : 0 : goto exit;
4379 : : }
4380 : : /* AQ call requires hw_vsi_id(s) */
4381 : 0 : s_rule->pdata.vsi_list.vsi[i] =
4382 : 0 : CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
4383 : : }
4384 : :
4385 : 0 : s_rule->type = CPU_TO_LE16(rule_type);
4386 : 0 : s_rule->pdata.vsi_list.number_vsi = CPU_TO_LE16(num_vsi);
4387 : 0 : s_rule->pdata.vsi_list.index = CPU_TO_LE16(vsi_list_id);
4388 : :
4389 : 0 : status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
4390 : :
4391 : 0 : exit:
4392 : 0 : ice_free(hw, s_rule);
4393 : 0 : return status;
4394 : : }
4395 : :
4396 : : /**
4397 : : * ice_create_vsi_list_rule - Creates and populates a VSI list rule
4398 : : * @hw: pointer to the HW struct
4399 : : * @vsi_handle_arr: array of VSI handles to form a VSI list
4400 : : * @num_vsi: number of VSI handles in the array
4401 : : * @vsi_list_id: stores the ID of the VSI list to be created
4402 : : * @lkup_type: switch rule filter's lookup type
4403 : : */
4404 : : static enum ice_status
4405 : 0 : ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4406 : : u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
4407 : : {
4408 : : enum ice_status status;
4409 : :
4410 : 0 : status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
4411 : : ice_aqc_opc_alloc_res);
4412 [ # # ]: 0 : if (status)
4413 : : return status;
4414 : :
4415 : : /* Update the newly created VSI list to include the specified VSIs */
4416 : 0 : return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
4417 : 0 : *vsi_list_id, false,
4418 : : ice_aqc_opc_add_sw_rules, lkup_type);
4419 : : }
4420 : :
4421 : : /**
4422 : : * ice_create_pkt_fwd_rule
4423 : : * @hw: pointer to the hardware structure
4424 : : * @recp_list: corresponding filter management list
4425 : : * @f_entry: entry containing packet forwarding information
4426 : : *
4427 : : * Create switch rule with given filter information and add an entry
4428 : : * to the corresponding filter management list to track this switch rule
4429 : : * and VSI mapping
4430 : : */
4431 : : static enum ice_status
4432 : 0 : ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4433 : : struct ice_fltr_list_entry *f_entry)
4434 : : {
4435 : : struct ice_fltr_mgmt_list_entry *fm_entry;
4436 : : struct ice_aqc_sw_rules_elem *s_rule;
4437 : : enum ice_status status;
4438 : :
4439 : : s_rule = (struct ice_aqc_sw_rules_elem *)
4440 : 0 : ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
4441 [ # # ]: 0 : if (!s_rule)
4442 : : return ICE_ERR_NO_MEMORY;
4443 : : fm_entry = (struct ice_fltr_mgmt_list_entry *)
4444 : 0 : ice_malloc(hw, sizeof(*fm_entry));
4445 [ # # ]: 0 : if (!fm_entry) {
4446 : : status = ICE_ERR_NO_MEMORY;
4447 : 0 : goto ice_create_pkt_fwd_rule_exit;
4448 : : }
4449 : :
4450 : 0 : fm_entry->fltr_info = f_entry->fltr_info;
4451 : :
4452 : : /* Initialize all the fields for the management entry */
4453 : 0 : fm_entry->vsi_count = 1;
4454 : 0 : fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
4455 : 0 : fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
4456 : 0 : fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
4457 : :
4458 : 0 : ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
4459 : : ice_aqc_opc_add_sw_rules);
4460 : :
4461 : 0 : status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
4462 : : ice_aqc_opc_add_sw_rules, NULL);
4463 [ # # ]: 0 : if (status) {
4464 : 0 : ice_free(hw, fm_entry);
4465 : 0 : goto ice_create_pkt_fwd_rule_exit;
4466 : : }
4467 : :
4468 : 0 : f_entry->fltr_info.fltr_rule_id =
4469 : 0 : LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
4470 : 0 : fm_entry->fltr_info.fltr_rule_id =
4471 : : LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index);
4472 : :
4473 : : /* The book keeping entries will get removed when base driver
4474 : : * calls remove filter AQ command
4475 : : */
4476 [ # # ]: 0 : LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules);
4477 : :
4478 : 0 : ice_create_pkt_fwd_rule_exit:
4479 : 0 : ice_free(hw, s_rule);
4480 : 0 : return status;
4481 : : }
4482 : :
4483 : : /**
4484 : : * ice_update_pkt_fwd_rule
4485 : : * @hw: pointer to the hardware structure
4486 : : * @f_info: filter information for switch rule
4487 : : *
4488 : : * Call AQ command to update a previously created switch rule with a
4489 : : * VSI list ID
4490 : : */
4491 : : static enum ice_status
4492 : 0 : ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
4493 : : {
4494 : : struct ice_aqc_sw_rules_elem *s_rule;
4495 : : enum ice_status status;
4496 : :
4497 : : s_rule = (struct ice_aqc_sw_rules_elem *)
4498 : 0 : ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE);
4499 [ # # ]: 0 : if (!s_rule)
4500 : : return ICE_ERR_NO_MEMORY;
4501 : :
4502 : 0 : ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
4503 : :
4504 : 0 : s_rule->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_info->fltr_rule_id);
4505 : :
4506 : : /* Update switch rule with new rule set to forward VSI list */
4507 : 0 : status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1,
4508 : : ice_aqc_opc_update_sw_rules, NULL);
4509 : :
4510 : 0 : ice_free(hw, s_rule);
4511 : 0 : return status;
4512 : : }
4513 : :
4514 : : /**
4515 : : * ice_update_sw_rule_bridge_mode
4516 : : * @hw: pointer to the HW struct
4517 : : *
4518 : : * Updates unicast switch filter rules based on VEB/VEPA mode
4519 : : */
4520 : 0 : enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
4521 : : {
4522 : : struct ice_fltr_mgmt_list_entry *fm_entry;
4523 : : enum ice_status status = ICE_SUCCESS;
4524 : : struct LIST_HEAD_TYPE *rule_head;
4525 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4526 : : struct ice_switch_info *sw;
4527 : 0 : sw = hw->switch_info;
4528 : :
4529 : 0 : rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
4530 : : rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4531 : :
4532 : 0 : ice_acquire_lock(rule_lock);
4533 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry,
# # ]
4534 : : list_entry) {
4535 : 0 : struct ice_fltr_info *fi = &fm_entry->fltr_info;
4536 : : u8 *addr = fi->l_data.mac.mac_addr;
4537 : :
4538 : : /* Update unicast Tx rules to reflect the selected
4539 : : * VEB/VEPA mode
4540 : : */
4541 [ # # # # ]: 0 : if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) &&
4542 [ # # ]: 0 : (fi->fltr_act == ICE_FWD_TO_VSI ||
4543 : : fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
4544 : : fi->fltr_act == ICE_FWD_TO_Q ||
4545 : : fi->fltr_act == ICE_FWD_TO_QGRP)) {
4546 : 0 : status = ice_update_pkt_fwd_rule(hw, fi);
4547 [ # # ]: 0 : if (status)
4548 : : break;
4549 : : }
4550 : : }
4551 : :
4552 : : ice_release_lock(rule_lock);
4553 : :
4554 : 0 : return status;
4555 : : }
4556 : :
4557 : : /**
4558 : : * ice_add_update_vsi_list
4559 : : * @hw: pointer to the hardware structure
4560 : : * @m_entry: pointer to current filter management list entry
4561 : : * @cur_fltr: filter information from the book keeping entry
4562 : : * @new_fltr: filter information with the new VSI to be added
4563 : : *
4564 : : * Call AQ command to add or update previously created VSI list with new VSI.
4565 : : *
4566 : : * Helper function to do book keeping associated with adding filter information
4567 : : * The algorithm to do the book keeping is described below :
4568 : : * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
4569 : : * if only one VSI has been added till now
4570 : : * Allocate a new VSI list and add two VSIs
4571 : : * to this list using switch rule command
4572 : : * Update the previously created switch rule with the
4573 : : * newly created VSI list ID
4574 : : * if a VSI list was previously created
4575 : : * Add the new VSI to the previously created VSI list set
4576 : : * using the update switch rule command
4577 : : */
4578 : : static enum ice_status
4579 : 0 : ice_add_update_vsi_list(struct ice_hw *hw,
4580 : : struct ice_fltr_mgmt_list_entry *m_entry,
4581 : : struct ice_fltr_info *cur_fltr,
4582 : : struct ice_fltr_info *new_fltr)
4583 : : {
4584 : : enum ice_status status = ICE_SUCCESS;
4585 : 0 : u16 vsi_list_id = 0;
4586 : :
4587 [ # # ]: 0 : if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
4588 : : cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
4589 : : return ICE_ERR_NOT_IMPL;
4590 : :
4591 [ # # ]: 0 : if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
4592 [ # # ]: 0 : new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
4593 : : (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
4594 : : cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
4595 : : return ICE_ERR_NOT_IMPL;
4596 : :
4597 [ # # # # ]: 0 : if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
4598 : : /* Only one entry existed in the mapping and it was not already
4599 : : * a part of a VSI list. So, create a VSI list with the old and
4600 : : * new VSIs.
4601 : : */
4602 : : struct ice_fltr_info tmp_fltr;
4603 : : u16 vsi_handle_arr[2];
4604 : :
4605 : : /* A rule already exists with the new VSI being added */
4606 [ # # ]: 0 : if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
4607 : 0 : return ICE_ERR_ALREADY_EXISTS;
4608 : :
4609 : 0 : vsi_handle_arr[0] = cur_fltr->vsi_handle;
4610 : 0 : vsi_handle_arr[1] = new_fltr->vsi_handle;
4611 : 0 : status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4612 : : &vsi_list_id,
4613 : : new_fltr->lkup_type);
4614 [ # # ]: 0 : if (status)
4615 : : return status;
4616 : :
4617 : 0 : tmp_fltr = *new_fltr;
4618 : 0 : tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
4619 : 0 : tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4620 : 0 : tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4621 : : /* Update the previous switch rule of "MAC forward to VSI" to
4622 : : * "MAC fwd to VSI list"
4623 : : */
4624 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4625 [ # # ]: 0 : if (status)
4626 : : return status;
4627 : :
4628 : 0 : cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
4629 : 0 : cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4630 : 0 : m_entry->vsi_list_info =
4631 : 0 : ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4632 : : vsi_list_id);
4633 : :
4634 [ # # ]: 0 : if (!m_entry->vsi_list_info)
4635 : : return ICE_ERR_NO_MEMORY;
4636 : :
4637 : : /* If this entry was large action then the large action needs
4638 : : * to be updated to point to FWD to VSI list
4639 : : */
4640 [ # # ]: 0 : if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
4641 : : status =
4642 : 0 : ice_add_marker_act(hw, m_entry,
4643 : : m_entry->sw_marker_id,
4644 : 0 : m_entry->lg_act_idx);
4645 : : } else {
4646 : 0 : u16 vsi_handle = new_fltr->vsi_handle;
4647 : : enum ice_adminq_opc opcode;
4648 : :
4649 [ # # ]: 0 : if (!m_entry->vsi_list_info)
4650 : 0 : return ICE_ERR_CFG;
4651 : :
4652 : : /* A rule already exists with the new VSI being added */
4653 [ # # ]: 0 : if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
4654 : : return ICE_SUCCESS;
4655 : :
4656 : : /* Update the previously created VSI list set with
4657 : : * the new VSI ID passed in
4658 : : */
4659 : 0 : vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
4660 : : opcode = ice_aqc_opc_update_sw_rules;
4661 : :
4662 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
4663 : : vsi_list_id, false, opcode,
4664 : : new_fltr->lkup_type);
4665 : : /* update VSI list mapping info with new VSI ID */
4666 [ # # ]: 0 : if (!status)
4667 : 0 : ice_set_bit(vsi_handle,
4668 : 0 : m_entry->vsi_list_info->vsi_map);
4669 : : }
4670 [ # # ]: 0 : if (!status)
4671 : 0 : m_entry->vsi_count++;
4672 : : return status;
4673 : : }
4674 : :
4675 : : /**
4676 : : * ice_find_rule_entry - Search a rule entry
4677 : : * @list_head: head of rule list
4678 : : * @f_info: rule information
4679 : : *
4680 : : * Helper function to search for a given rule entry
4681 : : * Returns pointer to entry storing the rule if found
4682 : : */
4683 : : static struct ice_fltr_mgmt_list_entry *
4684 : 0 : ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head,
4685 : : struct ice_fltr_info *f_info)
4686 : : {
4687 : : struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
4688 : :
4689 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
# # ]
4690 : : list_entry) {
4691 [ # # ]: 0 : if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
4692 : 0 : sizeof(f_info->l_data)) &&
4693 [ # # ]: 0 : f_info->flag == list_itr->fltr_info.flag) {
4694 : : ret = list_itr;
4695 : : break;
4696 : : }
4697 : : }
4698 : 0 : return ret;
4699 : : }
4700 : :
4701 : : /**
4702 : : * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
4703 : : * @recp_list: VSI lists needs to be searched
4704 : : * @vsi_handle: VSI handle to be found in VSI list
4705 : : * @vsi_list_id: VSI list ID found containing vsi_handle
4706 : : *
4707 : : * Helper function to search a VSI list with single entry containing given VSI
4708 : : * handle element. This can be extended further to search VSI list with more
4709 : : * than 1 vsi_count. Returns pointer to VSI list entry if found.
4710 : : */
4711 : : static struct ice_vsi_list_map_info *
4712 : 0 : ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle,
4713 : : u16 *vsi_list_id)
4714 : : {
4715 : : struct ice_vsi_list_map_info *map_info = NULL;
4716 : : struct LIST_HEAD_TYPE *list_head;
4717 : :
4718 : : list_head = &recp_list->filt_rules;
4719 [ # # ]: 0 : if (recp_list->adv_rule) {
4720 : : struct ice_adv_fltr_mgmt_list_entry *list_itr;
4721 : :
4722 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head,
# # ]
4723 : : ice_adv_fltr_mgmt_list_entry,
4724 : : list_entry) {
4725 [ # # ]: 0 : if (list_itr->vsi_list_info) {
4726 : : map_info = list_itr->vsi_list_info;
4727 [ # # ]: 0 : if (ice_is_bit_set(map_info->vsi_map,
4728 : : vsi_handle)) {
4729 : 0 : *vsi_list_id = map_info->vsi_list_id;
4730 : 0 : return map_info;
4731 : : }
4732 : : }
4733 : : }
4734 : : } else {
4735 : : struct ice_fltr_mgmt_list_entry *list_itr;
4736 : :
4737 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head,
# # ]
4738 : : ice_fltr_mgmt_list_entry,
4739 : : list_entry) {
4740 [ # # ]: 0 : if (list_itr->vsi_count == 1 &&
4741 [ # # ]: 0 : list_itr->vsi_list_info) {
4742 : : map_info = list_itr->vsi_list_info;
4743 [ # # ]: 0 : if (ice_is_bit_set(map_info->vsi_map,
4744 : : vsi_handle)) {
4745 : 0 : *vsi_list_id = map_info->vsi_list_id;
4746 : 0 : return map_info;
4747 : : }
4748 : : }
4749 : : }
4750 : : }
4751 : : return NULL;
4752 : : }
4753 : :
4754 : : /**
4755 : : * ice_add_rule_internal - add rule for a given lookup type
4756 : : * @hw: pointer to the hardware structure
4757 : : * @recp_list: recipe list for which rule has to be added
4758 : : * @lport: logic port number on which function add rule
4759 : : * @f_entry: structure containing MAC forwarding information
4760 : : *
4761 : : * Adds or updates the rule lists for a given recipe
4762 : : */
4763 : : static enum ice_status
4764 : 0 : ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4765 : : u8 lport, struct ice_fltr_list_entry *f_entry)
4766 : : {
4767 : : struct ice_fltr_info *new_fltr, *cur_fltr;
4768 : : struct ice_fltr_mgmt_list_entry *m_entry;
4769 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4770 : : enum ice_status status = ICE_SUCCESS;
4771 : :
4772 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4773 : : return ICE_ERR_PARAM;
4774 : :
4775 : : /* Load the hw_vsi_id only if the fwd action is fwd to VSI */
4776 [ # # ]: 0 : if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI)
4777 : 0 : f_entry->fltr_info.fwd_id.hw_vsi_id =
4778 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4779 : :
4780 : : rule_lock = &recp_list->filt_rule_lock;
4781 : :
4782 : 0 : ice_acquire_lock(rule_lock);
4783 : 0 : new_fltr = &f_entry->fltr_info;
4784 [ # # ]: 0 : if (new_fltr->flag & ICE_FLTR_RX)
4785 : 0 : new_fltr->src = lport;
4786 [ # # ]: 0 : else if (new_fltr->flag & ICE_FLTR_TX)
4787 : 0 : new_fltr->src =
4788 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4789 : :
4790 : 0 : m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4791 [ # # ]: 0 : if (!m_entry) {
4792 : 0 : status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4793 : 0 : goto exit_add_rule_internal;
4794 : : }
4795 : :
4796 : 0 : cur_fltr = &m_entry->fltr_info;
4797 : 0 : status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
4798 : :
4799 : 0 : exit_add_rule_internal:
4800 : : ice_release_lock(rule_lock);
4801 : 0 : return status;
4802 : : }
4803 : :
4804 : : /**
4805 : : * ice_remove_vsi_list_rule
4806 : : * @hw: pointer to the hardware structure
4807 : : * @vsi_list_id: VSI list ID generated as part of allocate resource
4808 : : * @lkup_type: switch rule filter lookup type
4809 : : *
4810 : : * The VSI list should be emptied before this function is called to remove the
4811 : : * VSI list.
4812 : : */
4813 : : static enum ice_status
4814 : : ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
4815 : : enum ice_sw_lkup_type lkup_type)
4816 : : {
4817 : : /* Free the vsi_list resource that we allocated. It is assumed that the
4818 : : * list is empty at this point.
4819 : : */
4820 : 0 : return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
4821 : : ice_aqc_opc_free_res);
4822 : : }
4823 : :
4824 : : /**
4825 : : * ice_rem_update_vsi_list
4826 : : * @hw: pointer to the hardware structure
4827 : : * @vsi_handle: VSI handle of the VSI to remove
4828 : : * @fm_list: filter management entry for which the VSI list management needs to
4829 : : * be done
4830 : : */
4831 : : static enum ice_status
4832 : 0 : ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
4833 : : struct ice_fltr_mgmt_list_entry *fm_list)
4834 : : {
4835 : : enum ice_sw_lkup_type lkup_type;
4836 : : enum ice_status status = ICE_SUCCESS;
4837 : : u16 vsi_list_id;
4838 : :
4839 [ # # ]: 0 : if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
4840 [ # # ]: 0 : fm_list->vsi_count == 0)
4841 : : return ICE_ERR_PARAM;
4842 : :
4843 : : /* A rule with the VSI being removed does not exist */
4844 [ # # ]: 0 : if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
4845 : : return ICE_ERR_DOES_NOT_EXIST;
4846 : :
4847 : 0 : lkup_type = fm_list->fltr_info.lkup_type;
4848 : 0 : vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
4849 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
4850 : : ice_aqc_opc_update_sw_rules,
4851 : : lkup_type);
4852 [ # # ]: 0 : if (status)
4853 : : return status;
4854 : :
4855 : 0 : fm_list->vsi_count--;
4856 [ # # ]: 0 : ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
4857 : :
4858 [ # # # # ]: 0 : if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
4859 : 0 : struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
4860 : : struct ice_vsi_list_map_info *vsi_list_info =
4861 : : fm_list->vsi_list_info;
4862 : : u16 rem_vsi_handle;
4863 : :
4864 : 0 : rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
4865 : : ICE_MAX_VSI);
4866 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, rem_vsi_handle))
4867 : 0 : return ICE_ERR_OUT_OF_RANGE;
4868 : :
4869 : : /* Make sure VSI list is empty before removing it below */
4870 : 0 : status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
4871 : : vsi_list_id, true,
4872 : : ice_aqc_opc_update_sw_rules,
4873 : : lkup_type);
4874 [ # # ]: 0 : if (status)
4875 : : return status;
4876 : :
4877 : 0 : tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
4878 : 0 : tmp_fltr_info.fwd_id.hw_vsi_id =
4879 : 0 : ice_get_hw_vsi_num(hw, rem_vsi_handle);
4880 : 0 : tmp_fltr_info.vsi_handle = rem_vsi_handle;
4881 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
4882 [ # # ]: 0 : if (status) {
4883 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
4884 : : tmp_fltr_info.fwd_id.hw_vsi_id, status);
4885 : 0 : return status;
4886 : : }
4887 : :
4888 : 0 : fm_list->fltr_info = tmp_fltr_info;
4889 : : }
4890 : :
4891 [ # # # # : 0 : if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
# # ]
4892 [ # # ]: 0 : (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
4893 : 0 : struct ice_vsi_list_map_info *vsi_list_info =
4894 : : fm_list->vsi_list_info;
4895 : :
4896 : : /* Remove the VSI list since it is no longer used */
4897 : 0 : status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
4898 [ # # ]: 0 : if (status) {
4899 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
4900 : : vsi_list_id, status);
4901 : 0 : return status;
4902 : : }
4903 : :
4904 [ # # ]: 0 : LIST_DEL(&vsi_list_info->list_entry);
4905 : 0 : ice_free(hw, vsi_list_info);
4906 : 0 : fm_list->vsi_list_info = NULL;
4907 : : }
4908 : :
4909 : : return status;
4910 : : }
4911 : :
4912 : : /**
4913 : : * ice_remove_rule_internal - Remove a filter rule of a given type
4914 : : *
4915 : : * @hw: pointer to the hardware structure
4916 : : * @recp_list: recipe list for which the rule needs to removed
4917 : : * @f_entry: rule entry containing filter information
4918 : : */
4919 : : static enum ice_status
4920 : 0 : ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4921 : : struct ice_fltr_list_entry *f_entry)
4922 : : {
4923 : : struct ice_fltr_mgmt_list_entry *list_elem;
4924 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4925 : : enum ice_status status = ICE_SUCCESS;
4926 : : bool remove_rule = false;
4927 : : u16 vsi_handle;
4928 : :
4929 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4930 : : return ICE_ERR_PARAM;
4931 : 0 : f_entry->fltr_info.fwd_id.hw_vsi_id =
4932 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4933 : :
4934 : : rule_lock = &recp_list->filt_rule_lock;
4935 : 0 : ice_acquire_lock(rule_lock);
4936 : 0 : list_elem = ice_find_rule_entry(&recp_list->filt_rules,
4937 : : &f_entry->fltr_info);
4938 [ # # ]: 0 : if (!list_elem) {
4939 : : status = ICE_ERR_DOES_NOT_EXIST;
4940 : 0 : goto exit;
4941 : : }
4942 : :
4943 [ # # ]: 0 : if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
4944 : : remove_rule = true;
4945 [ # # ]: 0 : } else if (!list_elem->vsi_list_info) {
4946 : : status = ICE_ERR_DOES_NOT_EXIST;
4947 : 0 : goto exit;
4948 [ # # ]: 0 : } else if (list_elem->vsi_list_info->ref_cnt > 1) {
4949 : : /* a ref_cnt > 1 indicates that the vsi_list is being
4950 : : * shared by multiple rules. Decrement the ref_cnt and
4951 : : * remove this rule, but do not modify the list, as it
4952 : : * is in-use by other rules.
4953 : : */
4954 : 0 : list_elem->vsi_list_info->ref_cnt--;
4955 : : remove_rule = true;
4956 : : } else {
4957 : : /* a ref_cnt of 1 indicates the vsi_list is only used
4958 : : * by one rule. However, the original removal request is only
4959 : : * for a single VSI. Update the vsi_list first, and only
4960 : : * remove the rule if there are no further VSIs in this list.
4961 : : */
4962 : 0 : vsi_handle = f_entry->fltr_info.vsi_handle;
4963 : 0 : status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
4964 [ # # ]: 0 : if (status)
4965 : 0 : goto exit;
4966 : : /* if VSI count goes to zero after updating the VSI list */
4967 [ # # ]: 0 : if (list_elem->vsi_count == 0)
4968 : : remove_rule = true;
4969 : : }
4970 : :
4971 : : if (remove_rule) {
4972 : : /* Remove the lookup rule */
4973 : : struct ice_aqc_sw_rules_elem *s_rule;
4974 : :
4975 : : s_rule = (struct ice_aqc_sw_rules_elem *)
4976 : 0 : ice_malloc(hw, ICE_SW_RULE_RX_TX_NO_HDR_SIZE);
4977 [ # # ]: 0 : if (!s_rule) {
4978 : : status = ICE_ERR_NO_MEMORY;
4979 : 0 : goto exit;
4980 : : }
4981 : :
4982 : : ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
4983 : : ice_aqc_opc_remove_sw_rules);
4984 : :
4985 : 0 : status = ice_aq_sw_rules(hw, s_rule,
4986 : : ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1,
4987 : : ice_aqc_opc_remove_sw_rules, NULL);
4988 : :
4989 : : /* Remove a book keeping from the list */
4990 : 0 : ice_free(hw, s_rule);
4991 : :
4992 [ # # ]: 0 : if (status)
4993 : 0 : goto exit;
4994 : :
4995 [ # # ]: 0 : LIST_DEL(&list_elem->list_entry);
4996 : 0 : ice_free(hw, list_elem);
4997 : : }
4998 : 0 : exit:
4999 : : ice_release_lock(rule_lock);
5000 : 0 : return status;
5001 : : }
5002 : :
5003 : : /**
5004 : : * ice_aq_get_res_alloc - get allocated resources
5005 : : * @hw: pointer to the HW struct
5006 : : * @num_entries: pointer to u16 to store the number of resource entries returned
5007 : : * @buf: pointer to buffer
5008 : : * @buf_size: size of buf
5009 : : * @cd: pointer to command details structure or NULL
5010 : : *
5011 : : * The caller-supplied buffer must be large enough to store the resource
5012 : : * information for all resource types. Each resource type is an
5013 : : * ice_aqc_get_res_resp_elem structure.
5014 : : */
5015 : : enum ice_status
5016 : 0 : ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries,
5017 : : struct ice_aqc_get_res_resp_elem *buf, u16 buf_size,
5018 : : struct ice_sq_cd *cd)
5019 : : {
5020 : : struct ice_aqc_get_res_alloc *resp;
5021 : : enum ice_status status;
5022 : : struct ice_aq_desc desc;
5023 : :
5024 [ # # ]: 0 : if (!buf)
5025 : : return ICE_ERR_BAD_PTR;
5026 : :
5027 [ # # ]: 0 : if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN)
5028 : : return ICE_ERR_INVAL_SIZE;
5029 : :
5030 : : resp = &desc.params.get_res;
5031 : :
5032 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc);
5033 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
5034 : :
5035 [ # # ]: 0 : if (!status && num_entries)
5036 : 0 : *num_entries = LE16_TO_CPU(resp->resp_elem_num);
5037 : :
5038 : : return status;
5039 : : }
5040 : :
5041 : : /**
5042 : : * ice_aq_get_res_descs - get allocated resource descriptors
5043 : : * @hw: pointer to the hardware structure
5044 : : * @num_entries: number of resource entries in buffer
5045 : : * @buf: structure to hold response data buffer
5046 : : * @buf_size: size of buffer
5047 : : * @res_type: resource type
5048 : : * @res_shared: is resource shared
5049 : : * @desc_id: input - first desc ID to start; output - next desc ID
5050 : : * @cd: pointer to command details structure or NULL
5051 : : */
5052 : : enum ice_status
5053 : 0 : ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries,
5054 : : struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type,
5055 : : bool res_shared, u16 *desc_id, struct ice_sq_cd *cd)
5056 : : {
5057 : : struct ice_aqc_get_allocd_res_desc *cmd;
5058 : : struct ice_aq_desc desc;
5059 : : enum ice_status status;
5060 : :
5061 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
5062 : :
5063 : : cmd = &desc.params.get_res_desc;
5064 : :
5065 [ # # ]: 0 : if (!buf)
5066 : : return ICE_ERR_PARAM;
5067 : :
5068 [ # # ]: 0 : if (buf_size != (num_entries * sizeof(*buf)))
5069 : : return ICE_ERR_PARAM;
5070 : :
5071 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc);
5072 : :
5073 [ # # ]: 0 : cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) &
5074 : : ICE_AQC_RES_TYPE_M) | (res_shared ?
5075 : : ICE_AQC_RES_TYPE_FLAG_SHARED : 0));
5076 : 0 : cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id);
5077 : :
5078 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
5079 [ # # ]: 0 : if (!status)
5080 : 0 : *desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc);
5081 : :
5082 : : return status;
5083 : : }
5084 : :
5085 : : /**
5086 : : * ice_add_mac_rule - Add a MAC address based filter rule
5087 : : * @hw: pointer to the hardware structure
5088 : : * @m_list: list of MAC addresses and forwarding information
5089 : : * @sw: pointer to switch info struct for which function add rule
5090 : : * @lport: logic port number on which function add rule
5091 : : *
5092 : : * IMPORTANT: When the umac_shared flag is set to false and m_list has
5093 : : * multiple unicast addresses, the function assumes that all the
5094 : : * addresses are unique in a given add_mac call. It doesn't
5095 : : * check for duplicates in this case, removing duplicates from a given
5096 : : * list should be taken care of in the caller of this function.
5097 : : */
5098 : : static enum ice_status
5099 : 0 : ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5100 : : struct ice_switch_info *sw, u8 lport)
5101 : : {
5102 : 0 : struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC];
5103 : : struct ice_aqc_sw_rules_elem *s_rule, *r_iter;
5104 : : struct ice_fltr_list_entry *m_list_itr;
5105 : : struct LIST_HEAD_TYPE *rule_head;
5106 : : u16 total_elem_left, s_rule_size;
5107 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5108 : : enum ice_status status = ICE_SUCCESS;
5109 : : u16 num_unicast = 0;
5110 : : u8 elem_sent;
5111 : :
5112 : : s_rule = NULL;
5113 : : rule_lock = &recp_list->filt_rule_lock;
5114 : 0 : rule_head = &recp_list->filt_rules;
5115 : :
5116 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
# # ]
5117 : : list_entry) {
5118 : : u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
5119 : : u16 vsi_handle;
5120 : : u16 hw_vsi_id;
5121 : :
5122 : 0 : m_list_itr->fltr_info.flag = ICE_FLTR_TX;
5123 : 0 : vsi_handle = m_list_itr->fltr_info.vsi_handle;
5124 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5125 : : return ICE_ERR_PARAM;
5126 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5127 [ # # ]: 0 : if (m_list_itr->fltr_info.fltr_act == ICE_FWD_TO_VSI)
5128 : 0 : m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
5129 : : /* update the src in case it is VSI num */
5130 [ # # ]: 0 : if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
5131 : : return ICE_ERR_PARAM;
5132 : 0 : m_list_itr->fltr_info.src = hw_vsi_id;
5133 [ # # ]: 0 : if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
5134 [ # # # # : 0 : IS_ZERO_ETHER_ADDR(add))
# # ]
5135 : : return ICE_ERR_PARAM;
5136 [ # # # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(add) && !hw->umac_shared) {
5137 : : /* Don't overwrite the unicast address */
5138 : 0 : ice_acquire_lock(rule_lock);
5139 [ # # ]: 0 : if (ice_find_rule_entry(rule_head,
5140 : : &m_list_itr->fltr_info)) {
5141 : : ice_release_lock(rule_lock);
5142 : 0 : continue;
5143 : : }
5144 : : ice_release_lock(rule_lock);
5145 : 0 : num_unicast++;
5146 [ # # ]: 0 : } else if (IS_MULTICAST_ETHER_ADDR(add) ||
5147 [ # # ]: 0 : (IS_UNICAST_ETHER_ADDR(add) && hw->umac_shared)) {
5148 : 0 : m_list_itr->status =
5149 : 0 : ice_add_rule_internal(hw, recp_list, lport,
5150 : : m_list_itr);
5151 [ # # ]: 0 : if (m_list_itr->status)
5152 : 0 : return m_list_itr->status;
5153 : : }
5154 : : }
5155 : :
5156 : 0 : ice_acquire_lock(rule_lock);
5157 : : /* Exit if no suitable entries were found for adding bulk switch rule */
5158 [ # # ]: 0 : if (!num_unicast) {
5159 : : status = ICE_SUCCESS;
5160 : 0 : goto ice_add_mac_exit;
5161 : : }
5162 : :
5163 : : /* Allocate switch rule buffer for the bulk update for unicast */
5164 : : s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE;
5165 : : s_rule = (struct ice_aqc_sw_rules_elem *)
5166 : 0 : ice_calloc(hw, num_unicast, s_rule_size);
5167 [ # # ]: 0 : if (!s_rule) {
5168 : : status = ICE_ERR_NO_MEMORY;
5169 : 0 : goto ice_add_mac_exit;
5170 : : }
5171 : :
5172 : : r_iter = s_rule;
5173 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
# # ]
5174 : : list_entry) {
5175 : : struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
5176 : : u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
5177 : :
5178 [ # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
5179 : 0 : ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
5180 : : ice_aqc_opc_add_sw_rules);
5181 : 0 : r_iter = (struct ice_aqc_sw_rules_elem *)
5182 : : ((u8 *)r_iter + s_rule_size);
5183 : : }
5184 : : }
5185 : :
5186 : : /* Call AQ bulk switch rule update for all unicast addresses */
5187 : : r_iter = s_rule;
5188 : : /* Call AQ switch rule in AQ_MAX chunk */
5189 [ # # ]: 0 : for (total_elem_left = num_unicast; total_elem_left > 0;
5190 : 0 : total_elem_left -= elem_sent) {
5191 : : struct ice_aqc_sw_rules_elem *entry = r_iter;
5192 : :
5193 : 0 : elem_sent = MIN_T(u8, total_elem_left,
5194 : : (ICE_AQ_MAX_BUF_LEN / s_rule_size));
5195 : 0 : status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
5196 : : elem_sent, ice_aqc_opc_add_sw_rules,
5197 : : NULL);
5198 [ # # ]: 0 : if (status)
5199 : 0 : goto ice_add_mac_exit;
5200 : 0 : r_iter = (struct ice_aqc_sw_rules_elem *)
5201 : 0 : ((u8 *)r_iter + (elem_sent * s_rule_size));
5202 : : }
5203 : :
5204 : : /* Fill up rule ID based on the value returned from FW */
5205 : : r_iter = s_rule;
5206 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
# # ]
5207 : : list_entry) {
5208 : : struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
5209 : : u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
5210 : : struct ice_fltr_mgmt_list_entry *fm_entry;
5211 : :
5212 [ # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
5213 : 0 : f_info->fltr_rule_id =
5214 : 0 : LE16_TO_CPU(r_iter->pdata.lkup_tx_rx.index);
5215 : 0 : f_info->fltr_act = ICE_FWD_TO_VSI;
5216 : : /* Create an entry to track this MAC address */
5217 : : fm_entry = (struct ice_fltr_mgmt_list_entry *)
5218 : 0 : ice_malloc(hw, sizeof(*fm_entry));
5219 [ # # ]: 0 : if (!fm_entry) {
5220 : : status = ICE_ERR_NO_MEMORY;
5221 : 0 : goto ice_add_mac_exit;
5222 : : }
5223 : 0 : fm_entry->fltr_info = *f_info;
5224 : 0 : fm_entry->vsi_count = 1;
5225 : : /* The book keeping entries will get removed when
5226 : : * base driver calls remove filter AQ command
5227 : : */
5228 : :
5229 [ # # ]: 0 : LIST_ADD(&fm_entry->list_entry, rule_head);
5230 : 0 : r_iter = (struct ice_aqc_sw_rules_elem *)
5231 : : ((u8 *)r_iter + s_rule_size);
5232 : : }
5233 : : }
5234 : :
5235 : 0 : ice_add_mac_exit:
5236 : : ice_release_lock(rule_lock);
5237 [ # # ]: 0 : if (s_rule)
5238 : 0 : ice_free(hw, s_rule);
5239 : : return status;
5240 : : }
5241 : :
5242 : : /**
5243 : : * ice_add_mac - Add a MAC address based filter rule
5244 : : * @hw: pointer to the hardware structure
5245 : : * @m_list: list of MAC addresses and forwarding information
5246 : : *
5247 : : * Function add MAC rule for logical port from HW struct
5248 : : */
5249 : 0 : enum ice_status ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5250 : : {
5251 [ # # ]: 0 : if (!m_list || !hw)
5252 : : return ICE_ERR_PARAM;
5253 : :
5254 : 0 : return ice_add_mac_rule(hw, m_list, hw->switch_info,
5255 : 0 : hw->port_info->lport);
5256 : : }
5257 : :
5258 : : /**
5259 : : * ice_add_vlan_internal - Add one VLAN based filter rule
5260 : : * @hw: pointer to the hardware structure
5261 : : * @recp_list: recipe list for which rule has to be added
5262 : : * @f_entry: filter entry containing one VLAN information
5263 : : */
5264 : : static enum ice_status
5265 : 0 : ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
5266 : : struct ice_fltr_list_entry *f_entry)
5267 : : {
5268 : : struct ice_fltr_mgmt_list_entry *v_list_itr;
5269 : : struct ice_fltr_info *new_fltr, *cur_fltr;
5270 : : enum ice_sw_lkup_type lkup_type;
5271 : 0 : u16 vsi_list_id = 0, vsi_handle;
5272 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5273 : : enum ice_status status = ICE_SUCCESS;
5274 : :
5275 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
5276 : : return ICE_ERR_PARAM;
5277 : :
5278 : 0 : f_entry->fltr_info.fwd_id.hw_vsi_id =
5279 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
5280 : 0 : new_fltr = &f_entry->fltr_info;
5281 : :
5282 : : /* VLAN ID should only be 12 bits */
5283 [ # # ]: 0 : if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
5284 : : return ICE_ERR_PARAM;
5285 : :
5286 [ # # ]: 0 : if (new_fltr->src_id != ICE_SRC_ID_VSI)
5287 : : return ICE_ERR_PARAM;
5288 : :
5289 : 0 : new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
5290 : 0 : lkup_type = new_fltr->lkup_type;
5291 : 0 : vsi_handle = new_fltr->vsi_handle;
5292 : : rule_lock = &recp_list->filt_rule_lock;
5293 : 0 : ice_acquire_lock(rule_lock);
5294 : 0 : v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
5295 [ # # ]: 0 : if (!v_list_itr) {
5296 : : struct ice_vsi_list_map_info *map_info = NULL;
5297 : :
5298 [ # # ]: 0 : if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
5299 : : /* All VLAN pruning rules use a VSI list. Check if
5300 : : * there is already a VSI list containing VSI that we
5301 : : * want to add. If found, use the same vsi_list_id for
5302 : : * this new VLAN rule or else create a new list.
5303 : : */
5304 : 0 : map_info = ice_find_vsi_list_entry(recp_list,
5305 : : vsi_handle,
5306 : : &vsi_list_id);
5307 [ # # ]: 0 : if (!map_info) {
5308 : 0 : status = ice_create_vsi_list_rule(hw,
5309 : : &vsi_handle,
5310 : : 1,
5311 : : &vsi_list_id,
5312 : : lkup_type);
5313 [ # # ]: 0 : if (status)
5314 : 0 : goto exit;
5315 : : }
5316 : : /* Convert the action to forwarding to a VSI list. */
5317 : 0 : new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
5318 : 0 : new_fltr->fwd_id.vsi_list_id = vsi_list_id;
5319 : : }
5320 : :
5321 : 0 : status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
5322 [ # # ]: 0 : if (!status) {
5323 : 0 : v_list_itr = ice_find_rule_entry(&recp_list->filt_rules,
5324 : : new_fltr);
5325 [ # # ]: 0 : if (!v_list_itr) {
5326 : : status = ICE_ERR_DOES_NOT_EXIST;
5327 : 0 : goto exit;
5328 : : }
5329 : : /* reuse VSI list for new rule and increment ref_cnt */
5330 [ # # ]: 0 : if (map_info) {
5331 : 0 : v_list_itr->vsi_list_info = map_info;
5332 : 0 : map_info->ref_cnt++;
5333 : : } else {
5334 : 0 : v_list_itr->vsi_list_info =
5335 : 0 : ice_create_vsi_list_map(hw, &vsi_handle,
5336 : : 1, vsi_list_id);
5337 : : }
5338 : : }
5339 [ # # ]: 0 : } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
5340 : : /* Update existing VSI list to add new VSI ID only if it used
5341 : : * by one VLAN rule.
5342 : : */
5343 : 0 : cur_fltr = &v_list_itr->fltr_info;
5344 : 0 : status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
5345 : : new_fltr);
5346 : : } else {
5347 : : /* If VLAN rule exists and VSI list being used by this rule is
5348 : : * referenced by more than 1 VLAN rule. Then create a new VSI
5349 : : * list appending previous VSI with new VSI and update existing
5350 : : * VLAN rule to point to new VSI list ID
5351 : : */
5352 : : struct ice_fltr_info tmp_fltr;
5353 : : u16 vsi_handle_arr[2];
5354 : : u16 cur_handle;
5355 : :
5356 : : /* Current implementation only supports reusing VSI list with
5357 : : * one VSI count. We should never hit below condition
5358 : : */
5359 [ # # # # ]: 0 : if (v_list_itr->vsi_count > 1 &&
5360 : : v_list_itr->vsi_list_info->ref_cnt > 1) {
5361 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
5362 : : status = ICE_ERR_CFG;
5363 : 0 : goto exit;
5364 : : }
5365 : :
5366 : : cur_handle =
5367 : 0 : ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map,
5368 : : ICE_MAX_VSI);
5369 : :
5370 : : /* A rule already exists with the new VSI being added */
5371 [ # # ]: 0 : if (cur_handle == vsi_handle) {
5372 : : status = ICE_ERR_ALREADY_EXISTS;
5373 : 0 : goto exit;
5374 : : }
5375 : :
5376 : 0 : vsi_handle_arr[0] = cur_handle;
5377 : 0 : vsi_handle_arr[1] = vsi_handle;
5378 : 0 : status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
5379 : : &vsi_list_id, lkup_type);
5380 [ # # ]: 0 : if (status)
5381 : 0 : goto exit;
5382 : :
5383 : 0 : tmp_fltr = v_list_itr->fltr_info;
5384 : : tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
5385 : 0 : tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
5386 : 0 : tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
5387 : : /* Update the previous switch rule to a new VSI list which
5388 : : * includes current VSI that is requested
5389 : : */
5390 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
5391 [ # # ]: 0 : if (status)
5392 : 0 : goto exit;
5393 : :
5394 : : /* before overriding VSI list map info. decrement ref_cnt of
5395 : : * previous VSI list
5396 : : */
5397 : 0 : v_list_itr->vsi_list_info->ref_cnt--;
5398 : :
5399 : : /* now update to newly created list */
5400 : 0 : v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
5401 : 0 : v_list_itr->vsi_list_info =
5402 : 0 : ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
5403 : : vsi_list_id);
5404 : 0 : v_list_itr->vsi_count++;
5405 : : }
5406 : :
5407 : 0 : exit:
5408 : : ice_release_lock(rule_lock);
5409 : 0 : return status;
5410 : : }
5411 : :
5412 : : /**
5413 : : * ice_add_vlan_rule - Add VLAN based filter rule
5414 : : * @hw: pointer to the hardware structure
5415 : : * @v_list: list of VLAN entries and forwarding information
5416 : : * @sw: pointer to switch info struct for which function add rule
5417 : : */
5418 : : static enum ice_status
5419 : 0 : ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5420 : : struct ice_switch_info *sw)
5421 : : {
5422 : : struct ice_fltr_list_entry *v_list_itr;
5423 : : struct ice_sw_recipe *recp_list;
5424 : :
5425 : 0 : recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN];
5426 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry,
# # ]
5427 : : list_entry) {
5428 [ # # ]: 0 : if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
5429 : : return ICE_ERR_PARAM;
5430 : 0 : v_list_itr->fltr_info.flag = ICE_FLTR_TX;
5431 : 0 : v_list_itr->status = ice_add_vlan_internal(hw, recp_list,
5432 : : v_list_itr);
5433 [ # # ]: 0 : if (v_list_itr->status)
5434 : 0 : return v_list_itr->status;
5435 : : }
5436 : : return ICE_SUCCESS;
5437 : : }
5438 : :
5439 : : /**
5440 : : * ice_add_vlan - Add a VLAN based filter rule
5441 : : * @hw: pointer to the hardware structure
5442 : : * @v_list: list of VLAN and forwarding information
5443 : : *
5444 : : * Function add VLAN rule for logical port from HW struct
5445 : : */
5446 : 0 : enum ice_status ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5447 : : {
5448 [ # # ]: 0 : if (!v_list || !hw)
5449 : : return ICE_ERR_PARAM;
5450 : :
5451 : 0 : return ice_add_vlan_rule(hw, v_list, hw->switch_info);
5452 : : }
5453 : :
5454 : : /**
5455 : : * ice_add_mac_vlan_rule - Add MAC and VLAN pair based filter rule
5456 : : * @hw: pointer to the hardware structure
5457 : : * @mv_list: list of MAC and VLAN filters
5458 : : * @sw: pointer to switch info struct for which function add rule
5459 : : * @lport: logic port number on which function add rule
5460 : : *
5461 : : * If the VSI on which the MAC-VLAN pair has to be added has Rx and Tx VLAN
5462 : : * pruning bits enabled, then it is the responsibility of the caller to make
5463 : : * sure to add a VLAN only filter on the same VSI. Packets belonging to that
5464 : : * VLAN won't be received on that VSI otherwise.
5465 : : */
5466 : : static enum ice_status
5467 : 0 : ice_add_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list,
5468 : : struct ice_switch_info *sw, u8 lport)
5469 : : {
5470 : : struct ice_fltr_list_entry *mv_list_itr;
5471 : : struct ice_sw_recipe *recp_list;
5472 : :
5473 [ # # ]: 0 : if (!mv_list || !hw)
5474 : : return ICE_ERR_PARAM;
5475 : :
5476 : 0 : recp_list = &sw->recp_list[ICE_SW_LKUP_MAC_VLAN];
5477 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(mv_list_itr, mv_list, ice_fltr_list_entry,
# # ]
5478 : : list_entry) {
5479 : 0 : enum ice_sw_lkup_type l_type =
5480 : : mv_list_itr->fltr_info.lkup_type;
5481 : :
5482 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_MAC_VLAN)
5483 : : return ICE_ERR_PARAM;
5484 : 0 : mv_list_itr->fltr_info.flag = ICE_FLTR_TX;
5485 : 0 : mv_list_itr->status =
5486 : 0 : ice_add_rule_internal(hw, recp_list, lport,
5487 : : mv_list_itr);
5488 [ # # ]: 0 : if (mv_list_itr->status)
5489 : 0 : return mv_list_itr->status;
5490 : : }
5491 : : return ICE_SUCCESS;
5492 : : }
5493 : :
5494 : : /**
5495 : : * ice_add_mac_vlan - Add a MAC VLAN address based filter rule
5496 : : * @hw: pointer to the hardware structure
5497 : : * @mv_list: list of MAC VLAN addresses and forwarding information
5498 : : *
5499 : : * Function add MAC VLAN rule for logical port from HW struct
5500 : : */
5501 : : enum ice_status
5502 : 0 : ice_add_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5503 : : {
5504 [ # # ]: 0 : if (!mv_list || !hw)
5505 : : return ICE_ERR_PARAM;
5506 : :
5507 : 0 : return ice_add_mac_vlan_rule(hw, mv_list, hw->switch_info,
5508 : 0 : hw->port_info->lport);
5509 : : }
5510 : :
5511 : : /**
5512 : : * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule
5513 : : * @hw: pointer to the hardware structure
5514 : : * @em_list: list of ether type MAC filter, MAC is optional
5515 : : * @sw: pointer to switch info struct for which function add rule
5516 : : * @lport: logic port number on which function add rule
5517 : : *
5518 : : * This function requires the caller to populate the entries in
5519 : : * the filter list with the necessary fields (including flags to
5520 : : * indicate Tx or Rx rules).
5521 : : */
5522 : : static enum ice_status
5523 : 0 : ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5524 : : struct ice_switch_info *sw, u8 lport)
5525 : : {
5526 : : struct ice_fltr_list_entry *em_list_itr;
5527 : :
5528 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry,
# # ]
5529 : : list_entry) {
5530 : : struct ice_sw_recipe *recp_list;
5531 : : enum ice_sw_lkup_type l_type;
5532 : :
5533 : 0 : l_type = em_list_itr->fltr_info.lkup_type;
5534 : 0 : recp_list = &sw->recp_list[l_type];
5535 : :
5536 : 0 : if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5537 [ # # ]: 0 : l_type != ICE_SW_LKUP_ETHERTYPE)
5538 : : return ICE_ERR_PARAM;
5539 : :
5540 : 0 : em_list_itr->status = ice_add_rule_internal(hw, recp_list,
5541 : : lport,
5542 : : em_list_itr);
5543 [ # # ]: 0 : if (em_list_itr->status)
5544 : 0 : return em_list_itr->status;
5545 : : }
5546 : : return ICE_SUCCESS;
5547 : : }
5548 : :
5549 : : /**
5550 : : * ice_add_eth_mac - Add a ethertype based filter rule
5551 : : * @hw: pointer to the hardware structure
5552 : : * @em_list: list of ethertype and forwarding information
5553 : : *
5554 : : * Function add ethertype rule for logical port from HW struct
5555 : : */
5556 : : enum ice_status
5557 : 0 : ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5558 : : {
5559 [ # # ]: 0 : if (!em_list || !hw)
5560 : : return ICE_ERR_PARAM;
5561 : :
5562 : 0 : return ice_add_eth_mac_rule(hw, em_list, hw->switch_info,
5563 : 0 : hw->port_info->lport);
5564 : : }
5565 : :
5566 : : /**
5567 : : * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule
5568 : : * @hw: pointer to the hardware structure
5569 : : * @em_list: list of ethertype or ethertype MAC entries
5570 : : * @sw: pointer to switch info struct for which function add rule
5571 : : */
5572 : : static enum ice_status
5573 : 0 : ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5574 : : struct ice_switch_info *sw)
5575 : : {
5576 : : struct ice_fltr_list_entry *em_list_itr, *tmp;
5577 : :
5578 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry,
# # # # #
# ]
5579 : : list_entry) {
5580 : : struct ice_sw_recipe *recp_list;
5581 : : enum ice_sw_lkup_type l_type;
5582 : :
5583 : 0 : l_type = em_list_itr->fltr_info.lkup_type;
5584 : :
5585 : 0 : if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5586 [ # # ]: 0 : l_type != ICE_SW_LKUP_ETHERTYPE)
5587 : : return ICE_ERR_PARAM;
5588 : :
5589 : 0 : recp_list = &sw->recp_list[l_type];
5590 : 0 : em_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5591 : : em_list_itr);
5592 [ # # ]: 0 : if (em_list_itr->status)
5593 : 0 : return em_list_itr->status;
5594 : : }
5595 : : return ICE_SUCCESS;
5596 : : }
5597 : :
5598 : : /**
5599 : : * ice_remove_eth_mac - remove a ethertype based filter rule
5600 : : * @hw: pointer to the hardware structure
5601 : : * @em_list: list of ethertype and forwarding information
5602 : : *
5603 : : */
5604 : : enum ice_status
5605 : 0 : ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5606 : : {
5607 [ # # ]: 0 : if (!em_list || !hw)
5608 : : return ICE_ERR_PARAM;
5609 : :
5610 : 0 : return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info);
5611 : : }
5612 : :
5613 : : /**
5614 : : * ice_get_lg_act_aqc_res_type - get resource type for a large action
5615 : : * @res_type: resource type to be filled in case of function success
5616 : : * @num_acts: number of actions to hold with a large action entry
5617 : : *
5618 : : * Get resource type for a large action depending on the number
5619 : : * of single actions that it contains.
5620 : : */
5621 : : static enum ice_status
5622 : : ice_get_lg_act_aqc_res_type(u16 *res_type, int num_acts)
5623 : : {
5624 : : if (!res_type)
5625 : : return ICE_ERR_BAD_PTR;
5626 : :
5627 : : /* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1.
5628 : : * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3.
5629 : : * If num_acts is greater than 2, then use
5630 : : * ICE_AQC_RES_TYPE_WIDE_TABLE_4.
5631 : : * The num_acts cannot be equal to 0 or greater than 4.
5632 : : */
5633 : : switch (num_acts) {
5634 : : case 1:
5635 : : *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_1;
5636 : : break;
5637 : : case 2:
5638 : : *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_2;
5639 : : break;
5640 : : case 3:
5641 : : case 4:
5642 : : *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_4;
5643 : : break;
5644 : : default:
5645 : : return ICE_ERR_PARAM;
5646 : : }
5647 : :
5648 : : return ICE_SUCCESS;
5649 : : }
5650 : :
5651 : : /**
5652 : : * ice_alloc_res_lg_act - add large action resource
5653 : : * @hw: pointer to the hardware structure
5654 : : * @l_id: large action ID to fill it in
5655 : : * @num_acts: number of actions to hold with a large action entry
5656 : : */
5657 : : static enum ice_status
5658 : 0 : ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts)
5659 : : {
5660 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
5661 : : enum ice_status status;
5662 : : u16 buf_len, res_type;
5663 : :
5664 [ # # ]: 0 : if (!l_id)
5665 : : return ICE_ERR_BAD_PTR;
5666 : :
5667 : : status = ice_get_lg_act_aqc_res_type(&res_type, num_acts);
5668 : : if (status)
5669 : : return status;
5670 : :
5671 : : /* Allocate resource for large action */
5672 : : buf_len = ice_struct_size(sw_buf, elem, 1);
5673 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
5674 [ # # ]: 0 : if (!sw_buf)
5675 : : return ICE_ERR_NO_MEMORY;
5676 : :
5677 : 0 : sw_buf->res_type = CPU_TO_LE16(res_type);
5678 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
5679 : :
5680 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
5681 : : ice_aqc_opc_alloc_res, NULL);
5682 [ # # ]: 0 : if (!status)
5683 : 0 : *l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
5684 : :
5685 : 0 : ice_free(hw, sw_buf);
5686 : :
5687 : 0 : return status;
5688 : : }
5689 : :
5690 : : /**
5691 : : * ice_rem_sw_rule_info
5692 : : * @hw: pointer to the hardware structure
5693 : : * @rule_head: pointer to the switch list structure that we want to delete
5694 : : */
5695 : : static void
5696 : 0 : ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5697 : : {
5698 [ # # ]: 0 : if (!LIST_EMPTY(rule_head)) {
5699 : : struct ice_fltr_mgmt_list_entry *entry;
5700 : : struct ice_fltr_mgmt_list_entry *tmp;
5701 : :
5702 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head,
# # # # #
# ]
5703 : : ice_fltr_mgmt_list_entry, list_entry) {
5704 [ # # ]: 0 : LIST_DEL(&entry->list_entry);
5705 : 0 : ice_free(hw, entry);
5706 : : }
5707 : : }
5708 : 0 : }
5709 : :
5710 : : /**
5711 : : * ice_rem_adv_rule_info
5712 : : * @hw: pointer to the hardware structure
5713 : : * @rule_head: pointer to the switch list structure that we want to delete
5714 : : */
5715 : : static void
5716 : 0 : ice_rem_adv_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5717 : : {
5718 : : struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
5719 : : struct ice_adv_fltr_mgmt_list_entry *lst_itr;
5720 : :
5721 [ # # ]: 0 : if (LIST_EMPTY(rule_head))
5722 : : return;
5723 : :
5724 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry, rule_head,
# # # # ]
5725 : : ice_adv_fltr_mgmt_list_entry, list_entry) {
5726 [ # # ]: 0 : LIST_DEL(&lst_itr->list_entry);
5727 : 0 : ice_free(hw, lst_itr->lkups);
5728 : 0 : ice_free(hw, lst_itr);
5729 : : }
5730 : : }
5731 : :
5732 : : /**
5733 : : * ice_rem_all_sw_rules_info
5734 : : * @hw: pointer to the hardware structure
5735 : : */
5736 : 0 : void ice_rem_all_sw_rules_info(struct ice_hw *hw)
5737 : : {
5738 : 0 : struct ice_switch_info *sw = hw->switch_info;
5739 : : u8 i;
5740 : :
5741 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
5742 : : struct LIST_HEAD_TYPE *rule_head;
5743 : :
5744 : 0 : rule_head = &sw->recp_list[i].filt_rules;
5745 [ # # ]: 0 : if (!sw->recp_list[i].adv_rule)
5746 : 0 : ice_rem_sw_rule_info(hw, rule_head);
5747 : : else
5748 : 0 : ice_rem_adv_rule_info(hw, rule_head);
5749 [ # # ]: 0 : if (sw->recp_list[i].adv_rule &&
5750 [ # # ]: 0 : LIST_EMPTY(&sw->recp_list[i].filt_rules))
5751 : 0 : sw->recp_list[i].adv_rule = false;
5752 : : }
5753 : 0 : }
5754 : :
5755 : : /**
5756 : : * ice_cfg_dflt_vsi - change state of VSI to set/clear default
5757 : : * @pi: pointer to the port_info structure
5758 : : * @vsi_handle: VSI handle to set as default
5759 : : * @set: true to add the above mentioned switch rule, false to remove it
5760 : : * @direction: ICE_FLTR_RX or ICE_FLTR_TX
5761 : : *
5762 : : * add filter rule to set/unset given VSI as default VSI for the switch
5763 : : * (represented by swid)
5764 : : */
5765 : : enum ice_status
5766 : 0 : ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
5767 : : u8 direction)
5768 : : {
5769 : : struct ice_fltr_list_entry f_list_entry;
5770 : : struct ice_sw_recipe *recp_list;
5771 : : struct ice_fltr_info f_info;
5772 : 0 : struct ice_hw *hw = pi->hw;
5773 : : enum ice_status status;
5774 : 0 : u8 lport = pi->lport;
5775 : : u16 hw_vsi_id;
5776 : 0 : recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
5777 : :
5778 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5779 : : return ICE_ERR_PARAM;
5780 : :
5781 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5782 : :
5783 : : ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM);
5784 : :
5785 : 0 : f_info.lkup_type = ICE_SW_LKUP_DFLT;
5786 : 0 : f_info.flag = direction;
5787 : : f_info.fltr_act = ICE_FWD_TO_VSI;
5788 : 0 : f_info.fwd_id.hw_vsi_id = hw_vsi_id;
5789 : 0 : f_info.vsi_handle = vsi_handle;
5790 : :
5791 [ # # ]: 0 : if (f_info.flag & ICE_FLTR_RX) {
5792 : 0 : f_info.src = pi->lport;
5793 : 0 : f_info.src_id = ICE_SRC_ID_LPORT;
5794 [ # # ]: 0 : } else if (f_info.flag & ICE_FLTR_TX) {
5795 : 0 : f_info.src_id = ICE_SRC_ID_VSI;
5796 : 0 : f_info.src = hw_vsi_id;
5797 : : }
5798 : 0 : f_list_entry.fltr_info = f_info;
5799 : :
5800 [ # # ]: 0 : if (set)
5801 : 0 : status = ice_add_rule_internal(hw, recp_list, lport,
5802 : : &f_list_entry);
5803 : : else
5804 : 0 : status = ice_remove_rule_internal(hw, recp_list,
5805 : : &f_list_entry);
5806 : :
5807 : : return status;
5808 : : }
5809 : :
5810 : : /**
5811 : : * ice_check_if_dflt_vsi - check if VSI is default VSI
5812 : : * @pi: pointer to the port_info structure
5813 : : * @vsi_handle: vsi handle to check for in filter list
5814 : : * @rule_exists: indicates if there are any VSI's in the rule list
5815 : : *
5816 : : * checks if the VSI is in a default VSI list, and also indicates
5817 : : * if the default VSI list is empty
5818 : : */
5819 : 0 : bool ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
5820 : : bool *rule_exists)
5821 : : {
5822 : : struct ice_fltr_mgmt_list_entry *fm_entry;
5823 : : struct LIST_HEAD_TYPE *rule_head;
5824 : : struct ice_sw_recipe *recp_list;
5825 : : struct ice_lock *rule_lock;
5826 : : bool ret = false;
5827 : 0 : recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
5828 : : rule_lock = &recp_list->filt_rule_lock;
5829 : : rule_head = &recp_list->filt_rules;
5830 : :
5831 : 0 : ice_acquire_lock(rule_lock);
5832 : :
5833 [ # # # # ]: 0 : if (rule_exists && !LIST_EMPTY(rule_head))
5834 : 0 : *rule_exists = true;
5835 : :
5836 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fm_entry, rule_head,
# # ]
5837 : : ice_fltr_mgmt_list_entry, list_entry) {
5838 : 0 : if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
5839 : : ret = true;
5840 : : break;
5841 : : }
5842 : : }
5843 : :
5844 : : ice_release_lock(rule_lock);
5845 : 0 : return ret;
5846 : : }
5847 : :
5848 : : /**
5849 : : * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
5850 : : * @list_head: head of rule list
5851 : : * @f_info: rule information
5852 : : *
5853 : : * Helper function to search for a unicast rule entry - this is to be used
5854 : : * to remove unicast MAC filter that is not shared with other VSIs on the
5855 : : * PF switch.
5856 : : *
5857 : : * Returns pointer to entry storing the rule if found
5858 : : */
5859 : : static struct ice_fltr_mgmt_list_entry *
5860 : 0 : ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head,
5861 : : struct ice_fltr_info *f_info)
5862 : : {
5863 : : struct ice_fltr_mgmt_list_entry *list_itr;
5864 : :
5865 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
# # ]
5866 : : list_entry) {
5867 [ # # ]: 0 : if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
5868 : 0 : sizeof(f_info->l_data)) &&
5869 : 0 : f_info->fwd_id.hw_vsi_id ==
5870 [ # # ]: 0 : list_itr->fltr_info.fwd_id.hw_vsi_id &&
5871 [ # # ]: 0 : f_info->flag == list_itr->fltr_info.flag)
5872 : 0 : return list_itr;
5873 : : }
5874 : : return NULL;
5875 : : }
5876 : :
5877 : : /**
5878 : : * ice_remove_mac_rule - remove a MAC based filter rule
5879 : : * @hw: pointer to the hardware structure
5880 : : * @m_list: list of MAC addresses and forwarding information
5881 : : * @recp_list: list from which function remove MAC address
5882 : : *
5883 : : * This function removes either a MAC filter rule or a specific VSI from a
5884 : : * VSI list for a multicast MAC address.
5885 : : *
5886 : : * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
5887 : : * ice_add_mac. Caller should be aware that this call will only work if all
5888 : : * the entries passed into m_list were added previously. It will not attempt to
5889 : : * do a partial remove of entries that were found.
5890 : : */
5891 : : static enum ice_status
5892 : 0 : ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5893 : : struct ice_sw_recipe *recp_list)
5894 : : {
5895 : : struct ice_fltr_list_entry *list_itr, *tmp;
5896 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5897 : :
5898 [ # # ]: 0 : if (!m_list)
5899 : : return ICE_ERR_PARAM;
5900 : :
5901 : : rule_lock = &recp_list->filt_rule_lock;
5902 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry,
# # # # #
# ]
5903 : : list_entry) {
5904 : 0 : enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
5905 : : u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
5906 : : u16 vsi_handle;
5907 : :
5908 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_MAC)
5909 : : return ICE_ERR_PARAM;
5910 : :
5911 : 0 : vsi_handle = list_itr->fltr_info.vsi_handle;
5912 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5913 : : return ICE_ERR_PARAM;
5914 : :
5915 : 0 : list_itr->fltr_info.fwd_id.hw_vsi_id =
5916 : 0 : ice_get_hw_vsi_num(hw, vsi_handle);
5917 [ # # # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(add) && !hw->umac_shared) {
5918 : : /* Don't remove the unicast address that belongs to
5919 : : * another VSI on the switch, since it is not being
5920 : : * shared...
5921 : : */
5922 : 0 : ice_acquire_lock(rule_lock);
5923 [ # # ]: 0 : if (!ice_find_ucast_rule_entry(&recp_list->filt_rules,
5924 : : &list_itr->fltr_info)) {
5925 : : ice_release_lock(rule_lock);
5926 : 0 : return ICE_ERR_DOES_NOT_EXIST;
5927 : : }
5928 : : ice_release_lock(rule_lock);
5929 : : }
5930 : 0 : list_itr->status = ice_remove_rule_internal(hw, recp_list,
5931 : : list_itr);
5932 [ # # ]: 0 : if (list_itr->status)
5933 : 0 : return list_itr->status;
5934 : : }
5935 : : return ICE_SUCCESS;
5936 : : }
5937 : :
5938 : : /**
5939 : : * ice_remove_mac - remove a MAC address based filter rule
5940 : : * @hw: pointer to the hardware structure
5941 : : * @m_list: list of MAC addresses and forwarding information
5942 : : *
5943 : : */
5944 : 0 : enum ice_status ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5945 : : {
5946 : : struct ice_sw_recipe *recp_list;
5947 : :
5948 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
5949 : 0 : return ice_remove_mac_rule(hw, m_list, recp_list);
5950 : : }
5951 : :
5952 : : /**
5953 : : * ice_remove_vlan_rule - Remove VLAN based filter rule
5954 : : * @hw: pointer to the hardware structure
5955 : : * @v_list: list of VLAN entries and forwarding information
5956 : : * @recp_list: list from which function remove VLAN
5957 : : */
5958 : : static enum ice_status
5959 : 0 : ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5960 : : struct ice_sw_recipe *recp_list)
5961 : : {
5962 : : struct ice_fltr_list_entry *v_list_itr, *tmp;
5963 : :
5964 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
# # # # #
# ]
5965 : : list_entry) {
5966 : 0 : enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5967 : :
5968 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_VLAN)
5969 : : return ICE_ERR_PARAM;
5970 : 0 : v_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5971 : : v_list_itr);
5972 [ # # ]: 0 : if (v_list_itr->status)
5973 : 0 : return v_list_itr->status;
5974 : : }
5975 : : return ICE_SUCCESS;
5976 : : }
5977 : :
5978 : : /**
5979 : : * ice_remove_vlan - remove a VLAN address based filter rule
5980 : : * @hw: pointer to the hardware structure
5981 : : * @v_list: list of VLAN and forwarding information
5982 : : *
5983 : : */
5984 : : enum ice_status
5985 : 0 : ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5986 : : {
5987 : : struct ice_sw_recipe *recp_list;
5988 : :
5989 [ # # ]: 0 : if (!v_list || !hw)
5990 : : return ICE_ERR_PARAM;
5991 : :
5992 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN];
5993 : 0 : return ice_remove_vlan_rule(hw, v_list, recp_list);
5994 : : }
5995 : :
5996 : : /**
5997 : : * ice_remove_mac_vlan_rule - Remove MAC VLAN based filter rule
5998 : : * @hw: pointer to the hardware structure
5999 : : * @v_list: list of MAC VLAN entries and forwarding information
6000 : : * @recp_list: list from which function remove MAC VLAN
6001 : : */
6002 : : static enum ice_status
6003 : 0 : ice_remove_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
6004 : : struct ice_sw_recipe *recp_list)
6005 : : {
6006 : : struct ice_fltr_list_entry *v_list_itr, *tmp;
6007 : :
6008 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
6009 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
# # # # #
# ]
6010 : : list_entry) {
6011 : 0 : enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
6012 : :
6013 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_MAC_VLAN)
6014 : : return ICE_ERR_PARAM;
6015 : 0 : v_list_itr->status =
6016 : 0 : ice_remove_rule_internal(hw, recp_list,
6017 : : v_list_itr);
6018 [ # # ]: 0 : if (v_list_itr->status)
6019 : 0 : return v_list_itr->status;
6020 : : }
6021 : : return ICE_SUCCESS;
6022 : : }
6023 : :
6024 : : /**
6025 : : * ice_remove_mac_vlan - remove a MAC VLAN address based filter rule
6026 : : * @hw: pointer to the hardware structure
6027 : : * @mv_list: list of MAC VLAN and forwarding information
6028 : : */
6029 : : enum ice_status
6030 : 0 : ice_remove_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
6031 : : {
6032 : : struct ice_sw_recipe *recp_list;
6033 : :
6034 [ # # ]: 0 : if (!mv_list || !hw)
6035 : : return ICE_ERR_PARAM;
6036 : :
6037 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
6038 : 0 : return ice_remove_mac_vlan_rule(hw, mv_list, recp_list);
6039 : : }
6040 : :
6041 : : /**
6042 : : * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
6043 : : * @fm_entry: filter entry to inspect
6044 : : * @vsi_handle: VSI handle to compare with filter info
6045 : : */
6046 : : static bool
6047 : : ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
6048 : : {
6049 : 0 : return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
6050 [ # # # # : 0 : fm_entry->fltr_info.vsi_handle == vsi_handle) ||
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
6051 : 0 : (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
6052 [ # # # # : 0 : fm_entry->vsi_list_info &&
# # # # #
# # # # #
# # ]
6053 [ # # # # : 0 : (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map,
# # # # ]
6054 : : vsi_handle))));
6055 : : }
6056 : :
6057 : : /**
6058 : : * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
6059 : : * @hw: pointer to the hardware structure
6060 : : * @vsi_handle: VSI handle to remove filters from
6061 : : * @vsi_list_head: pointer to the list to add entry to
6062 : : * @fi: pointer to fltr_info of filter entry to copy & add
6063 : : *
6064 : : * Helper function, used when creating a list of filters to remove from
6065 : : * a specific VSI. The entry added to vsi_list_head is a COPY of the
6066 : : * original filter entry, with the exception of fltr_info.fltr_act and
6067 : : * fltr_info.fwd_id fields. These are set such that later logic can
6068 : : * extract which VSI to remove the fltr from, and pass on that information.
6069 : : */
6070 : : static enum ice_status
6071 : 0 : ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
6072 : : struct LIST_HEAD_TYPE *vsi_list_head,
6073 : : struct ice_fltr_info *fi)
6074 : : {
6075 : : struct ice_fltr_list_entry *tmp;
6076 : :
6077 : : /* this memory is freed up in the caller function
6078 : : * once filters for this VSI are removed
6079 : : */
6080 : 0 : tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp));
6081 [ # # ]: 0 : if (!tmp)
6082 : : return ICE_ERR_NO_MEMORY;
6083 : :
6084 : 0 : tmp->fltr_info = *fi;
6085 : :
6086 : : /* Overwrite these fields to indicate which VSI to remove filter from,
6087 : : * so find and remove logic can extract the information from the
6088 : : * list entries. Note that original entries will still have proper
6089 : : * values.
6090 : : */
6091 : 0 : tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
6092 : 0 : tmp->fltr_info.vsi_handle = vsi_handle;
6093 : 0 : tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6094 : :
6095 [ # # ]: 0 : LIST_ADD(&tmp->list_entry, vsi_list_head);
6096 : :
6097 : 0 : return ICE_SUCCESS;
6098 : : }
6099 : :
6100 : : /**
6101 : : * ice_add_to_vsi_fltr_list - Add VSI filters to the list
6102 : : * @hw: pointer to the hardware structure
6103 : : * @vsi_handle: VSI handle to remove filters from
6104 : : * @lkup_list_head: pointer to the list that has certain lookup type filters
6105 : : * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
6106 : : *
6107 : : * Locates all filters in lkup_list_head that are used by the given VSI,
6108 : : * and adds COPIES of those entries to vsi_list_head (intended to be used
6109 : : * to remove the listed filters).
6110 : : * Note that this means all entries in vsi_list_head must be explicitly
6111 : : * deallocated by the caller when done with list.
6112 : : */
6113 : : static enum ice_status
6114 : 0 : ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
6115 : : struct LIST_HEAD_TYPE *lkup_list_head,
6116 : : struct LIST_HEAD_TYPE *vsi_list_head)
6117 : : {
6118 : : struct ice_fltr_mgmt_list_entry *fm_entry;
6119 : : enum ice_status status = ICE_SUCCESS;
6120 : :
6121 : : /* check to make sure VSI ID is valid and within boundary */
6122 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
6123 : : return ICE_ERR_PARAM;
6124 : :
6125 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head,
# # ]
6126 : : ice_fltr_mgmt_list_entry, list_entry) {
6127 [ # # ]: 0 : if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
6128 : 0 : continue;
6129 : :
6130 : 0 : status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
6131 : : vsi_list_head,
6132 : : &fm_entry->fltr_info);
6133 [ # # ]: 0 : if (status)
6134 : 0 : return status;
6135 : : }
6136 : : return status;
6137 : : }
6138 : :
6139 : : /**
6140 : : * ice_determine_promisc_mask
6141 : : * @fi: filter info to parse
6142 : : *
6143 : : * Helper function to determine which ICE_PROMISC_ mask corresponds
6144 : : * to given filter into.
6145 : : */
6146 : 0 : static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
6147 : : {
6148 : 0 : u16 vid = fi->l_data.mac_vlan.vlan_id;
6149 : : u8 *macaddr = fi->l_data.mac.mac_addr;
6150 : : bool is_tx_fltr = false;
6151 : : u8 promisc_mask = 0;
6152 : :
6153 [ # # ]: 0 : if (fi->flag == ICE_FLTR_TX)
6154 : : is_tx_fltr = true;
6155 : :
6156 [ # # ]: 0 : if (IS_BROADCAST_ETHER_ADDR(macaddr))
6157 [ # # ]: 0 : promisc_mask |= is_tx_fltr ?
6158 : : ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
6159 [ # # ]: 0 : else if (IS_MULTICAST_ETHER_ADDR(macaddr))
6160 [ # # ]: 0 : promisc_mask |= is_tx_fltr ?
6161 : : ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
6162 : : else if (IS_UNICAST_ETHER_ADDR(macaddr))
6163 [ # # ]: 0 : promisc_mask |= is_tx_fltr ?
6164 : : ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
6165 [ # # ]: 0 : if (vid)
6166 [ # # ]: 0 : promisc_mask |= is_tx_fltr ?
6167 : : ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
6168 : :
6169 : 0 : return promisc_mask;
6170 : : }
6171 : :
6172 : : /**
6173 : : * _ice_get_vsi_promisc - get promiscuous mode of given VSI
6174 : : * @hw: pointer to the hardware structure
6175 : : * @vsi_handle: VSI handle to retrieve info from
6176 : : * @promisc_mask: pointer to mask to be filled in
6177 : : * @vid: VLAN ID of promisc VLAN VSI
6178 : : * @sw: pointer to switch info struct for which function add rule
6179 : : * @lkup: switch rule filter lookup type
6180 : : */
6181 : : static enum ice_status
6182 : 0 : _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
6183 : : u16 *vid, struct ice_switch_info *sw,
6184 : : enum ice_sw_lkup_type lkup)
6185 : : {
6186 : : struct ice_fltr_mgmt_list_entry *itr;
6187 : : struct LIST_HEAD_TYPE *rule_head;
6188 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6189 : :
6190 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle) ||
6191 [ # # ]: 0 : (lkup != ICE_SW_LKUP_PROMISC && lkup != ICE_SW_LKUP_PROMISC_VLAN))
6192 : : return ICE_ERR_PARAM;
6193 : :
6194 : 0 : *vid = 0;
6195 : 0 : *promisc_mask = 0;
6196 : 0 : rule_head = &sw->recp_list[lkup].filt_rules;
6197 : : rule_lock = &sw->recp_list[lkup].filt_rule_lock;
6198 : :
6199 : 0 : ice_acquire_lock(rule_lock);
6200 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(itr, rule_head,
# # ]
6201 : : ice_fltr_mgmt_list_entry, list_entry) {
6202 : : /* Continue if this filter doesn't apply to this VSI or the
6203 : : * VSI ID is not in the VSI map for this filter
6204 : : */
6205 [ # # ]: 0 : if (!ice_vsi_uses_fltr(itr, vsi_handle))
6206 : 0 : continue;
6207 : :
6208 : 0 : *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info);
6209 : : }
6210 : : ice_release_lock(rule_lock);
6211 : :
6212 : 0 : return ICE_SUCCESS;
6213 : : }
6214 : :
6215 : : /**
6216 : : * ice_get_vsi_promisc - get promiscuous mode of given VSI
6217 : : * @hw: pointer to the hardware structure
6218 : : * @vsi_handle: VSI handle to retrieve info from
6219 : : * @promisc_mask: pointer to mask to be filled in
6220 : : * @vid: VLAN ID of promisc VLAN VSI
6221 : : */
6222 : : enum ice_status
6223 : 0 : ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
6224 : : u16 *vid)
6225 : : {
6226 : 0 : return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
6227 : : vid, hw->switch_info, ICE_SW_LKUP_PROMISC);
6228 : : }
6229 : :
6230 : : /**
6231 : : * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
6232 : : * @hw: pointer to the hardware structure
6233 : : * @vsi_handle: VSI handle to retrieve info from
6234 : : * @promisc_mask: pointer to mask to be filled in
6235 : : * @vid: VLAN ID of promisc VLAN VSI
6236 : : */
6237 : : enum ice_status
6238 : 0 : ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask,
6239 : : u16 *vid)
6240 : : {
6241 : 0 : return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
6242 : : vid, hw->switch_info,
6243 : : ICE_SW_LKUP_PROMISC_VLAN);
6244 : : }
6245 : :
6246 : : /**
6247 : : * ice_remove_promisc - Remove promisc based filter rules
6248 : : * @hw: pointer to the hardware structure
6249 : : * @recp_id: recipe ID for which the rule needs to removed
6250 : : * @v_list: list of promisc entries
6251 : : */
6252 : : static enum ice_status
6253 : 0 : ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
6254 : : struct LIST_HEAD_TYPE *v_list)
6255 : : {
6256 : : struct ice_fltr_list_entry *v_list_itr, *tmp;
6257 : : struct ice_sw_recipe *recp_list;
6258 : :
6259 : 0 : recp_list = &hw->switch_info->recp_list[recp_id];
6260 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
# # # # #
# ]
6261 : : list_entry) {
6262 : 0 : v_list_itr->status =
6263 : 0 : ice_remove_rule_internal(hw, recp_list, v_list_itr);
6264 [ # # ]: 0 : if (v_list_itr->status)
6265 : 0 : return v_list_itr->status;
6266 : : }
6267 : : return ICE_SUCCESS;
6268 : : }
6269 : :
6270 : : /**
6271 : : * _ice_clear_vsi_promisc - clear specified promiscuous mode(s)
6272 : : * @hw: pointer to the hardware structure
6273 : : * @vsi_handle: VSI handle to clear mode
6274 : : * @promisc_mask: mask of promiscuous config bits to clear
6275 : : * @vid: VLAN ID to clear VLAN promiscuous
6276 : : * @sw: pointer to switch info struct for which function add rule
6277 : : */
6278 : : static enum ice_status
6279 : 0 : _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6280 : : u16 vid, struct ice_switch_info *sw)
6281 : : {
6282 : : struct ice_fltr_list_entry *fm_entry, *tmp;
6283 : : struct LIST_HEAD_TYPE remove_list_head;
6284 : : struct ice_fltr_mgmt_list_entry *itr;
6285 : : struct LIST_HEAD_TYPE *rule_head;
6286 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6287 : : enum ice_status status = ICE_SUCCESS;
6288 : : u8 recipe_id;
6289 : :
6290 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
6291 : : return ICE_ERR_PARAM;
6292 : :
6293 [ # # ]: 0 : if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
6294 : : recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
6295 : : else
6296 : : recipe_id = ICE_SW_LKUP_PROMISC;
6297 : :
6298 : 0 : rule_head = &sw->recp_list[recipe_id].filt_rules;
6299 : : rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
6300 : :
6301 : 0 : INIT_LIST_HEAD(&remove_list_head);
6302 : :
6303 : 0 : ice_acquire_lock(rule_lock);
6304 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(itr, rule_head,
# # ]
6305 : : ice_fltr_mgmt_list_entry, list_entry) {
6306 : : struct ice_fltr_info *fltr_info;
6307 : : u8 fltr_promisc_mask = 0;
6308 : :
6309 [ # # ]: 0 : if (!ice_vsi_uses_fltr(itr, vsi_handle))
6310 : 0 : continue;
6311 : 0 : fltr_info = &itr->fltr_info;
6312 : :
6313 [ # # ]: 0 : if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
6314 [ # # ]: 0 : vid != fltr_info->l_data.mac_vlan.vlan_id)
6315 : 0 : continue;
6316 : :
6317 : 0 : fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
6318 : :
6319 : : /* Skip if filter is not completely specified by given mask */
6320 [ # # ]: 0 : if (fltr_promisc_mask & ~promisc_mask)
6321 : 0 : continue;
6322 : :
6323 : 0 : status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
6324 : : &remove_list_head,
6325 : : fltr_info);
6326 [ # # ]: 0 : if (status) {
6327 : : ice_release_lock(rule_lock);
6328 : 0 : goto free_fltr_list;
6329 : : }
6330 : : }
6331 : : ice_release_lock(rule_lock);
6332 : :
6333 : 0 : status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
6334 : :
6335 : 0 : free_fltr_list:
6336 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
# # # # #
# ]
6337 : : ice_fltr_list_entry, list_entry) {
6338 [ # # ]: 0 : LIST_DEL(&fm_entry->list_entry);
6339 : 0 : ice_free(hw, fm_entry);
6340 : : }
6341 : :
6342 : : return status;
6343 : : }
6344 : :
6345 : : /**
6346 : : * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
6347 : : * @hw: pointer to the hardware structure
6348 : : * @vsi_handle: VSI handle to clear mode
6349 : : * @promisc_mask: mask of promiscuous config bits to clear
6350 : : * @vid: VLAN ID to clear VLAN promiscuous
6351 : : */
6352 : : enum ice_status
6353 : 0 : ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6354 : : u8 promisc_mask, u16 vid)
6355 : : {
6356 : 0 : return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask,
6357 : : vid, hw->switch_info);
6358 : : }
6359 : :
6360 : : /**
6361 : : * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
6362 : : * @hw: pointer to the hardware structure
6363 : : * @vsi_handle: VSI handle to configure
6364 : : * @promisc_mask: mask of promiscuous config bits
6365 : : * @vid: VLAN ID to set VLAN promiscuous
6366 : : * @lport: logical port number to configure promisc mode
6367 : : * @sw: pointer to switch info struct for which function add rule
6368 : : */
6369 : : static enum ice_status
6370 : 0 : _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6371 : : u16 vid, u8 lport, struct ice_switch_info *sw)
6372 : : {
6373 : : enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
6374 : : struct ice_fltr_list_entry f_list_entry;
6375 : : struct ice_fltr_info new_fltr;
6376 : : enum ice_status status = ICE_SUCCESS;
6377 : : bool is_tx_fltr;
6378 : : u16 hw_vsi_id;
6379 : : int pkt_type;
6380 : : u8 recipe_id;
6381 : :
6382 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6383 : :
6384 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
6385 : : return ICE_ERR_PARAM;
6386 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6387 : :
6388 : : ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM);
6389 : :
6390 [ # # ]: 0 : if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
6391 : 0 : new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
6392 : 0 : new_fltr.l_data.mac_vlan.vlan_id = vid;
6393 : : recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
6394 : : } else {
6395 : 0 : new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
6396 : : recipe_id = ICE_SW_LKUP_PROMISC;
6397 : : }
6398 : :
6399 : : /* Separate filters must be set for each direction/packet type
6400 : : * combination, so we will loop over the mask value, store the
6401 : : * individual type, and clear it out in the input mask as it
6402 : : * is found.
6403 : : */
6404 [ # # ]: 0 : while (promisc_mask) {
6405 : : struct ice_sw_recipe *recp_list;
6406 : : u8 *mac_addr;
6407 : :
6408 : : pkt_type = 0;
6409 : : is_tx_fltr = false;
6410 : :
6411 [ # # ]: 0 : if (promisc_mask & ICE_PROMISC_UCAST_RX) {
6412 : 0 : promisc_mask &= ~ICE_PROMISC_UCAST_RX;
6413 : : pkt_type = UCAST_FLTR;
6414 [ # # ]: 0 : } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
6415 : 0 : promisc_mask &= ~ICE_PROMISC_UCAST_TX;
6416 : : pkt_type = UCAST_FLTR;
6417 : : is_tx_fltr = true;
6418 [ # # ]: 0 : } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
6419 : 0 : promisc_mask &= ~ICE_PROMISC_MCAST_RX;
6420 : : pkt_type = MCAST_FLTR;
6421 [ # # ]: 0 : } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
6422 : 0 : promisc_mask &= ~ICE_PROMISC_MCAST_TX;
6423 : : pkt_type = MCAST_FLTR;
6424 : : is_tx_fltr = true;
6425 [ # # ]: 0 : } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
6426 : 0 : promisc_mask &= ~ICE_PROMISC_BCAST_RX;
6427 : : pkt_type = BCAST_FLTR;
6428 [ # # ]: 0 : } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
6429 : 0 : promisc_mask &= ~ICE_PROMISC_BCAST_TX;
6430 : : pkt_type = BCAST_FLTR;
6431 : : is_tx_fltr = true;
6432 : : }
6433 : :
6434 : : /* Check for VLAN promiscuous flag */
6435 [ # # ]: 0 : if (promisc_mask & ICE_PROMISC_VLAN_RX) {
6436 : 0 : promisc_mask &= ~ICE_PROMISC_VLAN_RX;
6437 [ # # ]: 0 : } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
6438 : 0 : promisc_mask &= ~ICE_PROMISC_VLAN_TX;
6439 : : is_tx_fltr = true;
6440 : : }
6441 : :
6442 : : /* Set filter DA based on packet type */
6443 : : mac_addr = new_fltr.l_data.mac.mac_addr;
6444 [ # # ]: 0 : if (pkt_type == BCAST_FLTR) {
6445 : : ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM);
6446 [ # # ]: 0 : } else if (pkt_type == MCAST_FLTR ||
6447 : : pkt_type == UCAST_FLTR) {
6448 : : /* Use the dummy ether header DA */
6449 : : ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN,
6450 : : ICE_NONDMA_TO_NONDMA);
6451 [ # # ]: 0 : if (pkt_type == MCAST_FLTR)
6452 : 0 : mac_addr[0] |= 0x1; /* Set multicast bit */
6453 : : }
6454 : :
6455 : : /* Need to reset this to zero for all iterations */
6456 : : new_fltr.flag = 0;
6457 [ # # ]: 0 : if (is_tx_fltr) {
6458 : 0 : new_fltr.flag |= ICE_FLTR_TX;
6459 : 0 : new_fltr.src = hw_vsi_id;
6460 : : } else {
6461 : 0 : new_fltr.flag |= ICE_FLTR_RX;
6462 : 0 : new_fltr.src = lport;
6463 : : }
6464 : :
6465 : 0 : new_fltr.fltr_act = ICE_FWD_TO_VSI;
6466 : 0 : new_fltr.vsi_handle = vsi_handle;
6467 : 0 : new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
6468 : 0 : f_list_entry.fltr_info = new_fltr;
6469 : 0 : recp_list = &sw->recp_list[recipe_id];
6470 : :
6471 : 0 : status = ice_add_rule_internal(hw, recp_list, lport,
6472 : : &f_list_entry);
6473 [ # # ]: 0 : if (status != ICE_SUCCESS)
6474 : 0 : goto set_promisc_exit;
6475 : : }
6476 : :
6477 : 0 : set_promisc_exit:
6478 : : return status;
6479 : : }
6480 : :
6481 : : /**
6482 : : * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
6483 : : * @hw: pointer to the hardware structure
6484 : : * @vsi_handle: VSI handle to configure
6485 : : * @promisc_mask: mask of promiscuous config bits
6486 : : * @vid: VLAN ID to set VLAN promiscuous
6487 : : */
6488 : : enum ice_status
6489 : 0 : ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6490 : : u16 vid)
6491 : : {
6492 : 0 : return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid,
6493 : 0 : hw->port_info->lport,
6494 : : hw->switch_info);
6495 : : }
6496 : :
6497 : : /**
6498 : : * _ice_set_vlan_vsi_promisc
6499 : : * @hw: pointer to the hardware structure
6500 : : * @vsi_handle: VSI handle to configure
6501 : : * @promisc_mask: mask of promiscuous config bits
6502 : : * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6503 : : * @lport: logical port number to configure promisc mode
6504 : : * @sw: pointer to switch info struct for which function add rule
6505 : : *
6506 : : * Configure VSI with all associated VLANs to given promiscuous mode(s)
6507 : : */
6508 : : static enum ice_status
6509 : 0 : _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6510 : : bool rm_vlan_promisc, u8 lport,
6511 : : struct ice_switch_info *sw)
6512 : : {
6513 : : struct ice_fltr_list_entry *list_itr, *tmp;
6514 : : struct LIST_HEAD_TYPE vsi_list_head;
6515 : : struct LIST_HEAD_TYPE *vlan_head;
6516 : : struct ice_lock *vlan_lock; /* Lock to protect filter rule list */
6517 : : enum ice_status status;
6518 : : u16 vlan_id;
6519 : :
6520 : 0 : INIT_LIST_HEAD(&vsi_list_head);
6521 : 0 : vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
6522 : 0 : vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
6523 : 0 : ice_acquire_lock(vlan_lock);
6524 : 0 : status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
6525 : : &vsi_list_head);
6526 : : ice_release_lock(vlan_lock);
6527 [ # # ]: 0 : if (status)
6528 : 0 : goto free_fltr_list;
6529 : :
6530 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry,
# # ]
6531 : : list_entry) {
6532 : : /* Avoid enabling or disabling vlan zero twice when in double
6533 : : * vlan mode
6534 : : */
6535 [ # # ]: 0 : if (ice_is_dvm_ena(hw) &&
6536 [ # # ]: 0 : list_itr->fltr_info.l_data.vlan.tpid == 0)
6537 : 0 : continue;
6538 : :
6539 : 0 : vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
6540 [ # # ]: 0 : if (rm_vlan_promisc)
6541 : 0 : status = _ice_clear_vsi_promisc(hw, vsi_handle,
6542 : : promisc_mask,
6543 : : vlan_id, sw);
6544 : : else
6545 : 0 : status = _ice_set_vsi_promisc(hw, vsi_handle,
6546 : : promisc_mask, vlan_id,
6547 : : lport, sw);
6548 [ # # ]: 0 : if (status && status != ICE_ERR_ALREADY_EXISTS)
6549 : : break;
6550 : : }
6551 : :
6552 : 0 : free_fltr_list:
6553 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head,
# # # # #
# ]
6554 : : ice_fltr_list_entry, list_entry) {
6555 [ # # ]: 0 : LIST_DEL(&list_itr->list_entry);
6556 : 0 : ice_free(hw, list_itr);
6557 : : }
6558 : 0 : return status;
6559 : : }
6560 : :
6561 : : /**
6562 : : * ice_set_vlan_vsi_promisc
6563 : : * @hw: pointer to the hardware structure
6564 : : * @vsi_handle: VSI handle to configure
6565 : : * @promisc_mask: mask of promiscuous config bits
6566 : : * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6567 : : *
6568 : : * Configure VSI with all associated VLANs to given promiscuous mode(s)
6569 : : */
6570 : : enum ice_status
6571 : 0 : ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
6572 : : bool rm_vlan_promisc)
6573 : : {
6574 : 0 : return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask,
6575 : 0 : rm_vlan_promisc, hw->port_info->lport,
6576 : : hw->switch_info);
6577 : : }
6578 : :
6579 : : /**
6580 : : * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
6581 : : * @hw: pointer to the hardware structure
6582 : : * @vsi_handle: VSI handle to remove filters from
6583 : : * @recp_list: recipe list from which function remove fltr
6584 : : * @lkup: switch rule filter lookup type
6585 : : */
6586 : : static void
6587 : 0 : ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
6588 : : struct ice_sw_recipe *recp_list,
6589 : : enum ice_sw_lkup_type lkup)
6590 : : {
6591 : : struct ice_fltr_list_entry *fm_entry;
6592 : : struct LIST_HEAD_TYPE remove_list_head;
6593 : : struct LIST_HEAD_TYPE *rule_head;
6594 : : struct ice_fltr_list_entry *tmp;
6595 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6596 : : enum ice_status status;
6597 : :
6598 : 0 : INIT_LIST_HEAD(&remove_list_head);
6599 : 0 : rule_lock = &recp_list[lkup].filt_rule_lock;
6600 : 0 : rule_head = &recp_list[lkup].filt_rules;
6601 : 0 : ice_acquire_lock(rule_lock);
6602 : 0 : status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
6603 : : &remove_list_head);
6604 : : ice_release_lock(rule_lock);
6605 [ # # ]: 0 : if (status)
6606 : 0 : goto free_fltr_list;
6607 : :
6608 [ # # # # : 0 : switch (lkup) {
# # # # ]
6609 : 0 : case ICE_SW_LKUP_MAC:
6610 : 0 : ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]);
6611 : 0 : break;
6612 : 0 : case ICE_SW_LKUP_VLAN:
6613 : 0 : ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]);
6614 : 0 : break;
6615 : 0 : case ICE_SW_LKUP_PROMISC:
6616 : : case ICE_SW_LKUP_PROMISC_VLAN:
6617 : 0 : ice_remove_promisc(hw, (u8)lkup, &remove_list_head);
6618 : 0 : break;
6619 : 0 : case ICE_SW_LKUP_MAC_VLAN:
6620 : 0 : ice_remove_mac_vlan(hw, &remove_list_head);
6621 : 0 : break;
6622 : 0 : case ICE_SW_LKUP_ETHERTYPE:
6623 : : case ICE_SW_LKUP_ETHERTYPE_MAC:
6624 : 0 : ice_remove_eth_mac(hw, &remove_list_head);
6625 : 0 : break;
6626 : 0 : case ICE_SW_LKUP_DFLT:
6627 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n");
6628 : : break;
6629 : 0 : case ICE_SW_LKUP_LAST:
6630 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n");
6631 : : break;
6632 : : }
6633 : :
6634 : 0 : free_fltr_list:
6635 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
# # # # #
# ]
6636 : : ice_fltr_list_entry, list_entry) {
6637 [ # # ]: 0 : LIST_DEL(&fm_entry->list_entry);
6638 : 0 : ice_free(hw, fm_entry);
6639 : : }
6640 : 0 : }
6641 : :
6642 : : /**
6643 : : * ice_remove_vsi_fltr_rule - Remove all filters for a VSI
6644 : : * @hw: pointer to the hardware structure
6645 : : * @vsi_handle: VSI handle to remove filters from
6646 : : * @sw: pointer to switch info struct
6647 : : */
6648 : : static void
6649 : 0 : ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle,
6650 : : struct ice_switch_info *sw)
6651 : : {
6652 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6653 : :
6654 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6655 : : sw->recp_list, ICE_SW_LKUP_MAC);
6656 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6657 : : sw->recp_list, ICE_SW_LKUP_MAC_VLAN);
6658 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6659 : : sw->recp_list, ICE_SW_LKUP_PROMISC);
6660 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6661 : : sw->recp_list, ICE_SW_LKUP_VLAN);
6662 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6663 : : sw->recp_list, ICE_SW_LKUP_DFLT);
6664 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6665 : : sw->recp_list, ICE_SW_LKUP_ETHERTYPE);
6666 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6667 : : sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC);
6668 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6669 : : sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN);
6670 : 0 : }
6671 : :
6672 : : /**
6673 : : * ice_remove_vsi_fltr - Remove all filters for a VSI
6674 : : * @hw: pointer to the hardware structure
6675 : : * @vsi_handle: VSI handle to remove filters from
6676 : : */
6677 : 0 : void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
6678 : : {
6679 : 0 : ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info);
6680 : 0 : }
6681 : :
6682 : : /**
6683 : : * ice_alloc_res_cntr - allocating resource counter
6684 : : * @hw: pointer to the hardware structure
6685 : : * @type: type of resource
6686 : : * @alloc_shared: if set it is shared else dedicated
6687 : : * @num_items: number of entries requested for FD resource type
6688 : : * @counter_id: counter index returned by AQ call
6689 : : */
6690 : : enum ice_status
6691 : 0 : ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6692 : : u16 *counter_id)
6693 : : {
6694 : : struct ice_aqc_alloc_free_res_elem *buf;
6695 : : enum ice_status status;
6696 : : u16 buf_len;
6697 : :
6698 : : /* Allocate resource */
6699 : : buf_len = ice_struct_size(buf, elem, 1);
6700 : 0 : buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6701 [ # # ]: 0 : if (!buf)
6702 : : return ICE_ERR_NO_MEMORY;
6703 : :
6704 : 0 : buf->num_elems = CPU_TO_LE16(num_items);
6705 : 0 : buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6706 : : ICE_AQC_RES_TYPE_M) | alloc_shared);
6707 : :
6708 : 0 : status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6709 : : ice_aqc_opc_alloc_res, NULL);
6710 [ # # ]: 0 : if (status)
6711 : 0 : goto exit;
6712 : :
6713 : 0 : *counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp);
6714 : :
6715 : 0 : exit:
6716 : 0 : ice_free(hw, buf);
6717 : 0 : return status;
6718 : : }
6719 : :
6720 : : /**
6721 : : * ice_free_res_cntr - free resource counter
6722 : : * @hw: pointer to the hardware structure
6723 : : * @type: type of resource
6724 : : * @alloc_shared: if set it is shared else dedicated
6725 : : * @num_items: number of entries to be freed for FD resource type
6726 : : * @counter_id: counter ID resource which needs to be freed
6727 : : */
6728 : : enum ice_status
6729 : 0 : ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6730 : : u16 counter_id)
6731 : : {
6732 : : struct ice_aqc_alloc_free_res_elem *buf;
6733 : : enum ice_status status;
6734 : : u16 buf_len;
6735 : :
6736 : : /* Free resource */
6737 : : buf_len = ice_struct_size(buf, elem, 1);
6738 : 0 : buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6739 [ # # ]: 0 : if (!buf)
6740 : : return ICE_ERR_NO_MEMORY;
6741 : :
6742 : 0 : buf->num_elems = CPU_TO_LE16(num_items);
6743 : 0 : buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6744 : : ICE_AQC_RES_TYPE_M) | alloc_shared);
6745 : 0 : buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
6746 : :
6747 : 0 : status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6748 : : ice_aqc_opc_free_res, NULL);
6749 [ # # ]: 0 : if (status)
6750 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
6751 : :
6752 : 0 : ice_free(hw, buf);
6753 : 0 : return status;
6754 : : }
6755 : :
6756 : : /**
6757 : : * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type
6758 : : * @hw: pointer to the hardware structure
6759 : : * @counter_id: returns counter index
6760 : : */
6761 : 0 : enum ice_status ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id)
6762 : : {
6763 : 0 : return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6764 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6765 : : counter_id);
6766 : : }
6767 : :
6768 : : /**
6769 : : * ice_free_vlan_res_counter - Free counter resource for VLAN type
6770 : : * @hw: pointer to the hardware structure
6771 : : * @counter_id: counter index to be freed
6772 : : */
6773 : 0 : enum ice_status ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id)
6774 : : {
6775 : 0 : return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6776 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6777 : : counter_id);
6778 : : }
6779 : :
6780 : : /**
6781 : : * ice_add_mac_with_sw_marker - add filter with sw marker
6782 : : * @hw: pointer to the hardware structure
6783 : : * @f_info: filter info structure containing the MAC filter information
6784 : : * @sw_marker: sw marker to tag the Rx descriptor with
6785 : : */
6786 : : enum ice_status
6787 : 0 : ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info,
6788 : : u16 sw_marker)
6789 : : {
6790 : : struct ice_fltr_mgmt_list_entry *m_entry;
6791 : : struct ice_fltr_list_entry fl_info;
6792 : : struct ice_sw_recipe *recp_list;
6793 : : struct LIST_HEAD_TYPE l_head;
6794 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6795 : : enum ice_status ret;
6796 : : bool entry_exists;
6797 : : u16 lg_act_id;
6798 : :
6799 [ # # ]: 0 : if (f_info->fltr_act != ICE_FWD_TO_VSI)
6800 : : return ICE_ERR_PARAM;
6801 : :
6802 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6803 : : return ICE_ERR_PARAM;
6804 : :
6805 [ # # ]: 0 : if (sw_marker == ICE_INVAL_SW_MARKER_ID)
6806 : : return ICE_ERR_PARAM;
6807 : :
6808 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6809 : : return ICE_ERR_PARAM;
6810 : 0 : f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6811 : :
6812 : : /* Add filter if it doesn't exist so then the adding of large
6813 : : * action always results in update
6814 : : */
6815 : :
6816 : : INIT_LIST_HEAD(&l_head);
6817 : 0 : fl_info.fltr_info = *f_info;
6818 : 0 : LIST_ADD(&fl_info.list_entry, &l_head);
6819 : :
6820 : : entry_exists = false;
6821 : 0 : ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6822 : 0 : hw->port_info->lport);
6823 [ # # ]: 0 : if (ret == ICE_ERR_ALREADY_EXISTS)
6824 : : entry_exists = true;
6825 [ # # ]: 0 : else if (ret)
6826 : : return ret;
6827 : :
6828 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6829 : : rule_lock = &recp_list->filt_rule_lock;
6830 : 0 : ice_acquire_lock(rule_lock);
6831 : : /* Get the book keeping entry for the filter */
6832 : 0 : m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6833 [ # # ]: 0 : if (!m_entry)
6834 : 0 : goto exit_error;
6835 : :
6836 : : /* If counter action was enabled for this rule then don't enable
6837 : : * sw marker large action
6838 : : */
6839 [ # # ]: 0 : if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6840 : : ret = ICE_ERR_PARAM;
6841 : 0 : goto exit_error;
6842 : : }
6843 : :
6844 : : /* if same marker was added before */
6845 [ # # ]: 0 : if (m_entry->sw_marker_id == sw_marker) {
6846 : : ret = ICE_ERR_ALREADY_EXISTS;
6847 : 0 : goto exit_error;
6848 : : }
6849 : :
6850 : : /* Allocate a hardware table entry to hold large act. Three actions
6851 : : * for marker based large action
6852 : : */
6853 : 0 : ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3);
6854 [ # # ]: 0 : if (ret)
6855 : 0 : goto exit_error;
6856 : :
6857 [ # # ]: 0 : if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6858 : 0 : goto exit_error;
6859 : :
6860 : : /* Update the switch rule to add the marker action */
6861 : 0 : ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id);
6862 [ # # ]: 0 : if (!ret) {
6863 : : ice_release_lock(rule_lock);
6864 : 0 : return ret;
6865 : : }
6866 : :
6867 : 0 : exit_error:
6868 : : ice_release_lock(rule_lock);
6869 : : /* only remove entry if it did not exist previously */
6870 [ # # ]: 0 : if (!entry_exists)
6871 : 0 : ret = ice_remove_mac(hw, &l_head);
6872 : :
6873 : : return ret;
6874 : : }
6875 : :
6876 : : /**
6877 : : * ice_add_mac_with_counter - add filter with counter enabled
6878 : : * @hw: pointer to the hardware structure
6879 : : * @f_info: pointer to filter info structure containing the MAC filter
6880 : : * information
6881 : : */
6882 : : enum ice_status
6883 : 0 : ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info)
6884 : : {
6885 : : struct ice_fltr_mgmt_list_entry *m_entry;
6886 : : struct ice_fltr_list_entry fl_info;
6887 : : struct ice_sw_recipe *recp_list;
6888 : : struct LIST_HEAD_TYPE l_head;
6889 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6890 : : enum ice_status ret;
6891 : : bool entry_exist;
6892 : : u16 counter_id;
6893 : : u16 lg_act_id;
6894 : :
6895 [ # # ]: 0 : if (f_info->fltr_act != ICE_FWD_TO_VSI)
6896 : : return ICE_ERR_PARAM;
6897 : :
6898 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6899 : : return ICE_ERR_PARAM;
6900 : :
6901 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6902 : : return ICE_ERR_PARAM;
6903 : 0 : f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6904 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6905 : :
6906 : : entry_exist = false;
6907 : :
6908 : : rule_lock = &recp_list->filt_rule_lock;
6909 : :
6910 : : /* Add filter if it doesn't exist so then the adding of large
6911 : : * action always results in update
6912 : : */
6913 : : INIT_LIST_HEAD(&l_head);
6914 : :
6915 : 0 : fl_info.fltr_info = *f_info;
6916 : 0 : LIST_ADD(&fl_info.list_entry, &l_head);
6917 : :
6918 : 0 : ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6919 : 0 : hw->port_info->lport);
6920 [ # # ]: 0 : if (ret == ICE_ERR_ALREADY_EXISTS)
6921 : : entry_exist = true;
6922 [ # # ]: 0 : else if (ret)
6923 : : return ret;
6924 : :
6925 : 0 : ice_acquire_lock(rule_lock);
6926 : 0 : m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6927 [ # # ]: 0 : if (!m_entry) {
6928 : : ret = ICE_ERR_BAD_PTR;
6929 : 0 : goto exit_error;
6930 : : }
6931 : :
6932 : : /* Don't enable counter for a filter for which sw marker was enabled */
6933 [ # # ]: 0 : if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) {
6934 : : ret = ICE_ERR_PARAM;
6935 : 0 : goto exit_error;
6936 : : }
6937 : :
6938 : : /* If a counter was already enabled then don't need to add again */
6939 [ # # ]: 0 : if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6940 : : ret = ICE_ERR_ALREADY_EXISTS;
6941 : 0 : goto exit_error;
6942 : : }
6943 : :
6944 : : /* Allocate a hardware table entry to VLAN counter */
6945 : 0 : ret = ice_alloc_vlan_res_counter(hw, &counter_id);
6946 [ # # ]: 0 : if (ret)
6947 : 0 : goto exit_error;
6948 : :
6949 : : /* Allocate a hardware table entry to hold large act. Two actions for
6950 : : * counter based large action
6951 : : */
6952 : 0 : ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2);
6953 [ # # ]: 0 : if (ret)
6954 : 0 : goto exit_error;
6955 : :
6956 [ # # ]: 0 : if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6957 : 0 : goto exit_error;
6958 : :
6959 : : /* Update the switch rule to add the counter action */
6960 : 0 : ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id);
6961 [ # # ]: 0 : if (!ret) {
6962 : : ice_release_lock(rule_lock);
6963 : 0 : return ret;
6964 : : }
6965 : :
6966 : 0 : exit_error:
6967 : : ice_release_lock(rule_lock);
6968 : : /* only remove entry if it did not exist previously */
6969 [ # # ]: 0 : if (!entry_exist)
6970 : 0 : ret = ice_remove_mac(hw, &l_head);
6971 : :
6972 : : return ret;
6973 : : }
6974 : :
6975 : : /* This is mapping table entry that maps every word within a given protocol
6976 : : * structure to the real byte offset as per the specification of that
6977 : : * protocol header.
6978 : : * for example dst address is 3 words in ethertype header and corresponding
6979 : : * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
6980 : : * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
6981 : : * matching entry describing its field. This needs to be updated if new
6982 : : * structure is added to that union.
6983 : : */
6984 : : static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
6985 : : { ICE_MAC_OFOS, { 0, 2, 4, 6, 8, 10, 12 } },
6986 : : { ICE_MAC_IL, { 0, 2, 4, 6, 8, 10, 12 } },
6987 : : { ICE_ETYPE_OL, { 0 } },
6988 : : { ICE_ETYPE_IL, { 0 } },
6989 : : { ICE_VLAN_OFOS, { 2, 0 } },
6990 : : { ICE_IPV4_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6991 : : { ICE_IPV4_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
6992 : : { ICE_IPV6_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6993 : : 26, 28, 30, 32, 34, 36, 38 } },
6994 : : { ICE_IPV6_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
6995 : : 26, 28, 30, 32, 34, 36, 38 } },
6996 : : { ICE_TCP_IL, { 0, 2 } },
6997 : : { ICE_UDP_OF, { 0, 2 } },
6998 : : { ICE_UDP_ILOS, { 0, 2 } },
6999 : : { ICE_SCTP_IL, { 0, 2 } },
7000 : : { ICE_VXLAN, { 8, 10, 12, 14 } },
7001 : : { ICE_GENEVE, { 8, 10, 12, 14 } },
7002 : : { ICE_VXLAN_GPE, { 8, 10, 12, 14 } },
7003 : : { ICE_NVGRE, { 0, 2, 4, 6 } },
7004 : : { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
7005 : : { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } },
7006 : : { ICE_PPPOE, { 0, 2, 4, 6 } },
7007 : : { ICE_PFCP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
7008 : : { ICE_L2TPV3, { 0, 2, 4, 6, 8, 10 } },
7009 : : { ICE_ESP, { 0, 2, 4, 6 } },
7010 : : { ICE_AH, { 0, 2, 4, 6, 8, 10 } },
7011 : : { ICE_NAT_T, { 8, 10, 12, 14 } },
7012 : : { ICE_VLAN_EX, { 2, 0 } },
7013 : : { ICE_VLAN_IN, { 2, 0 } },
7014 : : };
7015 : :
7016 : : /* The following table describes preferred grouping of recipes.
7017 : : * If a recipe that needs to be programmed is a superset or matches one of the
7018 : : * following combinations, then the recipe needs to be chained as per the
7019 : : * following policy.
7020 : : */
7021 : :
7022 : : static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
7023 : : { ICE_MAC_OFOS, ICE_MAC_OFOS_HW },
7024 : : { ICE_MAC_IL, ICE_MAC_IL_HW },
7025 : : { ICE_ETYPE_OL, ICE_ETYPE_OL_HW },
7026 : : { ICE_ETYPE_IL, ICE_ETYPE_IL_HW },
7027 : : { ICE_VLAN_OFOS, ICE_VLAN_OL_HW },
7028 : : { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW },
7029 : : { ICE_IPV4_IL, ICE_IPV4_IL_HW },
7030 : : { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW },
7031 : : { ICE_IPV6_IL, ICE_IPV6_IL_HW },
7032 : : { ICE_TCP_IL, ICE_TCP_IL_HW },
7033 : : { ICE_UDP_OF, ICE_UDP_OF_HW },
7034 : : { ICE_UDP_ILOS, ICE_UDP_ILOS_HW },
7035 : : { ICE_SCTP_IL, ICE_SCTP_IL_HW },
7036 : : { ICE_VXLAN, ICE_UDP_OF_HW },
7037 : : { ICE_GENEVE, ICE_UDP_OF_HW },
7038 : : { ICE_VXLAN_GPE, ICE_UDP_OF_HW },
7039 : : { ICE_NVGRE, ICE_GRE_OF_HW },
7040 : : { ICE_GTP, ICE_UDP_OF_HW },
7041 : : { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
7042 : : { ICE_PPPOE, ICE_PPPOE_HW },
7043 : : { ICE_PFCP, ICE_UDP_ILOS_HW },
7044 : : { ICE_L2TPV3, ICE_L2TPV3_HW },
7045 : : { ICE_ESP, ICE_ESP_HW },
7046 : : { ICE_AH, ICE_AH_HW },
7047 : : { ICE_NAT_T, ICE_UDP_ILOS_HW },
7048 : : { ICE_VLAN_EX, ICE_VLAN_OF_HW },
7049 : : { ICE_VLAN_IN, ICE_VLAN_OL_HW },
7050 : : { ICE_FLG_DIR, ICE_META_DATA_ID_HW},
7051 : : };
7052 : :
7053 : : /**
7054 : : * ice_find_recp - find a recipe
7055 : : * @hw: pointer to the hardware structure
7056 : : * @lkup_exts: extension sequence to match
7057 : : *
7058 : : * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
7059 : : */
7060 : 0 : static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
7061 : : enum ice_sw_tunnel_type tun_type, u32 priority)
7062 : : {
7063 : 0 : bool refresh_required = true;
7064 : : struct ice_sw_recipe *recp;
7065 : : u8 i;
7066 : :
7067 : : /* Walk through existing recipes to find a match */
7068 : 0 : recp = hw->switch_info->recp_list;
7069 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
7070 : : /* If recipe was not created for this ID, in SW bookkeeping,
7071 : : * check if FW has an entry for this recipe. If the FW has an
7072 : : * entry update it in our SW bookkeeping and continue with the
7073 : : * matching.
7074 : : */
7075 [ # # ]: 0 : if (!recp[i].recp_created)
7076 [ # # ]: 0 : if (ice_get_recp_frm_fw(hw,
7077 : 0 : hw->switch_info->recp_list, i,
7078 : : &refresh_required))
7079 : 0 : continue;
7080 : :
7081 : : /* Skip inverse action recipes */
7082 [ # # # # ]: 0 : if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
7083 : : ICE_AQ_RECIPE_ACT_INV_ACT)
7084 : 0 : continue;
7085 : :
7086 : : /* if number of words we are looking for match */
7087 [ # # ]: 0 : if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
7088 : 0 : struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
7089 : 0 : struct ice_fv_word *be = lkup_exts->fv_words;
7090 : 0 : u16 *cr = recp[i].lkup_exts.field_mask;
7091 : 0 : u16 *de = lkup_exts->field_mask;
7092 : : bool found = true;
7093 : : u8 pe, qr;
7094 : :
7095 : : /* ar, cr, and qr are related to the recipe words, while
7096 : : * be, de, and pe are related to the lookup words
7097 : : */
7098 [ # # ]: 0 : for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
7099 [ # # ]: 0 : for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
7100 : 0 : qr++) {
7101 [ # # ]: 0 : if (ar[qr].off == be[pe].off &&
7102 [ # # ]: 0 : ar[qr].prot_id == be[pe].prot_id &&
7103 [ # # ]: 0 : cr[qr] == de[pe])
7104 : : /* Found the "pe"th word in the
7105 : : * given recipe
7106 : : */
7107 : : break;
7108 : : }
7109 : : /* After walking through all the words in the
7110 : : * "i"th recipe if "p"th word was not found then
7111 : : * this recipe is not what we are looking for.
7112 : : * So break out from this loop and try the next
7113 : : * recipe
7114 : : */
7115 [ # # ]: 0 : if (qr >= recp[i].lkup_exts.n_val_words) {
7116 : : found = false;
7117 : : break;
7118 : : }
7119 : : }
7120 : : /* If for "i"th recipe the found was never set to false
7121 : : * then it means we found our match
7122 : : */
7123 [ # # # # ]: 0 : if (tun_type == recp[i].tun_type && found &&
7124 [ # # ]: 0 : priority == recp[i].priority)
7125 : 0 : return i; /* Return the recipe ID */
7126 : : }
7127 : : }
7128 : : return ICE_MAX_NUM_RECIPES;
7129 : : }
7130 : :
7131 : : /**
7132 : : * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
7133 : : *
7134 : : * As protocol id for outer vlan is different in dvm and svm, if dvm is
7135 : : * supported protocol array record for outer vlan has to be modified to
7136 : : * reflect the value proper for DVM.
7137 : : */
7138 : 0 : void ice_change_proto_id_to_dvm(void)
7139 : : {
7140 : : u8 i;
7141 : :
7142 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
7143 [ # # ]: 0 : if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
7144 [ # # ]: 0 : ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
7145 : 0 : ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
7146 : 0 : }
7147 : :
7148 : : /**
7149 : : * ice_prot_type_to_id - get protocol ID from protocol type
7150 : : * @type: protocol type
7151 : : * @id: pointer to variable that will receive the ID
7152 : : *
7153 : : * Returns true if found, false otherwise
7154 : : */
7155 : : static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
7156 : : {
7157 : : u8 i;
7158 : :
7159 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
7160 [ # # ]: 0 : if (ice_prot_id_tbl[i].type == type) {
7161 : : *id = ice_prot_id_tbl[i].protocol_id;
7162 : : return true;
7163 : : }
7164 : : return false;
7165 : : }
7166 : :
7167 : : /**
7168 : : * ice_fill_valid_words - count valid words
7169 : : * @rule: advanced rule with lookup information
7170 : : * @lkup_exts: byte offset extractions of the words that are valid
7171 : : *
7172 : : * calculate valid words in a lookup rule using mask value
7173 : : */
7174 : : static u8
7175 : 0 : ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
7176 : : struct ice_prot_lkup_ext *lkup_exts)
7177 : : {
7178 : : u8 j, word, prot_id, ret_val;
7179 : :
7180 : 0 : if (!ice_prot_type_to_id(rule->type, &prot_id))
7181 : : return 0;
7182 : :
7183 : 0 : word = lkup_exts->n_val_words;
7184 : :
7185 [ # # ]: 0 : for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
7186 [ # # # # ]: 0 : if (((u16 *)&rule->m_u)[j] &&
7187 : : (size_t)rule->type < ARRAY_SIZE(ice_prot_ext)) {
7188 : : /* No more space to accommodate */
7189 [ # # ]: 0 : if (word >= ICE_MAX_CHAIN_WORDS)
7190 : : return 0;
7191 : 0 : lkup_exts->fv_words[word].off =
7192 : 0 : ice_prot_ext[rule->type].offs[j];
7193 : 0 : lkup_exts->fv_words[word].prot_id =
7194 : 0 : ice_prot_id_tbl[rule->type].protocol_id;
7195 : 0 : lkup_exts->field_mask[word] =
7196 [ # # ]: 0 : BE16_TO_CPU(((_FORCE_ __be16 *)&rule->m_u)[j]);
7197 : 0 : word++;
7198 : : }
7199 : :
7200 : 0 : ret_val = word - lkup_exts->n_val_words;
7201 : 0 : lkup_exts->n_val_words = word;
7202 : :
7203 : 0 : return ret_val;
7204 : : }
7205 : :
7206 : : /**
7207 : : * ice_create_first_fit_recp_def - Create a recipe grouping
7208 : : * @hw: pointer to the hardware structure
7209 : : * @lkup_exts: an array of protocol header extractions
7210 : : * @rg_list: pointer to a list that stores new recipe groups
7211 : : * @recp_cnt: pointer to a variable that stores returned number of recipe groups
7212 : : *
7213 : : * Using first fit algorithm, take all the words that are still not done
7214 : : * and start grouping them in 4-word groups. Each group makes up one
7215 : : * recipe.
7216 : : */
7217 : : static enum ice_status
7218 : 0 : ice_create_first_fit_recp_def(struct ice_hw *hw,
7219 : : struct ice_prot_lkup_ext *lkup_exts,
7220 : : struct LIST_HEAD_TYPE *rg_list,
7221 : : u8 *recp_cnt)
7222 : : {
7223 : : struct ice_pref_recipe_group *grp = NULL;
7224 : : u8 j;
7225 : :
7226 : 0 : *recp_cnt = 0;
7227 : :
7228 [ # # ]: 0 : if (!lkup_exts->n_val_words) {
7229 : : struct ice_recp_grp_entry *entry;
7230 : :
7231 : : entry = (struct ice_recp_grp_entry *)
7232 : 0 : ice_malloc(hw, sizeof(*entry));
7233 [ # # ]: 0 : if (!entry)
7234 : : return ICE_ERR_NO_MEMORY;
7235 [ # # ]: 0 : LIST_ADD(&entry->l_entry, rg_list);
7236 : 0 : grp = &entry->r_group;
7237 : 0 : (*recp_cnt)++;
7238 : 0 : grp->n_val_pairs = 0;
7239 : : }
7240 : :
7241 : : /* Walk through every word in the rule to check if it is not done. If so
7242 : : * then this word needs to be part of a new recipe.
7243 : : */
7244 [ # # ]: 0 : for (j = 0; j < lkup_exts->n_val_words; j++)
7245 [ # # ]: 0 : if (!ice_is_bit_set(lkup_exts->done, j)) {
7246 [ # # ]: 0 : if (!grp ||
7247 [ # # ]: 0 : grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
7248 : : struct ice_recp_grp_entry *entry;
7249 : :
7250 : : entry = (struct ice_recp_grp_entry *)
7251 : 0 : ice_malloc(hw, sizeof(*entry));
7252 [ # # ]: 0 : if (!entry)
7253 : : return ICE_ERR_NO_MEMORY;
7254 [ # # ]: 0 : LIST_ADD(&entry->l_entry, rg_list);
7255 : 0 : grp = &entry->r_group;
7256 : 0 : (*recp_cnt)++;
7257 : : }
7258 : :
7259 : 0 : grp->pairs[grp->n_val_pairs].prot_id =
7260 : 0 : lkup_exts->fv_words[j].prot_id;
7261 : 0 : grp->pairs[grp->n_val_pairs].off =
7262 : 0 : lkup_exts->fv_words[j].off;
7263 : 0 : grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
7264 : 0 : grp->n_val_pairs++;
7265 : : }
7266 : :
7267 : : return ICE_SUCCESS;
7268 : : }
7269 : :
7270 : : /**
7271 : : * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
7272 : : * @hw: pointer to the hardware structure
7273 : : * @fv_list: field vector with the extraction sequence information
7274 : : * @rg_list: recipe groupings with protocol-offset pairs
7275 : : *
7276 : : * Helper function to fill in the field vector indices for protocol-offset
7277 : : * pairs. These indexes are then ultimately programmed into a recipe.
7278 : : */
7279 : : static enum ice_status
7280 : 0 : ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,
7281 : : struct LIST_HEAD_TYPE *rg_list)
7282 : : {
7283 : : struct ice_sw_fv_list_entry *fv;
7284 : : struct ice_recp_grp_entry *rg;
7285 : : struct ice_fv_word *fv_ext;
7286 : :
7287 [ # # ]: 0 : if (LIST_EMPTY(fv_list))
7288 : : return ICE_SUCCESS;
7289 : :
7290 : : fv = LIST_FIRST_ENTRY(fv_list, struct ice_sw_fv_list_entry, list_entry);
7291 : 0 : fv_ext = fv->fv_ptr->ew;
7292 : :
7293 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(rg, rg_list, ice_recp_grp_entry, l_entry) {
# # ]
7294 : : u8 i;
7295 : :
7296 [ # # ]: 0 : for (i = 0; i < rg->r_group.n_val_pairs; i++) {
7297 : : struct ice_fv_word *pr;
7298 : : bool found = false;
7299 : : u16 mask;
7300 : : u8 j;
7301 : :
7302 : 0 : pr = &rg->r_group.pairs[i];
7303 : 0 : mask = rg->r_group.mask[i];
7304 : :
7305 [ # # ]: 0 : for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
7306 [ # # ]: 0 : if (fv_ext[j].prot_id == pr->prot_id &&
7307 [ # # ]: 0 : fv_ext[j].off == pr->off) {
7308 : : found = true;
7309 : :
7310 : : /* Store index of field vector */
7311 : 0 : rg->fv_idx[i] = j;
7312 : 0 : rg->fv_mask[i] = mask;
7313 : : break;
7314 : : }
7315 : :
7316 : : /* Protocol/offset could not be found, caller gave an
7317 : : * invalid pair
7318 : : */
7319 : : if (!found)
7320 : : return ICE_ERR_PARAM;
7321 : : }
7322 : : }
7323 : :
7324 : : return ICE_SUCCESS;
7325 : : }
7326 : :
7327 : : /**
7328 : : * ice_find_free_recp_res_idx - find free result indexes for recipe
7329 : : * @hw: pointer to hardware structure
7330 : : * @profiles: bitmap of profiles that will be associated with the new recipe
7331 : : * @free_idx: pointer to variable to receive the free index bitmap
7332 : : *
7333 : : * The algorithm used here is:
7334 : : * 1. When creating a new recipe, create a set P which contains all
7335 : : * Profiles that will be associated with our new recipe
7336 : : *
7337 : : * 2. For each Profile p in set P:
7338 : : * a. Add all recipes associated with Profile p into set R
7339 : : * b. Optional : PossibleIndexes &= profile[p].possibleIndexes
7340 : : * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
7341 : : * i. Or just assume they all have the same possible indexes:
7342 : : * 44, 45, 46, 47
7343 : : * i.e., PossibleIndexes = 0x0000F00000000000
7344 : : *
7345 : : * 3. For each Recipe r in set R:
7346 : : * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
7347 : : * b. FreeIndexes = UsedIndexes ^ PossibleIndexes
7348 : : *
7349 : : * FreeIndexes will contain the bits indicating the indexes free for use,
7350 : : * then the code needs to update the recipe[r].used_result_idx_bits to
7351 : : * indicate which indexes were selected for use by this recipe.
7352 : : */
7353 : : static u16
7354 : 0 : ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles,
7355 : : ice_bitmap_t *free_idx)
7356 : : {
7357 : : ice_declare_bitmap(possible_idx, ICE_MAX_FV_WORDS);
7358 : : ice_declare_bitmap(recipes, ICE_MAX_NUM_RECIPES);
7359 : : ice_declare_bitmap(used_idx, ICE_MAX_FV_WORDS);
7360 : : u16 bit;
7361 : :
7362 : : ice_zero_bitmap(possible_idx, ICE_MAX_FV_WORDS);
7363 : : ice_zero_bitmap(recipes, ICE_MAX_NUM_RECIPES);
7364 : : ice_zero_bitmap(used_idx, ICE_MAX_FV_WORDS);
7365 : : ice_zero_bitmap(free_idx, ICE_MAX_FV_WORDS);
7366 : :
7367 : : ice_bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);
7368 : :
7369 : : /* For each profile we are going to associate the recipe with, add the
7370 : : * recipes that are associated with that profile. This will give us
7371 : : * the set of recipes that our recipe may collide with. Also, determine
7372 : : * what possible result indexes are usable given this set of profiles.
7373 : : */
7374 [ # # ]: 0 : ice_for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
7375 : 0 : ice_or_bitmap(recipes, recipes, profile_to_recipe[bit],
7376 : : ICE_MAX_NUM_RECIPES);
7377 : 0 : ice_and_bitmap(possible_idx, possible_idx,
7378 : 0 : hw->switch_info->prof_res_bm[bit],
7379 : : ICE_MAX_FV_WORDS);
7380 : : }
7381 : :
7382 : : /* For each recipe that our new recipe may collide with, determine
7383 : : * which indexes have been used.
7384 : : */
7385 [ # # ]: 0 : ice_for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
7386 : 0 : ice_or_bitmap(used_idx, used_idx,
7387 : 0 : hw->switch_info->recp_list[bit].res_idxs,
7388 : : ICE_MAX_FV_WORDS);
7389 : :
7390 : 0 : ice_xor_bitmap(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
7391 : :
7392 : : /* return number of free indexes */
7393 : 0 : return (u16)ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS);
7394 : : }
7395 : :
7396 : : static void ice_set_recipe_index(unsigned long idx, u8 *bitmap)
7397 : : {
7398 : 0 : u32 byte = idx / BITS_PER_BYTE;
7399 : 0 : u32 bit = idx % BITS_PER_BYTE;
7400 : :
7401 : 0 : if (byte >= 8)
7402 : : return;
7403 : :
7404 : 0 : bitmap[byte] |= 1 << bit;
7405 : : }
7406 : :
7407 : : /**
7408 : : * ice_add_sw_recipe - function to call AQ calls to create switch recipe
7409 : : * @hw: pointer to hardware structure
7410 : : * @rm: recipe management list entry
7411 : : * @profiles: bitmap of profiles that will be associated.
7412 : : */
7413 : : static enum ice_status
7414 : 0 : ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
7415 : : ice_bitmap_t *profiles)
7416 : : {
7417 : : ice_declare_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
7418 : : struct ice_aqc_recipe_data_elem *tmp;
7419 : : struct ice_aqc_recipe_data_elem *buf;
7420 : : struct ice_recp_grp_entry *entry;
7421 : : enum ice_status status;
7422 : : u16 free_res_idx;
7423 : : u16 recipe_count;
7424 : : u8 chain_idx;
7425 : : u8 recps = 0;
7426 : :
7427 : : /* When more than one recipe are required, another recipe is needed to
7428 : : * chain them together. Matching a tunnel metadata ID takes up one of
7429 : : * the match fields in the chaining recipe reducing the number of
7430 : : * chained recipes by one.
7431 : : */
7432 : : /* check number of free result indices */
7433 : : ice_zero_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
7434 : 0 : free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
7435 : :
7436 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
7437 : : free_res_idx, rm->n_grp_count);
7438 : :
7439 [ # # ]: 0 : if (rm->n_grp_count > 1) {
7440 [ # # ]: 0 : if (rm->n_grp_count > free_res_idx)
7441 : : return ICE_ERR_MAX_LIMIT;
7442 : :
7443 : 0 : rm->n_grp_count++;
7444 : : }
7445 : :
7446 [ # # ]: 0 : if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
7447 : : return ICE_ERR_MAX_LIMIT;
7448 : :
7449 : 0 : tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
7450 : : ICE_MAX_NUM_RECIPES,
7451 : : sizeof(*tmp));
7452 [ # # ]: 0 : if (!tmp)
7453 : : return ICE_ERR_NO_MEMORY;
7454 : :
7455 : : buf = (struct ice_aqc_recipe_data_elem *)
7456 : 0 : ice_calloc(hw, rm->n_grp_count, sizeof(*buf));
7457 [ # # ]: 0 : if (!buf) {
7458 : : status = ICE_ERR_NO_MEMORY;
7459 : 0 : goto err_mem;
7460 : : }
7461 : :
7462 : 0 : ice_zero_bitmap(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
7463 : 0 : recipe_count = ICE_MAX_NUM_RECIPES;
7464 : 0 : status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
7465 : : NULL);
7466 [ # # # # ]: 0 : if (status || recipe_count == 0)
7467 : 0 : goto err_unroll;
7468 : :
7469 : : /* Allocate the recipe resources, and configure them according to the
7470 : : * match fields from protocol headers and extracted field vectors.
7471 : : */
7472 : 0 : chain_idx = (u8)ice_find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
7473 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7474 : : u8 i;
7475 : :
7476 : 0 : status = ice_alloc_recipe(hw, &entry->rid);
7477 [ # # ]: 0 : if (status)
7478 : 0 : goto err_unroll;
7479 : :
7480 : : /* Clear the result index of the located recipe, as this will be
7481 : : * updated, if needed, later in the recipe creation process.
7482 : : */
7483 : 0 : tmp[0].content.result_indx = 0;
7484 : :
7485 : 0 : buf[recps] = tmp[0];
7486 : 0 : buf[recps].recipe_indx = (u8)entry->rid;
7487 : : /* if the recipe is a non-root recipe RID should be programmed
7488 : : * as 0 for the rules to be applied correctly.
7489 : : */
7490 : 0 : buf[recps].content.rid = 0;
7491 : 0 : ice_memset(&buf[recps].content.lkup_indx, 0,
7492 : : sizeof(buf[recps].content.lkup_indx),
7493 : : ICE_NONDMA_MEM);
7494 : :
7495 : : /* All recipes use look-up index 0 to match switch ID. */
7496 : : buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7497 : 0 : buf[recps].content.mask[0] =
7498 : : CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7499 : : /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
7500 : : * to be 0
7501 : : */
7502 [ # # ]: 0 : for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7503 : 0 : buf[recps].content.lkup_indx[i] = 0x80;
7504 : 0 : buf[recps].content.mask[i] = 0;
7505 : : }
7506 : :
7507 [ # # ]: 0 : for (i = 0; i < entry->r_group.n_val_pairs; i++) {
7508 : 0 : buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
7509 : 0 : buf[recps].content.mask[i + 1] =
7510 : 0 : CPU_TO_LE16(entry->fv_mask[i]);
7511 : : }
7512 : :
7513 [ # # ]: 0 : if (rm->n_grp_count > 1) {
7514 : : /* Checks to see if there really is a valid result index
7515 : : * that can be used.
7516 : : */
7517 [ # # ]: 0 : if (chain_idx >= ICE_MAX_FV_WORDS) {
7518 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
7519 : : status = ICE_ERR_MAX_LIMIT;
7520 : 0 : goto err_unroll;
7521 : : }
7522 : :
7523 : 0 : entry->chain_idx = chain_idx;
7524 : 0 : buf[recps].content.result_indx =
7525 : 0 : ICE_AQ_RECIPE_RESULT_EN |
7526 : 0 : ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
7527 : : ICE_AQ_RECIPE_RESULT_DATA_M);
7528 : : ice_clear_bit(chain_idx, result_idx_bm);
7529 : 0 : chain_idx = ice_find_first_bit(result_idx_bm,
7530 : : ICE_MAX_FV_WORDS);
7531 : : }
7532 : :
7533 : : /* fill recipe dependencies */
7534 [ # # ]: 0 : ice_memset(buf[recps].recipe_bitmap, 0,
7535 : : sizeof(buf[recps].recipe_bitmap), ICE_NONDMA_MEM);
7536 [ # # ]: 0 : ice_set_recipe_index(buf[recps].recipe_indx,
7537 : : buf[recps].recipe_bitmap);
7538 : 0 : buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7539 [ # # ]: 0 : recps++;
7540 : : }
7541 : :
7542 [ # # ]: 0 : if (rm->n_grp_count == 1) {
7543 [ # # ]: 0 : rm->root_rid = buf[0].recipe_indx;
7544 : : ice_set_bit(buf[0].recipe_indx, rm->r_bitmap);
7545 : 0 : buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
7546 : : if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
7547 [ # # ]: 0 : ice_memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
7548 : : sizeof(buf[0].recipe_bitmap),
7549 : : ICE_NONDMA_TO_NONDMA);
7550 : : } else {
7551 : : status = ICE_ERR_BAD_PTR;
7552 : : goto err_unroll;
7553 : : }
7554 : : /* Applicable only for ROOT_RECIPE, set the fwd_priority for
7555 : : * the recipe which is getting created if specified
7556 : : * by user. Usually any advanced switch filter, which results
7557 : : * into new extraction sequence, ended up creating a new recipe
7558 : : * of type ROOT and usually recipes are associated with profiles
7559 : : * Switch rule referreing newly created recipe, needs to have
7560 : : * either/or 'fwd' or 'join' priority, otherwise switch rule
7561 : : * evaluation will not happen correctly. In other words, if
7562 : : * switch rule to be evaluated on priority basis, then recipe
7563 : : * needs to have priority, otherwise it will be evaluated last.
7564 : : */
7565 : 0 : buf[0].content.act_ctrl_fwd_priority = rm->priority;
7566 : : } else {
7567 : : struct ice_recp_grp_entry *last_chain_entry;
7568 : : u16 rid, i;
7569 : :
7570 : : /* Allocate the last recipe that will chain the outcomes of the
7571 : : * other recipes together
7572 : : */
7573 : 0 : status = ice_alloc_recipe(hw, &rid);
7574 [ # # ]: 0 : if (status)
7575 : 0 : goto err_unroll;
7576 : :
7577 : 0 : buf[recps].recipe_indx = (u8)rid;
7578 : : buf[recps].content.rid = (u8)rid;
7579 : 0 : buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
7580 : : /* the new entry created should also be part of rg_list to
7581 : : * make sure we have complete recipe
7582 : : */
7583 : 0 : last_chain_entry = (struct ice_recp_grp_entry *)ice_malloc(hw,
7584 : : sizeof(*last_chain_entry));
7585 [ # # ]: 0 : if (!last_chain_entry) {
7586 : : status = ICE_ERR_NO_MEMORY;
7587 : 0 : goto err_unroll;
7588 : : }
7589 : 0 : last_chain_entry->rid = rid;
7590 : 0 : ice_memset(&buf[recps].content.lkup_indx, 0,
7591 : : sizeof(buf[recps].content.lkup_indx),
7592 : : ICE_NONDMA_MEM);
7593 : : /* All recipes use look-up index 0 to match switch ID. */
7594 : : buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7595 : 0 : buf[recps].content.mask[0] =
7596 : : CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7597 [ # # ]: 0 : for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7598 : 0 : buf[recps].content.lkup_indx[i] =
7599 : : ICE_AQ_RECIPE_LKUP_IGNORE;
7600 : 0 : buf[recps].content.mask[i] = 0;
7601 : : }
7602 : :
7603 : : i = 1;
7604 : : /* update r_bitmap with the recp that is used for chaining */
7605 : : ice_set_bit(rid, rm->r_bitmap);
7606 : : /* this is the recipe that chains all the other recipes so it
7607 : : * should not have a chaining ID to indicate the same
7608 : : */
7609 : 0 : last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
7610 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry,
# # ]
7611 : : l_entry) {
7612 : 0 : buf[recps].content.lkup_indx[i] = entry->chain_idx;
7613 : 0 : buf[recps].content.mask[i++] = CPU_TO_LE16(0xFFFF);
7614 [ # # ]: 0 : ice_set_bit(entry->rid, rm->r_bitmap);
7615 : : }
7616 [ # # ]: 0 : LIST_ADD(&last_chain_entry->l_entry, &rm->rg_list);
7617 : : if (sizeof(buf[recps].recipe_bitmap) >=
7618 : : sizeof(rm->r_bitmap)) {
7619 [ # # ]: 0 : ice_memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
7620 : : sizeof(buf[recps].recipe_bitmap),
7621 : : ICE_NONDMA_TO_NONDMA);
7622 : : } else {
7623 : : status = ICE_ERR_BAD_PTR;
7624 : : goto err_unroll;
7625 : : }
7626 : 0 : buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7627 : :
7628 : : recps++;
7629 : 0 : rm->root_rid = (u8)rid;
7630 : : }
7631 : 0 : status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7632 [ # # ]: 0 : if (status)
7633 : 0 : goto err_unroll;
7634 : :
7635 : 0 : status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
7636 : 0 : ice_release_change_lock(hw);
7637 [ # # ]: 0 : if (status)
7638 : 0 : goto err_unroll;
7639 : :
7640 : : /* Every recipe that just got created add it to the recipe
7641 : : * book keeping list
7642 : : */
7643 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7644 : 0 : struct ice_switch_info *sw = hw->switch_info;
7645 : : bool is_root, idx_found = false;
7646 : : struct ice_sw_recipe *recp;
7647 : : u16 idx, buf_idx = 0;
7648 : :
7649 : : /* find buffer index for copying some data */
7650 [ # # ]: 0 : for (idx = 0; idx < rm->n_grp_count; idx++)
7651 [ # # ]: 0 : if (buf[idx].recipe_indx == entry->rid) {
7652 : : buf_idx = idx;
7653 : : idx_found = true;
7654 : : }
7655 : :
7656 [ # # ]: 0 : if (!idx_found) {
7657 : : status = ICE_ERR_OUT_OF_RANGE;
7658 : 0 : goto err_unroll;
7659 : : }
7660 : :
7661 : 0 : recp = &sw->recp_list[entry->rid];
7662 : 0 : is_root = (rm->root_rid == entry->rid);
7663 : 0 : recp->is_root = is_root;
7664 : :
7665 : 0 : recp->root_rid = (u8)entry->rid;
7666 [ # # # # ]: 0 : recp->big_recp = (is_root && rm->n_grp_count > 1);
7667 : :
7668 [ # # ]: 0 : ice_memcpy(&recp->ext_words, entry->r_group.pairs,
7669 : : entry->r_group.n_val_pairs *
7670 : : sizeof(struct ice_fv_word),
7671 : : ICE_NONDMA_TO_NONDMA);
7672 : :
7673 [ # # ]: 0 : ice_memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
7674 : : sizeof(recp->r_bitmap), ICE_NONDMA_TO_NONDMA);
7675 : :
7676 : : /* Copy non-result fv index values and masks to recipe. This
7677 : : * call will also update the result recipe bitmask.
7678 : : */
7679 : : ice_collect_result_idx(&buf[buf_idx], recp);
7680 : :
7681 : : /* for non-root recipes, also copy to the root, this allows
7682 : : * easier matching of a complete chained recipe
7683 : : */
7684 [ # # ]: 0 : if (!is_root)
7685 : 0 : ice_collect_result_idx(&buf[buf_idx],
7686 [ # # ]: 0 : &sw->recp_list[rm->root_rid]);
7687 : :
7688 : 0 : recp->n_ext_words = entry->r_group.n_val_pairs;
7689 : 0 : recp->chain_idx = entry->chain_idx;
7690 : 0 : recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
7691 : 0 : recp->n_grp_count = rm->n_grp_count;
7692 : 0 : recp->tun_type = rm->tun_type;
7693 [ # # ]: 0 : recp->recp_created = true;
7694 : : }
7695 : 0 : rm->root_buf = buf;
7696 : 0 : ice_free(hw, tmp);
7697 : 0 : return status;
7698 : :
7699 : 0 : err_unroll:
7700 : 0 : err_mem:
7701 : 0 : ice_free(hw, tmp);
7702 : 0 : ice_free(hw, buf);
7703 : 0 : return status;
7704 : : }
7705 : :
7706 : : /**
7707 : : * ice_create_recipe_group - creates recipe group
7708 : : * @hw: pointer to hardware structure
7709 : : * @rm: recipe management list entry
7710 : : * @lkup_exts: lookup elements
7711 : : */
7712 : : static enum ice_status
7713 : 0 : ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
7714 : : struct ice_prot_lkup_ext *lkup_exts)
7715 : : {
7716 : : enum ice_status status;
7717 : 0 : u8 recp_count = 0;
7718 : :
7719 : 0 : rm->n_grp_count = 0;
7720 : :
7721 : : /* Create recipes for words that are marked not done by packing them
7722 : : * as best fit.
7723 : : */
7724 : 0 : status = ice_create_first_fit_recp_def(hw, lkup_exts,
7725 : : &rm->rg_list, &recp_count);
7726 [ # # ]: 0 : if (!status) {
7727 : 0 : rm->n_grp_count += recp_count;
7728 : 0 : rm->n_ext_words = lkup_exts->n_val_words;
7729 [ # # ]: 0 : ice_memcpy(&rm->ext_words, lkup_exts->fv_words,
7730 : : sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA);
7731 [ # # ]: 0 : ice_memcpy(rm->word_masks, lkup_exts->field_mask,
7732 : : sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA);
7733 : : }
7734 : :
7735 : 0 : return status;
7736 : : }
7737 : :
7738 : : /**
7739 : : * ice_tun_type_match_word - determine if tun type needs a match mask
7740 : : * @rinfo: other information regarding the rule e.g. priority and action info
7741 : : * @off: offset of packet flag
7742 : : * @mask: mask to be used for the tunnel
7743 : : */
7744 : : static bool
7745 : 0 : ice_tun_type_match_word(struct ice_adv_rule_info *rinfo, u16 *off, u16 *mask)
7746 : : {
7747 [ # # # # ]: 0 : switch (rinfo->tun_type) {
7748 : 0 : case ICE_SW_TUN_VXLAN_GPE:
7749 : : case ICE_SW_TUN_GENEVE:
7750 : : case ICE_SW_TUN_VXLAN:
7751 : : case ICE_SW_TUN_NVGRE:
7752 : : case ICE_SW_TUN_UDP:
7753 : : case ICE_ALL_TUNNELS:
7754 : : case ICE_SW_TUN_AND_NON_TUN_QINQ:
7755 : : case ICE_NON_TUN_QINQ:
7756 : : case ICE_SW_TUN_PPPOE_QINQ:
7757 : : case ICE_SW_TUN_PPPOE_PAY_QINQ:
7758 : : case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7759 : : case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7760 : 0 : *mask = ICE_TUN_FLAG_MASK;
7761 : 0 : *off = ICE_TUN_FLAG_MDID_OFF(1);
7762 : 0 : return true;
7763 : :
7764 : 0 : case ICE_SW_TUN_AND_NON_TUN:
7765 [ # # ]: 0 : if (rinfo->add_dir_lkup) {
7766 : 0 : *mask = ICE_DIR_FLAG_MASK;
7767 : 0 : *off = ICE_TUN_FLAG_MDID_OFF(0);
7768 : 0 : return true;
7769 : : }
7770 : 0 : *mask = 0;
7771 : 0 : *off = 0;
7772 : 0 : return false;
7773 : :
7774 : 0 : case ICE_SW_TUN_GENEVE_VLAN:
7775 : : case ICE_SW_TUN_VXLAN_VLAN:
7776 : 0 : *mask = ICE_TUN_FLAG_MASK & ~(ICE_TUN_FLAG_VLAN_MASK |
7777 : : ICE_TUN_FLAG_IN_VLAN_MASK);
7778 : 0 : *off = ICE_TUN_FLAG_MDID_OFF(1);
7779 : 0 : return true;
7780 : :
7781 : 0 : default:
7782 : 0 : *mask = 0;
7783 : 0 : *off = 0;
7784 : 0 : return false;
7785 : : }
7786 : : }
7787 : :
7788 : : /**
7789 : : * ice_add_special_words - Add words that are not protocols, such as metadata
7790 : : * @rinfo: other information regarding the rule e.g. priority and action info
7791 : : * @lkup_exts: lookup word structure
7792 : : * @dvm_ena: is double VLAN mode enabled
7793 : : */
7794 : : static enum ice_status
7795 : 0 : ice_add_special_words(struct ice_adv_rule_info *rinfo,
7796 : : struct ice_prot_lkup_ext *lkup_exts, bool dvm_ena)
7797 : : {
7798 : : u16 mask;
7799 : : u16 off;
7800 : :
7801 : : /* If this is a tunneled packet, then add recipe index to match the
7802 : : * tunnel bit in the packet metadata flags. If this is a tun_and_non_tun
7803 : : * packet, then add recipe index to match the direction bit in the flag.
7804 : : */
7805 [ # # ]: 0 : if (ice_tun_type_match_word(rinfo, &off, &mask)) {
7806 [ # # ]: 0 : if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7807 : 0 : u8 word = lkup_exts->n_val_words++;
7808 : :
7809 : 0 : lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7810 : 0 : lkup_exts->fv_words[word].off = off;
7811 : 0 : lkup_exts->field_mask[word] = mask;
7812 : : } else {
7813 : : return ICE_ERR_MAX_LIMIT;
7814 : : }
7815 : : }
7816 : :
7817 [ # # # # ]: 0 : if (rinfo->vlan_type != 0 && dvm_ena) {
7818 [ # # ]: 0 : if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7819 : 0 : u8 word = lkup_exts->n_val_words++;
7820 : :
7821 : 0 : lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7822 : 0 : lkup_exts->fv_words[word].off = ICE_VLAN_FLAG_MDID_OFF;
7823 : 0 : lkup_exts->field_mask[word] =
7824 : : ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK;
7825 : : } else {
7826 : : return ICE_ERR_MAX_LIMIT;
7827 : : }
7828 : : }
7829 : :
7830 : : return ICE_SUCCESS;
7831 : : }
7832 : :
7833 : : /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
7834 : : * @hw: pointer to hardware structure
7835 : : * @rinfo: other information regarding the rule e.g. priority and action info
7836 : : * @bm: pointer to memory for returning the bitmap of field vectors
7837 : : */
7838 : : static void
7839 [ # # # # : 0 : ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
7840 : : ice_bitmap_t *bm)
7841 : : {
7842 : : enum ice_prof_type prof_type;
7843 : :
7844 : : ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
7845 : :
7846 [ # # # # : 0 : switch (rinfo->tun_type) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
7847 : : case ICE_NON_TUN:
7848 : : case ICE_NON_TUN_QINQ:
7849 : : prof_type = ICE_PROF_NON_TUN;
7850 : : break;
7851 : 0 : case ICE_ALL_TUNNELS:
7852 : : prof_type = ICE_PROF_TUN_ALL;
7853 : 0 : break;
7854 : 0 : case ICE_SW_TUN_VXLAN_GPE:
7855 : : case ICE_SW_TUN_GENEVE:
7856 : : case ICE_SW_TUN_GENEVE_VLAN:
7857 : : case ICE_SW_TUN_VXLAN:
7858 : : case ICE_SW_TUN_VXLAN_VLAN:
7859 : : case ICE_SW_TUN_UDP:
7860 : : case ICE_SW_TUN_GTP:
7861 : : prof_type = ICE_PROF_TUN_UDP;
7862 : 0 : break;
7863 : 0 : case ICE_SW_TUN_NVGRE:
7864 : : prof_type = ICE_PROF_TUN_GRE;
7865 : 0 : break;
7866 : 0 : case ICE_SW_TUN_PPPOE:
7867 : : case ICE_SW_TUN_PPPOE_QINQ:
7868 : : prof_type = ICE_PROF_TUN_PPPOE;
7869 : 0 : break;
7870 : : case ICE_SW_TUN_PPPOE_PAY:
7871 : : case ICE_SW_TUN_PPPOE_PAY_QINQ:
7872 : : ice_set_bit(ICE_PROFID_PPPOE_PAY, bm);
7873 : : return;
7874 : : case ICE_SW_TUN_PPPOE_IPV4:
7875 : : case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7876 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_OTHER, bm);
7877 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7878 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7879 : : return;
7880 : : case ICE_SW_TUN_PPPOE_IPV4_TCP:
7881 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7882 : : return;
7883 : : case ICE_SW_TUN_PPPOE_IPV4_UDP:
7884 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7885 : : return;
7886 : : case ICE_SW_TUN_PPPOE_IPV6:
7887 : : case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7888 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_OTHER, bm);
7889 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7890 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7891 : : return;
7892 : : case ICE_SW_TUN_PPPOE_IPV6_TCP:
7893 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7894 : : return;
7895 : : case ICE_SW_TUN_PPPOE_IPV6_UDP:
7896 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7897 : : return;
7898 : : case ICE_SW_TUN_PROFID_IPV6_ESP:
7899 : : case ICE_SW_TUN_IPV6_ESP:
7900 : : ice_set_bit(ICE_PROFID_IPV6_ESP, bm);
7901 : : return;
7902 : : case ICE_SW_TUN_PROFID_IPV6_AH:
7903 : : case ICE_SW_TUN_IPV6_AH:
7904 : : ice_set_bit(ICE_PROFID_IPV6_AH, bm);
7905 : : return;
7906 : : case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
7907 : : case ICE_SW_TUN_IPV6_L2TPV3:
7908 : : ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm);
7909 : : return;
7910 : : case ICE_SW_TUN_PROFID_IPV6_NAT_T:
7911 : : case ICE_SW_TUN_IPV6_NAT_T:
7912 : : ice_set_bit(ICE_PROFID_IPV6_NAT_T, bm);
7913 : : return;
7914 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
7915 : : ice_set_bit(ICE_PROFID_IPV4_PFCP_NODE, bm);
7916 : : return;
7917 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
7918 : : ice_set_bit(ICE_PROFID_IPV4_PFCP_SESSION, bm);
7919 : : return;
7920 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
7921 : : ice_set_bit(ICE_PROFID_IPV6_PFCP_NODE, bm);
7922 : : return;
7923 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
7924 : : ice_set_bit(ICE_PROFID_IPV6_PFCP_SESSION, bm);
7925 : : return;
7926 : : case ICE_SW_TUN_IPV4_NAT_T:
7927 : : ice_set_bit(ICE_PROFID_IPV4_NAT_T, bm);
7928 : : return;
7929 : : case ICE_SW_TUN_IPV4_L2TPV3:
7930 : : ice_set_bit(ICE_PROFID_MAC_IPV4_L2TPV3, bm);
7931 : : return;
7932 : : case ICE_SW_TUN_IPV4_ESP:
7933 : : ice_set_bit(ICE_PROFID_IPV4_ESP, bm);
7934 : : return;
7935 : : case ICE_SW_TUN_IPV4_AH:
7936 : : ice_set_bit(ICE_PROFID_IPV4_AH, bm);
7937 : : return;
7938 : : case ICE_SW_IPV4_TCP:
7939 : : ice_set_bit(ICE_PROFID_IPV4_TCP, bm);
7940 : : return;
7941 : : case ICE_SW_IPV4_UDP:
7942 : : ice_set_bit(ICE_PROFID_IPV4_UDP, bm);
7943 : : return;
7944 : : case ICE_SW_IPV6_TCP:
7945 : : ice_set_bit(ICE_PROFID_IPV6_TCP, bm);
7946 : : return;
7947 : : case ICE_SW_IPV6_UDP:
7948 : : ice_set_bit(ICE_PROFID_IPV6_UDP, bm);
7949 : : return;
7950 : : case ICE_SW_TUN_IPV4_GTPU_NO_PAY:
7951 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_TEID, bm);
7952 : : return;
7953 : : case ICE_SW_TUN_IPV6_GTPU_NO_PAY:
7954 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_TEID, bm);
7955 : : return;
7956 : : case ICE_SW_TUN_IPV4_GTPU_IPV4:
7957 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_OTHER, bm);
7958 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
7959 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
7960 : : return;
7961 : : case ICE_SW_TUN_IPV4_GTPU_IPV4_UDP:
7962 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
7963 : : return;
7964 : : case ICE_SW_TUN_IPV4_GTPU_IPV4_TCP:
7965 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
7966 : : return;
7967 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV4:
7968 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, bm);
7969 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
7970 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
7971 : : return;
7972 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP:
7973 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
7974 : : return;
7975 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP:
7976 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
7977 : : return;
7978 : : case ICE_SW_TUN_IPV6_GTPU_IPV4:
7979 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_OTHER, bm);
7980 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
7981 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
7982 : : return;
7983 : : case ICE_SW_TUN_IPV6_GTPU_IPV4_UDP:
7984 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
7985 : : return;
7986 : : case ICE_SW_TUN_IPV6_GTPU_IPV4_TCP:
7987 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
7988 : : return;
7989 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV4:
7990 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, bm);
7991 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
7992 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
7993 : : return;
7994 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP:
7995 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
7996 : : return;
7997 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP:
7998 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
7999 : : return;
8000 : : case ICE_SW_TUN_IPV4_GTPU_IPV6:
8001 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_OTHER, bm);
8002 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
8003 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
8004 : : return;
8005 : : case ICE_SW_TUN_IPV4_GTPU_IPV6_UDP:
8006 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
8007 : : return;
8008 : : case ICE_SW_TUN_IPV4_GTPU_IPV6_TCP:
8009 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
8010 : : return;
8011 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV6:
8012 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, bm);
8013 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
8014 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
8015 : : return;
8016 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP:
8017 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
8018 : : return;
8019 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP:
8020 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
8021 : : return;
8022 : : case ICE_SW_TUN_IPV6_GTPU_IPV6:
8023 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_OTHER, bm);
8024 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
8025 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
8026 : : return;
8027 : : case ICE_SW_TUN_IPV6_GTPU_IPV6_UDP:
8028 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
8029 : : return;
8030 : : case ICE_SW_TUN_IPV6_GTPU_IPV6_TCP:
8031 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
8032 : : return;
8033 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV6:
8034 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, bm);
8035 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
8036 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
8037 : : return;
8038 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP:
8039 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
8040 : : return;
8041 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP:
8042 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
8043 : : return;
8044 : 0 : case ICE_SW_TUN_AND_NON_TUN:
8045 : : case ICE_SW_TUN_AND_NON_TUN_QINQ:
8046 : : default:
8047 : : prof_type = ICE_PROF_ALL;
8048 : 0 : break;
8049 : : }
8050 : :
8051 : 0 : ice_get_sw_fv_bitmap(hw, prof_type, bm);
8052 : : }
8053 : :
8054 : : /**
8055 : : * ice_is_prof_rule - determine if rule type is a profile rule
8056 : : * @type: the rule type
8057 : : *
8058 : : * if the rule type is a profile rule, that means that there no field value
8059 : : * match required, in this case just a profile hit is required.
8060 : : */
8061 : 0 : bool ice_is_prof_rule(enum ice_sw_tunnel_type type)
8062 : : {
8063 [ # # ]: 0 : switch (type) {
8064 : : case ICE_SW_TUN_AND_NON_TUN:
8065 : : case ICE_SW_TUN_PROFID_IPV6_ESP:
8066 : : case ICE_SW_TUN_PROFID_IPV6_AH:
8067 : : case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
8068 : : case ICE_SW_TUN_PROFID_IPV6_NAT_T:
8069 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
8070 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
8071 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
8072 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
8073 : : return true;
8074 : : default:
8075 : : break;
8076 : : }
8077 : :
8078 : 0 : return false;
8079 : : }
8080 : :
8081 : : /**
8082 : : * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
8083 : : * @hw: pointer to hardware structure
8084 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
8085 : : * structure per protocol header
8086 : : * @lkups_cnt: number of protocols
8087 : : * @rinfo: other information regarding the rule e.g. priority and action info
8088 : : * @rid: return the recipe ID of the recipe created
8089 : : */
8090 : : static enum ice_status
8091 : 0 : ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8092 : : u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
8093 : : {
8094 : : ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES);
8095 : : ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES);
8096 : : struct ice_prot_lkup_ext *lkup_exts;
8097 : : struct ice_recp_grp_entry *r_entry;
8098 : : struct ice_sw_fv_list_entry *fvit;
8099 : : struct ice_recp_grp_entry *r_tmp;
8100 : : struct ice_sw_fv_list_entry *tmp;
8101 : : enum ice_status status = ICE_SUCCESS;
8102 : : struct ice_sw_recipe *rm;
8103 : : u8 i;
8104 : :
8105 [ # # # # ]: 0 : if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt)
8106 : : return ICE_ERR_PARAM;
8107 : :
8108 : : lkup_exts = (struct ice_prot_lkup_ext *)
8109 : 0 : ice_malloc(hw, sizeof(*lkup_exts));
8110 [ # # ]: 0 : if (!lkup_exts)
8111 : : return ICE_ERR_NO_MEMORY;
8112 : :
8113 : : /* Determine the number of words to be matched and if it exceeds a
8114 : : * recipe's restrictions
8115 : : */
8116 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
8117 : : u16 count;
8118 : :
8119 [ # # ]: 0 : if (lkups[i].type >= ICE_PROTOCOL_LAST) {
8120 : : status = ICE_ERR_CFG;
8121 : 0 : goto err_free_lkup_exts;
8122 : : }
8123 : :
8124 : 0 : count = ice_fill_valid_words(&lkups[i], lkup_exts);
8125 [ # # ]: 0 : if (!count) {
8126 : : status = ICE_ERR_CFG;
8127 : 0 : goto err_free_lkup_exts;
8128 : : }
8129 : : }
8130 : :
8131 : 0 : rm = (struct ice_sw_recipe *)ice_malloc(hw, sizeof(*rm));
8132 [ # # ]: 0 : if (!rm) {
8133 : : status = ICE_ERR_NO_MEMORY;
8134 : 0 : goto err_free_lkup_exts;
8135 : : }
8136 : :
8137 : : /* Get field vectors that contain fields extracted from all the protocol
8138 : : * headers being programmed.
8139 : : */
8140 : 0 : INIT_LIST_HEAD(&rm->fv_list);
8141 : 0 : INIT_LIST_HEAD(&rm->rg_list);
8142 : :
8143 : : /* Get bitmap of field vectors (profiles) that are compatible with the
8144 : : * rule request; only these will be searched in the subsequent call to
8145 : : * ice_get_sw_fv_list.
8146 : : */
8147 : 0 : ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
8148 : :
8149 : 0 : status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
8150 [ # # ]: 0 : if (status)
8151 : 0 : goto err_unroll;
8152 : :
8153 : : /* Create any special protocol/offset pairs, such as looking at tunnel
8154 : : * bits by extracting metadata
8155 : : */
8156 : 0 : status = ice_add_special_words(rinfo, lkup_exts, ice_is_dvm_ena(hw));
8157 [ # # ]: 0 : if (status)
8158 : 0 : goto err_free_lkup_exts;
8159 : :
8160 : : /* Group match words into recipes using preferred recipe grouping
8161 : : * criteria.
8162 : : */
8163 : 0 : status = ice_create_recipe_group(hw, rm, lkup_exts);
8164 [ # # ]: 0 : if (status)
8165 : 0 : goto err_unroll;
8166 : :
8167 : : /* set the recipe priority if specified */
8168 : 0 : rm->priority = (u8)rinfo->priority;
8169 : :
8170 : : /* Find offsets from the field vector. Pick the first one for all the
8171 : : * recipes.
8172 : : */
8173 : 0 : status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
8174 [ # # ]: 0 : if (status)
8175 : 0 : goto err_unroll;
8176 : :
8177 : : /* An empty FV list means to use all the profiles returned in the
8178 : : * profile bitmap
8179 : : */
8180 [ # # ]: 0 : if (LIST_EMPTY(&rm->fv_list)) {
8181 : : u16 j;
8182 : :
8183 [ # # ]: 0 : ice_for_each_set_bit(j, fv_bitmap, ICE_MAX_NUM_PROFILES) {
8184 : : struct ice_sw_fv_list_entry *fvl;
8185 : :
8186 : : fvl = (struct ice_sw_fv_list_entry *)
8187 : 0 : ice_malloc(hw, sizeof(*fvl));
8188 [ # # ]: 0 : if (!fvl)
8189 : 0 : goto err_unroll;
8190 : 0 : fvl->fv_ptr = NULL;
8191 : 0 : fvl->profile_id = j;
8192 [ # # ]: 0 : LIST_ADD(&fvl->list_entry, &rm->fv_list);
8193 : : }
8194 : : }
8195 : :
8196 : : /* get bitmap of all profiles the recipe will be associated with */
8197 : : ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES);
8198 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
# # ]
8199 : : list_entry) {
8200 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
8201 [ # # ]: 0 : ice_set_bit((u16)fvit->profile_id, profiles);
8202 : : }
8203 : :
8204 : : /* Look for a recipe which matches our requested fv / mask list */
8205 : 0 : *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type, rinfo->priority);
8206 [ # # ]: 0 : if (*rid < ICE_MAX_NUM_RECIPES)
8207 : : /* Success if found a recipe that match the existing criteria */
8208 : 0 : goto err_unroll;
8209 : :
8210 : 0 : rm->tun_type = rinfo->tun_type;
8211 : : /* Recipe we need does not exist, add a recipe */
8212 : 0 : status = ice_add_sw_recipe(hw, rm, profiles);
8213 [ # # ]: 0 : if (status)
8214 : 0 : goto err_unroll;
8215 : :
8216 : : /* Associate all the recipes created with all the profiles in the
8217 : : * common field vector.
8218 : : */
8219 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
# # ]
8220 : : list_entry) {
8221 : : ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
8222 : : u16 j;
8223 : :
8224 : 0 : status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
8225 : : (u8 *)r_bitmap, NULL);
8226 [ # # ]: 0 : if (status)
8227 : 0 : goto err_unroll;
8228 : :
8229 : 0 : ice_or_bitmap(r_bitmap, r_bitmap, rm->r_bitmap,
8230 : : ICE_MAX_NUM_RECIPES);
8231 : 0 : status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
8232 [ # # ]: 0 : if (status)
8233 : 0 : goto err_unroll;
8234 : :
8235 : 0 : status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
8236 : : (u8 *)r_bitmap,
8237 : : NULL);
8238 : 0 : ice_release_change_lock(hw);
8239 : :
8240 [ # # ]: 0 : if (status)
8241 : 0 : goto err_unroll;
8242 : :
8243 : : /* Update profile to recipe bitmap array */
8244 : 0 : ice_cp_bitmap(profile_to_recipe[fvit->profile_id], r_bitmap,
8245 : : ICE_MAX_NUM_RECIPES);
8246 : :
8247 : : /* Update recipe to profile bitmap array */
8248 [ # # ]: 0 : ice_for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
8249 : 0 : ice_set_bit((u16)fvit->profile_id,
8250 : 0 : recipe_to_profile[j]);
8251 : : }
8252 : :
8253 : 0 : *rid = rm->root_rid;
8254 [ # # ]: 0 : ice_memcpy(&hw->switch_info->recp_list[*rid].lkup_exts,
8255 : : lkup_exts, sizeof(*lkup_exts), ICE_NONDMA_TO_NONDMA);
8256 : 0 : err_unroll:
8257 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(r_entry, r_tmp, &rm->rg_list,
# # # # #
# ]
8258 : : ice_recp_grp_entry, l_entry) {
8259 [ # # ]: 0 : LIST_DEL(&r_entry->l_entry);
8260 : 0 : ice_free(hw, r_entry);
8261 : : }
8262 : :
8263 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(fvit, tmp, &rm->fv_list, ice_sw_fv_list_entry,
# # # # #
# ]
8264 : : list_entry) {
8265 [ # # ]: 0 : LIST_DEL(&fvit->list_entry);
8266 : 0 : ice_free(hw, fvit);
8267 : : }
8268 : :
8269 [ # # ]: 0 : if (rm->root_buf)
8270 : 0 : ice_free(hw, rm->root_buf);
8271 : :
8272 : 0 : ice_free(hw, rm);
8273 : :
8274 : 0 : err_free_lkup_exts:
8275 : 0 : ice_free(hw, lkup_exts);
8276 : :
8277 : 0 : return status;
8278 : : }
8279 : :
8280 : : /**
8281 : : * ice_find_dummy_packet - find dummy packet by tunnel type
8282 : : *
8283 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
8284 : : * structure per protocol header
8285 : : * @lkups_cnt: number of protocols
8286 : : * @tun_type: tunnel type from the match criteria
8287 : : * @pkt: dummy packet to fill according to filter match criteria
8288 : : * @pkt_len: packet length of dummy packet
8289 : : * @offsets: pointer to receive the pointer to the offsets for the packet
8290 : : */
8291 : : static void
8292 : 0 : ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8293 : : enum ice_sw_tunnel_type tun_type, const u8 **pkt,
8294 : : u16 *pkt_len,
8295 : : const struct ice_dummy_pkt_offsets **offsets)
8296 : : {
8297 : : bool tcp = false, udp = false, outer_ipv6 = false, vlan = false;
8298 : : bool inner_ipv6 = false, pppoe = false;
8299 : : bool cvlan = false;
8300 : : bool gre = false, mpls = false;
8301 : : u16 i;
8302 : :
8303 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
8304 [ # # ]: 0 : if (lkups[i].type == ICE_UDP_ILOS)
8305 : : udp = true;
8306 : : else if (lkups[i].type == ICE_TCP_IL)
8307 : : tcp = true;
8308 : : else if (lkups[i].type == ICE_IPV6_OFOS)
8309 : : outer_ipv6 = true;
8310 : : else if (lkups[i].type == ICE_VLAN_OFOS ||
8311 : : lkups[i].type == ICE_VLAN_EX)
8312 : : vlan = true;
8313 : :
8314 : : else if (lkups[i].type == ICE_VLAN_IN)
8315 : : cvlan = true;
8316 : 0 : else if (lkups[i].type == ICE_ETYPE_OL &&
8317 [ # # ]: 0 : lkups[i].h_u.ethertype.ethtype_id ==
8318 : 0 : CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
8319 [ # # ]: 0 : lkups[i].m_u.ethertype.ethtype_id ==
8320 : : CPU_TO_BE16(0xFFFF))
8321 : : outer_ipv6 = true;
8322 [ # # ]: 0 : else if (lkups[i].type == ICE_ETYPE_IL &&
8323 [ # # ]: 0 : lkups[i].h_u.ethertype.ethtype_id ==
8324 : 0 : CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
8325 [ # # ]: 0 : lkups[i].m_u.ethertype.ethtype_id ==
8326 : : CPU_TO_BE16(0xFFFF))
8327 : : inner_ipv6 = true;
8328 [ # # ]: 0 : else if (lkups[i].type == ICE_PPPOE) {
8329 : : pppoe = true;
8330 [ # # ]: 0 : if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
8331 : 0 : CPU_TO_BE16(ICE_PPP_IPV6_PROTO_ID) &&
8332 [ # # ]: 0 : lkups[i].m_u.pppoe_hdr.ppp_prot_id ==
8333 : : CPU_TO_BE16(0xFFFF))
8334 : : outer_ipv6 = true;
8335 : : }
8336 [ # # ]: 0 : else if (lkups[i].type == ICE_IPV4_OFOS &&
8337 [ # # ]: 0 : lkups[i].h_u.ipv4_hdr.protocol ==
8338 : 0 : ICE_IPV4_NVGRE_PROTO_ID &&
8339 [ # # ]: 0 : lkups[i].m_u.ipv4_hdr.protocol ==
8340 : : 0xFF)
8341 : : gre = true;
8342 [ # # ]: 0 : else if (lkups[i].type == ICE_IPV4_IL &&
8343 [ # # ]: 0 : lkups[i].h_u.ipv4_hdr.protocol ==
8344 : 0 : ICE_TCP_PROTO_ID &&
8345 [ # # ]: 0 : lkups[i].m_u.ipv4_hdr.protocol ==
8346 : : 0xFF)
8347 : : tcp = true;
8348 [ # # ]: 0 : else if (lkups[i].type == ICE_ETYPE_OL &&
8349 [ # # ]: 0 : lkups[i].h_u.ethertype.ethtype_id ==
8350 : 0 : CPU_TO_BE16(ICE_MPLS_ETHER_ID) &&
8351 [ # # ]: 0 : lkups[i].m_u.ethertype.ethtype_id == 0xFFFF)
8352 : : mpls = true;
8353 : : }
8354 : :
8355 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
8356 : : tun_type == ICE_NON_TUN_QINQ) {
8357 [ # # ]: 0 : if (outer_ipv6) {
8358 [ # # ]: 0 : if (tcp) {
8359 : 0 : *pkt = dummy_qinq_ipv6_tcp_pkt;
8360 : 0 : *pkt_len = sizeof(dummy_qinq_ipv6_tcp_pkt);
8361 : 0 : *offsets = dummy_qinq_ipv6_tcp_packet_offsets;
8362 : 0 : return;
8363 : : }
8364 : :
8365 [ # # ]: 0 : if (udp) {
8366 : 0 : *pkt = dummy_qinq_ipv6_udp_pkt;
8367 : 0 : *pkt_len = sizeof(dummy_qinq_ipv6_udp_pkt);
8368 : 0 : *offsets = dummy_qinq_ipv6_udp_packet_offsets;
8369 : 0 : return;
8370 : : }
8371 : :
8372 : 0 : *pkt = dummy_qinq_ipv6_pkt;
8373 : 0 : *pkt_len = sizeof(dummy_qinq_ipv6_pkt);
8374 : 0 : *offsets = dummy_qinq_ipv6_packet_offsets;
8375 : 0 : return;
8376 : : } else {
8377 [ # # ]: 0 : if (tcp) {
8378 : 0 : *pkt = dummy_qinq_ipv4_tcp_pkt;
8379 : 0 : *pkt_len = sizeof(dummy_qinq_ipv4_tcp_pkt);
8380 : 0 : *offsets = dummy_qinq_ipv4_tcp_packet_offsets;
8381 : 0 : return;
8382 : : }
8383 : :
8384 [ # # ]: 0 : if (udp) {
8385 : 0 : *pkt = dummy_qinq_ipv4_udp_pkt;
8386 : 0 : *pkt_len = sizeof(dummy_qinq_ipv4_udp_pkt);
8387 : 0 : *offsets = dummy_qinq_ipv4_udp_packet_offsets;
8388 : 0 : return;
8389 : : }
8390 : :
8391 : 0 : *pkt = dummy_qinq_ipv4_pkt;
8392 : 0 : *pkt_len = sizeof(dummy_qinq_ipv4_pkt);
8393 : 0 : *offsets = dummy_qinq_ipv4_packet_offsets;
8394 : 0 : return;
8395 : : }
8396 : : }
8397 : :
8398 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_PPPOE_IPV6_QINQ) {
8399 : 0 : *pkt = dummy_qinq_pppoe_ipv6_packet;
8400 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
8401 : 0 : *offsets = dummy_qinq_pppoe_packet_ipv6_offsets;
8402 : 0 : return;
8403 [ # # ]: 0 : } else if (tun_type == ICE_SW_TUN_PPPOE_IPV4_QINQ) {
8404 : 0 : *pkt = dummy_qinq_pppoe_ipv4_pkt;
8405 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
8406 : 0 : *offsets = dummy_qinq_pppoe_ipv4_packet_offsets;
8407 : 0 : return;
8408 [ # # ]: 0 : } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ && outer_ipv6) {
8409 : 0 : *pkt = dummy_qinq_pppoe_ipv6_packet;
8410 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
8411 : 0 : *offsets = dummy_qinq_pppoe_packet_offsets;
8412 : 0 : return;
8413 [ # # # # : 0 : } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ ||
# # # # #
# # # # #
# # # # #
# # # # #
# ]
8414 : : tun_type == ICE_SW_TUN_PPPOE_PAY_QINQ) {
8415 : 0 : *pkt = dummy_qinq_pppoe_ipv4_pkt;
8416 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
8417 : 0 : *offsets = dummy_qinq_pppoe_packet_offsets;
8418 : 0 : return;
8419 : : }
8420 : :
8421 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_NO_PAY) {
8422 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_packet;
8423 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
8424 : 0 : *offsets = dummy_ipv4_gtp_no_pay_packet_offsets;
8425 : 0 : return;
8426 : : } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_NO_PAY) {
8427 : 0 : *pkt = dummy_ipv6_gtp_packet;
8428 : 0 : *pkt_len = sizeof(dummy_ipv6_gtp_packet);
8429 : 0 : *offsets = dummy_ipv6_gtp_no_pay_packet_offsets;
8430 : 0 : return;
8431 : : }
8432 : :
8433 : : if (tun_type == ICE_SW_TUN_IPV4_ESP) {
8434 : 0 : *pkt = dummy_ipv4_esp_pkt;
8435 : 0 : *pkt_len = sizeof(dummy_ipv4_esp_pkt);
8436 : 0 : *offsets = dummy_ipv4_esp_packet_offsets;
8437 : 0 : return;
8438 : : }
8439 : :
8440 : : if (tun_type == ICE_SW_TUN_IPV6_ESP) {
8441 : 0 : *pkt = dummy_ipv6_esp_pkt;
8442 : 0 : *pkt_len = sizeof(dummy_ipv6_esp_pkt);
8443 : 0 : *offsets = dummy_ipv6_esp_packet_offsets;
8444 : 0 : return;
8445 : : }
8446 : :
8447 : : if (tun_type == ICE_SW_TUN_IPV4_AH) {
8448 : 0 : *pkt = dummy_ipv4_ah_pkt;
8449 : 0 : *pkt_len = sizeof(dummy_ipv4_ah_pkt);
8450 : 0 : *offsets = dummy_ipv4_ah_packet_offsets;
8451 : 0 : return;
8452 : : }
8453 : :
8454 : : if (tun_type == ICE_SW_TUN_IPV6_AH) {
8455 : 0 : *pkt = dummy_ipv6_ah_pkt;
8456 : 0 : *pkt_len = sizeof(dummy_ipv6_ah_pkt);
8457 : 0 : *offsets = dummy_ipv6_ah_packet_offsets;
8458 : 0 : return;
8459 : : }
8460 : :
8461 : : if (tun_type == ICE_SW_TUN_IPV4_NAT_T) {
8462 : 0 : *pkt = dummy_ipv4_nat_pkt;
8463 : 0 : *pkt_len = sizeof(dummy_ipv4_nat_pkt);
8464 : 0 : *offsets = dummy_ipv4_nat_packet_offsets;
8465 : 0 : return;
8466 : : }
8467 : :
8468 : : if (tun_type == ICE_SW_TUN_IPV6_NAT_T) {
8469 : 0 : *pkt = dummy_ipv6_nat_pkt;
8470 : 0 : *pkt_len = sizeof(dummy_ipv6_nat_pkt);
8471 : 0 : *offsets = dummy_ipv6_nat_packet_offsets;
8472 : 0 : return;
8473 : : }
8474 : :
8475 : : if (tun_type == ICE_SW_TUN_IPV4_L2TPV3) {
8476 : 0 : *pkt = dummy_ipv4_l2tpv3_pkt;
8477 : 0 : *pkt_len = sizeof(dummy_ipv4_l2tpv3_pkt);
8478 : 0 : *offsets = dummy_ipv4_l2tpv3_packet_offsets;
8479 : 0 : return;
8480 : : }
8481 : :
8482 : : if (tun_type == ICE_SW_TUN_IPV6_L2TPV3) {
8483 : 0 : *pkt = dummy_ipv6_l2tpv3_pkt;
8484 : 0 : *pkt_len = sizeof(dummy_ipv6_l2tpv3_pkt);
8485 : 0 : *offsets = dummy_ipv6_l2tpv3_packet_offsets;
8486 : 0 : return;
8487 : : }
8488 : :
8489 : : if (tun_type == ICE_SW_TUN_GTP) {
8490 : 0 : *pkt = dummy_udp_gtp_packet;
8491 : 0 : *pkt_len = sizeof(dummy_udp_gtp_packet);
8492 : 0 : *offsets = dummy_udp_gtp_packet_offsets;
8493 : 0 : return;
8494 : : }
8495 : :
8496 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4 ||
8497 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4) {
8498 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_packet;
8499 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
8500 : 0 : *offsets = dummy_ipv4_gtpu_ipv4_packet_offsets;
8501 : 0 : return;
8502 : : }
8503 : :
8504 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4_UDP ||
8505 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP) {
8506 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_udp_packet;
8507 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_udp_packet);
8508 : 0 : *offsets = dummy_ipv4_gtpu_ipv4_udp_packet_offsets;
8509 : 0 : return;
8510 : : }
8511 : :
8512 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4_TCP ||
8513 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP) {
8514 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_tcp_packet;
8515 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_tcp_packet);
8516 : 0 : *offsets = dummy_ipv4_gtpu_ipv4_tcp_packet_offsets;
8517 : 0 : return;
8518 : : }
8519 : :
8520 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6 ||
8521 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6) {
8522 : 0 : *pkt = dummy_ipv4_gtpu_ipv6_packet;
8523 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_packet);
8524 : 0 : *offsets = dummy_ipv4_gtpu_ipv6_packet_offsets;
8525 : 0 : return;
8526 : : }
8527 : :
8528 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6_UDP ||
8529 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP) {
8530 : 0 : *pkt = dummy_ipv4_gtpu_ipv6_udp_packet;
8531 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_udp_packet);
8532 : 0 : *offsets = dummy_ipv4_gtpu_ipv6_udp_packet_offsets;
8533 : 0 : return;
8534 : : }
8535 : :
8536 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6_TCP ||
8537 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP) {
8538 : 0 : *pkt = dummy_ipv4_gtpu_ipv6_tcp_packet;
8539 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_tcp_packet);
8540 : 0 : *offsets = dummy_ipv4_gtpu_ipv6_tcp_packet_offsets;
8541 : 0 : return;
8542 : : }
8543 : :
8544 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4 ||
8545 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4) {
8546 : 0 : *pkt = dummy_ipv6_gtpu_ipv4_packet;
8547 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_packet);
8548 : 0 : *offsets = dummy_ipv6_gtpu_ipv4_packet_offsets;
8549 : 0 : return;
8550 : : }
8551 : :
8552 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4_UDP ||
8553 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP) {
8554 : 0 : *pkt = dummy_ipv6_gtpu_ipv4_udp_packet;
8555 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_udp_packet);
8556 : 0 : *offsets = dummy_ipv6_gtpu_ipv4_udp_packet_offsets;
8557 : 0 : return;
8558 : : }
8559 : :
8560 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4_TCP ||
8561 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP) {
8562 : 0 : *pkt = dummy_ipv6_gtpu_ipv4_tcp_packet;
8563 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_tcp_packet);
8564 : 0 : *offsets = dummy_ipv6_gtpu_ipv4_tcp_packet_offsets;
8565 : 0 : return;
8566 : : }
8567 : :
8568 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6 ||
8569 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6) {
8570 : 0 : *pkt = dummy_ipv6_gtpu_ipv6_packet;
8571 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
8572 : 0 : *offsets = dummy_ipv6_gtpu_ipv6_packet_offsets;
8573 : 0 : return;
8574 : : }
8575 : :
8576 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6_UDP ||
8577 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP) {
8578 : 0 : *pkt = dummy_ipv6_gtpu_ipv6_udp_packet;
8579 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_udp_packet);
8580 : 0 : *offsets = dummy_ipv6_gtpu_ipv6_udp_packet_offsets;
8581 : 0 : return;
8582 : : }
8583 : :
8584 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6_TCP ||
8585 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP) {
8586 : 0 : *pkt = dummy_ipv6_gtpu_ipv6_tcp_packet;
8587 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_tcp_packet);
8588 : 0 : *offsets = dummy_ipv6_gtpu_ipv6_tcp_packet_offsets;
8589 : 0 : return;
8590 : : }
8591 : :
8592 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_PPPOE && outer_ipv6) {
8593 : 0 : *pkt = dummy_pppoe_ipv6_packet;
8594 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
8595 : 0 : *offsets = dummy_pppoe_packet_offsets;
8596 : 0 : return;
8597 [ # # # # : 0 : } else if (tun_type == ICE_SW_TUN_PPPOE ||
# # # # #
# # # # ]
8598 : : tun_type == ICE_SW_TUN_PPPOE_PAY) {
8599 : 0 : *pkt = dummy_pppoe_ipv4_packet;
8600 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
8601 : 0 : *offsets = dummy_pppoe_packet_offsets;
8602 : 0 : return;
8603 : : }
8604 : :
8605 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV4) {
8606 : 0 : *pkt = dummy_pppoe_ipv4_packet;
8607 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
8608 : 0 : *offsets = dummy_pppoe_packet_ipv4_offsets;
8609 : 0 : return;
8610 : : }
8611 : :
8612 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV4_TCP) {
8613 : 0 : *pkt = dummy_pppoe_ipv4_tcp_packet;
8614 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
8615 : 0 : *offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
8616 : 0 : return;
8617 : : }
8618 : :
8619 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV4_UDP) {
8620 : 0 : *pkt = dummy_pppoe_ipv4_udp_packet;
8621 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
8622 : 0 : *offsets = dummy_pppoe_ipv4_udp_packet_offsets;
8623 : 0 : return;
8624 : : }
8625 : :
8626 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6) {
8627 : 0 : *pkt = dummy_pppoe_ipv6_packet;
8628 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
8629 : 0 : *offsets = dummy_pppoe_packet_ipv6_offsets;
8630 : 0 : return;
8631 : : }
8632 : :
8633 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6_TCP) {
8634 : 0 : *pkt = dummy_pppoe_ipv6_tcp_packet;
8635 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
8636 : 0 : *offsets = dummy_pppoe_ipv6_tcp_packet_offsets;
8637 : 0 : return;
8638 : : }
8639 : :
8640 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6_UDP) {
8641 : 0 : *pkt = dummy_pppoe_ipv6_udp_packet;
8642 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
8643 : 0 : *offsets = dummy_pppoe_ipv6_udp_packet_offsets;
8644 : 0 : return;
8645 : : }
8646 : :
8647 : : if (tun_type == ICE_SW_IPV4_TCP) {
8648 : 0 : *pkt = dummy_tcp_packet;
8649 : 0 : *pkt_len = sizeof(dummy_tcp_packet);
8650 : 0 : *offsets = dummy_tcp_packet_offsets;
8651 : 0 : return;
8652 : : }
8653 : :
8654 : : if (tun_type == ICE_SW_IPV4_UDP) {
8655 : 0 : *pkt = dummy_udp_packet;
8656 : 0 : *pkt_len = sizeof(dummy_udp_packet);
8657 : 0 : *offsets = dummy_udp_packet_offsets;
8658 : 0 : return;
8659 : : }
8660 : :
8661 : : if (tun_type == ICE_SW_IPV6_TCP) {
8662 : 0 : *pkt = dummy_tcp_ipv6_packet;
8663 : 0 : *pkt_len = sizeof(dummy_tcp_ipv6_packet);
8664 : 0 : *offsets = dummy_tcp_ipv6_packet_offsets;
8665 : 0 : return;
8666 : : }
8667 : :
8668 : : if (tun_type == ICE_SW_IPV6_UDP) {
8669 : 0 : *pkt = dummy_udp_ipv6_packet;
8670 : 0 : *pkt_len = sizeof(dummy_udp_ipv6_packet);
8671 : 0 : *offsets = dummy_udp_ipv6_packet_offsets;
8672 : 0 : return;
8673 : : }
8674 : :
8675 : : if (tun_type == ICE_ALL_TUNNELS) {
8676 : 0 : *pkt = dummy_gre_udp_packet;
8677 : 0 : *pkt_len = sizeof(dummy_gre_udp_packet);
8678 : 0 : *offsets = dummy_gre_udp_packet_offsets;
8679 : 0 : return;
8680 : : }
8681 : :
8682 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_NVGRE || gre) {
8683 [ # # ]: 0 : if (tcp && inner_ipv6) {
8684 : 0 : *pkt = dummy_gre_ipv6_tcp_packet;
8685 : 0 : *pkt_len = sizeof(dummy_gre_ipv6_tcp_packet);
8686 : 0 : *offsets = dummy_gre_ipv6_tcp_packet_offsets;
8687 : 0 : return;
8688 : : }
8689 : :
8690 [ # # ]: 0 : if (tcp) {
8691 : 0 : *pkt = dummy_gre_tcp_packet;
8692 : 0 : *pkt_len = sizeof(dummy_gre_tcp_packet);
8693 : 0 : *offsets = dummy_gre_tcp_packet_offsets;
8694 : 0 : return;
8695 : : }
8696 : :
8697 [ # # ]: 0 : if (inner_ipv6) {
8698 : 0 : *pkt = dummy_gre_ipv6_udp_packet;
8699 : 0 : *pkt_len = sizeof(dummy_gre_ipv6_udp_packet);
8700 : 0 : *offsets = dummy_gre_ipv6_udp_packet_offsets;
8701 : 0 : return;
8702 : : }
8703 : :
8704 : 0 : *pkt = dummy_gre_udp_packet;
8705 : 0 : *pkt_len = sizeof(dummy_gre_udp_packet);
8706 : 0 : *offsets = dummy_gre_udp_packet_offsets;
8707 : 0 : return;
8708 : : }
8709 : :
8710 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE ||
8711 [ # # ]: 0 : tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP ||
8712 : 0 : tun_type == ICE_SW_TUN_GENEVE_VLAN ||
8713 [ # # ]: 0 : tun_type == ICE_SW_TUN_VXLAN_VLAN) {
8714 [ # # ]: 0 : if (tcp && inner_ipv6) {
8715 : 0 : *pkt = dummy_udp_tun_ipv6_tcp_packet;
8716 : 0 : *pkt_len = sizeof(dummy_udp_tun_ipv6_tcp_packet);
8717 : 0 : *offsets = dummy_udp_tun_ipv6_tcp_packet_offsets;
8718 : 0 : return;
8719 : : }
8720 : :
8721 [ # # ]: 0 : if (tcp) {
8722 : 0 : *pkt = dummy_udp_tun_tcp_packet;
8723 : 0 : *pkt_len = sizeof(dummy_udp_tun_tcp_packet);
8724 : 0 : *offsets = dummy_udp_tun_tcp_packet_offsets;
8725 : 0 : return;
8726 : : }
8727 : :
8728 [ # # ]: 0 : if (inner_ipv6) {
8729 : 0 : *pkt = dummy_udp_tun_ipv6_udp_packet;
8730 : 0 : *pkt_len = sizeof(dummy_udp_tun_ipv6_udp_packet);
8731 : 0 : *offsets = dummy_udp_tun_ipv6_udp_packet_offsets;
8732 : 0 : return;
8733 : : }
8734 : :
8735 : 0 : *pkt = dummy_udp_tun_udp_packet;
8736 : 0 : *pkt_len = sizeof(dummy_udp_tun_udp_packet);
8737 : 0 : *offsets = dummy_udp_tun_udp_packet_offsets;
8738 : 0 : return;
8739 : : }
8740 : :
8741 [ # # ]: 0 : if (udp && !outer_ipv6) {
8742 [ # # ]: 0 : if (vlan) {
8743 : 0 : *pkt = dummy_vlan_udp_packet;
8744 : 0 : *pkt_len = sizeof(dummy_vlan_udp_packet);
8745 : 0 : *offsets = dummy_vlan_udp_packet_offsets;
8746 : 0 : return;
8747 [ # # ]: 0 : } else if (pppoe) {
8748 : 0 : *pkt = dummy_pppoe_ipv4_udp_packet;
8749 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
8750 : 0 : *offsets = dummy_pppoe_ipv4_udp_packet_offsets;
8751 : 0 : return;
8752 : : }
8753 : 0 : *pkt = dummy_udp_packet;
8754 : 0 : *pkt_len = sizeof(dummy_udp_packet);
8755 : 0 : *offsets = dummy_udp_packet_offsets;
8756 : 0 : return;
8757 [ # # ]: 0 : } else if (udp && outer_ipv6) {
8758 [ # # ]: 0 : if (vlan) {
8759 : 0 : *pkt = dummy_vlan_udp_ipv6_packet;
8760 : 0 : *pkt_len = sizeof(dummy_vlan_udp_ipv6_packet);
8761 : 0 : *offsets = dummy_vlan_udp_ipv6_packet_offsets;
8762 : 0 : return;
8763 [ # # ]: 0 : } else if (pppoe) {
8764 : 0 : *pkt = dummy_pppoe_ipv6_udp_packet;
8765 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
8766 : 0 : *offsets = dummy_pppoe_ipv6_udp_packet_offsets;
8767 : 0 : return;
8768 : : }
8769 : 0 : *pkt = dummy_udp_ipv6_packet;
8770 : 0 : *pkt_len = sizeof(dummy_udp_ipv6_packet);
8771 : 0 : *offsets = dummy_udp_ipv6_packet_offsets;
8772 : 0 : return;
8773 [ # # # # ]: 0 : } else if ((tcp && outer_ipv6) || outer_ipv6) {
8774 [ # # ]: 0 : if (vlan) {
8775 : 0 : *pkt = dummy_vlan_tcp_ipv6_packet;
8776 : 0 : *pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet);
8777 : 0 : *offsets = dummy_vlan_tcp_ipv6_packet_offsets;
8778 : 0 : return;
8779 [ # # ]: 0 : } else if (pppoe) {
8780 : 0 : *pkt = dummy_pppoe_ipv6_tcp_packet;
8781 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
8782 : 0 : *offsets = dummy_pppoe_ipv6_tcp_packet_offsets;
8783 : 0 : return;
8784 : : }
8785 : 0 : *pkt = dummy_tcp_ipv6_packet;
8786 : 0 : *pkt_len = sizeof(dummy_tcp_ipv6_packet);
8787 : 0 : *offsets = dummy_tcp_ipv6_packet_offsets;
8788 : 0 : return;
8789 : : }
8790 : :
8791 [ # # ]: 0 : if (vlan) {
8792 : 0 : *pkt = dummy_vlan_tcp_packet;
8793 : 0 : *pkt_len = sizeof(dummy_vlan_tcp_packet);
8794 : 0 : *offsets = dummy_vlan_tcp_packet_offsets;
8795 [ # # ]: 0 : } else if (pppoe) {
8796 : 0 : *pkt = dummy_pppoe_ipv4_tcp_packet;
8797 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
8798 : 0 : *offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
8799 : 0 : return;
8800 [ # # ]: 0 : } else if (mpls) {
8801 : 0 : *pkt = dummy_mpls_packet;
8802 : 0 : *pkt_len = sizeof(dummy_mpls_packet);
8803 : 0 : *offsets = dummy_mpls_packet_offsets;
8804 : : } else {
8805 : 0 : *pkt = dummy_tcp_packet;
8806 : 0 : *pkt_len = sizeof(dummy_tcp_packet);
8807 : 0 : *offsets = dummy_tcp_packet_offsets;
8808 : : }
8809 : : }
8810 : :
8811 : : /**
8812 : : * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
8813 : : *
8814 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
8815 : : * structure per protocol header
8816 : : * @lkups_cnt: number of protocols
8817 : : * @s_rule: stores rule information from the match criteria
8818 : : * @dummy_pkt: dummy packet to fill according to filter match criteria
8819 : : * @pkt_len: packet length of dummy packet
8820 : : * @offsets: offset info for the dummy packet
8821 : : */
8822 : : static enum ice_status
8823 : 0 : ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8824 : : struct ice_aqc_sw_rules_elem *s_rule,
8825 : : const u8 *dummy_pkt, u16 pkt_len,
8826 : : const struct ice_dummy_pkt_offsets *offsets)
8827 : : {
8828 : : u8 *pkt;
8829 : : u16 i;
8830 : :
8831 : : /* Start with a packet with a pre-defined/dummy content. Then, fill
8832 : : * in the header values to be looked up or matched.
8833 : : */
8834 : 0 : pkt = s_rule->pdata.lkup_tx_rx.hdr;
8835 : :
8836 [ # # ]: 0 : ice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA);
8837 : :
8838 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
8839 : : enum ice_protocol_type type;
8840 : : u16 offset = 0, len = 0, j;
8841 : : bool found = false;
8842 : :
8843 : : /* find the start of this layer; it should be found since this
8844 : : * was already checked when search for the dummy packet
8845 : : */
8846 : 0 : type = lkups[i].type;
8847 [ # # ]: 0 : for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
8848 [ # # ]: 0 : if (type == offsets[j].type) {
8849 : 0 : offset = offsets[j].offset;
8850 : : found = true;
8851 : 0 : break;
8852 : : }
8853 : : }
8854 : : /* this should never happen in a correct calling sequence */
8855 [ # # ]: 0 : if (!found)
8856 : : return ICE_ERR_PARAM;
8857 : :
8858 [ # # # # : 0 : switch (lkups[i].type) {
# # # # #
# # # #
# ]
8859 : : case ICE_MAC_OFOS:
8860 : : case ICE_MAC_IL:
8861 : : len = sizeof(struct ice_ether_hdr);
8862 : : break;
8863 : 0 : case ICE_ETYPE_OL:
8864 : : case ICE_ETYPE_IL:
8865 : : len = sizeof(struct ice_ethtype_hdr);
8866 : 0 : break;
8867 : 0 : case ICE_VLAN_OFOS:
8868 : : case ICE_VLAN_EX:
8869 : : case ICE_VLAN_IN:
8870 : : len = sizeof(struct ice_vlan_hdr);
8871 : 0 : break;
8872 : 0 : case ICE_IPV4_OFOS:
8873 : : case ICE_IPV4_IL:
8874 : : len = sizeof(struct ice_ipv4_hdr);
8875 : 0 : break;
8876 : 0 : case ICE_IPV6_OFOS:
8877 : : case ICE_IPV6_IL:
8878 : : len = sizeof(struct ice_ipv6_hdr);
8879 : 0 : break;
8880 : 0 : case ICE_TCP_IL:
8881 : : case ICE_UDP_OF:
8882 : : case ICE_UDP_ILOS:
8883 : : len = sizeof(struct ice_l4_hdr);
8884 : 0 : break;
8885 : : case ICE_SCTP_IL:
8886 : : len = sizeof(struct ice_sctp_hdr);
8887 : : break;
8888 : 0 : case ICE_NVGRE:
8889 : : len = sizeof(struct ice_nvgre);
8890 : 0 : break;
8891 : 0 : case ICE_VXLAN:
8892 : : case ICE_GENEVE:
8893 : : case ICE_VXLAN_GPE:
8894 : : len = sizeof(struct ice_udp_tnl_hdr);
8895 : 0 : break;
8896 : :
8897 : 0 : case ICE_PPPOE:
8898 : : len = sizeof(struct ice_pppoe_hdr);
8899 : 0 : break;
8900 : 0 : case ICE_ESP:
8901 : : len = sizeof(struct ice_esp_hdr);
8902 : 0 : break;
8903 : 0 : case ICE_NAT_T:
8904 : : len = sizeof(struct ice_nat_t_hdr);
8905 : 0 : break;
8906 : : case ICE_AH:
8907 : : len = sizeof(struct ice_ah_hdr);
8908 : : break;
8909 : 0 : case ICE_L2TPV3:
8910 : : len = sizeof(struct ice_l2tpv3_sess_hdr);
8911 : 0 : break;
8912 : 0 : case ICE_GTP:
8913 : : case ICE_GTP_NO_PAY:
8914 : : len = sizeof(struct ice_udp_gtp_hdr);
8915 : 0 : break;
8916 : : default:
8917 : : return ICE_ERR_PARAM;
8918 : : }
8919 : :
8920 : : /* the length should be a word multiple */
8921 : : if (len % ICE_BYTES_PER_WORD)
8922 : : return ICE_ERR_CFG;
8923 : :
8924 : : /* We have the offset to the header start, the length, the
8925 : : * caller's header values and mask. Use this information to
8926 : : * copy the data into the dummy packet appropriately based on
8927 : : * the mask. Note that we need to only write the bits as
8928 : : * indicated by the mask to make sure we don't improperly write
8929 : : * over any significant packet data.
8930 : : */
8931 [ # # ]: 0 : for (j = 0; j < len / sizeof(u16); j++)
8932 [ # # ]: 0 : if (((u16 *)&lkups[i].m_u)[j])
8933 : 0 : ((u16 *)(pkt + offset))[j] =
8934 : 0 : (((u16 *)(pkt + offset))[j] &
8935 : 0 : ~((u16 *)&lkups[i].m_u)[j]) |
8936 : 0 : (((u16 *)&lkups[i].h_u)[j] &
8937 : : ((u16 *)&lkups[i].m_u)[j]);
8938 : : }
8939 : :
8940 : 0 : s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(pkt_len);
8941 : :
8942 : 0 : return ICE_SUCCESS;
8943 : : }
8944 : :
8945 : : /**
8946 : : * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
8947 : : * @hw: pointer to the hardware structure
8948 : : * @tun_type: tunnel type
8949 : : * @pkt: dummy packet to fill in
8950 : : * @offsets: offset info for the dummy packet
8951 : : */
8952 : : static enum ice_status
8953 : 0 : ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
8954 : : u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
8955 : : {
8956 : : u16 open_port, i;
8957 : :
8958 [ # # # ]: 0 : switch (tun_type) {
8959 : 0 : case ICE_SW_TUN_AND_NON_TUN:
8960 : : case ICE_SW_TUN_VXLAN_GPE:
8961 : : case ICE_SW_TUN_VXLAN:
8962 : : case ICE_SW_TUN_VXLAN_VLAN:
8963 : : case ICE_SW_TUN_UDP:
8964 [ # # ]: 0 : if (!ice_get_open_tunnel_port(hw, TNL_VXLAN, &open_port))
8965 : : return ICE_ERR_CFG;
8966 : : break;
8967 : :
8968 : 0 : case ICE_SW_TUN_GENEVE:
8969 : : case ICE_SW_TUN_GENEVE_VLAN:
8970 [ # # ]: 0 : if (!ice_get_open_tunnel_port(hw, TNL_GENEVE, &open_port))
8971 : : return ICE_ERR_CFG;
8972 : : break;
8973 : :
8974 : : default:
8975 : : /* Nothing needs to be done for this tunnel type */
8976 : : return ICE_SUCCESS;
8977 : : }
8978 : :
8979 : : /* Find the outer UDP protocol header and insert the port number */
8980 [ # # ]: 0 : for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
8981 [ # # ]: 0 : if (offsets[i].type == ICE_UDP_OF) {
8982 : : struct ice_l4_hdr *hdr;
8983 : : u16 offset;
8984 : :
8985 : 0 : offset = offsets[i].offset;
8986 : 0 : hdr = (struct ice_l4_hdr *)&pkt[offset];
8987 [ # # ]: 0 : hdr->dst_port = CPU_TO_BE16(open_port);
8988 : :
8989 : 0 : return ICE_SUCCESS;
8990 : : }
8991 : : }
8992 : :
8993 : : return ICE_ERR_CFG;
8994 : : }
8995 : :
8996 : : /**
8997 : : * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
8998 : : * @vlan_type: VLAN tag type
8999 : : * @pkt: dummy packet to fill in
9000 : : * @offsets: offset info for the dummy packet
9001 : : */
9002 : : static enum ice_status
9003 : 0 : ice_fill_adv_packet_vlan(u16 vlan_type, u8 *pkt,
9004 : : const struct ice_dummy_pkt_offsets *offsets)
9005 : : {
9006 : : u16 i;
9007 : :
9008 : : /* Find VLAN header and insert VLAN TPID */
9009 [ # # ]: 0 : for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
9010 [ # # ]: 0 : if (offsets[i].type == ICE_VLAN_OFOS ||
9011 : : offsets[i].type == ICE_VLAN_EX) {
9012 : : struct ice_vlan_hdr *hdr;
9013 : : u16 offset;
9014 : :
9015 : 0 : offset = offsets[i].offset;
9016 : 0 : hdr = (struct ice_vlan_hdr *)&pkt[offset];
9017 [ # # ]: 0 : hdr->type = CPU_TO_BE16(vlan_type);
9018 : :
9019 : 0 : return ICE_SUCCESS;
9020 : : }
9021 : : }
9022 : :
9023 : : return ICE_ERR_CFG;
9024 : : }
9025 : :
9026 : : /**
9027 : : * ice_find_adv_rule_entry - Search a rule entry
9028 : : * @hw: pointer to the hardware structure
9029 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
9030 : : * structure per protocol header
9031 : : * @lkups_cnt: number of protocols
9032 : : * @recp_id: recipe ID for which we are finding the rule
9033 : : * @rinfo: other information regarding the rule e.g. priority and action info
9034 : : *
9035 : : * Helper function to search for a given advance rule entry
9036 : : * Returns pointer to entry storing the rule if found
9037 : : */
9038 : : static struct ice_adv_fltr_mgmt_list_entry *
9039 : 0 : ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
9040 : : u16 lkups_cnt, u16 recp_id,
9041 : : struct ice_adv_rule_info *rinfo)
9042 : : {
9043 : : struct ice_adv_fltr_mgmt_list_entry *list_itr;
9044 : 0 : struct ice_switch_info *sw = hw->switch_info;
9045 : : int i;
9046 : :
9047 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, &sw->recp_list[recp_id].filt_rules,
# # ]
9048 : : ice_adv_fltr_mgmt_list_entry, list_entry) {
9049 : : bool lkups_matched = true;
9050 : :
9051 [ # # ]: 0 : if (lkups_cnt != list_itr->lkups_cnt)
9052 : 0 : continue;
9053 [ # # ]: 0 : for (i = 0; i < list_itr->lkups_cnt; i++)
9054 [ # # ]: 0 : if (memcmp(&list_itr->lkups[i], &lkups[i],
9055 : : sizeof(*lkups))) {
9056 : : lkups_matched = false;
9057 : : break;
9058 : : }
9059 [ # # ]: 0 : if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
9060 [ # # ]: 0 : rinfo->tun_type == list_itr->rule_info.tun_type &&
9061 [ # # # # ]: 0 : rinfo->vlan_type == list_itr->rule_info.vlan_type &&
9062 : : lkups_matched)
9063 : 0 : return list_itr;
9064 : : }
9065 : : return NULL;
9066 : : }
9067 : :
9068 : : /**
9069 : : * ice_adv_add_update_vsi_list
9070 : : * @hw: pointer to the hardware structure
9071 : : * @m_entry: pointer to current adv filter management list entry
9072 : : * @cur_fltr: filter information from the book keeping entry
9073 : : * @new_fltr: filter information with the new VSI to be added
9074 : : *
9075 : : * Call AQ command to add or update previously created VSI list with new VSI.
9076 : : *
9077 : : * Helper function to do book keeping associated with adding filter information
9078 : : * The algorithm to do the booking keeping is described below :
9079 : : * When a VSI needs to subscribe to a given advanced filter
9080 : : * if only one VSI has been added till now
9081 : : * Allocate a new VSI list and add two VSIs
9082 : : * to this list using switch rule command
9083 : : * Update the previously created switch rule with the
9084 : : * newly created VSI list ID
9085 : : * if a VSI list was previously created
9086 : : * Add the new VSI to the previously created VSI list set
9087 : : * using the update switch rule command
9088 : : */
9089 : : static enum ice_status
9090 : 0 : ice_adv_add_update_vsi_list(struct ice_hw *hw,
9091 : : struct ice_adv_fltr_mgmt_list_entry *m_entry,
9092 : : struct ice_adv_rule_info *cur_fltr,
9093 : : struct ice_adv_rule_info *new_fltr)
9094 : : {
9095 : : enum ice_status status;
9096 : 0 : u16 vsi_list_id = 0;
9097 : :
9098 : 0 : if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
9099 [ # # ]: 0 : cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
9100 : : cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
9101 : : return ICE_ERR_NOT_IMPL;
9102 : :
9103 [ # # ]: 0 : if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
9104 [ # # ]: 0 : new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
9105 : : (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
9106 : : cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
9107 : : return ICE_ERR_NOT_IMPL;
9108 : :
9109 [ # # # # ]: 0 : if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
9110 : : /* Only one entry existed in the mapping and it was not already
9111 : : * a part of a VSI list. So, create a VSI list with the old and
9112 : : * new VSIs.
9113 : : */
9114 : : struct ice_fltr_info tmp_fltr;
9115 : : u16 vsi_handle_arr[2];
9116 : :
9117 : : /* A rule already exists with the new VSI being added */
9118 [ # # ]: 0 : if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
9119 : : new_fltr->sw_act.fwd_id.hw_vsi_id)
9120 : 0 : return ICE_ERR_ALREADY_EXISTS;
9121 : :
9122 : 0 : vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
9123 : 0 : vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
9124 : 0 : status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
9125 : : &vsi_list_id,
9126 : : ICE_SW_LKUP_LAST);
9127 [ # # ]: 0 : if (status)
9128 : : return status;
9129 : :
9130 : : ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
9131 : 0 : tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
9132 : 0 : tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
9133 : 0 : tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
9134 : 0 : tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
9135 : 0 : tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
9136 : :
9137 : : /* Update the previous switch rule of "forward to VSI" to
9138 : : * "fwd to VSI list"
9139 : : */
9140 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
9141 [ # # ]: 0 : if (status)
9142 : : return status;
9143 : :
9144 : 0 : cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
9145 : 0 : cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
9146 : 0 : m_entry->vsi_list_info =
9147 : 0 : ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
9148 : : vsi_list_id);
9149 : : } else {
9150 : 0 : u16 vsi_handle = new_fltr->sw_act.vsi_handle;
9151 : :
9152 [ # # ]: 0 : if (!m_entry->vsi_list_info)
9153 : 0 : return ICE_ERR_CFG;
9154 : :
9155 : : /* A rule already exists with the new VSI being added */
9156 [ # # ]: 0 : if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
9157 : : return ICE_ERR_ALREADY_EXISTS;
9158 : :
9159 : : /* Update the previously created VSI list set with
9160 : : * the new VSI ID passed in
9161 : : */
9162 : 0 : vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
9163 : :
9164 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
9165 : : vsi_list_id, false,
9166 : : ice_aqc_opc_update_sw_rules,
9167 : : ICE_SW_LKUP_LAST);
9168 : : /* update VSI list mapping info with new VSI ID */
9169 [ # # ]: 0 : if (!status)
9170 : 0 : ice_set_bit(vsi_handle,
9171 : 0 : m_entry->vsi_list_info->vsi_map);
9172 : : }
9173 [ # # ]: 0 : if (!status)
9174 : 0 : m_entry->vsi_count++;
9175 : : return status;
9176 : : }
9177 : :
9178 : : /**
9179 : : * ice_set_lg_action_entry
9180 : : * @act_type: large action type is defined in struct ice_sw_rule_lg_act
9181 : : * @lg_act_entry: large action entry content
9182 : : *
9183 : : * Helper function to set large action entry. Each entry represents a single
9184 : : * action and up to 4 actions can be chained.
9185 : : */
9186 : : static u32
9187 : 0 : ice_set_lg_action_entry(u8 act_type, union lg_act_entry *lg_entry)
9188 : : {
9189 : 0 : u32 act = act_type;
9190 : :
9191 [ # # # # : 0 : switch (act_type) {
# # # ]
9192 : 0 : case ICE_LG_ACT_VSI_FORWARDING:
9193 : 0 : act |= ICE_LG_ACT_VALID_BIT;
9194 : 0 : act |= (lg_entry->vsi_fwd.vsi_list <<
9195 : 0 : ICE_LG_ACT_VSI_LIST_ID_S) &
9196 : : ICE_LG_ACT_VSI_LIST_ID_M;
9197 : 0 : break;
9198 : 0 : case ICE_LG_ACT_TO_Q:
9199 : 0 : act |= ICE_LG_ACT_Q_PRIORITY_SET;
9200 : 0 : act |= (lg_entry->to_q.q_idx << ICE_LG_ACT_Q_INDEX_S) &
9201 : : ICE_LG_ACT_Q_INDEX_M;
9202 : 0 : act |= (lg_entry->to_q.q_region_sz << ICE_LG_ACT_Q_REGION_S) &
9203 : : ICE_LG_ACT_Q_REGION_M;
9204 : 0 : act |= (lg_entry->to_q.q_pri << ICE_LG_ACT_Q_REGION_S) &
9205 : : ICE_LG_ACT_Q_REGION_M;
9206 : 0 : break;
9207 : 0 : case ICE_LG_ACT_PRUNE:
9208 : 0 : act |= (lg_entry->prune.vsi_list << ICE_LG_ACT_VSI_LIST_ID_S) &
9209 : : ICE_LG_ACT_VSI_LIST_ID_M;
9210 : :
9211 [ # # ]: 0 : if (lg_entry->prune.egr)
9212 : 0 : act |= ICE_LG_ACT_EGRESS;
9213 [ # # ]: 0 : if (lg_entry->prune.ing)
9214 : 0 : act |= ICE_LG_ACT_INGRESS;
9215 [ # # ]: 0 : if (lg_entry->prune.prune_t)
9216 : 0 : act |= ICE_LG_ACT_PRUNET;
9217 : : break;
9218 : 0 : case ICE_LG_OTHER_ACT_MIRROR:
9219 : 0 : act |= (lg_entry->mirror.mirror_vsi <<
9220 : 0 : ICE_LG_ACT_MIRROR_VSI_ID_S) &
9221 : : ICE_LG_ACT_MIRROR_VSI_ID_M;
9222 : 0 : break;
9223 : 0 : case ICE_LG_ACT_GENERIC:
9224 : 0 : act |= (lg_entry->generic_act.generic_value <<
9225 : 0 : ICE_LG_ACT_GENERIC_VALUE_S) &
9226 : : ICE_LG_ACT_GENERIC_VALUE_M;
9227 : 0 : act |= (lg_entry->generic_act.offset <<
9228 : 0 : ICE_LG_ACT_GENERIC_OFFSET_S) &
9229 : : ICE_LG_ACT_GENERIC_OFFSET_M;
9230 : 0 : act |= (lg_entry->generic_act.priority <<
9231 : 0 : ICE_LG_ACT_GENERIC_PRIORITY_S) &
9232 : : ICE_LG_ACT_GENERIC_PRIORITY_M;
9233 : 0 : break;
9234 : 0 : case ICE_LG_ACT_STAT_COUNT:
9235 : 0 : act |= (lg_entry->statistics.counter_idx <<
9236 : 0 : ICE_LG_ACT_STAT_COUNT_S) &
9237 : : ICE_LG_ACT_STAT_COUNT_M;
9238 : 0 : break;
9239 : : }
9240 : :
9241 : 0 : return act;
9242 : : }
9243 : :
9244 : : /**
9245 : : * ice_fill_sw_marker_lg_act
9246 : : * @hw: pointer to the hardware structure
9247 : : * @sw_marker: sw marker to tag the Rx descriptor with
9248 : : * @l_id: large action resource ID
9249 : : * @lkup_rule_sz: lookup rule size
9250 : : * @lg_act_size: large action rule size
9251 : : * @num_lg_acts: number of actions to hold with a large action entry
9252 : : * @s_rule: switch lookup rule structure
9253 : : *
9254 : : * Fill a large action to hold software marker and link the lookup rule
9255 : : * with an action pointing to this larger action
9256 : : */
9257 : : static struct ice_aqc_sw_rules_elem *
9258 : 0 : ice_fill_sw_marker_lg_act(struct ice_hw *hw, u32 sw_marker, u16 l_id,
9259 : : u16 lkup_rule_sz, u16 lg_act_size, u16 num_lg_acts,
9260 : : struct ice_aqc_sw_rules_elem *s_rule)
9261 : : {
9262 : : struct ice_aqc_sw_rules_elem *rx_tx, *lg_act;
9263 : : const u16 offset_generic_md_word_0 = 0;
9264 : : const u16 offset_generic_md_word_1 = 1;
9265 : : enum ice_status status = ICE_SUCCESS;
9266 : : union lg_act_entry lg_e_lo;
9267 : : union lg_act_entry lg_e_hi;
9268 : : const u8 priority = 0x3;
9269 : : u16 rules_size;
9270 : : u32 act;
9271 : :
9272 : : /* For software marker we need 2 large actions for 32 bit mark id */
9273 : 0 : rules_size = lg_act_size + lkup_rule_sz;
9274 : 0 : lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size);
9275 [ # # ]: 0 : if (!lg_act)
9276 : : return NULL;
9277 : :
9278 : 0 : rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size);
9279 : :
9280 [ # # ]: 0 : ice_memcpy(rx_tx, s_rule, lkup_rule_sz, ICE_NONDMA_TO_NONDMA);
9281 : 0 : ice_free(hw, s_rule);
9282 : : s_rule = NULL;
9283 : :
9284 : 0 : lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
9285 : 0 : lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id);
9286 : 0 : lg_act->pdata.lg_act.size = CPU_TO_LE16(num_lg_acts);
9287 : :
9288 : : /* GENERIC VALUE action to hold the software marker ID low 16 bits */
9289 : : /* and set in meta data index 4 by default. */
9290 : 0 : lg_e_lo.generic_act.generic_value = (u16)(sw_marker & 0xFFFF);
9291 : 0 : lg_e_lo.generic_act.offset = offset_generic_md_word_0;
9292 : 0 : lg_e_lo.generic_act.priority = priority;
9293 : 0 : act = ice_set_lg_action_entry(ICE_LG_ACT_GENERIC, &lg_e_lo);
9294 : 0 : lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act);
9295 : :
9296 [ # # ]: 0 : if (num_lg_acts == 1)
9297 : : return lg_act;
9298 : :
9299 : : /* This is a 32 bits marker id, chain a new entry to set higher 16 bits
9300 : : * and set in meta data index 5 by default.
9301 : : */
9302 : 0 : lg_e_hi.generic_act.generic_value = (u16)((sw_marker >> 16) & 0xFFFF);
9303 : 0 : lg_e_hi.generic_act.offset = offset_generic_md_word_1;
9304 : 0 : lg_e_hi.generic_act.priority = priority;
9305 : 0 : act = ice_set_lg_action_entry(ICE_LG_ACT_GENERIC, &lg_e_hi);
9306 : 0 : lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act);
9307 : :
9308 : 0 : return lg_act;
9309 : : }
9310 : :
9311 : : /**
9312 : : * ice_add_adv_rule - helper function to create an advanced switch rule
9313 : : * @hw: pointer to the hardware structure
9314 : : * @lkups: information on the words that needs to be looked up. All words
9315 : : * together makes one recipe
9316 : : * @lkups_cnt: num of entries in the lkups array
9317 : : * @rinfo: other information related to the rule that needs to be programmed
9318 : : * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
9319 : : * ignored is case of error.
9320 : : *
9321 : : * This function can program only 1 rule at a time. The lkups is used to
9322 : : * describe the all the words that forms the "lookup" portion of the recipe.
9323 : : * These words can span multiple protocols. Callers to this function need to
9324 : : * pass in a list of protocol headers with lookup information along and mask
9325 : : * that determines which words are valid from the given protocol header.
9326 : : * rinfo describes other information related to this rule such as forwarding
9327 : : * IDs, priority of this rule, etc.
9328 : : */
9329 : : enum ice_status
9330 : 0 : ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
9331 : : u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
9332 : : struct ice_rule_query_data *added_entry)
9333 : : {
9334 : : struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
9335 : 0 : u16 lg_act_size, lg_act_id = ICE_INVAL_LG_ACT_INDEX;
9336 : 0 : u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;
9337 : : const struct ice_dummy_pkt_offsets *pkt_offsets;
9338 : : struct ice_aqc_sw_rules_elem *s_rule = NULL;
9339 : : struct ice_aqc_sw_rules_elem *rx_tx;
9340 : : struct LIST_HEAD_TYPE *rule_head;
9341 : : struct ice_switch_info *sw;
9342 : : u16 nb_lg_acts_mark = 1;
9343 : : enum ice_status status;
9344 : 0 : const u8 *pkt = NULL;
9345 : : u16 num_rules = 1;
9346 : : bool prof_rule;
9347 : : u16 word_cnt;
9348 : : u32 act = 0;
9349 : : u8 q_rgn;
9350 : :
9351 : : /* Initialize profile to result index bitmap */
9352 [ # # ]: 0 : if (!hw->switch_info->prof_res_bm_init) {
9353 : 0 : hw->switch_info->prof_res_bm_init = 1;
9354 : 0 : ice_init_prof_result_bm(hw);
9355 : : }
9356 : :
9357 : 0 : prof_rule = ice_is_prof_rule(rinfo->tun_type);
9358 [ # # ]: 0 : if (!prof_rule && !lkups_cnt)
9359 : : return ICE_ERR_PARAM;
9360 : :
9361 : : /* get # of words we need to match */
9362 : : word_cnt = 0;
9363 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
9364 : : u16 j, *ptr;
9365 : :
9366 : 0 : ptr = (u16 *)&lkups[i].m_u;
9367 [ # # ]: 0 : for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)
9368 [ # # ]: 0 : if (ptr[j] != 0)
9369 : 0 : word_cnt++;
9370 : : }
9371 : :
9372 [ # # ]: 0 : if (prof_rule) {
9373 [ # # ]: 0 : if (word_cnt > ICE_MAX_CHAIN_WORDS)
9374 : : return ICE_ERR_PARAM;
9375 : : } else {
9376 [ # # ]: 0 : if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS)
9377 : : return ICE_ERR_PARAM;
9378 : : }
9379 : :
9380 : : /* make sure that we can locate a dummy packet */
9381 : 0 : ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
9382 : : &pkt_offsets);
9383 [ # # ]: 0 : if (!pkt) {
9384 : : status = ICE_ERR_PARAM;
9385 : 0 : goto err_ice_add_adv_rule;
9386 : : }
9387 : :
9388 [ # # # # ]: 0 : if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
9389 [ # # ]: 0 : rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
9390 [ # # ]: 0 : rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
9391 : : rinfo->sw_act.fltr_act == ICE_SET_MARK ||
9392 : : rinfo->sw_act.fltr_act == ICE_DROP_PACKET))
9393 : : return ICE_ERR_CFG;
9394 : :
9395 : 0 : vsi_handle = rinfo->sw_act.vsi_handle;
9396 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
9397 : : return ICE_ERR_PARAM;
9398 : :
9399 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
9400 : 0 : rinfo->sw_act.fwd_id.hw_vsi_id =
9401 : 0 : ice_get_hw_vsi_num(hw, vsi_handle);
9402 [ # # ]: 0 : if (rinfo->sw_act.flag & ICE_FLTR_TX)
9403 : 0 : rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
9404 : :
9405 : 0 : status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
9406 [ # # ]: 0 : if (status)
9407 : : return status;
9408 : 0 : m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
9409 [ # # ]: 0 : if (m_entry) {
9410 : : /* we have to add VSI to VSI_LIST and increment vsi_count.
9411 : : * Also Update VSI list so that we can change forwarding rule
9412 : : * if the rule already exists, we will check if it exists with
9413 : : * same vsi_id, if not then add it to the VSI list if it already
9414 : : * exists if not then create a VSI list and add the existing VSI
9415 : : * ID and the new VSI ID to the list
9416 : : * We will add that VSI to the list
9417 : : */
9418 : 0 : status = ice_adv_add_update_vsi_list(hw, m_entry,
9419 : : &m_entry->rule_info,
9420 : : rinfo);
9421 [ # # ]: 0 : if (added_entry) {
9422 : 0 : added_entry->rid = rid;
9423 : 0 : added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
9424 : 0 : added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
9425 : : }
9426 : 0 : return status;
9427 : : }
9428 : 0 : rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len;
9429 : 0 : s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rule_buf_sz);
9430 [ # # ]: 0 : if (!s_rule)
9431 : : return ICE_ERR_NO_MEMORY;
9432 [ # # ]: 0 : if (!rinfo->flags_info.act_valid)
9433 : : act |= ICE_SINGLE_ACT_LAN_ENABLE;
9434 : : else
9435 : 0 : act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
9436 : : ICE_SINGLE_ACT_LB_ENABLE);
9437 : :
9438 [ # # # # : 0 : switch (rinfo->sw_act.fltr_act) {
# # ]
9439 : 0 : case ICE_FWD_TO_VSI:
9440 : 0 : act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
9441 : 0 : ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
9442 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
9443 : 0 : break;
9444 : 0 : case ICE_FWD_TO_Q:
9445 : 0 : act |= ICE_SINGLE_ACT_TO_Q;
9446 : 0 : act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
9447 : : ICE_SINGLE_ACT_Q_INDEX_M;
9448 : 0 : break;
9449 : 0 : case ICE_FWD_TO_QGRP:
9450 [ # # ]: 0 : q_rgn = rinfo->sw_act.qgrp_size > 0 ?
9451 : 0 : (u8)ice_ilog2(rinfo->sw_act.qgrp_size) : 0;
9452 : 0 : act |= ICE_SINGLE_ACT_TO_Q;
9453 : 0 : act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
9454 : : ICE_SINGLE_ACT_Q_INDEX_M;
9455 : 0 : act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
9456 : : ICE_SINGLE_ACT_Q_REGION_M;
9457 : 0 : break;
9458 : 0 : case ICE_SET_MARK:
9459 [ # # ]: 0 : if (rinfo->sw_act.markid != (rinfo->sw_act.markid & 0xFFFF))
9460 : : nb_lg_acts_mark += 1;
9461 : : /* Allocate a hardware table entry to hold large act. */
9462 : 0 : status = ice_alloc_res_lg_act(hw, &lg_act_id, nb_lg_acts_mark);
9463 [ # # # # ]: 0 : if (status || lg_act_id == ICE_INVAL_LG_ACT_INDEX)
9464 : : return ICE_ERR_NO_MEMORY;
9465 : :
9466 : : act = ICE_SINGLE_ACT_PTR;
9467 : 0 : act |= (lg_act_id << ICE_SINGLE_ACT_PTR_VAL_S) &
9468 : : ICE_SINGLE_ACT_PTR_VAL_M;
9469 : 0 : act |= ICE_SINGLE_ACT_PTR_BIT;
9470 : 0 : break;
9471 : 0 : case ICE_DROP_PACKET:
9472 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
9473 : : ICE_SINGLE_ACT_VALID_BIT;
9474 : 0 : break;
9475 : 0 : default:
9476 : : status = ICE_ERR_CFG;
9477 : 0 : goto err_ice_add_adv_rule;
9478 : : }
9479 : :
9480 : : /* set the rule LOOKUP type based on caller specified 'RX'
9481 : : * instead of hardcoding it to be either LOOKUP_TX/RX
9482 : : *
9483 : : * for 'RX' set the source to be the port number
9484 : : * for 'TX' set the source to be the source HW VSI number (determined
9485 : : * by caller)
9486 : : */
9487 [ # # ]: 0 : if (rinfo->rx) {
9488 : 0 : s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX);
9489 : 0 : s_rule->pdata.lkup_tx_rx.src =
9490 : 0 : CPU_TO_LE16(hw->port_info->lport);
9491 : : } else {
9492 : 0 : s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
9493 : 0 : s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(rinfo->sw_act.src);
9494 : : }
9495 : :
9496 : 0 : s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(rid);
9497 : 0 : s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act);
9498 : :
9499 : 0 : status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt,
9500 : : pkt_len, pkt_offsets);
9501 [ # # ]: 0 : if (status)
9502 : 0 : goto err_ice_add_adv_rule;
9503 : :
9504 [ # # ]: 0 : if (rinfo->tun_type != ICE_NON_TUN &&
9505 : : rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
9506 : 0 : status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
9507 : 0 : s_rule->pdata.lkup_tx_rx.hdr,
9508 : : pkt_offsets);
9509 [ # # ]: 0 : if (status)
9510 : 0 : goto err_ice_add_adv_rule;
9511 : : }
9512 : :
9513 [ # # # # ]: 0 : if (rinfo->vlan_type != 0 && ice_is_dvm_ena(hw)) {
9514 : 0 : status = ice_fill_adv_packet_vlan(rinfo->vlan_type,
9515 : 0 : s_rule->pdata.lkup_tx_rx.hdr,
9516 : : pkt_offsets);
9517 [ # # ]: 0 : if (status)
9518 : 0 : goto err_ice_add_adv_rule;
9519 : : }
9520 : :
9521 : : rx_tx = s_rule;
9522 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_SET_MARK) {
9523 : 0 : lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(nb_lg_acts_mark);
9524 : 0 : s_rule = ice_fill_sw_marker_lg_act(hw, rinfo->sw_act.markid,
9525 : : lg_act_id, rule_buf_sz,
9526 : : lg_act_size, nb_lg_acts_mark,
9527 : : s_rule);
9528 [ # # ]: 0 : if (!s_rule)
9529 : 0 : goto err_ice_add_adv_rule;
9530 : :
9531 : 0 : rule_buf_sz += lg_act_size;
9532 : : num_rules += 1;
9533 : 0 : rx_tx = (struct ice_aqc_sw_rules_elem *)
9534 : : ((u8 *)s_rule + lg_act_size);
9535 : : }
9536 : :
9537 : 0 : status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
9538 : : rule_buf_sz, num_rules,
9539 : : ice_aqc_opc_add_sw_rules, NULL);
9540 [ # # ]: 0 : if (status)
9541 : 0 : goto err_ice_add_adv_rule;
9542 : : adv_fltr = (struct ice_adv_fltr_mgmt_list_entry *)
9543 : 0 : ice_malloc(hw, sizeof(struct ice_adv_fltr_mgmt_list_entry));
9544 [ # # ]: 0 : if (!adv_fltr) {
9545 : : status = ICE_ERR_NO_MEMORY;
9546 : 0 : goto err_ice_add_adv_rule;
9547 : : }
9548 : :
9549 [ # # ]: 0 : if (lkups_cnt) {
9550 : 0 : adv_fltr->lkups = (struct ice_adv_lkup_elem *)
9551 : 0 : ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups),
9552 : : ICE_NONDMA_TO_NONDMA);
9553 : : } else {
9554 : 0 : adv_fltr->lkups = NULL;
9555 : : }
9556 [ # # # # ]: 0 : if (!adv_fltr->lkups && !prof_rule) {
9557 : : status = ICE_ERR_NO_MEMORY;
9558 : 0 : goto err_ice_add_adv_rule;
9559 : : }
9560 : :
9561 : 0 : adv_fltr->lkups_cnt = lkups_cnt;
9562 : 0 : adv_fltr->rule_info = *rinfo;
9563 : 0 : adv_fltr->rule_info.fltr_rule_id =
9564 : 0 : LE16_TO_CPU(rx_tx->pdata.lkup_tx_rx.index);
9565 : 0 : adv_fltr->rule_info.lg_id = LE16_TO_CPU(lg_act_id);
9566 : 0 : sw = hw->switch_info;
9567 : 0 : sw->recp_list[rid].adv_rule = true;
9568 : : rule_head = &sw->recp_list[rid].filt_rules;
9569 : :
9570 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
9571 : 0 : adv_fltr->vsi_count = 1;
9572 : :
9573 : : /* Add rule entry to book keeping list */
9574 [ # # ]: 0 : LIST_ADD(&adv_fltr->list_entry, rule_head);
9575 [ # # ]: 0 : if (added_entry) {
9576 : 0 : added_entry->rid = rid;
9577 : 0 : added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
9578 : 0 : added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
9579 : : }
9580 : 0 : err_ice_add_adv_rule:
9581 [ # # # # ]: 0 : if (status && rinfo->sw_act.fltr_act == ICE_SET_MARK)
9582 : 0 : ice_free_sw_marker_lg(hw, lg_act_id, rinfo->sw_act.markid);
9583 : :
9584 [ # # ]: 0 : if (status && adv_fltr) {
9585 : 0 : ice_free(hw, adv_fltr->lkups);
9586 : 0 : ice_free(hw, adv_fltr);
9587 : : }
9588 : :
9589 : 0 : ice_free(hw, s_rule);
9590 : :
9591 : 0 : return status;
9592 : : }
9593 : :
9594 : : /**
9595 : : * ice_adv_rem_update_vsi_list
9596 : : * @hw: pointer to the hardware structure
9597 : : * @vsi_handle: VSI handle of the VSI to remove
9598 : : * @fm_list: filter management entry for which the VSI list management needs to
9599 : : * be done
9600 : : */
9601 : : static enum ice_status
9602 : 0 : ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
9603 : : struct ice_adv_fltr_mgmt_list_entry *fm_list)
9604 : : {
9605 : : struct ice_vsi_list_map_info *vsi_list_info;
9606 : : enum ice_sw_lkup_type lkup_type;
9607 : : enum ice_status status;
9608 : : u16 vsi_list_id;
9609 : :
9610 [ # # ]: 0 : if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
9611 [ # # ]: 0 : fm_list->vsi_count == 0)
9612 : : return ICE_ERR_PARAM;
9613 : :
9614 : : /* A rule with the VSI being removed does not exist */
9615 [ # # ]: 0 : if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
9616 : : return ICE_ERR_DOES_NOT_EXIST;
9617 : :
9618 : : lkup_type = ICE_SW_LKUP_LAST;
9619 : 0 : vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
9620 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
9621 : : ice_aqc_opc_update_sw_rules,
9622 : : lkup_type);
9623 [ # # ]: 0 : if (status)
9624 : : return status;
9625 : :
9626 : 0 : fm_list->vsi_count--;
9627 [ # # ]: 0 : ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
9628 : : vsi_list_info = fm_list->vsi_list_info;
9629 [ # # ]: 0 : if (fm_list->vsi_count == 1) {
9630 : : struct ice_fltr_info tmp_fltr;
9631 : : u16 rem_vsi_handle;
9632 : :
9633 : 0 : rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
9634 : : ICE_MAX_VSI);
9635 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, rem_vsi_handle))
9636 : 0 : return ICE_ERR_OUT_OF_RANGE;
9637 : :
9638 : : /* Make sure VSI list is empty before removing it below */
9639 : 0 : status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
9640 : : vsi_list_id, true,
9641 : : ice_aqc_opc_update_sw_rules,
9642 : : lkup_type);
9643 [ # # ]: 0 : if (status)
9644 : : return status;
9645 : :
9646 : : ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
9647 : 0 : tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
9648 : 0 : tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
9649 : 0 : fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
9650 : : tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
9651 : 0 : tmp_fltr.fwd_id.hw_vsi_id =
9652 : 0 : ice_get_hw_vsi_num(hw, rem_vsi_handle);
9653 : 0 : fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
9654 : 0 : ice_get_hw_vsi_num(hw, rem_vsi_handle);
9655 : 0 : fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
9656 : :
9657 : : /* Update the previous switch rule of "MAC forward to VSI" to
9658 : : * "MAC fwd to VSI list"
9659 : : */
9660 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
9661 [ # # ]: 0 : if (status) {
9662 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
9663 : : tmp_fltr.fwd_id.hw_vsi_id, status);
9664 : 0 : return status;
9665 : : }
9666 : 0 : fm_list->vsi_list_info->ref_cnt--;
9667 : :
9668 : : /* Remove the VSI list since it is no longer used */
9669 : 0 : status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
9670 [ # # ]: 0 : if (status) {
9671 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
9672 : : vsi_list_id, status);
9673 : 0 : return status;
9674 : : }
9675 : :
9676 [ # # ]: 0 : LIST_DEL(&vsi_list_info->list_entry);
9677 : 0 : ice_free(hw, vsi_list_info);
9678 : 0 : fm_list->vsi_list_info = NULL;
9679 : : }
9680 : :
9681 : : return status;
9682 : : }
9683 : :
9684 : : /**
9685 : : * ice_rem_adv_rule - removes existing advanced switch rule
9686 : : * @hw: pointer to the hardware structure
9687 : : * @lkups: information on the words that needs to be looked up. All words
9688 : : * together makes one recipe
9689 : : * @lkups_cnt: num of entries in the lkups array
9690 : : * @rinfo: Its the pointer to the rule information for the rule
9691 : : *
9692 : : * This function can be used to remove 1 rule at a time. The lkups is
9693 : : * used to describe all the words that forms the "lookup" portion of the
9694 : : * rule. These words can span multiple protocols. Callers to this function
9695 : : * need to pass in a list of protocol headers with lookup information along
9696 : : * and mask that determines which words are valid from the given protocol
9697 : : * header. rinfo describes other information related to this rule such as
9698 : : * forwarding IDs, priority of this rule, etc.
9699 : : */
9700 : : enum ice_status
9701 : 0 : ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
9702 : : u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
9703 : : {
9704 : : struct ice_adv_fltr_mgmt_list_entry *list_elem;
9705 : : struct ice_prot_lkup_ext lkup_exts;
9706 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
9707 : : enum ice_status status = ICE_SUCCESS;
9708 : : bool remove_rule = false;
9709 : : u16 i, rid, vsi_handle;
9710 : :
9711 : : ice_memset(&lkup_exts, 0, sizeof(lkup_exts), ICE_NONDMA_MEM);
9712 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
9713 : : u16 count;
9714 : :
9715 [ # # ]: 0 : if (lkups[i].type >= ICE_PROTOCOL_LAST)
9716 : : return ICE_ERR_CFG;
9717 : :
9718 : 0 : count = ice_fill_valid_words(&lkups[i], &lkup_exts);
9719 [ # # ]: 0 : if (!count)
9720 : : return ICE_ERR_CFG;
9721 : : }
9722 : :
9723 : : /* Create any special protocol/offset pairs, such as looking at tunnel
9724 : : * bits by extracting metadata
9725 : : */
9726 : 0 : status = ice_add_special_words(rinfo, &lkup_exts, ice_is_dvm_ena(hw));
9727 [ # # ]: 0 : if (status)
9728 : : return status;
9729 : :
9730 : 0 : rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type, rinfo->priority);
9731 : : /* If did not find a recipe that match the existing criteria */
9732 [ # # ]: 0 : if (rid == ICE_MAX_NUM_RECIPES)
9733 : : return ICE_ERR_PARAM;
9734 : :
9735 : 0 : rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
9736 : 0 : list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
9737 : : /* the rule is already removed */
9738 [ # # ]: 0 : if (!list_elem)
9739 : : return ICE_SUCCESS;
9740 : 0 : ice_acquire_lock(rule_lock);
9741 [ # # ]: 0 : if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
9742 : : remove_rule = true;
9743 [ # # ]: 0 : } else if (list_elem->vsi_count > 1) {
9744 : : remove_rule = false;
9745 : 0 : vsi_handle = rinfo->sw_act.vsi_handle;
9746 : 0 : status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
9747 : : } else {
9748 : 0 : vsi_handle = rinfo->sw_act.vsi_handle;
9749 : 0 : status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
9750 [ # # ]: 0 : if (status) {
9751 : : ice_release_lock(rule_lock);
9752 : 0 : return status;
9753 : : }
9754 [ # # ]: 0 : if (list_elem->vsi_count == 0)
9755 : : remove_rule = true;
9756 : : }
9757 : : ice_release_lock(rule_lock);
9758 [ # # ]: 0 : if (remove_rule) {
9759 : : struct ice_aqc_sw_rules_elem *s_rule;
9760 : : u16 rule_buf_sz;
9761 : :
9762 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_SET_MARK)
9763 : 0 : ice_free_sw_marker_lg(hw, list_elem->rule_info.lg_id,
9764 : : rinfo->sw_act.markid);
9765 : : rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE;
9766 : : s_rule = (struct ice_aqc_sw_rules_elem *)
9767 : 0 : ice_malloc(hw, rule_buf_sz);
9768 [ # # ]: 0 : if (!s_rule)
9769 : : return ICE_ERR_NO_MEMORY;
9770 : 0 : s_rule->pdata.lkup_tx_rx.act = 0;
9771 : 0 : s_rule->pdata.lkup_tx_rx.index =
9772 : 0 : CPU_TO_LE16(list_elem->rule_info.fltr_rule_id);
9773 : 0 : s_rule->pdata.lkup_tx_rx.hdr_len = 0;
9774 : 0 : status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
9775 : : rule_buf_sz, 1,
9776 : : ice_aqc_opc_remove_sw_rules, NULL);
9777 [ # # ]: 0 : if (status == ICE_SUCCESS || status == ICE_ERR_DOES_NOT_EXIST) {
9778 : 0 : struct ice_switch_info *sw = hw->switch_info;
9779 : :
9780 : : ice_acquire_lock(rule_lock);
9781 [ # # ]: 0 : LIST_DEL(&list_elem->list_entry);
9782 : 0 : ice_free(hw, list_elem->lkups);
9783 : 0 : ice_free(hw, list_elem);
9784 : : ice_release_lock(rule_lock);
9785 [ # # ]: 0 : if (LIST_EMPTY(&sw->recp_list[rid].filt_rules))
9786 : 0 : sw->recp_list[rid].adv_rule = false;
9787 : : }
9788 : 0 : ice_free(hw, s_rule);
9789 : : }
9790 : : return status;
9791 : : }
9792 : :
9793 : : /**
9794 : : * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
9795 : : * @hw: pointer to the hardware structure
9796 : : * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
9797 : : *
9798 : : * This function is used to remove 1 rule at a time. The removal is based on
9799 : : * the remove_entry parameter. This function will remove rule for a given
9800 : : * vsi_handle with a given rule_id which is passed as parameter in remove_entry
9801 : : */
9802 : : enum ice_status
9803 : 0 : ice_rem_adv_rule_by_id(struct ice_hw *hw,
9804 : : struct ice_rule_query_data *remove_entry)
9805 : : {
9806 : : struct ice_adv_fltr_mgmt_list_entry *list_itr;
9807 : : struct LIST_HEAD_TYPE *list_head;
9808 : : struct ice_adv_rule_info rinfo;
9809 : : struct ice_switch_info *sw;
9810 : :
9811 : 0 : sw = hw->switch_info;
9812 [ # # ]: 0 : if (!sw->recp_list[remove_entry->rid].recp_created)
9813 : : return ICE_ERR_PARAM;
9814 : : list_head = &sw->recp_list[remove_entry->rid].filt_rules;
9815 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_adv_fltr_mgmt_list_entry,
# # ]
9816 : : list_entry) {
9817 : 0 : if (list_itr->rule_info.fltr_rule_id ==
9818 [ # # ]: 0 : remove_entry->rule_id) {
9819 : 0 : rinfo = list_itr->rule_info;
9820 : 0 : rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
9821 : 0 : return ice_rem_adv_rule(hw, list_itr->lkups,
9822 : 0 : list_itr->lkups_cnt, &rinfo);
9823 : : }
9824 : : }
9825 : : /* either list is empty or unable to find rule */
9826 : : return ICE_ERR_DOES_NOT_EXIST;
9827 : : }
9828 : :
9829 : : /**
9830 : : * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a
9831 : : * given VSI handle
9832 : : * @hw: pointer to the hardware structure
9833 : : * @vsi_handle: VSI handle for which we are supposed to remove all the rules.
9834 : : *
9835 : : * This function is used to remove all the rules for a given VSI and as soon
9836 : : * as removing a rule fails, it will return immediately with the error code,
9837 : : * else it will return ICE_SUCCESS
9838 : : */
9839 : 0 : enum ice_status ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
9840 : : {
9841 : : struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
9842 : : struct ice_vsi_list_map_info *map_info;
9843 : : struct LIST_HEAD_TYPE *list_head;
9844 : : struct ice_adv_rule_info rinfo;
9845 : : struct ice_switch_info *sw;
9846 : : enum ice_status status;
9847 : : u8 rid;
9848 : :
9849 : 0 : sw = hw->switch_info;
9850 [ # # ]: 0 : for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
9851 [ # # ]: 0 : if (!sw->recp_list[rid].recp_created)
9852 : 0 : continue;
9853 [ # # ]: 0 : if (!sw->recp_list[rid].adv_rule)
9854 : 0 : continue;
9855 : :
9856 : : list_head = &sw->recp_list[rid].filt_rules;
9857 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp_entry, list_head,
# # # # #
# ]
9858 : : ice_adv_fltr_mgmt_list_entry,
9859 : : list_entry) {
9860 : 0 : rinfo = list_itr->rule_info;
9861 : :
9862 [ # # ]: 0 : if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
9863 : 0 : map_info = list_itr->vsi_list_info;
9864 [ # # ]: 0 : if (!map_info)
9865 : 0 : continue;
9866 : :
9867 [ # # ]: 0 : if (!ice_is_bit_set(map_info->vsi_map,
9868 : : vsi_handle))
9869 : 0 : continue;
9870 [ # # ]: 0 : } else if (rinfo.sw_act.vsi_handle != vsi_handle) {
9871 : 0 : continue;
9872 : : }
9873 : :
9874 : 0 : rinfo.sw_act.vsi_handle = vsi_handle;
9875 : 0 : status = ice_rem_adv_rule(hw, list_itr->lkups,
9876 : 0 : list_itr->lkups_cnt, &rinfo);
9877 : :
9878 [ # # ]: 0 : if (status)
9879 : 0 : return status;
9880 : : }
9881 : : }
9882 : : return ICE_SUCCESS;
9883 : : }
9884 : :
9885 : : /**
9886 : : * ice_replay_fltr - Replay all the filters stored by a specific list head
9887 : : * @hw: pointer to the hardware structure
9888 : : * @list_head: list for which filters needs to be replayed
9889 : : * @recp_id: Recipe ID for which rules need to be replayed
9890 : : */
9891 : : static enum ice_status
9892 : 0 : ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head)
9893 : : {
9894 : : struct ice_fltr_mgmt_list_entry *itr;
9895 : : enum ice_status status = ICE_SUCCESS;
9896 : : struct ice_sw_recipe *recp_list;
9897 : 0 : u8 lport = hw->port_info->lport;
9898 : : struct LIST_HEAD_TYPE l_head;
9899 : :
9900 [ # # ]: 0 : if (LIST_EMPTY(list_head))
9901 : : return status;
9902 : :
9903 : 0 : recp_list = &hw->switch_info->recp_list[recp_id];
9904 : : /* Move entries from the given list_head to a temporary l_head so that
9905 : : * they can be replayed. Otherwise when trying to re-add the same
9906 : : * filter, the function will return already exists
9907 : : */
9908 : 0 : LIST_REPLACE_INIT(list_head, &l_head);
9909 : :
9910 : : /* Mark the given list_head empty by reinitializing it so filters
9911 : : * could be added again by *handler
9912 : : */
9913 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry,
9914 : : list_entry) {
9915 : : struct ice_fltr_list_entry f_entry;
9916 : : u16 vsi_handle;
9917 : :
9918 : 0 : f_entry.fltr_info = itr->fltr_info;
9919 [ # # # # ]: 0 : if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
9920 : 0 : status = ice_add_rule_internal(hw, recp_list, lport,
9921 : : &f_entry);
9922 [ # # ]: 0 : if (status != ICE_SUCCESS)
9923 : 0 : goto end;
9924 : 0 : continue;
9925 : : }
9926 : :
9927 : : /* Add a filter per VSI separately */
9928 [ # # ]: 0 : ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map,
9929 : : ICE_MAX_VSI) {
9930 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
9931 : : break;
9932 : :
9933 : 0 : ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
9934 : 0 : f_entry.fltr_info.vsi_handle = vsi_handle;
9935 : 0 : f_entry.fltr_info.fwd_id.hw_vsi_id =
9936 : 0 : ice_get_hw_vsi_num(hw, vsi_handle);
9937 : 0 : f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
9938 [ # # ]: 0 : if (recp_id == ICE_SW_LKUP_VLAN)
9939 : 0 : status = ice_add_vlan_internal(hw, recp_list,
9940 : : &f_entry);
9941 : : else
9942 : 0 : status = ice_add_rule_internal(hw, recp_list,
9943 : : lport,
9944 : : &f_entry);
9945 [ # # ]: 0 : if (status != ICE_SUCCESS)
9946 : 0 : goto end;
9947 : : }
9948 : : }
9949 : 0 : end:
9950 : : /* Clear the filter management list */
9951 : 0 : ice_rem_sw_rule_info(hw, &l_head);
9952 : 0 : return status;
9953 : : }
9954 : :
9955 : : /**
9956 : : * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
9957 : : * @hw: pointer to the hardware structure
9958 : : *
9959 : : * NOTE: This function does not clean up partially added filters on error.
9960 : : * It is up to caller of the function to issue a reset or fail early.
9961 : : */
9962 : 0 : enum ice_status ice_replay_all_fltr(struct ice_hw *hw)
9963 : : {
9964 : 0 : struct ice_switch_info *sw = hw->switch_info;
9965 : : enum ice_status status = ICE_SUCCESS;
9966 : : u8 i;
9967 : :
9968 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
9969 : 0 : struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules;
9970 : :
9971 : 0 : status = ice_replay_fltr(hw, i, head);
9972 [ # # ]: 0 : if (status != ICE_SUCCESS)
9973 : 0 : return status;
9974 : : }
9975 : : return status;
9976 : : }
9977 : :
9978 : : /**
9979 : : * ice_replay_vsi_fltr - Replay filters for requested VSI
9980 : : * @hw: pointer to the hardware structure
9981 : : * @pi: pointer to port information structure
9982 : : * @sw: pointer to switch info struct for which function replays filters
9983 : : * @vsi_handle: driver VSI handle
9984 : : * @recp_id: Recipe ID for which rules need to be replayed
9985 : : * @list_head: list for which filters need to be replayed
9986 : : *
9987 : : * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
9988 : : * It is required to pass valid VSI handle.
9989 : : */
9990 : : static enum ice_status
9991 : 0 : ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi,
9992 : : struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id,
9993 : : struct LIST_HEAD_TYPE *list_head)
9994 : : {
9995 : : struct ice_fltr_mgmt_list_entry *itr;
9996 : : enum ice_status status = ICE_SUCCESS;
9997 : : struct ice_sw_recipe *recp_list;
9998 : : u16 hw_vsi_id;
9999 : :
10000 [ # # ]: 0 : if (LIST_EMPTY(list_head))
10001 : : return status;
10002 : 0 : recp_list = &sw->recp_list[recp_id];
10003 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
10004 : :
10005 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry,
# # ]
10006 : : list_entry) {
10007 : : struct ice_fltr_list_entry f_entry;
10008 : :
10009 : 0 : f_entry.fltr_info = itr->fltr_info;
10010 [ # # # # ]: 0 : if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
10011 [ # # ]: 0 : itr->fltr_info.vsi_handle == vsi_handle) {
10012 : : /* update the src in case it is VSI num */
10013 [ # # ]: 0 : if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
10014 : 0 : f_entry.fltr_info.src = hw_vsi_id;
10015 : 0 : status = ice_add_rule_internal(hw, recp_list,
10016 : 0 : pi->lport,
10017 : : &f_entry);
10018 [ # # ]: 0 : if (status != ICE_SUCCESS)
10019 : 0 : goto end;
10020 : 0 : continue;
10021 : : }
10022 [ # # # # ]: 0 : if (!itr->vsi_list_info ||
10023 [ # # ]: 0 : !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle))
10024 : 0 : continue;
10025 : : /* Clearing it so that the logic can add it back */
10026 : : ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
10027 : 0 : f_entry.fltr_info.vsi_handle = vsi_handle;
10028 : 0 : f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
10029 : : /* update the src in case it is VSI num */
10030 [ # # ]: 0 : if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
10031 : 0 : f_entry.fltr_info.src = hw_vsi_id;
10032 [ # # ]: 0 : if (recp_id == ICE_SW_LKUP_VLAN)
10033 : 0 : status = ice_add_vlan_internal(hw, recp_list, &f_entry);
10034 : : else
10035 : 0 : status = ice_add_rule_internal(hw, recp_list,
10036 : 0 : pi->lport,
10037 : : &f_entry);
10038 [ # # ]: 0 : if (status != ICE_SUCCESS)
10039 : 0 : goto end;
10040 : : }
10041 : 0 : end:
10042 : : return status;
10043 : : }
10044 : :
10045 : : /**
10046 : : * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
10047 : : * @hw: pointer to the hardware structure
10048 : : * @vsi_handle: driver VSI handle
10049 : : * @list_head: list for which filters need to be replayed
10050 : : *
10051 : : * Replay the advanced rule for the given VSI.
10052 : : */
10053 : : static enum ice_status
10054 : 0 : ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
10055 : : struct LIST_HEAD_TYPE *list_head)
10056 : : {
10057 : 0 : struct ice_rule_query_data added_entry = { 0 };
10058 : : struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
10059 : : enum ice_status status = ICE_SUCCESS;
10060 : :
10061 [ # # ]: 0 : if (LIST_EMPTY(list_head))
10062 : : return status;
10063 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(adv_fltr, list_head, ice_adv_fltr_mgmt_list_entry,
10064 : : list_entry) {
10065 : 0 : struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
10066 : 0 : u16 lk_cnt = adv_fltr->lkups_cnt;
10067 : :
10068 [ # # ]: 0 : if (vsi_handle != rinfo->sw_act.vsi_handle)
10069 : 0 : continue;
10070 : 0 : status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
10071 : : &added_entry);
10072 [ # # ]: 0 : if (status)
10073 : : break;
10074 : : }
10075 : : return status;
10076 : : }
10077 : :
10078 : : /**
10079 : : * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
10080 : : * @hw: pointer to the hardware structure
10081 : : * @pi: pointer to port information structure
10082 : : * @vsi_handle: driver VSI handle
10083 : : *
10084 : : * Replays filters for requested VSI via vsi_handle.
10085 : : */
10086 : : enum ice_status
10087 : 0 : ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi,
10088 : : u16 vsi_handle)
10089 : : {
10090 : : struct ice_switch_info *sw;
10091 : : enum ice_status status;
10092 : : u8 i;
10093 : :
10094 : 0 : sw = hw->switch_info;
10095 : :
10096 : : /* Update the recipes that were created */
10097 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
10098 : : struct LIST_HEAD_TYPE *head;
10099 : :
10100 : 0 : head = &sw->recp_list[i].filt_replay_rules;
10101 [ # # ]: 0 : if (!sw->recp_list[i].adv_rule)
10102 : 0 : status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i,
10103 : : head);
10104 : : else
10105 : 0 : status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
10106 [ # # ]: 0 : if (status != ICE_SUCCESS)
10107 : 0 : return status;
10108 : : }
10109 : :
10110 : : return ICE_SUCCESS;
10111 : : }
10112 : :
10113 : : /**
10114 : : * ice_rm_sw_replay_rule_info - helper function to delete filter replay rules
10115 : : * @hw: pointer to the HW struct
10116 : : * @sw: pointer to switch info struct for which function removes filters
10117 : : *
10118 : : * Deletes the filter replay rules for given switch
10119 : : */
10120 : 0 : void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw)
10121 : : {
10122 : : u8 i;
10123 : :
10124 [ # # ]: 0 : if (!sw)
10125 : : return;
10126 : :
10127 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
10128 [ # # ]: 0 : if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) {
10129 : : struct LIST_HEAD_TYPE *l_head;
10130 : :
10131 : 0 : l_head = &sw->recp_list[i].filt_replay_rules;
10132 [ # # ]: 0 : if (!sw->recp_list[i].adv_rule)
10133 : 0 : ice_rem_sw_rule_info(hw, l_head);
10134 : : else
10135 : 0 : ice_rem_adv_rule_info(hw, l_head);
10136 : : }
10137 : : }
10138 : : }
10139 : :
10140 : : /**
10141 : : * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
10142 : : * @hw: pointer to the HW struct
10143 : : *
10144 : : * Deletes the filter replay rules.
10145 : : */
10146 : 0 : void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
10147 : : {
10148 : 0 : ice_rm_sw_replay_rule_info(hw, hw->switch_info);
10149 : 0 : }
|