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_PPP_IPV6_PROTO_ID 0x0057
16 : : #define ICE_IPV4_NVGRE_PROTO_ID 0x002F
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_sw_rule_*
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 : : static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = {
42 : : { ICE_MAC_OFOS, 0 },
43 : : { ICE_ETYPE_OL, 12 },
44 : : { ICE_IPV4_OFOS, 14 },
45 : : { ICE_NVGRE, 34 },
46 : : { ICE_MAC_IL, 42 },
47 : : { ICE_ETYPE_IL, 54 },
48 : : { ICE_IPV4_IL, 56 },
49 : : { ICE_TCP_IL, 76 },
50 : : { ICE_PROTOCOL_LAST, 0 },
51 : : };
52 : :
53 : : static const u8 dummy_gre_tcp_packet[] = {
54 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
55 : : 0x00, 0x00, 0x00, 0x00,
56 : : 0x00, 0x00, 0x00, 0x00,
57 : :
58 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
59 : :
60 : : 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
61 : : 0x00, 0x00, 0x00, 0x00,
62 : : 0x00, 0x2F, 0x00, 0x00,
63 : : 0x00, 0x00, 0x00, 0x00,
64 : : 0x00, 0x00, 0x00, 0x00,
65 : :
66 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
67 : : 0x00, 0x00, 0x00, 0x00,
68 : :
69 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
70 : : 0x00, 0x00, 0x00, 0x00,
71 : : 0x00, 0x00, 0x00, 0x00,
72 : :
73 : : 0x08, 0x00, /* ICE_ETYPE_IL 54 */
74 : :
75 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
76 : : 0x00, 0x00, 0x00, 0x00,
77 : : 0x00, 0x06, 0x00, 0x00,
78 : : 0x00, 0x00, 0x00, 0x00,
79 : : 0x00, 0x00, 0x00, 0x00,
80 : :
81 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */
82 : : 0x00, 0x00, 0x00, 0x00,
83 : : 0x00, 0x00, 0x00, 0x00,
84 : : 0x50, 0x02, 0x20, 0x00,
85 : : 0x00, 0x00, 0x00, 0x00
86 : : };
87 : :
88 : : static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = {
89 : : { ICE_MAC_OFOS, 0 },
90 : : { ICE_ETYPE_OL, 12 },
91 : : { ICE_IPV4_OFOS, 14 },
92 : : { ICE_NVGRE, 34 },
93 : : { ICE_MAC_IL, 42 },
94 : : { ICE_ETYPE_IL, 54 },
95 : : { ICE_IPV4_IL, 56 },
96 : : { ICE_UDP_ILOS, 76 },
97 : : { ICE_PROTOCOL_LAST, 0 },
98 : : };
99 : :
100 : : static const u8 dummy_gre_udp_packet[] = {
101 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
102 : : 0x00, 0x00, 0x00, 0x00,
103 : : 0x00, 0x00, 0x00, 0x00,
104 : :
105 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
106 : :
107 : : 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */
108 : : 0x00, 0x00, 0x00, 0x00,
109 : : 0x00, 0x2F, 0x00, 0x00,
110 : : 0x00, 0x00, 0x00, 0x00,
111 : : 0x00, 0x00, 0x00, 0x00,
112 : :
113 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
114 : : 0x00, 0x00, 0x00, 0x00,
115 : :
116 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
117 : : 0x00, 0x00, 0x00, 0x00,
118 : : 0x00, 0x00, 0x00, 0x00,
119 : :
120 : : 0x08, 0x00, /* ICE_ETYPE_IL 54 */
121 : :
122 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */
123 : : 0x00, 0x00, 0x00, 0x00,
124 : : 0x00, 0x11, 0x00, 0x00,
125 : : 0x00, 0x00, 0x00, 0x00,
126 : : 0x00, 0x00, 0x00, 0x00,
127 : :
128 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */
129 : : 0x00, 0x08, 0x00, 0x00,
130 : : };
131 : :
132 : : static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
133 : : { ICE_MAC_OFOS, 0 },
134 : : { ICE_ETYPE_OL, 12 },
135 : : { ICE_IPV4_OFOS, 14 },
136 : : { ICE_UDP_OF, 34 },
137 : : { ICE_VXLAN, 42 },
138 : : { ICE_GENEVE, 42 },
139 : : { ICE_VXLAN_GPE, 42 },
140 : : { ICE_MAC_IL, 50 },
141 : : { ICE_ETYPE_IL, 62 },
142 : : { ICE_IPV4_IL, 64 },
143 : : { ICE_TCP_IL, 84 },
144 : : { ICE_PROTOCOL_LAST, 0 },
145 : : };
146 : :
147 : : static const u8 dummy_udp_tun_tcp_packet[] = {
148 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
149 : : 0x00, 0x00, 0x00, 0x00,
150 : : 0x00, 0x00, 0x00, 0x00,
151 : :
152 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
153 : :
154 : : 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
155 : : 0x00, 0x01, 0x00, 0x00,
156 : : 0x40, 0x11, 0x00, 0x00,
157 : : 0x00, 0x00, 0x00, 0x00,
158 : : 0x00, 0x00, 0x00, 0x00,
159 : :
160 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
161 : : 0x00, 0x46, 0x00, 0x00,
162 : :
163 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
164 : : 0x00, 0x00, 0x00, 0x00,
165 : :
166 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
167 : : 0x00, 0x00, 0x00, 0x00,
168 : : 0x00, 0x00, 0x00, 0x00,
169 : :
170 : : 0x08, 0x00, /* ICE_ETYPE_IL 62*/
171 : :
172 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
173 : : 0x00, 0x01, 0x00, 0x00,
174 : : 0x40, 0x06, 0x00, 0x00,
175 : : 0x00, 0x00, 0x00, 0x00,
176 : : 0x00, 0x00, 0x00, 0x00,
177 : :
178 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
179 : : 0x00, 0x00, 0x00, 0x00,
180 : : 0x00, 0x00, 0x00, 0x00,
181 : : 0x50, 0x02, 0x20, 0x00,
182 : : 0x00, 0x00, 0x00, 0x00
183 : : };
184 : :
185 : : static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
186 : : { ICE_MAC_OFOS, 0 },
187 : : { ICE_ETYPE_OL, 12 },
188 : : { ICE_IPV4_OFOS, 14 },
189 : : { ICE_UDP_OF, 34 },
190 : : { ICE_VXLAN, 42 },
191 : : { ICE_GENEVE, 42 },
192 : : { ICE_VXLAN_GPE, 42 },
193 : : { ICE_MAC_IL, 50 },
194 : : { ICE_ETYPE_IL, 62 },
195 : : { ICE_IPV4_IL, 64 },
196 : : { ICE_UDP_ILOS, 84 },
197 : : { ICE_PROTOCOL_LAST, 0 },
198 : : };
199 : :
200 : : static const u8 dummy_udp_tun_udp_packet[] = {
201 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
202 : : 0x00, 0x00, 0x00, 0x00,
203 : : 0x00, 0x00, 0x00, 0x00,
204 : :
205 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
206 : :
207 : : 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */
208 : : 0x00, 0x01, 0x00, 0x00,
209 : : 0x00, 0x11, 0x00, 0x00,
210 : : 0x00, 0x00, 0x00, 0x00,
211 : : 0x00, 0x00, 0x00, 0x00,
212 : :
213 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
214 : : 0x00, 0x3a, 0x00, 0x00,
215 : :
216 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
217 : : 0x00, 0x00, 0x00, 0x00,
218 : :
219 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
220 : : 0x00, 0x00, 0x00, 0x00,
221 : : 0x00, 0x00, 0x00, 0x00,
222 : :
223 : : 0x08, 0x00, /* ICE_ETYPE_IL 62 */
224 : :
225 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
226 : : 0x00, 0x01, 0x00, 0x00,
227 : : 0x00, 0x11, 0x00, 0x00,
228 : : 0x00, 0x00, 0x00, 0x00,
229 : : 0x00, 0x00, 0x00, 0x00,
230 : :
231 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
232 : : 0x00, 0x08, 0x00, 0x00,
233 : : };
234 : :
235 : : static const struct ice_dummy_pkt_offsets
236 : : dummy_gre_ipv6_tcp_packet_offsets[] = {
237 : : { ICE_MAC_OFOS, 0 },
238 : : { ICE_ETYPE_OL, 12 },
239 : : { ICE_IPV4_OFOS, 14 },
240 : : { ICE_NVGRE, 34 },
241 : : { ICE_MAC_IL, 42 },
242 : : { ICE_ETYPE_IL, 54 },
243 : : { ICE_IPV6_IL, 56 },
244 : : { ICE_TCP_IL, 96 },
245 : : { ICE_PROTOCOL_LAST, 0 },
246 : : };
247 : :
248 : : static const u8 dummy_gre_ipv6_tcp_packet[] = {
249 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
250 : : 0x00, 0x00, 0x00, 0x00,
251 : : 0x00, 0x00, 0x00, 0x00,
252 : :
253 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
254 : :
255 : : 0x45, 0x00, 0x00, 0x66, /* ICE_IPV4_OFOS 14 */
256 : : 0x00, 0x00, 0x00, 0x00,
257 : : 0x00, 0x2F, 0x00, 0x00,
258 : : 0x00, 0x00, 0x00, 0x00,
259 : : 0x00, 0x00, 0x00, 0x00,
260 : :
261 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
262 : : 0x00, 0x00, 0x00, 0x00,
263 : :
264 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
265 : : 0x00, 0x00, 0x00, 0x00,
266 : : 0x00, 0x00, 0x00, 0x00,
267 : :
268 : : 0x86, 0xdd, /* ICE_ETYPE_IL 54 */
269 : :
270 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
271 : : 0x00, 0x08, 0x06, 0x40,
272 : : 0x00, 0x00, 0x00, 0x00,
273 : : 0x00, 0x00, 0x00, 0x00,
274 : : 0x00, 0x00, 0x00, 0x00,
275 : : 0x00, 0x00, 0x00, 0x00,
276 : : 0x00, 0x00, 0x00, 0x00,
277 : : 0x00, 0x00, 0x00, 0x00,
278 : : 0x00, 0x00, 0x00, 0x00,
279 : : 0x00, 0x00, 0x00, 0x00,
280 : :
281 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */
282 : : 0x00, 0x00, 0x00, 0x00,
283 : : 0x00, 0x00, 0x00, 0x00,
284 : : 0x50, 0x02, 0x20, 0x00,
285 : : 0x00, 0x00, 0x00, 0x00
286 : : };
287 : :
288 : : static const struct ice_dummy_pkt_offsets
289 : : dummy_gre_ipv6_udp_packet_offsets[] = {
290 : : { ICE_MAC_OFOS, 0 },
291 : : { ICE_ETYPE_OL, 12 },
292 : : { ICE_IPV4_OFOS, 14 },
293 : : { ICE_NVGRE, 34 },
294 : : { ICE_MAC_IL, 42 },
295 : : { ICE_ETYPE_IL, 54 },
296 : : { ICE_IPV6_IL, 56 },
297 : : { ICE_UDP_ILOS, 96 },
298 : : { ICE_PROTOCOL_LAST, 0 },
299 : : };
300 : :
301 : : static const u8 dummy_gre_ipv6_udp_packet[] = {
302 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
303 : : 0x00, 0x00, 0x00, 0x00,
304 : : 0x00, 0x00, 0x00, 0x00,
305 : :
306 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
307 : :
308 : : 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */
309 : : 0x00, 0x00, 0x00, 0x00,
310 : : 0x00, 0x2F, 0x00, 0x00,
311 : : 0x00, 0x00, 0x00, 0x00,
312 : : 0x00, 0x00, 0x00, 0x00,
313 : :
314 : : 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */
315 : : 0x00, 0x00, 0x00, 0x00,
316 : :
317 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */
318 : : 0x00, 0x00, 0x00, 0x00,
319 : : 0x00, 0x00, 0x00, 0x00,
320 : :
321 : : 0x86, 0xdd, /* ICE_ETYPE_IL 54 */
322 : :
323 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */
324 : : 0x00, 0x08, 0x11, 0x40,
325 : : 0x00, 0x00, 0x00, 0x00,
326 : : 0x00, 0x00, 0x00, 0x00,
327 : : 0x00, 0x00, 0x00, 0x00,
328 : : 0x00, 0x00, 0x00, 0x00,
329 : : 0x00, 0x00, 0x00, 0x00,
330 : : 0x00, 0x00, 0x00, 0x00,
331 : : 0x00, 0x00, 0x00, 0x00,
332 : : 0x00, 0x00, 0x00, 0x00,
333 : :
334 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */
335 : : 0x00, 0x08, 0x00, 0x00,
336 : : };
337 : :
338 : : static const struct ice_dummy_pkt_offsets
339 : : dummy_udp_tun_ipv6_tcp_packet_offsets[] = {
340 : : { ICE_MAC_OFOS, 0 },
341 : : { ICE_ETYPE_OL, 12 },
342 : : { ICE_IPV4_OFOS, 14 },
343 : : { ICE_UDP_OF, 34 },
344 : : { ICE_VXLAN, 42 },
345 : : { ICE_GENEVE, 42 },
346 : : { ICE_VXLAN_GPE, 42 },
347 : : { ICE_MAC_IL, 50 },
348 : : { ICE_ETYPE_IL, 62 },
349 : : { ICE_IPV6_IL, 64 },
350 : : { ICE_TCP_IL, 104 },
351 : : { ICE_PROTOCOL_LAST, 0 },
352 : : };
353 : :
354 : : static const u8 dummy_udp_tun_ipv6_tcp_packet[] = {
355 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
356 : : 0x00, 0x00, 0x00, 0x00,
357 : : 0x00, 0x00, 0x00, 0x00,
358 : :
359 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
360 : :
361 : : 0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */
362 : : 0x00, 0x01, 0x00, 0x00,
363 : : 0x40, 0x11, 0x00, 0x00,
364 : : 0x00, 0x00, 0x00, 0x00,
365 : : 0x00, 0x00, 0x00, 0x00,
366 : :
367 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
368 : : 0x00, 0x5a, 0x00, 0x00,
369 : :
370 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
371 : : 0x00, 0x00, 0x00, 0x00,
372 : :
373 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
374 : : 0x00, 0x00, 0x00, 0x00,
375 : : 0x00, 0x00, 0x00, 0x00,
376 : :
377 : : 0x86, 0xdd, /* ICE_ETYPE_IL 62 */
378 : :
379 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
380 : : 0x00, 0x08, 0x06, 0x40,
381 : : 0x00, 0x00, 0x00, 0x00,
382 : : 0x00, 0x00, 0x00, 0x00,
383 : : 0x00, 0x00, 0x00, 0x00,
384 : : 0x00, 0x00, 0x00, 0x00,
385 : : 0x00, 0x00, 0x00, 0x00,
386 : : 0x00, 0x00, 0x00, 0x00,
387 : : 0x00, 0x00, 0x00, 0x00,
388 : : 0x00, 0x00, 0x00, 0x00,
389 : :
390 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */
391 : : 0x00, 0x00, 0x00, 0x00,
392 : : 0x00, 0x00, 0x00, 0x00,
393 : : 0x50, 0x02, 0x20, 0x00,
394 : : 0x00, 0x00, 0x00, 0x00
395 : : };
396 : :
397 : : static const struct ice_dummy_pkt_offsets
398 : : dummy_udp_tun_ipv6_udp_packet_offsets[] = {
399 : : { ICE_MAC_OFOS, 0 },
400 : : { ICE_ETYPE_OL, 12 },
401 : : { ICE_IPV4_OFOS, 14 },
402 : : { ICE_UDP_OF, 34 },
403 : : { ICE_VXLAN, 42 },
404 : : { ICE_GENEVE, 42 },
405 : : { ICE_VXLAN_GPE, 42 },
406 : : { ICE_MAC_IL, 50 },
407 : : { ICE_ETYPE_IL, 62 },
408 : : { ICE_IPV6_IL, 64 },
409 : : { ICE_UDP_ILOS, 104 },
410 : : { ICE_PROTOCOL_LAST, 0 },
411 : : };
412 : :
413 : : static const u8 dummy_udp_tun_ipv6_udp_packet[] = {
414 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
415 : : 0x00, 0x00, 0x00, 0x00,
416 : : 0x00, 0x00, 0x00, 0x00,
417 : :
418 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
419 : :
420 : : 0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */
421 : : 0x00, 0x01, 0x00, 0x00,
422 : : 0x00, 0x11, 0x00, 0x00,
423 : : 0x00, 0x00, 0x00, 0x00,
424 : : 0x00, 0x00, 0x00, 0x00,
425 : :
426 : : 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
427 : : 0x00, 0x4e, 0x00, 0x00,
428 : :
429 : : 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
430 : : 0x00, 0x00, 0x00, 0x00,
431 : :
432 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
433 : : 0x00, 0x00, 0x00, 0x00,
434 : : 0x00, 0x00, 0x00, 0x00,
435 : :
436 : : 0x86, 0xdd, /* ICE_ETYPE_IL 62 */
437 : :
438 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */
439 : : 0x00, 0x08, 0x11, 0x40,
440 : : 0x00, 0x00, 0x00, 0x00,
441 : : 0x00, 0x00, 0x00, 0x00,
442 : : 0x00, 0x00, 0x00, 0x00,
443 : : 0x00, 0x00, 0x00, 0x00,
444 : : 0x00, 0x00, 0x00, 0x00,
445 : : 0x00, 0x00, 0x00, 0x00,
446 : : 0x00, 0x00, 0x00, 0x00,
447 : : 0x00, 0x00, 0x00, 0x00,
448 : :
449 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */
450 : : 0x00, 0x08, 0x00, 0x00,
451 : : };
452 : :
453 : : /* offset info for MAC + IPv4 + UDP dummy packet */
454 : : static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
455 : : { ICE_MAC_OFOS, 0 },
456 : : { ICE_ETYPE_OL, 12 },
457 : : { ICE_IPV4_OFOS, 14 },
458 : : { ICE_UDP_ILOS, 34 },
459 : : { ICE_PROTOCOL_LAST, 0 },
460 : : };
461 : :
462 : : /* Dummy packet for MAC + IPv4 + UDP */
463 : : static const u8 dummy_udp_packet[] = {
464 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
465 : : 0x00, 0x00, 0x00, 0x00,
466 : : 0x00, 0x00, 0x00, 0x00,
467 : :
468 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
469 : :
470 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */
471 : : 0x00, 0x01, 0x00, 0x00,
472 : : 0x00, 0x11, 0x00, 0x00,
473 : : 0x00, 0x00, 0x00, 0x00,
474 : : 0x00, 0x00, 0x00, 0x00,
475 : :
476 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */
477 : : 0x00, 0x08, 0x00, 0x00,
478 : :
479 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
480 : : };
481 : :
482 : : /* offset info for MAC + VLAN + IPv4 + UDP dummy packet */
483 : : static const struct ice_dummy_pkt_offsets dummy_vlan_udp_packet_offsets[] = {
484 : : { ICE_MAC_OFOS, 0 },
485 : : { ICE_VLAN_OFOS, 12 },
486 : : { ICE_ETYPE_OL, 16 },
487 : : { ICE_IPV4_OFOS, 18 },
488 : : { ICE_UDP_ILOS, 38 },
489 : : { ICE_PROTOCOL_LAST, 0 },
490 : : };
491 : :
492 : : /* C-tag (801.1Q), IPv4:UDP dummy packet */
493 : : static const u8 dummy_vlan_udp_packet[] = {
494 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
495 : : 0x00, 0x00, 0x00, 0x00,
496 : : 0x00, 0x00, 0x00, 0x00,
497 : :
498 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
499 : :
500 : : 0x08, 0x00, /* ICE_ETYPE_OL 16 */
501 : :
502 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 18 */
503 : : 0x00, 0x01, 0x00, 0x00,
504 : : 0x00, 0x11, 0x00, 0x00,
505 : : 0x00, 0x00, 0x00, 0x00,
506 : : 0x00, 0x00, 0x00, 0x00,
507 : :
508 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 38 */
509 : : 0x00, 0x08, 0x00, 0x00,
510 : :
511 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
512 : : };
513 : :
514 : : /* offset info for MAC + IPv4 + TCP dummy packet */
515 : : static const struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = {
516 : : { ICE_MAC_OFOS, 0 },
517 : : { ICE_ETYPE_OL, 12 },
518 : : { ICE_IPV4_OFOS, 14 },
519 : : { ICE_TCP_IL, 34 },
520 : : { ICE_PROTOCOL_LAST, 0 },
521 : : };
522 : :
523 : : /* Dummy packet for MAC + IPv4 + TCP */
524 : : static const u8 dummy_tcp_packet[] = {
525 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
526 : : 0x00, 0x00, 0x00, 0x00,
527 : : 0x00, 0x00, 0x00, 0x00,
528 : :
529 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
530 : :
531 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */
532 : : 0x00, 0x01, 0x00, 0x00,
533 : : 0x00, 0x06, 0x00, 0x00,
534 : : 0x00, 0x00, 0x00, 0x00,
535 : : 0x00, 0x00, 0x00, 0x00,
536 : :
537 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */
538 : : 0x00, 0x00, 0x00, 0x00,
539 : : 0x00, 0x00, 0x00, 0x00,
540 : : 0x50, 0x00, 0x00, 0x00,
541 : : 0x00, 0x00, 0x00, 0x00,
542 : :
543 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
544 : : };
545 : :
546 : : /* offset info for MAC + VLAN (C-tag, 802.1Q) + IPv4 + TCP dummy packet */
547 : : static const struct ice_dummy_pkt_offsets dummy_vlan_tcp_packet_offsets[] = {
548 : : { ICE_MAC_OFOS, 0 },
549 : : { ICE_VLAN_OFOS, 12 },
550 : : { ICE_ETYPE_OL, 16 },
551 : : { ICE_IPV4_OFOS, 18 },
552 : : { ICE_TCP_IL, 38 },
553 : : { ICE_PROTOCOL_LAST, 0 },
554 : : };
555 : :
556 : : /* C-tag (801.1Q), IPv4:TCP dummy packet */
557 : : static const u8 dummy_vlan_tcp_packet[] = {
558 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
559 : : 0x00, 0x00, 0x00, 0x00,
560 : : 0x00, 0x00, 0x00, 0x00,
561 : :
562 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
563 : :
564 : : 0x08, 0x00, /* ICE_ETYPE_OL 16 */
565 : :
566 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 18 */
567 : : 0x00, 0x01, 0x00, 0x00,
568 : : 0x00, 0x06, 0x00, 0x00,
569 : : 0x00, 0x00, 0x00, 0x00,
570 : : 0x00, 0x00, 0x00, 0x00,
571 : :
572 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 38 */
573 : : 0x00, 0x00, 0x00, 0x00,
574 : : 0x00, 0x00, 0x00, 0x00,
575 : : 0x50, 0x00, 0x00, 0x00,
576 : : 0x00, 0x00, 0x00, 0x00,
577 : :
578 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
579 : : };
580 : :
581 : : static const struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = {
582 : : { ICE_MAC_OFOS, 0 },
583 : : { ICE_ETYPE_OL, 12 },
584 : : { ICE_IPV6_OFOS, 14 },
585 : : { ICE_TCP_IL, 54 },
586 : : { ICE_PROTOCOL_LAST, 0 },
587 : : };
588 : :
589 : : static const u8 dummy_tcp_ipv6_packet[] = {
590 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
591 : : 0x00, 0x00, 0x00, 0x00,
592 : : 0x00, 0x00, 0x00, 0x00,
593 : :
594 : : 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
595 : :
596 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
597 : : 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
598 : : 0x00, 0x00, 0x00, 0x00,
599 : : 0x00, 0x00, 0x00, 0x00,
600 : : 0x00, 0x00, 0x00, 0x00,
601 : : 0x00, 0x00, 0x00, 0x00,
602 : : 0x00, 0x00, 0x00, 0x00,
603 : : 0x00, 0x00, 0x00, 0x00,
604 : : 0x00, 0x00, 0x00, 0x00,
605 : : 0x00, 0x00, 0x00, 0x00,
606 : :
607 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */
608 : : 0x00, 0x00, 0x00, 0x00,
609 : : 0x00, 0x00, 0x00, 0x00,
610 : : 0x50, 0x00, 0x00, 0x00,
611 : : 0x00, 0x00, 0x00, 0x00,
612 : :
613 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
614 : : };
615 : :
616 : : /* C-tag (802.1Q): IPv6 + TCP */
617 : : static const struct ice_dummy_pkt_offsets
618 : : dummy_vlan_tcp_ipv6_packet_offsets[] = {
619 : : { ICE_MAC_OFOS, 0 },
620 : : { ICE_VLAN_OFOS, 12 },
621 : : { ICE_ETYPE_OL, 16 },
622 : : { ICE_IPV6_OFOS, 18 },
623 : : { ICE_TCP_IL, 58 },
624 : : { ICE_PROTOCOL_LAST, 0 },
625 : : };
626 : :
627 : : /* C-tag (802.1Q), IPv6 + TCP dummy packet */
628 : : static const u8 dummy_vlan_tcp_ipv6_packet[] = {
629 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
630 : : 0x00, 0x00, 0x00, 0x00,
631 : : 0x00, 0x00, 0x00, 0x00,
632 : :
633 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
634 : :
635 : : 0x86, 0xDD, /* ICE_ETYPE_OL 16 */
636 : :
637 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
638 : : 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
639 : : 0x00, 0x00, 0x00, 0x00,
640 : : 0x00, 0x00, 0x00, 0x00,
641 : : 0x00, 0x00, 0x00, 0x00,
642 : : 0x00, 0x00, 0x00, 0x00,
643 : : 0x00, 0x00, 0x00, 0x00,
644 : : 0x00, 0x00, 0x00, 0x00,
645 : : 0x00, 0x00, 0x00, 0x00,
646 : : 0x00, 0x00, 0x00, 0x00,
647 : :
648 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 58 */
649 : : 0x00, 0x00, 0x00, 0x00,
650 : : 0x00, 0x00, 0x00, 0x00,
651 : : 0x50, 0x00, 0x00, 0x00,
652 : : 0x00, 0x00, 0x00, 0x00,
653 : :
654 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
655 : : };
656 : :
657 : : /* IPv6 + UDP */
658 : : static const struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = {
659 : : { ICE_MAC_OFOS, 0 },
660 : : { ICE_ETYPE_OL, 12 },
661 : : { ICE_IPV6_OFOS, 14 },
662 : : { ICE_UDP_ILOS, 54 },
663 : : { ICE_PROTOCOL_LAST, 0 },
664 : : };
665 : :
666 : : /* IPv6 + UDP dummy packet */
667 : : static const u8 dummy_udp_ipv6_packet[] = {
668 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
669 : : 0x00, 0x00, 0x00, 0x00,
670 : : 0x00, 0x00, 0x00, 0x00,
671 : :
672 : : 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
673 : :
674 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */
675 : : 0x00, 0x10, 0x11, 0x00, /* Next header UDP */
676 : : 0x00, 0x00, 0x00, 0x00,
677 : : 0x00, 0x00, 0x00, 0x00,
678 : : 0x00, 0x00, 0x00, 0x00,
679 : : 0x00, 0x00, 0x00, 0x00,
680 : : 0x00, 0x00, 0x00, 0x00,
681 : : 0x00, 0x00, 0x00, 0x00,
682 : : 0x00, 0x00, 0x00, 0x00,
683 : : 0x00, 0x00, 0x00, 0x00,
684 : :
685 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */
686 : : 0x00, 0x10, 0x00, 0x00,
687 : :
688 : : 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */
689 : : 0x00, 0x00, 0x00, 0x00,
690 : :
691 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
692 : : };
693 : :
694 : : /* C-tag (802.1Q): IPv6 + UDP */
695 : : static const struct ice_dummy_pkt_offsets
696 : : dummy_vlan_udp_ipv6_packet_offsets[] = {
697 : : { ICE_MAC_OFOS, 0 },
698 : : { ICE_VLAN_OFOS, 12 },
699 : : { ICE_ETYPE_OL, 16 },
700 : : { ICE_IPV6_OFOS, 18 },
701 : : { ICE_UDP_ILOS, 58 },
702 : : { ICE_PROTOCOL_LAST, 0 },
703 : : };
704 : :
705 : : /* C-tag (802.1Q), IPv6 + UDP dummy packet */
706 : : static const u8 dummy_vlan_udp_ipv6_packet[] = {
707 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
708 : : 0x00, 0x00, 0x00, 0x00,
709 : : 0x00, 0x00, 0x00, 0x00,
710 : :
711 : : 0x81, 0x00, 0x00, 0x00,/* ICE_VLAN_OFOS 12 */
712 : :
713 : : 0x86, 0xDD, /* ICE_ETYPE_OL 16 */
714 : :
715 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */
716 : : 0x00, 0x08, 0x11, 0x00, /* Next header UDP */
717 : : 0x00, 0x00, 0x00, 0x00,
718 : : 0x00, 0x00, 0x00, 0x00,
719 : : 0x00, 0x00, 0x00, 0x00,
720 : : 0x00, 0x00, 0x00, 0x00,
721 : : 0x00, 0x00, 0x00, 0x00,
722 : : 0x00, 0x00, 0x00, 0x00,
723 : : 0x00, 0x00, 0x00, 0x00,
724 : : 0x00, 0x00, 0x00, 0x00,
725 : :
726 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 58 */
727 : : 0x00, 0x08, 0x00, 0x00,
728 : :
729 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
730 : : };
731 : :
732 : : /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
733 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = {
734 : : { ICE_MAC_OFOS, 0 },
735 : : { ICE_IPV4_OFOS, 14 },
736 : : { ICE_UDP_OF, 34 },
737 : : { ICE_GTP, 42 },
738 : : { ICE_IPV4_IL, 62 },
739 : : { ICE_TCP_IL, 82 },
740 : : { ICE_PROTOCOL_LAST, 0 },
741 : : };
742 : :
743 : : static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = {
744 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
745 : : 0x00, 0x00, 0x00, 0x00,
746 : : 0x00, 0x00, 0x00, 0x00,
747 : : 0x08, 0x00,
748 : :
749 : : 0x45, 0x00, 0x00, 0x58, /* IP 14 */
750 : : 0x00, 0x00, 0x00, 0x00,
751 : : 0x00, 0x11, 0x00, 0x00,
752 : : 0x00, 0x00, 0x00, 0x00,
753 : : 0x00, 0x00, 0x00, 0x00,
754 : :
755 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
756 : : 0x00, 0x44, 0x00, 0x00,
757 : :
758 : : 0x34, 0xff, 0x00, 0x34, /* GTP-U Header 42 */
759 : : 0x00, 0x00, 0x00, 0x00,
760 : : 0x00, 0x00, 0x00, 0x85,
761 : :
762 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
763 : : 0x00, 0x00, 0x00, 0x00,
764 : :
765 : : 0x45, 0x00, 0x00, 0x28, /* IP 62 */
766 : : 0x00, 0x00, 0x00, 0x00,
767 : : 0x00, 0x06, 0x00, 0x00,
768 : : 0x00, 0x00, 0x00, 0x00,
769 : : 0x00, 0x00, 0x00, 0x00,
770 : :
771 : : 0x00, 0x00, 0x00, 0x00, /* TCP 82 */
772 : : 0x00, 0x00, 0x00, 0x00,
773 : : 0x00, 0x00, 0x00, 0x00,
774 : : 0x50, 0x00, 0x00, 0x00,
775 : : 0x00, 0x00, 0x00, 0x00,
776 : :
777 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
778 : : };
779 : :
780 : : /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */
781 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = {
782 : : { ICE_MAC_OFOS, 0 },
783 : : { ICE_IPV4_OFOS, 14 },
784 : : { ICE_UDP_OF, 34 },
785 : : { ICE_GTP, 42 },
786 : : { ICE_IPV4_IL, 62 },
787 : : { ICE_UDP_ILOS, 82 },
788 : : { ICE_PROTOCOL_LAST, 0 },
789 : : };
790 : :
791 : : static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = {
792 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
793 : : 0x00, 0x00, 0x00, 0x00,
794 : : 0x00, 0x00, 0x00, 0x00,
795 : : 0x08, 0x00,
796 : :
797 : : 0x45, 0x00, 0x00, 0x4c, /* IP 14 */
798 : : 0x00, 0x00, 0x00, 0x00,
799 : : 0x00, 0x11, 0x00, 0x00,
800 : : 0x00, 0x00, 0x00, 0x00,
801 : : 0x00, 0x00, 0x00, 0x00,
802 : :
803 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
804 : : 0x00, 0x38, 0x00, 0x00,
805 : :
806 : : 0x34, 0xff, 0x00, 0x28, /* GTP-U Header 42 */
807 : : 0x00, 0x00, 0x00, 0x00,
808 : : 0x00, 0x00, 0x00, 0x85,
809 : :
810 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
811 : : 0x00, 0x00, 0x00, 0x00,
812 : :
813 : : 0x45, 0x00, 0x00, 0x1c, /* IP 62 */
814 : : 0x00, 0x00, 0x00, 0x00,
815 : : 0x00, 0x11, 0x00, 0x00,
816 : : 0x00, 0x00, 0x00, 0x00,
817 : : 0x00, 0x00, 0x00, 0x00,
818 : :
819 : : 0x00, 0x00, 0x00, 0x00, /* UDP 82 */
820 : : 0x00, 0x08, 0x00, 0x00,
821 : :
822 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
823 : : };
824 : :
825 : : /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */
826 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = {
827 : : { ICE_MAC_OFOS, 0 },
828 : : { ICE_IPV4_OFOS, 14 },
829 : : { ICE_UDP_OF, 34 },
830 : : { ICE_GTP, 42 },
831 : : { ICE_IPV6_IL, 62 },
832 : : { ICE_TCP_IL, 102 },
833 : : { ICE_PROTOCOL_LAST, 0 },
834 : : };
835 : :
836 : : static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = {
837 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
838 : : 0x00, 0x00, 0x00, 0x00,
839 : : 0x00, 0x00, 0x00, 0x00,
840 : : 0x08, 0x00,
841 : :
842 : : 0x45, 0x00, 0x00, 0x6c, /* IP 14 */
843 : : 0x00, 0x00, 0x00, 0x00,
844 : : 0x00, 0x11, 0x00, 0x00,
845 : : 0x00, 0x00, 0x00, 0x00,
846 : : 0x00, 0x00, 0x00, 0x00,
847 : :
848 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
849 : : 0x00, 0x58, 0x00, 0x00,
850 : :
851 : : 0x34, 0xff, 0x00, 0x48, /* GTP-U Header 42 */
852 : : 0x00, 0x00, 0x00, 0x00,
853 : : 0x00, 0x00, 0x00, 0x85,
854 : :
855 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
856 : : 0x00, 0x00, 0x00, 0x00,
857 : :
858 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
859 : : 0x00, 0x14, 0x06, 0x00,
860 : : 0x00, 0x00, 0x00, 0x00,
861 : : 0x00, 0x00, 0x00, 0x00,
862 : : 0x00, 0x00, 0x00, 0x00,
863 : : 0x00, 0x00, 0x00, 0x00,
864 : : 0x00, 0x00, 0x00, 0x00,
865 : : 0x00, 0x00, 0x00, 0x00,
866 : : 0x00, 0x00, 0x00, 0x00,
867 : : 0x00, 0x00, 0x00, 0x00,
868 : :
869 : : 0x00, 0x00, 0x00, 0x00, /* TCP 102 */
870 : : 0x00, 0x00, 0x00, 0x00,
871 : : 0x00, 0x00, 0x00, 0x00,
872 : : 0x50, 0x00, 0x00, 0x00,
873 : : 0x00, 0x00, 0x00, 0x00,
874 : :
875 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
876 : : };
877 : :
878 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_udp_packet_offsets[] = {
879 : : { ICE_MAC_OFOS, 0 },
880 : : { ICE_IPV4_OFOS, 14 },
881 : : { ICE_UDP_OF, 34 },
882 : : { ICE_GTP, 42 },
883 : : { ICE_IPV6_IL, 62 },
884 : : { ICE_UDP_ILOS, 102 },
885 : : { ICE_PROTOCOL_LAST, 0 },
886 : : };
887 : :
888 : : static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = {
889 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
890 : : 0x00, 0x00, 0x00, 0x00,
891 : : 0x00, 0x00, 0x00, 0x00,
892 : : 0x08, 0x00,
893 : :
894 : : 0x45, 0x00, 0x00, 0x60, /* IP 14 */
895 : : 0x00, 0x00, 0x00, 0x00,
896 : : 0x00, 0x11, 0x00, 0x00,
897 : : 0x00, 0x00, 0x00, 0x00,
898 : : 0x00, 0x00, 0x00, 0x00,
899 : :
900 : : 0x00, 0x00, 0x08, 0x68, /* UDP 34 */
901 : : 0x00, 0x4c, 0x00, 0x00,
902 : :
903 : : 0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 42 */
904 : : 0x00, 0x00, 0x00, 0x00,
905 : : 0x00, 0x00, 0x00, 0x85,
906 : :
907 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */
908 : : 0x00, 0x00, 0x00, 0x00,
909 : :
910 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */
911 : : 0x00, 0x08, 0x11, 0x00,
912 : : 0x00, 0x00, 0x00, 0x00,
913 : : 0x00, 0x00, 0x00, 0x00,
914 : : 0x00, 0x00, 0x00, 0x00,
915 : : 0x00, 0x00, 0x00, 0x00,
916 : : 0x00, 0x00, 0x00, 0x00,
917 : : 0x00, 0x00, 0x00, 0x00,
918 : : 0x00, 0x00, 0x00, 0x00,
919 : : 0x00, 0x00, 0x00, 0x00,
920 : :
921 : : 0x00, 0x00, 0x00, 0x00, /* UDP 102 */
922 : : 0x00, 0x08, 0x00, 0x00,
923 : :
924 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
925 : : };
926 : :
927 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = {
928 : : { ICE_MAC_OFOS, 0 },
929 : : { ICE_IPV6_OFOS, 14 },
930 : : { ICE_UDP_OF, 54 },
931 : : { ICE_GTP, 62 },
932 : : { ICE_IPV4_IL, 82 },
933 : : { ICE_TCP_IL, 102 },
934 : : { ICE_PROTOCOL_LAST, 0 },
935 : : };
936 : :
937 : : static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = {
938 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
939 : : 0x00, 0x00, 0x00, 0x00,
940 : : 0x00, 0x00, 0x00, 0x00,
941 : : 0x86, 0xdd,
942 : :
943 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
944 : : 0x00, 0x44, 0x11, 0x00,
945 : : 0x00, 0x00, 0x00, 0x00,
946 : : 0x00, 0x00, 0x00, 0x00,
947 : : 0x00, 0x00, 0x00, 0x00,
948 : : 0x00, 0x00, 0x00, 0x00,
949 : : 0x00, 0x00, 0x00, 0x00,
950 : : 0x00, 0x00, 0x00, 0x00,
951 : : 0x00, 0x00, 0x00, 0x00,
952 : : 0x00, 0x00, 0x00, 0x00,
953 : :
954 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
955 : : 0x00, 0x44, 0x00, 0x00,
956 : :
957 : : 0x34, 0xff, 0x00, 0x34, /* GTP-U Header 62 */
958 : : 0x00, 0x00, 0x00, 0x00,
959 : : 0x00, 0x00, 0x00, 0x85,
960 : :
961 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
962 : : 0x00, 0x00, 0x00, 0x00,
963 : :
964 : : 0x45, 0x00, 0x00, 0x28, /* IP 82 */
965 : : 0x00, 0x00, 0x00, 0x00,
966 : : 0x00, 0x06, 0x00, 0x00,
967 : : 0x00, 0x00, 0x00, 0x00,
968 : : 0x00, 0x00, 0x00, 0x00,
969 : :
970 : : 0x00, 0x00, 0x00, 0x00, /* TCP 102 */
971 : : 0x00, 0x00, 0x00, 0x00,
972 : : 0x00, 0x00, 0x00, 0x00,
973 : : 0x50, 0x00, 0x00, 0x00,
974 : : 0x00, 0x00, 0x00, 0x00,
975 : :
976 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
977 : : };
978 : :
979 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_udp_packet_offsets[] = {
980 : : { ICE_MAC_OFOS, 0 },
981 : : { ICE_IPV6_OFOS, 14 },
982 : : { ICE_UDP_OF, 54 },
983 : : { ICE_GTP, 62 },
984 : : { ICE_IPV4_IL, 82 },
985 : : { ICE_UDP_ILOS, 102 },
986 : : { ICE_PROTOCOL_LAST, 0 },
987 : : };
988 : :
989 : : static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = {
990 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
991 : : 0x00, 0x00, 0x00, 0x00,
992 : : 0x00, 0x00, 0x00, 0x00,
993 : : 0x86, 0xdd,
994 : :
995 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
996 : : 0x00, 0x38, 0x11, 0x00,
997 : : 0x00, 0x00, 0x00, 0x00,
998 : : 0x00, 0x00, 0x00, 0x00,
999 : : 0x00, 0x00, 0x00, 0x00,
1000 : : 0x00, 0x00, 0x00, 0x00,
1001 : : 0x00, 0x00, 0x00, 0x00,
1002 : : 0x00, 0x00, 0x00, 0x00,
1003 : : 0x00, 0x00, 0x00, 0x00,
1004 : : 0x00, 0x00, 0x00, 0x00,
1005 : :
1006 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1007 : : 0x00, 0x38, 0x00, 0x00,
1008 : :
1009 : : 0x34, 0xff, 0x00, 0x28, /* GTP-U Header 62 */
1010 : : 0x00, 0x00, 0x00, 0x00,
1011 : : 0x00, 0x00, 0x00, 0x85,
1012 : :
1013 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1014 : : 0x00, 0x00, 0x00, 0x00,
1015 : :
1016 : : 0x45, 0x00, 0x00, 0x1c, /* IP 82 */
1017 : : 0x00, 0x00, 0x00, 0x00,
1018 : : 0x00, 0x11, 0x00, 0x00,
1019 : : 0x00, 0x00, 0x00, 0x00,
1020 : : 0x00, 0x00, 0x00, 0x00,
1021 : :
1022 : : 0x00, 0x00, 0x00, 0x00, /* UDP 102 */
1023 : : 0x00, 0x08, 0x00, 0x00,
1024 : :
1025 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1026 : : };
1027 : :
1028 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = {
1029 : : { ICE_MAC_OFOS, 0 },
1030 : : { ICE_IPV6_OFOS, 14 },
1031 : : { ICE_UDP_OF, 54 },
1032 : : { ICE_GTP, 62 },
1033 : : { ICE_IPV6_IL, 82 },
1034 : : { ICE_TCP_IL, 122 },
1035 : : { ICE_PROTOCOL_LAST, 0 },
1036 : : };
1037 : :
1038 : : static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = {
1039 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
1040 : : 0x00, 0x00, 0x00, 0x00,
1041 : : 0x00, 0x00, 0x00, 0x00,
1042 : : 0x86, 0xdd,
1043 : :
1044 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1045 : : 0x00, 0x58, 0x11, 0x00,
1046 : : 0x00, 0x00, 0x00, 0x00,
1047 : : 0x00, 0x00, 0x00, 0x00,
1048 : : 0x00, 0x00, 0x00, 0x00,
1049 : : 0x00, 0x00, 0x00, 0x00,
1050 : : 0x00, 0x00, 0x00, 0x00,
1051 : : 0x00, 0x00, 0x00, 0x00,
1052 : : 0x00, 0x00, 0x00, 0x00,
1053 : : 0x00, 0x00, 0x00, 0x00,
1054 : :
1055 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1056 : : 0x00, 0x58, 0x00, 0x00,
1057 : :
1058 : : 0x34, 0xff, 0x00, 0x48, /* GTP-U Header 62 */
1059 : : 0x00, 0x00, 0x00, 0x00,
1060 : : 0x00, 0x00, 0x00, 0x85,
1061 : :
1062 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1063 : : 0x00, 0x00, 0x00, 0x00,
1064 : :
1065 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
1066 : : 0x00, 0x14, 0x06, 0x00,
1067 : : 0x00, 0x00, 0x00, 0x00,
1068 : : 0x00, 0x00, 0x00, 0x00,
1069 : : 0x00, 0x00, 0x00, 0x00,
1070 : : 0x00, 0x00, 0x00, 0x00,
1071 : : 0x00, 0x00, 0x00, 0x00,
1072 : : 0x00, 0x00, 0x00, 0x00,
1073 : : 0x00, 0x00, 0x00, 0x00,
1074 : : 0x00, 0x00, 0x00, 0x00,
1075 : :
1076 : : 0x00, 0x00, 0x00, 0x00, /* TCP 122 */
1077 : : 0x00, 0x00, 0x00, 0x00,
1078 : : 0x00, 0x00, 0x00, 0x00,
1079 : : 0x50, 0x00, 0x00, 0x00,
1080 : : 0x00, 0x00, 0x00, 0x00,
1081 : :
1082 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1083 : : };
1084 : :
1085 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_udp_packet_offsets[] = {
1086 : : { ICE_MAC_OFOS, 0 },
1087 : : { ICE_IPV6_OFOS, 14 },
1088 : : { ICE_UDP_OF, 54 },
1089 : : { ICE_GTP, 62 },
1090 : : { ICE_IPV6_IL, 82 },
1091 : : { ICE_UDP_ILOS, 122 },
1092 : : { ICE_PROTOCOL_LAST, 0 },
1093 : : };
1094 : :
1095 : : static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = {
1096 : : 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */
1097 : : 0x00, 0x00, 0x00, 0x00,
1098 : : 0x00, 0x00, 0x00, 0x00,
1099 : : 0x86, 0xdd,
1100 : :
1101 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */
1102 : : 0x00, 0x4c, 0x11, 0x00,
1103 : : 0x00, 0x00, 0x00, 0x00,
1104 : : 0x00, 0x00, 0x00, 0x00,
1105 : : 0x00, 0x00, 0x00, 0x00,
1106 : : 0x00, 0x00, 0x00, 0x00,
1107 : : 0x00, 0x00, 0x00, 0x00,
1108 : : 0x00, 0x00, 0x00, 0x00,
1109 : : 0x00, 0x00, 0x00, 0x00,
1110 : : 0x00, 0x00, 0x00, 0x00,
1111 : :
1112 : : 0x00, 0x00, 0x08, 0x68, /* UDP 54 */
1113 : : 0x00, 0x4c, 0x00, 0x00,
1114 : :
1115 : : 0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 62 */
1116 : : 0x00, 0x00, 0x00, 0x00,
1117 : : 0x00, 0x00, 0x00, 0x85,
1118 : :
1119 : : 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */
1120 : : 0x00, 0x00, 0x00, 0x00,
1121 : :
1122 : : 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */
1123 : : 0x00, 0x08, 0x11, 0x00,
1124 : : 0x00, 0x00, 0x00, 0x00,
1125 : : 0x00, 0x00, 0x00, 0x00,
1126 : : 0x00, 0x00, 0x00, 0x00,
1127 : : 0x00, 0x00, 0x00, 0x00,
1128 : : 0x00, 0x00, 0x00, 0x00,
1129 : : 0x00, 0x00, 0x00, 0x00,
1130 : : 0x00, 0x00, 0x00, 0x00,
1131 : : 0x00, 0x00, 0x00, 0x00,
1132 : :
1133 : : 0x00, 0x00, 0x00, 0x00, /* UDP 122 */
1134 : : 0x00, 0x08, 0x00, 0x00,
1135 : :
1136 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1137 : : };
1138 : :
1139 : : static const u8 dummy_ipv4_gtpu_ipv4_packet[] = {
1140 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1141 : : 0x00, 0x00, 0x00, 0x00,
1142 : : 0x00, 0x00, 0x00, 0x00,
1143 : : 0x08, 0x00,
1144 : :
1145 : : 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */
1146 : : 0x00, 0x00, 0x40, 0x00,
1147 : : 0x40, 0x11, 0x00, 0x00,
1148 : : 0x00, 0x00, 0x00, 0x00,
1149 : : 0x00, 0x00, 0x00, 0x00,
1150 : :
1151 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
1152 : : 0x00, 0x00, 0x00, 0x00,
1153 : :
1154 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
1155 : : 0x00, 0x00, 0x00, 0x00,
1156 : : 0x00, 0x00, 0x00, 0x85,
1157 : :
1158 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1159 : : 0x00, 0x00, 0x00, 0x00,
1160 : :
1161 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */
1162 : : 0x00, 0x00, 0x40, 0x00,
1163 : : 0x40, 0x00, 0x00, 0x00,
1164 : : 0x00, 0x00, 0x00, 0x00,
1165 : : 0x00, 0x00, 0x00, 0x00,
1166 : : 0x00, 0x00,
1167 : : };
1168 : :
1169 : : static const struct
1170 : : ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_packet_offsets[] = {
1171 : : { ICE_MAC_OFOS, 0 },
1172 : : { ICE_IPV4_OFOS, 14 },
1173 : : { ICE_UDP_OF, 34 },
1174 : : { ICE_GTP, 42 },
1175 : : { ICE_IPV4_IL, 62 },
1176 : : { ICE_PROTOCOL_LAST, 0 },
1177 : : };
1178 : :
1179 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_packet_offsets[] = {
1180 : : { ICE_MAC_OFOS, 0 },
1181 : : { ICE_IPV4_OFOS, 14 },
1182 : : { ICE_UDP_OF, 34 },
1183 : : { ICE_GTP, 42 },
1184 : : { ICE_IPV6_IL, 62 },
1185 : : { ICE_PROTOCOL_LAST, 0 },
1186 : : };
1187 : :
1188 : : static const u8 dummy_ipv4_gtpu_ipv6_packet[] = {
1189 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1190 : : 0x00, 0x00, 0x00, 0x00,
1191 : : 0x00, 0x00, 0x00, 0x00,
1192 : : 0x08, 0x00,
1193 : :
1194 : : 0x45, 0x00, 0x00, 0x58, /* ICE_IPV4_OFOS 14 */
1195 : : 0x00, 0x00, 0x40, 0x00,
1196 : : 0x40, 0x11, 0x00, 0x00,
1197 : : 0x00, 0x00, 0x00, 0x00,
1198 : : 0x00, 0x00, 0x00, 0x00,
1199 : :
1200 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */
1201 : : 0x00, 0x00, 0x00, 0x00,
1202 : :
1203 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */
1204 : : 0x00, 0x00, 0x00, 0x00,
1205 : : 0x00, 0x00, 0x00, 0x85,
1206 : :
1207 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1208 : : 0x00, 0x00, 0x00, 0x00,
1209 : :
1210 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 62 */
1211 : : 0x00, 0x00, 0x3b, 0x00,
1212 : : 0x00, 0x00, 0x00, 0x00,
1213 : : 0x00, 0x00, 0x00, 0x00,
1214 : : 0x00, 0x00, 0x00, 0x00,
1215 : : 0x00, 0x00, 0x00, 0x00,
1216 : : 0x00, 0x00, 0x00, 0x00,
1217 : : 0x00, 0x00, 0x00, 0x00,
1218 : : 0x00, 0x00, 0x00, 0x00,
1219 : : 0x00, 0x00, 0x00, 0x00,
1220 : :
1221 : : 0x00, 0x00,
1222 : : };
1223 : :
1224 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_packet_offsets[] = {
1225 : : { ICE_MAC_OFOS, 0 },
1226 : : { ICE_IPV6_OFOS, 14 },
1227 : : { ICE_UDP_OF, 54 },
1228 : : { ICE_GTP, 62 },
1229 : : { ICE_IPV4_IL, 82 },
1230 : : { ICE_PROTOCOL_LAST, 0 },
1231 : : };
1232 : :
1233 : : static const u8 dummy_ipv6_gtpu_ipv4_packet[] = {
1234 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1235 : : 0x00, 0x00, 0x00, 0x00,
1236 : : 0x00, 0x00, 0x00, 0x00,
1237 : : 0x86, 0xdd,
1238 : :
1239 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1240 : : 0x00, 0x58, 0x11, 0x00, /* Next header UDP*/
1241 : : 0x00, 0x00, 0x00, 0x00,
1242 : : 0x00, 0x00, 0x00, 0x00,
1243 : : 0x00, 0x00, 0x00, 0x00,
1244 : : 0x00, 0x00, 0x00, 0x00,
1245 : : 0x00, 0x00, 0x00, 0x00,
1246 : : 0x00, 0x00, 0x00, 0x00,
1247 : : 0x00, 0x00, 0x00, 0x00,
1248 : : 0x00, 0x00, 0x00, 0x00,
1249 : :
1250 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1251 : : 0x00, 0x00, 0x00, 0x00,
1252 : :
1253 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 62 */
1254 : : 0x00, 0x00, 0x00, 0x00,
1255 : : 0x00, 0x00, 0x00, 0x85,
1256 : :
1257 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1258 : : 0x00, 0x00, 0x00, 0x00,
1259 : :
1260 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 82 */
1261 : : 0x00, 0x00, 0x40, 0x00,
1262 : : 0x40, 0x00, 0x00, 0x00,
1263 : : 0x00, 0x00, 0x00, 0x00,
1264 : : 0x00, 0x00, 0x00, 0x00,
1265 : :
1266 : : 0x00, 0x00,
1267 : : };
1268 : :
1269 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_packet_offsets[] = {
1270 : : { ICE_MAC_OFOS, 0 },
1271 : : { ICE_IPV6_OFOS, 14 },
1272 : : { ICE_UDP_OF, 54 },
1273 : : { ICE_GTP, 62 },
1274 : : { ICE_IPV6_IL, 82 },
1275 : : { ICE_PROTOCOL_LAST, 0 },
1276 : : };
1277 : :
1278 : : static const u8 dummy_ipv6_gtpu_ipv6_packet[] = {
1279 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1280 : : 0x00, 0x00, 0x00, 0x00,
1281 : : 0x00, 0x00, 0x00, 0x00,
1282 : : 0x86, 0xdd,
1283 : :
1284 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1285 : : 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1286 : : 0x00, 0x00, 0x00, 0x00,
1287 : : 0x00, 0x00, 0x00, 0x00,
1288 : : 0x00, 0x00, 0x00, 0x00,
1289 : : 0x00, 0x00, 0x00, 0x00,
1290 : : 0x00, 0x00, 0x00, 0x00,
1291 : : 0x00, 0x00, 0x00, 0x00,
1292 : : 0x00, 0x00, 0x00, 0x00,
1293 : : 0x00, 0x00, 0x00, 0x00,
1294 : :
1295 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1296 : : 0x00, 0x00, 0x00, 0x00,
1297 : :
1298 : : 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 62 */
1299 : : 0x00, 0x00, 0x00, 0x00,
1300 : : 0x00, 0x00, 0x00, 0x85,
1301 : :
1302 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1303 : : 0x00, 0x00, 0x00, 0x00,
1304 : :
1305 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFIL 82 */
1306 : : 0x00, 0x00, 0x3b, 0x00,
1307 : : 0x00, 0x00, 0x00, 0x00,
1308 : : 0x00, 0x00, 0x00, 0x00,
1309 : : 0x00, 0x00, 0x00, 0x00,
1310 : : 0x00, 0x00, 0x00, 0x00,
1311 : : 0x00, 0x00, 0x00, 0x00,
1312 : : 0x00, 0x00, 0x00, 0x00,
1313 : : 0x00, 0x00, 0x00, 0x00,
1314 : : 0x00, 0x00, 0x00, 0x00,
1315 : :
1316 : : 0x00, 0x00,
1317 : : };
1318 : :
1319 : : static const
1320 : : struct ice_dummy_pkt_offsets dummy_ipv4_gtp_no_pay_packet_offsets[] = {
1321 : : { ICE_MAC_OFOS, 0 },
1322 : : { ICE_IPV4_OFOS, 14 },
1323 : : { ICE_UDP_OF, 34 },
1324 : : { ICE_GTP_NO_PAY, 42 },
1325 : : { ICE_PROTOCOL_LAST, 0 },
1326 : : };
1327 : :
1328 : : static const
1329 : : struct ice_dummy_pkt_offsets dummy_ipv6_gtp_no_pay_packet_offsets[] = {
1330 : : { ICE_MAC_OFOS, 0 },
1331 : : { ICE_IPV6_OFOS, 14 },
1332 : : { ICE_UDP_OF, 54 },
1333 : : { ICE_GTP_NO_PAY, 62 },
1334 : : { ICE_PROTOCOL_LAST, 0 },
1335 : : };
1336 : :
1337 : : static const u8 dummy_ipv6_gtp_packet[] = {
1338 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1339 : : 0x00, 0x00, 0x00, 0x00,
1340 : : 0x00, 0x00, 0x00, 0x00,
1341 : : 0x86, 0xdd,
1342 : :
1343 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1344 : : 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/
1345 : : 0x00, 0x00, 0x00, 0x00,
1346 : : 0x00, 0x00, 0x00, 0x00,
1347 : : 0x00, 0x00, 0x00, 0x00,
1348 : : 0x00, 0x00, 0x00, 0x00,
1349 : : 0x00, 0x00, 0x00, 0x00,
1350 : : 0x00, 0x00, 0x00, 0x00,
1351 : : 0x00, 0x00, 0x00, 0x00,
1352 : : 0x00, 0x00, 0x00, 0x00,
1353 : :
1354 : : 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */
1355 : : 0x00, 0x00, 0x00, 0x00,
1356 : :
1357 : : 0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */
1358 : : 0x00, 0x00, 0x00, 0x00,
1359 : :
1360 : : 0x00, 0x00,
1361 : : };
1362 : :
1363 : : static const struct ice_dummy_pkt_offsets dummy_qinq_ipv4_packet_offsets[] = {
1364 : : { ICE_MAC_OFOS, 0 },
1365 : : { ICE_VLAN_EX, 12 },
1366 : : { ICE_VLAN_IN, 16 },
1367 : : { ICE_ETYPE_OL, 20 },
1368 : : { ICE_IPV4_OFOS, 22 },
1369 : : { ICE_PROTOCOL_LAST, 0 },
1370 : : };
1371 : :
1372 : : static const u8 dummy_qinq_ipv4_pkt[] = {
1373 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1374 : : 0x00, 0x00, 0x00, 0x00,
1375 : : 0x00, 0x00, 0x00, 0x00,
1376 : :
1377 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1378 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1379 : : 0x08, 0x00, /* ICE_ETYPE_OL 20 */
1380 : :
1381 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_OFOS 22 */
1382 : : 0x00, 0x01, 0x00, 0x00,
1383 : : 0x00, 0x00, 0x00, 0x00,
1384 : : 0x00, 0x00, 0x00, 0x00,
1385 : : 0x00, 0x00, 0x00, 0x00,
1386 : :
1387 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1388 : : };
1389 : :
1390 : : static const
1391 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv4_udp_packet_offsets[] = {
1392 : : { ICE_MAC_OFOS, 0 },
1393 : : { ICE_VLAN_EX, 12 },
1394 : : { ICE_VLAN_IN, 16 },
1395 : : { ICE_ETYPE_OL, 20 },
1396 : : { ICE_IPV4_OFOS, 22 },
1397 : : { ICE_UDP_ILOS, 42 },
1398 : : { ICE_PROTOCOL_LAST, 0 },
1399 : : };
1400 : :
1401 : : static const u8 dummy_qinq_ipv4_udp_pkt[] = {
1402 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1403 : : 0x00, 0x00, 0x00, 0x00,
1404 : : 0x00, 0x00, 0x00, 0x00,
1405 : :
1406 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1407 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1408 : : 0x08, 0x00, /* ICE_ETYPE_OL 20 */
1409 : :
1410 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
1411 : : 0x00, 0x01, 0x00, 0x00,
1412 : : 0x00, 0x11, 0x00, 0x00,
1413 : : 0x00, 0x00, 0x00, 0x00,
1414 : : 0x00, 0x00, 0x00, 0x00,
1415 : :
1416 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
1417 : : 0x00, 0x08, 0x00, 0x00,
1418 : :
1419 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1420 : : };
1421 : :
1422 : : static const
1423 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv4_tcp_packet_offsets[] = {
1424 : : { ICE_MAC_OFOS, 0 },
1425 : : { ICE_VLAN_EX, 12 },
1426 : : { ICE_VLAN_IN, 16 },
1427 : : { ICE_ETYPE_OL, 20 },
1428 : : { ICE_IPV4_OFOS, 22 },
1429 : : { ICE_TCP_IL, 42 },
1430 : : { ICE_PROTOCOL_LAST, 0 },
1431 : : };
1432 : :
1433 : : static const u8 dummy_qinq_ipv4_tcp_pkt[] = {
1434 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1435 : : 0x00, 0x00, 0x00, 0x00,
1436 : : 0x00, 0x00, 0x00, 0x00,
1437 : :
1438 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1439 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1440 : : 0x08, 0x00, /* ICE_ETYPE_OL 20 */
1441 : :
1442 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */
1443 : : 0x00, 0x01, 0x00, 0x00,
1444 : : 0x00, 0x06, 0x00, 0x00,
1445 : : 0x00, 0x00, 0x00, 0x00,
1446 : : 0x00, 0x00, 0x00, 0x00,
1447 : :
1448 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */
1449 : : 0x00, 0x00, 0x00, 0x00,
1450 : : 0x00, 0x00, 0x00, 0x00,
1451 : : 0x50, 0x00, 0x00, 0x00,
1452 : : 0x00, 0x00, 0x00, 0x00,
1453 : :
1454 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1455 : : };
1456 : :
1457 : : static const struct ice_dummy_pkt_offsets dummy_qinq_ipv6_packet_offsets[] = {
1458 : : { ICE_MAC_OFOS, 0 },
1459 : : { ICE_VLAN_EX, 12 },
1460 : : { ICE_VLAN_IN, 16 },
1461 : : { ICE_ETYPE_OL, 20 },
1462 : : { ICE_IPV6_OFOS, 22 },
1463 : : { ICE_PROTOCOL_LAST, 0 },
1464 : : };
1465 : :
1466 : : static const u8 dummy_qinq_ipv6_pkt[] = {
1467 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1468 : : 0x00, 0x00, 0x00, 0x00,
1469 : : 0x00, 0x00, 0x00, 0x00,
1470 : :
1471 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1472 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1473 : : 0x86, 0xDD, /* ICE_ETYPE_OL 20 */
1474 : :
1475 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1476 : : 0x00, 0x00, 0x3b, 0x00,
1477 : : 0x00, 0x00, 0x00, 0x00,
1478 : : 0x00, 0x00, 0x00, 0x00,
1479 : : 0x00, 0x00, 0x00, 0x00,
1480 : : 0x00, 0x00, 0x00, 0x00,
1481 : : 0x00, 0x00, 0x00, 0x00,
1482 : : 0x00, 0x00, 0x00, 0x00,
1483 : : 0x00, 0x00, 0x00, 0x00,
1484 : : 0x00, 0x00, 0x00, 0x00,
1485 : :
1486 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1487 : : };
1488 : :
1489 : : static const
1490 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv6_udp_packet_offsets[] = {
1491 : : { ICE_MAC_OFOS, 0 },
1492 : : { ICE_VLAN_EX, 12 },
1493 : : { ICE_VLAN_IN, 16 },
1494 : : { ICE_ETYPE_OL, 20 },
1495 : : { ICE_IPV6_OFOS, 22 },
1496 : : { ICE_UDP_ILOS, 62 },
1497 : : { ICE_PROTOCOL_LAST, 0 },
1498 : : };
1499 : :
1500 : : static const u8 dummy_qinq_ipv6_udp_pkt[] = {
1501 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1502 : : 0x00, 0x00, 0x00, 0x00,
1503 : : 0x00, 0x00, 0x00, 0x00,
1504 : :
1505 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1506 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1507 : : 0x86, 0xDD, /* ICE_ETYPE_OL 20 */
1508 : :
1509 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1510 : : 0x00, 0x08, 0x11, 0x00, /* Next header UDP */
1511 : : 0x00, 0x00, 0x00, 0x00,
1512 : : 0x00, 0x00, 0x00, 0x00,
1513 : : 0x00, 0x00, 0x00, 0x00,
1514 : : 0x00, 0x00, 0x00, 0x00,
1515 : : 0x00, 0x00, 0x00, 0x00,
1516 : : 0x00, 0x00, 0x00, 0x00,
1517 : : 0x00, 0x00, 0x00, 0x00,
1518 : : 0x00, 0x00, 0x00, 0x00,
1519 : :
1520 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */
1521 : : 0x00, 0x08, 0x00, 0x00,
1522 : :
1523 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1524 : : };
1525 : :
1526 : : static const
1527 : : struct ice_dummy_pkt_offsets dummy_qinq_ipv6_tcp_packet_offsets[] = {
1528 : : { ICE_MAC_OFOS, 0 },
1529 : : { ICE_VLAN_EX, 12 },
1530 : : { ICE_VLAN_IN, 16 },
1531 : : { ICE_ETYPE_OL, 20 },
1532 : : { ICE_IPV6_OFOS, 22 },
1533 : : { ICE_TCP_IL, 62 },
1534 : : { ICE_PROTOCOL_LAST, 0 },
1535 : : };
1536 : :
1537 : : static const u8 dummy_qinq_ipv6_tcp_pkt[] = {
1538 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1539 : : 0x00, 0x00, 0x00, 0x00,
1540 : : 0x00, 0x00, 0x00, 0x00,
1541 : :
1542 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1543 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1544 : : 0x86, 0xDD, /* ICE_ETYPE_OL 20 */
1545 : :
1546 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
1547 : : 0x00, 0x14, 0x06, 0x00, /* Next header TCP */
1548 : : 0x00, 0x00, 0x00, 0x00,
1549 : : 0x00, 0x00, 0x00, 0x00,
1550 : : 0x00, 0x00, 0x00, 0x00,
1551 : : 0x00, 0x00, 0x00, 0x00,
1552 : : 0x00, 0x00, 0x00, 0x00,
1553 : : 0x00, 0x00, 0x00, 0x00,
1554 : : 0x00, 0x00, 0x00, 0x00,
1555 : : 0x00, 0x00, 0x00, 0x00,
1556 : :
1557 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */
1558 : : 0x00, 0x00, 0x00, 0x00,
1559 : : 0x00, 0x00, 0x00, 0x00,
1560 : : 0x50, 0x00, 0x00, 0x00,
1561 : : 0x00, 0x00, 0x00, 0x00,
1562 : :
1563 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1564 : : };
1565 : :
1566 : : /* offset info for MAC + MPLS dummy packet */
1567 : : static const struct ice_dummy_pkt_offsets dummy_mpls_packet_offsets[] = {
1568 : : { ICE_MAC_OFOS, 0 },
1569 : : { ICE_ETYPE_OL, 12 },
1570 : : { ICE_PROTOCOL_LAST, 0 },
1571 : : };
1572 : :
1573 : : /* Dummy packet for MAC + MPLS */
1574 : : static const u8 dummy_mpls_packet[] = {
1575 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1576 : : 0x00, 0x00, 0x00, 0x00,
1577 : : 0x00, 0x00, 0x00, 0x00,
1578 : :
1579 : : 0x88, 0x47, /* ICE_ETYPE_OL 12 */
1580 : : 0x00, 0x00, 0x01, 0x00,
1581 : :
1582 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1583 : : };
1584 : :
1585 : : static const struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = {
1586 : : { ICE_MAC_OFOS, 0 },
1587 : : { ICE_IPV4_OFOS, 14 },
1588 : : { ICE_UDP_OF, 34 },
1589 : : { ICE_GTP, 42 },
1590 : : { ICE_PROTOCOL_LAST, 0 },
1591 : : };
1592 : :
1593 : : static const u8 dummy_udp_gtp_packet[] = {
1594 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1595 : : 0x00, 0x00, 0x00, 0x00,
1596 : : 0x00, 0x00, 0x00, 0x00,
1597 : : 0x08, 0x00,
1598 : :
1599 : : 0x45, 0x00, 0x00, 0x30, /* ICE_IPV4_OFOS 14 */
1600 : : 0x00, 0x00, 0x00, 0x00,
1601 : : 0x00, 0x11, 0x00, 0x00,
1602 : : 0x00, 0x00, 0x00, 0x00,
1603 : : 0x00, 0x00, 0x00, 0x00,
1604 : :
1605 : : 0x00, 0x00, 0x08, 0x68, /* ICE_UDP_OF 34 */
1606 : : 0x00, 0x1c, 0x00, 0x00,
1607 : :
1608 : : 0x34, 0xff, 0x00, 0x0c, /* ICE_GTP 42 */
1609 : : 0x00, 0x00, 0x00, 0x00,
1610 : : 0x00, 0x00, 0x00, 0x85,
1611 : :
1612 : : 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */
1613 : : 0x00, 0x00, 0x00, 0x00,
1614 : : };
1615 : :
1616 : : static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_offsets[] = {
1617 : : { ICE_MAC_OFOS, 0 },
1618 : : { ICE_VLAN_OFOS, 12 },
1619 : : { ICE_ETYPE_OL, 16 },
1620 : : { ICE_PPPOE, 18 },
1621 : : { ICE_PROTOCOL_LAST, 0 },
1622 : : };
1623 : :
1624 : : static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv4_offsets[] = {
1625 : : { ICE_MAC_OFOS, 0 },
1626 : : { ICE_VLAN_OFOS, 12 },
1627 : : { ICE_ETYPE_OL, 16 },
1628 : : { ICE_PPPOE, 18 },
1629 : : { ICE_IPV4_OFOS, 26 },
1630 : : { ICE_PROTOCOL_LAST, 0 },
1631 : : };
1632 : :
1633 : : static const u8 dummy_pppoe_ipv4_packet[] = {
1634 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1635 : : 0x00, 0x00, 0x00, 0x00,
1636 : : 0x00, 0x00, 0x00, 0x00,
1637 : :
1638 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1639 : :
1640 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1641 : :
1642 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1643 : : 0x00, 0x16,
1644 : :
1645 : : 0x00, 0x21, /* PPP Link Layer 24 */
1646 : :
1647 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 26 */
1648 : : 0x00, 0x00, 0x00, 0x00,
1649 : : 0x00, 0x00, 0x00, 0x00,
1650 : : 0x00, 0x00, 0x00, 0x00,
1651 : : 0x00, 0x00, 0x00, 0x00,
1652 : :
1653 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1654 : : };
1655 : :
1656 : : static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_offsets[] = {
1657 : : { ICE_MAC_OFOS, 0 },
1658 : : { ICE_VLAN_OFOS, 12 },
1659 : : { ICE_ETYPE_OL, 16 },
1660 : : { ICE_PPPOE, 18 },
1661 : : { ICE_IPV6_OFOS, 26 },
1662 : : { ICE_PROTOCOL_LAST, 0 },
1663 : : };
1664 : :
1665 : : static const u8 dummy_pppoe_ipv6_packet[] = {
1666 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1667 : : 0x00, 0x00, 0x00, 0x00,
1668 : : 0x00, 0x00, 0x00, 0x00,
1669 : :
1670 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
1671 : :
1672 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
1673 : :
1674 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
1675 : : 0x00, 0x2a,
1676 : :
1677 : : 0x00, 0x57, /* PPP Link Layer 24 */
1678 : :
1679 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
1680 : : 0x00, 0x00, 0x3b, 0x00,
1681 : : 0x00, 0x00, 0x00, 0x00,
1682 : : 0x00, 0x00, 0x00, 0x00,
1683 : : 0x00, 0x00, 0x00, 0x00,
1684 : : 0x00, 0x00, 0x00, 0x00,
1685 : : 0x00, 0x00, 0x00, 0x00,
1686 : : 0x00, 0x00, 0x00, 0x00,
1687 : : 0x00, 0x00, 0x00, 0x00,
1688 : : 0x00, 0x00, 0x00, 0x00,
1689 : :
1690 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1691 : : };
1692 : :
1693 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_esp_packet_offsets[] = {
1694 : : { ICE_MAC_OFOS, 0 },
1695 : : { ICE_IPV4_OFOS, 14 },
1696 : : { ICE_ESP, 34 },
1697 : : { ICE_PROTOCOL_LAST, 0 },
1698 : : };
1699 : :
1700 : : static const u8 dummy_ipv4_esp_pkt[] = {
1701 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1702 : : 0x00, 0x00, 0x00, 0x00,
1703 : : 0x00, 0x00, 0x00, 0x00,
1704 : : 0x08, 0x00,
1705 : :
1706 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 14 */
1707 : : 0x00, 0x00, 0x40, 0x00,
1708 : : 0x40, 0x32, 0x00, 0x00,
1709 : : 0x00, 0x00, 0x00, 0x00,
1710 : : 0x00, 0x00, 0x00, 0x00,
1711 : :
1712 : : 0x00, 0x00, 0x00, 0x00, /* ICE_ESP 34 */
1713 : : 0x00, 0x00, 0x00, 0x00,
1714 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1715 : : };
1716 : :
1717 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_esp_packet_offsets[] = {
1718 : : { ICE_MAC_OFOS, 0 },
1719 : : { ICE_IPV6_OFOS, 14 },
1720 : : { ICE_ESP, 54 },
1721 : : { ICE_PROTOCOL_LAST, 0 },
1722 : : };
1723 : :
1724 : : static const u8 dummy_ipv6_esp_pkt[] = {
1725 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1726 : : 0x00, 0x00, 0x00, 0x00,
1727 : : 0x00, 0x00, 0x00, 0x00,
1728 : : 0x86, 0xDD,
1729 : :
1730 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1731 : : 0x00, 0x08, 0x32, 0x00, /* Next header ESP */
1732 : : 0x00, 0x00, 0x00, 0x00,
1733 : : 0x00, 0x00, 0x00, 0x00,
1734 : : 0x00, 0x00, 0x00, 0x00,
1735 : : 0x00, 0x00, 0x00, 0x00,
1736 : : 0x00, 0x00, 0x00, 0x00,
1737 : : 0x00, 0x00, 0x00, 0x00,
1738 : : 0x00, 0x00, 0x00, 0x00,
1739 : : 0x00, 0x00, 0x00, 0x00,
1740 : :
1741 : : 0x00, 0x00, 0x00, 0x00, /* ICE_ESP 54 */
1742 : : 0x00, 0x00, 0x00, 0x00,
1743 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1744 : : };
1745 : :
1746 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_ah_packet_offsets[] = {
1747 : : { ICE_MAC_OFOS, 0 },
1748 : : { ICE_IPV4_OFOS, 14 },
1749 : : { ICE_AH, 34 },
1750 : : { ICE_PROTOCOL_LAST, 0 },
1751 : : };
1752 : :
1753 : : static const u8 dummy_ipv4_ah_pkt[] = {
1754 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1755 : : 0x00, 0x00, 0x00, 0x00,
1756 : : 0x00, 0x00, 0x00, 0x00,
1757 : : 0x08, 0x00,
1758 : :
1759 : : 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1760 : : 0x00, 0x00, 0x40, 0x00,
1761 : : 0x40, 0x33, 0x00, 0x00,
1762 : : 0x00, 0x00, 0x00, 0x00,
1763 : : 0x00, 0x00, 0x00, 0x00,
1764 : :
1765 : : 0x00, 0x00, 0x00, 0x00, /* ICE_AH 34 */
1766 : : 0x00, 0x00, 0x00, 0x00,
1767 : : 0x00, 0x00, 0x00, 0x00,
1768 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1769 : : };
1770 : :
1771 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_ah_packet_offsets[] = {
1772 : : { ICE_MAC_OFOS, 0 },
1773 : : { ICE_IPV6_OFOS, 14 },
1774 : : { ICE_AH, 54 },
1775 : : { ICE_PROTOCOL_LAST, 0 },
1776 : : };
1777 : :
1778 : : static const u8 dummy_ipv6_ah_pkt[] = {
1779 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1780 : : 0x00, 0x00, 0x00, 0x00,
1781 : : 0x00, 0x00, 0x00, 0x00,
1782 : : 0x86, 0xDD,
1783 : :
1784 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1785 : : 0x00, 0x0c, 0x33, 0x00, /* Next header AH */
1786 : : 0x00, 0x00, 0x00, 0x00,
1787 : : 0x00, 0x00, 0x00, 0x00,
1788 : : 0x00, 0x00, 0x00, 0x00,
1789 : : 0x00, 0x00, 0x00, 0x00,
1790 : : 0x00, 0x00, 0x00, 0x00,
1791 : : 0x00, 0x00, 0x00, 0x00,
1792 : : 0x00, 0x00, 0x00, 0x00,
1793 : : 0x00, 0x00, 0x00, 0x00,
1794 : :
1795 : : 0x00, 0x00, 0x00, 0x00, /* ICE_AH 54 */
1796 : : 0x00, 0x00, 0x00, 0x00,
1797 : : 0x00, 0x00, 0x00, 0x00,
1798 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1799 : : };
1800 : :
1801 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_nat_packet_offsets[] = {
1802 : : { ICE_MAC_OFOS, 0 },
1803 : : { ICE_IPV4_OFOS, 14 },
1804 : : { ICE_UDP_ILOS, 34 },
1805 : : { ICE_NAT_T, 42 },
1806 : : { ICE_PROTOCOL_LAST, 0 },
1807 : : };
1808 : :
1809 : : static const u8 dummy_ipv4_nat_pkt[] = {
1810 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1811 : : 0x00, 0x00, 0x00, 0x00,
1812 : : 0x00, 0x00, 0x00, 0x00,
1813 : : 0x08, 0x00,
1814 : :
1815 : : 0x45, 0x00, 0x00, 0x24, /* ICE_IPV4_IL 14 */
1816 : : 0x00, 0x00, 0x40, 0x00,
1817 : : 0x40, 0x11, 0x00, 0x00,
1818 : : 0x00, 0x00, 0x00, 0x00,
1819 : : 0x00, 0x00, 0x00, 0x00,
1820 : :
1821 : : 0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 34 */
1822 : : 0x00, 0x00, 0x00, 0x00,
1823 : :
1824 : : 0x00, 0x00, 0x00, 0x00,
1825 : : 0x00, 0x00, 0x00, 0x00,
1826 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1827 : : };
1828 : :
1829 : : static const struct ice_dummy_pkt_offsets dummy_ipv6_nat_packet_offsets[] = {
1830 : : { ICE_MAC_OFOS, 0 },
1831 : : { ICE_IPV6_OFOS, 14 },
1832 : : { ICE_UDP_ILOS, 54 },
1833 : : { ICE_NAT_T, 62 },
1834 : : { ICE_PROTOCOL_LAST, 0 },
1835 : : };
1836 : :
1837 : : static const u8 dummy_ipv6_nat_pkt[] = {
1838 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1839 : : 0x00, 0x00, 0x00, 0x00,
1840 : : 0x00, 0x00, 0x00, 0x00,
1841 : : 0x86, 0xDD,
1842 : :
1843 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */
1844 : : 0x00, 0x10, 0x11, 0x00, /* Next header NAT_T */
1845 : : 0x00, 0x00, 0x00, 0x00,
1846 : : 0x00, 0x00, 0x00, 0x00,
1847 : : 0x00, 0x00, 0x00, 0x00,
1848 : : 0x00, 0x00, 0x00, 0x00,
1849 : : 0x00, 0x00, 0x00, 0x00,
1850 : : 0x00, 0x00, 0x00, 0x00,
1851 : : 0x00, 0x00, 0x00, 0x00,
1852 : : 0x00, 0x00, 0x00, 0x00,
1853 : :
1854 : : 0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 54 */
1855 : : 0x00, 0x00, 0x00, 0x00,
1856 : :
1857 : : 0x00, 0x00, 0x00, 0x00,
1858 : : 0x00, 0x00, 0x00, 0x00,
1859 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1860 : :
1861 : : };
1862 : :
1863 : : static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = {
1864 : : { ICE_MAC_OFOS, 0 },
1865 : : { ICE_VLAN_EX, 12 },
1866 : : { ICE_VLAN_IN, 16 },
1867 : : { ICE_ETYPE_OL, 20 },
1868 : : { ICE_PPPOE, 22 },
1869 : : { ICE_PROTOCOL_LAST, 0 },
1870 : : };
1871 : :
1872 : : static const
1873 : : struct ice_dummy_pkt_offsets dummy_qinq_pppoe_ipv4_packet_offsets[] = {
1874 : : { ICE_MAC_OFOS, 0 },
1875 : : { ICE_VLAN_EX, 12 },
1876 : : { ICE_VLAN_IN, 16 },
1877 : : { ICE_ETYPE_OL, 20 },
1878 : : { ICE_PPPOE, 22 },
1879 : : { ICE_IPV4_OFOS, 30 },
1880 : : { ICE_PROTOCOL_LAST, 0 },
1881 : : };
1882 : :
1883 : : static const u8 dummy_qinq_pppoe_ipv4_pkt[] = {
1884 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1885 : : 0x00, 0x00, 0x00, 0x00,
1886 : : 0x00, 0x00, 0x00, 0x00,
1887 : :
1888 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1889 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1890 : : 0x88, 0x64, /* ICE_ETYPE_OL 20 */
1891 : :
1892 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
1893 : : 0x00, 0x16,
1894 : :
1895 : : 0x00, 0x21, /* PPP Link Layer 28 */
1896 : :
1897 : : 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_OFOS 30 */
1898 : : 0x00, 0x00, 0x00, 0x00,
1899 : : 0x00, 0x00, 0x00, 0x00,
1900 : : 0x00, 0x00, 0x00, 0x00,
1901 : : 0x00, 0x00, 0x00, 0x00,
1902 : :
1903 : : 0x00, 0x00, /* 2 bytes for 4 byte alignment */
1904 : : };
1905 : :
1906 : : static const
1907 : : struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_ipv6_offsets[] = {
1908 : : { ICE_MAC_OFOS, 0 },
1909 : : { ICE_VLAN_EX, 12 },
1910 : : { ICE_VLAN_IN, 16 },
1911 : : { ICE_ETYPE_OL, 20 },
1912 : : { ICE_PPPOE, 22 },
1913 : : { ICE_IPV6_OFOS, 30 },
1914 : : { ICE_PROTOCOL_LAST, 0 },
1915 : : };
1916 : :
1917 : : static const u8 dummy_qinq_pppoe_ipv6_packet[] = {
1918 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1919 : : 0x00, 0x00, 0x00, 0x00,
1920 : : 0x00, 0x00, 0x00, 0x00,
1921 : :
1922 : : 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */
1923 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */
1924 : : 0x88, 0x64, /* ICE_ETYPE_OL 20 */
1925 : :
1926 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */
1927 : : 0x00, 0x2a,
1928 : :
1929 : : 0x00, 0x57, /* PPP Link Layer 28*/
1930 : :
1931 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 30 */
1932 : : 0x00, 0x00, 0x3b, 0x00,
1933 : : 0x00, 0x00, 0x00, 0x00,
1934 : : 0x00, 0x00, 0x00, 0x00,
1935 : : 0x00, 0x00, 0x00, 0x00,
1936 : : 0x00, 0x00, 0x00, 0x00,
1937 : : 0x00, 0x00, 0x00, 0x00,
1938 : : 0x00, 0x00, 0x00, 0x00,
1939 : : 0x00, 0x00, 0x00, 0x00,
1940 : : 0x00, 0x00, 0x00, 0x00,
1941 : :
1942 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
1943 : : };
1944 : :
1945 : : static const struct ice_dummy_pkt_offsets dummy_ipv4_l2tpv3_packet_offsets[] = {
1946 : : { ICE_MAC_OFOS, 0 },
1947 : : { ICE_ETYPE_OL, 12 },
1948 : : { ICE_IPV4_OFOS, 14 },
1949 : : { ICE_L2TPV3, 34 },
1950 : : { ICE_PROTOCOL_LAST, 0 },
1951 : : };
1952 : :
1953 : : static const u8 dummy_ipv4_l2tpv3_pkt[] = {
1954 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1955 : : 0x00, 0x00, 0x00, 0x00,
1956 : : 0x00, 0x00, 0x00, 0x00,
1957 : :
1958 : : 0x08, 0x00, /* ICE_ETYPE_OL 12 */
1959 : :
1960 : : 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
1961 : : 0x00, 0x00, 0x40, 0x00,
1962 : : 0x40, 0x73, 0x00, 0x00,
1963 : : 0x00, 0x00, 0x00, 0x00,
1964 : : 0x00, 0x00, 0x00, 0x00,
1965 : :
1966 : : 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
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_ipv6_l2tpv3_packet_offsets[] = {
1973 : : { ICE_MAC_OFOS, 0 },
1974 : : { ICE_ETYPE_OL, 12 },
1975 : : { ICE_IPV6_OFOS, 14 },
1976 : : { ICE_L2TPV3, 54 },
1977 : : { ICE_PROTOCOL_LAST, 0 },
1978 : : };
1979 : :
1980 : : static const u8 dummy_ipv6_l2tpv3_pkt[] = {
1981 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
1982 : : 0x00, 0x00, 0x00, 0x00,
1983 : : 0x00, 0x00, 0x00, 0x00,
1984 : :
1985 : : 0x86, 0xDD, /* ICE_ETYPE_OL 12 */
1986 : :
1987 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
1988 : : 0x00, 0x0c, 0x73, 0x40,
1989 : : 0x00, 0x00, 0x00, 0x00,
1990 : : 0x00, 0x00, 0x00, 0x00,
1991 : : 0x00, 0x00, 0x00, 0x00,
1992 : : 0x00, 0x00, 0x00, 0x00,
1993 : : 0x00, 0x00, 0x00, 0x00,
1994 : : 0x00, 0x00, 0x00, 0x00,
1995 : : 0x00, 0x00, 0x00, 0x00,
1996 : : 0x00, 0x00, 0x00, 0x00,
1997 : :
1998 : : 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
1999 : : 0x00, 0x00, 0x00, 0x00,
2000 : : 0x00, 0x00, 0x00, 0x00,
2001 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2002 : : };
2003 : :
2004 : : static const
2005 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_tcp_packet_offsets[] = {
2006 : : { ICE_MAC_OFOS, 0 },
2007 : : { ICE_VLAN_OFOS, 12 },
2008 : : { ICE_ETYPE_OL, 16 },
2009 : : { ICE_PPPOE, 18 },
2010 : : { ICE_IPV4_OFOS, 26 },
2011 : : { ICE_TCP_IL, 46 },
2012 : : { ICE_PROTOCOL_LAST, 0 },
2013 : : };
2014 : :
2015 : : static const u8 dummy_pppoe_ipv4_tcp_packet[] = {
2016 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2017 : : 0x00, 0x00, 0x00, 0x00,
2018 : : 0x00, 0x00, 0x00, 0x00,
2019 : :
2020 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
2021 : :
2022 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
2023 : :
2024 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
2025 : : 0x00, 0x16,
2026 : :
2027 : : 0x00, 0x21, /* PPP Link Layer 24 */
2028 : :
2029 : : 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 26 */
2030 : : 0x00, 0x01, 0x00, 0x00,
2031 : : 0x00, 0x06, 0x00, 0x00,
2032 : : 0x00, 0x00, 0x00, 0x00,
2033 : : 0x00, 0x00, 0x00, 0x00,
2034 : :
2035 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 46 */
2036 : : 0x00, 0x00, 0x00, 0x00,
2037 : : 0x00, 0x00, 0x00, 0x00,
2038 : : 0x50, 0x00, 0x00, 0x00,
2039 : : 0x00, 0x00, 0x00, 0x00,
2040 : :
2041 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2042 : : };
2043 : :
2044 : : static const
2045 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_udp_packet_offsets[] = {
2046 : : { ICE_MAC_OFOS, 0 },
2047 : : { ICE_VLAN_OFOS, 12 },
2048 : : { ICE_ETYPE_OL, 16 },
2049 : : { ICE_PPPOE, 18 },
2050 : : { ICE_IPV4_OFOS, 26 },
2051 : : { ICE_UDP_ILOS, 46 },
2052 : : { ICE_PROTOCOL_LAST, 0 },
2053 : : };
2054 : :
2055 : : static const u8 dummy_pppoe_ipv4_udp_packet[] = {
2056 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2057 : : 0x00, 0x00, 0x00, 0x00,
2058 : : 0x00, 0x00, 0x00, 0x00,
2059 : :
2060 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
2061 : :
2062 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
2063 : :
2064 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
2065 : : 0x00, 0x16,
2066 : :
2067 : : 0x00, 0x21, /* PPP Link Layer 24 */
2068 : :
2069 : : 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 26 */
2070 : : 0x00, 0x01, 0x00, 0x00,
2071 : : 0x00, 0x11, 0x00, 0x00,
2072 : : 0x00, 0x00, 0x00, 0x00,
2073 : : 0x00, 0x00, 0x00, 0x00,
2074 : :
2075 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 46 */
2076 : : 0x00, 0x08, 0x00, 0x00,
2077 : :
2078 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2079 : : };
2080 : :
2081 : : static const
2082 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv6_tcp_packet_offsets[] = {
2083 : : { ICE_MAC_OFOS, 0 },
2084 : : { ICE_VLAN_OFOS, 12 },
2085 : : { ICE_ETYPE_OL, 16 },
2086 : : { ICE_PPPOE, 18 },
2087 : : { ICE_IPV6_OFOS, 26 },
2088 : : { ICE_TCP_IL, 66 },
2089 : : { ICE_PROTOCOL_LAST, 0 },
2090 : : };
2091 : :
2092 : : static const u8 dummy_pppoe_ipv6_tcp_packet[] = {
2093 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2094 : : 0x00, 0x00, 0x00, 0x00,
2095 : : 0x00, 0x00, 0x00, 0x00,
2096 : :
2097 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
2098 : :
2099 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
2100 : :
2101 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
2102 : : 0x00, 0x2a,
2103 : :
2104 : : 0x00, 0x57, /* PPP Link Layer 24 */
2105 : :
2106 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
2107 : : 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
2108 : : 0x00, 0x00, 0x00, 0x00,
2109 : : 0x00, 0x00, 0x00, 0x00,
2110 : : 0x00, 0x00, 0x00, 0x00,
2111 : : 0x00, 0x00, 0x00, 0x00,
2112 : : 0x00, 0x00, 0x00, 0x00,
2113 : : 0x00, 0x00, 0x00, 0x00,
2114 : : 0x00, 0x00, 0x00, 0x00,
2115 : : 0x00, 0x00, 0x00, 0x00,
2116 : :
2117 : : 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 66 */
2118 : : 0x00, 0x00, 0x00, 0x00,
2119 : : 0x00, 0x00, 0x00, 0x00,
2120 : : 0x50, 0x00, 0x00, 0x00,
2121 : : 0x00, 0x00, 0x00, 0x00,
2122 : :
2123 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2124 : : };
2125 : :
2126 : : static const
2127 : : struct ice_dummy_pkt_offsets dummy_pppoe_ipv6_udp_packet_offsets[] = {
2128 : : { ICE_MAC_OFOS, 0 },
2129 : : { ICE_VLAN_OFOS, 12 },
2130 : : { ICE_ETYPE_OL, 16 },
2131 : : { ICE_PPPOE, 18 },
2132 : : { ICE_IPV6_OFOS, 26 },
2133 : : { ICE_UDP_ILOS, 66 },
2134 : : { ICE_PROTOCOL_LAST, 0 },
2135 : : };
2136 : :
2137 : : static const u8 dummy_pppoe_ipv6_udp_packet[] = {
2138 : : 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
2139 : : 0x00, 0x00, 0x00, 0x00,
2140 : : 0x00, 0x00, 0x00, 0x00,
2141 : :
2142 : : 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */
2143 : :
2144 : : 0x88, 0x64, /* ICE_ETYPE_OL 16 */
2145 : :
2146 : : 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */
2147 : : 0x00, 0x2a,
2148 : :
2149 : : 0x00, 0x57, /* PPP Link Layer 24 */
2150 : :
2151 : : 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */
2152 : : 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
2153 : : 0x00, 0x00, 0x00, 0x00,
2154 : : 0x00, 0x00, 0x00, 0x00,
2155 : : 0x00, 0x00, 0x00, 0x00,
2156 : : 0x00, 0x00, 0x00, 0x00,
2157 : : 0x00, 0x00, 0x00, 0x00,
2158 : : 0x00, 0x00, 0x00, 0x00,
2159 : : 0x00, 0x00, 0x00, 0x00,
2160 : : 0x00, 0x00, 0x00, 0x00,
2161 : :
2162 : : 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 66 */
2163 : : 0x00, 0x08, 0x00, 0x00,
2164 : :
2165 : : 0x00, 0x00, /* 2 bytes for 4 bytes alignment */
2166 : : };
2167 : :
2168 : : /* this is a recipe to profile association bitmap */
2169 : : static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES],
2170 : : ICE_MAX_NUM_PROFILES);
2171 : :
2172 : : /* this is a profile to recipe association bitmap */
2173 : : static ice_declare_bitmap(profile_to_recipe[ICE_MAX_NUM_PROFILES],
2174 : : ICE_MAX_NUM_RECIPES);
2175 : :
2176 : : static void ice_get_recp_to_prof_map(struct ice_hw *hw);
2177 : :
2178 : : /**
2179 : : * ice_collect_result_idx - copy result index values
2180 : : * @buf: buffer that contains the result index
2181 : : * @recp: the recipe struct to copy data into
2182 : : */
2183 : : static void ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
2184 : : struct ice_sw_recipe *recp)
2185 : : {
2186 [ # # ]: 0 : if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2187 : 0 : ice_set_bit(buf->content.result_indx &
2188 : 0 : ~ICE_AQ_RECIPE_RESULT_EN, recp->res_idxs);
2189 : : }
2190 : :
2191 : : static struct ice_prof_type_entry ice_prof_type_tbl[ICE_GTPU_PROFILE] = {
2192 : : { ICE_PROFID_IPV4_GTPU_IPV4_OTHER, ICE_SW_TUN_IPV4_GTPU_IPV4},
2193 : : { ICE_PROFID_IPV4_GTPU_IPV4_UDP, ICE_SW_TUN_IPV4_GTPU_IPV4_UDP},
2194 : : { ICE_PROFID_IPV4_GTPU_IPV4_TCP, ICE_SW_TUN_IPV4_GTPU_IPV4_TCP},
2195 : : { ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, ICE_SW_TUN_IPV4_GTPU_EH_IPV4},
2196 : : { ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP},
2197 : : { ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP},
2198 : : { ICE_PROFID_IPV4_GTPU_IPV6_OTHER, ICE_SW_TUN_IPV4_GTPU_IPV6},
2199 : : { ICE_PROFID_IPV4_GTPU_IPV6_UDP, ICE_SW_TUN_IPV4_GTPU_IPV6_UDP},
2200 : : { ICE_PROFID_IPV4_GTPU_IPV6_TCP, ICE_SW_TUN_IPV4_GTPU_IPV6_TCP},
2201 : : { ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, ICE_SW_TUN_IPV4_GTPU_EH_IPV6},
2202 : : { ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP},
2203 : : { ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP},
2204 : : { ICE_PROFID_IPV6_GTPU_IPV4_OTHER, ICE_SW_TUN_IPV6_GTPU_IPV4},
2205 : : { ICE_PROFID_IPV6_GTPU_IPV4_UDP, ICE_SW_TUN_IPV6_GTPU_IPV4_UDP},
2206 : : { ICE_PROFID_IPV6_GTPU_IPV4_TCP, ICE_SW_TUN_IPV6_GTPU_IPV4_TCP},
2207 : : { ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, ICE_SW_TUN_IPV6_GTPU_EH_IPV4},
2208 : : { ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP},
2209 : : { ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP},
2210 : : { ICE_PROFID_IPV6_GTPU_IPV6_OTHER, ICE_SW_TUN_IPV6_GTPU_IPV6},
2211 : : { ICE_PROFID_IPV6_GTPU_IPV6_UDP, ICE_SW_TUN_IPV6_GTPU_IPV6_UDP},
2212 : : { ICE_PROFID_IPV6_GTPU_IPV6_TCP, ICE_SW_TUN_IPV6_GTPU_IPV6_TCP},
2213 : : { ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, ICE_SW_TUN_IPV6_GTPU_EH_IPV6},
2214 : : { ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP},
2215 : : { ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP},
2216 : : };
2217 : :
2218 : : /**
2219 : : * ice_get_tun_type_for_recipe - get tunnel type for the recipe
2220 : : * @rid: recipe ID that we are populating
2221 : : * @vlan: flag of vlan protocol
2222 : : */
2223 : 0 : static enum ice_sw_tunnel_type ice_get_tun_type_for_recipe(u8 rid, bool vlan)
2224 : : {
2225 : 0 : u8 udp_tun_profile[12] = {10, 11, 12, 16, 17, 18, 22, 23, 24, 25, 26,
2226 : : 27};
2227 : 0 : u8 gre_profile[12] = {13, 14, 15, 19, 20, 21, 28, 29, 30, 31, 32, 33};
2228 : 0 : u8 pppoe_profile[7] = {34, 35, 36, 37, 38, 39, 40};
2229 : 0 : u8 non_tun_profile[6] = {4, 5, 6, 7, 8, 9};
2230 : : enum ice_sw_tunnel_type tun_type;
2231 : : u16 i, j, profile_num = 0;
2232 : : u16 k;
2233 : : bool udp_tun_valid = false;
2234 : : bool non_tun_valid = false;
2235 : : bool pppoe_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 (udp_tun_profile[i] == j)
2253 : : udp_tun_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 && udp_tun_valid)
2278 : : tun_type = ICE_SW_TUN_UDP;
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 : (udp_tun_valid || gre_valid || gtp_valid || pppoe_valid))
2287 : : tun_type = ICE_SW_TUN_AND_NON_TUN;
2288 [ # # ]: 0 : else if (non_tun_valid && !udp_tun_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 int
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 : : u8 fv_word_idx = 0;
2442 : : bool vlan = false;
2443 : : u16 sub_recps;
2444 : : int status;
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 [ # # ]: 0 : if (!num_recps) {
2461 : : status = ICE_ERR_PARAM;
2462 : 0 : goto err_unroll;
2463 : : }
2464 : :
2465 : : /* Get recipe to profile map so that we can get the fv from lkups that
2466 : : * we read for a recipe from FW. Since we want to minimize the number of
2467 : : * times we make this FW call, just make one call and cache the copy
2468 : : * until a new recipe is added. This operation is only required the
2469 : : * first time to get the changes from FW. Then to search existing
2470 : : * entries we don't need to update the cache again until another recipe
2471 : : * gets added.
2472 : : */
2473 [ # # ]: 0 : if (*refresh_required) {
2474 : 0 : ice_get_recp_to_prof_map(hw);
2475 : 0 : *refresh_required = false;
2476 : : }
2477 : :
2478 : : /* Start populating all the entries for recps[rid] based on lkups from
2479 : : * firmware. Note that we are only creating the root recipe in our
2480 : : * database.
2481 : : */
2482 : 0 : lkup_exts = &recps[rid].lkup_exts;
2483 : :
2484 [ # # ]: 0 : for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2485 : 0 : struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2486 : : struct ice_recp_grp_entry *rg_entry;
2487 : 0 : u8 i, prof, idx, prot = 0;
2488 : : bool is_root;
2489 : 0 : u16 off = 0;
2490 : :
2491 : : rg_entry = (struct ice_recp_grp_entry *)
2492 : 0 : ice_malloc(hw, sizeof(*rg_entry));
2493 [ # # ]: 0 : if (!rg_entry) {
2494 : : status = ICE_ERR_NO_MEMORY;
2495 : 0 : goto err_unroll;
2496 : : }
2497 : :
2498 : 0 : idx = root_bufs.recipe_indx;
2499 : 0 : is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2500 : :
2501 : : /* Mark all result indices in this chain */
2502 [ # # ]: 0 : if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2503 : 0 : ice_set_bit(root_bufs.content.result_indx &
2504 : : ~ICE_AQ_RECIPE_RESULT_EN, result_bm);
2505 : :
2506 : : /* get the first profile that is associated with rid */
2507 : 0 : prof = (u8)ice_find_first_bit(recipe_to_profile[idx],
2508 : : ICE_MAX_NUM_PROFILES);
2509 [ # # ]: 0 : for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2510 : 0 : u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2511 : :
2512 : 0 : rg_entry->fv_idx[i] = lkup_indx;
2513 : 0 : rg_entry->fv_mask[i] =
2514 : 0 : LE16_TO_CPU(root_bufs.content.mask[i + 1]);
2515 : :
2516 : : /* If the recipe is a chained recipe then all its
2517 : : * child recipe's result will have a result index.
2518 : : * To fill fv_words we should not use those result
2519 : : * index, we only need the protocol ids and offsets.
2520 : : * We will skip all the fv_idx which stores result
2521 : : * index in them. We also need to skip any fv_idx which
2522 : : * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a
2523 : : * valid offset value.
2524 : : */
2525 [ # # ]: 0 : if (ice_is_bit_set(hw->switch_info->prof_res_bm[prof],
2526 [ # # ]: 0 : rg_entry->fv_idx[i]) ||
2527 [ # # ]: 0 : rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2528 : : rg_entry->fv_idx[i] == 0)
2529 : 0 : continue;
2530 : :
2531 : 0 : ice_find_prot_off(hw, ICE_BLK_SW, prof,
2532 : : rg_entry->fv_idx[i], &prot, &off);
2533 : 0 : lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2534 : 0 : lkup_exts->fv_words[fv_word_idx].off = off;
2535 : 0 : lkup_exts->field_mask[fv_word_idx] =
2536 : 0 : rg_entry->fv_mask[i];
2537 [ # # # # ]: 0 : if (prot == ICE_META_DATA_ID_HW &&
2538 : : off == ICE_TUN_FLAG_MDID_OFF(1))
2539 : : vlan = true;
2540 : 0 : fv_word_idx++;
2541 : : }
2542 : : /* populate rg_list with the data from the child entry of this
2543 : : * recipe
2544 : : */
2545 [ # # ]: 0 : LIST_ADD(&rg_entry->l_entry, &recps[rid].rg_list);
2546 : :
2547 : : /* Propagate some data to the recipe database */
2548 : 0 : recps[idx].is_root = is_root;
2549 : 0 : recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2550 [ # # ]: 0 : ice_zero_bitmap(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2551 [ # # ]: 0 : if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2552 : 0 : recps[idx].chain_idx = root_bufs.content.result_indx &
2553 : : ~ICE_AQ_RECIPE_RESULT_EN;
2554 : : ice_set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2555 : : } else {
2556 : 0 : recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2557 : : }
2558 : :
2559 [ # # ]: 0 : if (!is_root)
2560 : 0 : continue;
2561 : :
2562 : : /* Only do the following for root recipes entries */
2563 [ # # ]: 0 : ice_memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2564 : : sizeof(recps[idx].r_bitmap), ICE_NONDMA_TO_NONDMA);
2565 : 0 : recps[idx].root_rid = root_bufs.content.rid &
2566 : : ~ICE_AQ_RECIPE_ID_IS_ROOT;
2567 : 0 : recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2568 : : }
2569 : :
2570 : : /* Complete initialization of the root recipe entry */
2571 : 0 : lkup_exts->n_val_words = fv_word_idx;
2572 : 0 : recps[rid].big_recp = (num_recps > 1);
2573 : 0 : recps[rid].n_grp_count = (u8)num_recps;
2574 : 0 : recps[rid].tun_type = ice_get_tun_type_for_recipe(rid, vlan);
2575 [ # # ]: 0 : if (recps[rid].root_buf)
2576 : 0 : ice_free(hw, recps[rid].root_buf);
2577 : :
2578 : 0 : recps[rid].root_buf = (struct ice_aqc_recipe_data_elem *)
2579 : 0 : ice_memdup(hw, tmp, recps[rid].n_grp_count *
2580 : : sizeof(*recps[rid].root_buf), ICE_NONDMA_TO_NONDMA);
2581 [ # # ]: 0 : if (!recps[rid].root_buf)
2582 : 0 : goto err_unroll;
2583 : :
2584 : : /* Copy result indexes */
2585 : 0 : ice_cp_bitmap(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2586 : 0 : recps[rid].recp_created = true;
2587 : :
2588 : 0 : err_unroll:
2589 : 0 : ice_free(hw, tmp);
2590 : 0 : return status;
2591 : : }
2592 : :
2593 : : /**
2594 : : * ice_get_recp_to_prof_map - updates recipe to profile mapping
2595 : : * @hw: pointer to hardware structure
2596 : : *
2597 : : * This function is used to populate recipe_to_profile matrix where index to
2598 : : * this array is the recipe ID and the element is the mapping of which profiles
2599 : : * is this recipe mapped to.
2600 : : */
2601 : 0 : static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2602 : : {
2603 : : ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2604 : : u16 i;
2605 : :
2606 [ # # ]: 0 : for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2607 : : u16 j;
2608 : :
2609 : 0 : ice_zero_bitmap(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2610 : : ice_zero_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
2611 [ # # ]: 0 : if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
2612 : 0 : continue;
2613 : 0 : ice_cp_bitmap(profile_to_recipe[i], r_bitmap,
2614 : : ICE_MAX_NUM_RECIPES);
2615 [ # # ]: 0 : ice_for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2616 : 0 : ice_set_bit(i, recipe_to_profile[j]);
2617 : : }
2618 : 0 : }
2619 : :
2620 : : static bool
2621 : : ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle);
2622 : :
2623 : : /**
2624 : : * ice_init_def_sw_recp - initialize the recipe book keeping tables
2625 : : * @hw: pointer to the HW struct
2626 : : * @recp_list: pointer to sw recipe list
2627 : : *
2628 : : * Allocate memory for the entire recipe table and initialize the structures/
2629 : : * entries corresponding to basic recipes.
2630 : : */
2631 : : int
2632 : 0 : ice_init_def_sw_recp(struct ice_hw *hw, struct ice_sw_recipe **recp_list)
2633 : : {
2634 : : struct ice_sw_recipe *recps;
2635 : : u8 i;
2636 : :
2637 : : recps = (struct ice_sw_recipe *)
2638 : 0 : ice_calloc(hw, ICE_MAX_NUM_RECIPES, sizeof(*recps));
2639 [ # # ]: 0 : if (!recps)
2640 : : return ICE_ERR_NO_MEMORY;
2641 : :
2642 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
2643 : 0 : recps[i].root_rid = i;
2644 : 0 : INIT_LIST_HEAD(&recps[i].filt_rules);
2645 : 0 : INIT_LIST_HEAD(&recps[i].filt_replay_rules);
2646 : 0 : INIT_LIST_HEAD(&recps[i].rg_list);
2647 : : ice_init_lock(&recps[i].filt_rule_lock);
2648 : : }
2649 : :
2650 : 0 : *recp_list = recps;
2651 : :
2652 : 0 : return 0;
2653 : : }
2654 : :
2655 : : /**
2656 : : * ice_aq_get_sw_cfg - get switch configuration
2657 : : * @hw: pointer to the hardware structure
2658 : : * @buf: pointer to the result buffer
2659 : : * @buf_size: length of the buffer available for response
2660 : : * @req_desc: pointer to requested descriptor
2661 : : * @num_elems: pointer to number of elements
2662 : : * @cd: pointer to command details structure or NULL
2663 : : *
2664 : : * Get switch configuration (0x0200) to be placed in buf.
2665 : : * This admin command returns information such as initial VSI/port number
2666 : : * and switch ID it belongs to.
2667 : : *
2668 : : * NOTE: *req_desc is both an input/output parameter.
2669 : : * The caller of this function first calls this function with *request_desc set
2670 : : * to 0. If the response from f/w has *req_desc set to 0, all the switch
2671 : : * configuration information has been returned; if non-zero (meaning not all
2672 : : * the information was returned), the caller should call this function again
2673 : : * with *req_desc set to the previous value returned by f/w to get the
2674 : : * next block of switch configuration information.
2675 : : *
2676 : : * *num_elems is output only parameter. This reflects the number of elements
2677 : : * in response buffer. The caller of this function to use *num_elems while
2678 : : * parsing the response buffer.
2679 : : */
2680 : : static int
2681 : 0 : ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
2682 : : u16 buf_size, u16 *req_desc, u16 *num_elems,
2683 : : struct ice_sq_cd *cd)
2684 : : {
2685 : : struct ice_aqc_get_sw_cfg *cmd;
2686 : : struct ice_aq_desc desc;
2687 : : int status;
2688 : :
2689 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
2690 : : cmd = &desc.params.get_sw_conf;
2691 : 0 : cmd->element = CPU_TO_LE16(*req_desc);
2692 : :
2693 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
2694 [ # # ]: 0 : if (!status) {
2695 : 0 : *req_desc = LE16_TO_CPU(cmd->element);
2696 : 0 : *num_elems = LE16_TO_CPU(cmd->num_elems);
2697 : : }
2698 : :
2699 : 0 : return status;
2700 : : }
2701 : :
2702 : : /**
2703 : : * ice_alloc_rss_global_lut - allocate a RSS global LUT
2704 : : * @hw: pointer to the HW struct
2705 : : * @shared_res: true to allocate as a shared resource and false to allocate as a dedicated resource
2706 : : * @global_lut_id: output parameter for the RSS global LUT's ID
2707 : : */
2708 : 0 : int ice_alloc_rss_global_lut(struct ice_hw *hw, bool shared_res, u16 *global_lut_id)
2709 : : {
2710 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2711 : : int status;
2712 : : u16 buf_len;
2713 : :
2714 : : buf_len = ice_struct_size(sw_buf, elem, 1);
2715 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2716 [ # # ]: 0 : if (!sw_buf)
2717 : : return ICE_ERR_NO_MEMORY;
2718 : :
2719 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
2720 [ # # ]: 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH |
2721 : : (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2722 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2723 : :
2724 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, ice_aqc_opc_alloc_res, NULL);
2725 [ # # ]: 0 : if (status) {
2726 [ # # # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Failed to allocate %s RSS global LUT, status %d\n",
2727 : : shared_res ? "shared" : "dedicated", status);
2728 : 0 : goto ice_alloc_global_lut_exit;
2729 : : }
2730 : :
2731 : 0 : *global_lut_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
2732 : :
2733 : 0 : ice_alloc_global_lut_exit:
2734 : 0 : ice_free(hw, sw_buf);
2735 : 0 : return status;
2736 : : }
2737 : :
2738 : : /**
2739 : : * ice_free_sw_marker_lg - free a switch marker large action
2740 : : * @hw: pointer to the HW struct
2741 : : * @marker_lg_id: ID of the marker large action to free
2742 : : * @sw_marker: sw marker to tag the Rx descriptor with
2743 : : */
2744 : : static int
2745 : 0 : ice_free_sw_marker_lg(struct ice_hw *hw, u16 marker_lg_id, u32 sw_marker)
2746 : : {
2747 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2748 : : u16 buf_len, num_elems = 1;
2749 : : int status;
2750 : :
2751 : : buf_len = ice_struct_size(sw_buf, elem, num_elems);
2752 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2753 [ # # ]: 0 : if (!sw_buf)
2754 : : return ICE_ERR_NO_MEMORY;
2755 : :
2756 : 0 : sw_buf->num_elems = CPU_TO_LE16(num_elems);
2757 [ # # ]: 0 : if (sw_marker <= 0xFFFF)
2758 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_1);
2759 : : else
2760 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_2);
2761 : :
2762 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(marker_lg_id);
2763 : :
2764 : 0 : status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len,
2765 : : ice_aqc_opc_free_res, NULL);
2766 [ # # ]: 0 : if (status)
2767 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Failed to free sw marker lg %d, status %d\n",
2768 : : marker_lg_id, status);
2769 : :
2770 : 0 : ice_free(hw, sw_buf);
2771 : 0 : return status;
2772 : : }
2773 : :
2774 : : /**
2775 : : * ice_free_rss_global_lut - free a RSS global LUT
2776 : : * @hw: pointer to the HW struct
2777 : : * @global_lut_id: ID of the RSS global LUT to free
2778 : : */
2779 : 0 : int ice_free_rss_global_lut(struct ice_hw *hw, u16 global_lut_id)
2780 : : {
2781 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2782 : : u16 buf_len, num_elems = 1;
2783 : : int status;
2784 : :
2785 : : buf_len = ice_struct_size(sw_buf, elem, num_elems);
2786 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2787 [ # # ]: 0 : if (!sw_buf)
2788 : : return ICE_ERR_NO_MEMORY;
2789 : :
2790 : 0 : sw_buf->num_elems = CPU_TO_LE16(num_elems);
2791 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH);
2792 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(global_lut_id);
2793 : :
2794 : 0 : status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len, ice_aqc_opc_free_res, NULL);
2795 [ # # ]: 0 : if (status)
2796 [ # # ]: 0 : ice_debug(hw, ICE_DBG_RES, "Failed to free RSS global LUT %d, status %d\n",
2797 : : global_lut_id, status);
2798 : :
2799 : 0 : ice_free(hw, sw_buf);
2800 : 0 : return status;
2801 : : }
2802 : :
2803 : : /**
2804 : : * ice_alloc_sw - allocate resources specific to switch
2805 : : * @hw: pointer to the HW struct
2806 : : * @ena_stats: true to turn on VEB stats
2807 : : * @shared_res: true for shared resource, false for dedicated resource
2808 : : * @sw_id: switch ID returned
2809 : : * @counter_id: VEB counter ID returned
2810 : : *
2811 : : * allocates switch resources (SWID and VEB counter) (0x0208)
2812 : : */
2813 : : int
2814 : 0 : ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id,
2815 : : u16 *counter_id)
2816 : : {
2817 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
2818 : : struct ice_aqc_res_elem *sw_ele;
2819 : : u16 buf_len;
2820 : : int status;
2821 : :
2822 : : buf_len = ice_struct_size(sw_buf, elem, 1);
2823 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2824 [ # # ]: 0 : if (!sw_buf)
2825 : : return ICE_ERR_NO_MEMORY;
2826 : :
2827 : : /* Prepare buffer for switch ID.
2828 : : * The number of resource entries in buffer is passed as 1 since only a
2829 : : * single switch/VEB instance is allocated, and hence a single sw_id
2830 : : * is requested.
2831 : : */
2832 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
2833 [ # # ]: 0 : sw_buf->res_type =
2834 : : CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID |
2835 : : (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED :
2836 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED));
2837 : :
2838 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2839 : : ice_aqc_opc_alloc_res, NULL);
2840 : :
2841 [ # # ]: 0 : if (status)
2842 : 0 : goto ice_alloc_sw_exit;
2843 : :
2844 : : sw_ele = &sw_buf->elem[0];
2845 : 0 : *sw_id = LE16_TO_CPU(sw_ele->e.sw_resp);
2846 : :
2847 [ # # ]: 0 : if (ena_stats) {
2848 : : /* Prepare buffer for VEB Counter */
2849 : : enum ice_adminq_opc opc = ice_aqc_opc_alloc_res;
2850 : : struct ice_aqc_alloc_free_res_elem *counter_buf;
2851 : : struct ice_aqc_res_elem *counter_ele;
2852 : :
2853 : : counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2854 : 0 : ice_malloc(hw, buf_len);
2855 [ # # ]: 0 : if (!counter_buf) {
2856 : : status = ICE_ERR_NO_MEMORY;
2857 : 0 : goto ice_alloc_sw_exit;
2858 : : }
2859 : :
2860 : : /* The number of resource entries in buffer is passed as 1 since
2861 : : * only a single switch/VEB instance is allocated, and hence a
2862 : : * single VEB counter is requested.
2863 : : */
2864 : 0 : counter_buf->num_elems = CPU_TO_LE16(1);
2865 : 0 : counter_buf->res_type =
2866 : : CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER |
2867 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED);
2868 : 0 : status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2869 : : opc, NULL);
2870 : :
2871 [ # # ]: 0 : if (status) {
2872 : 0 : ice_free(hw, counter_buf);
2873 : 0 : goto ice_alloc_sw_exit;
2874 : : }
2875 : : counter_ele = &counter_buf->elem[0];
2876 : 0 : *counter_id = LE16_TO_CPU(counter_ele->e.sw_resp);
2877 : 0 : ice_free(hw, counter_buf);
2878 : : }
2879 : :
2880 : 0 : ice_alloc_sw_exit:
2881 : 0 : ice_free(hw, sw_buf);
2882 : 0 : return status;
2883 : : }
2884 : :
2885 : : /**
2886 : : * ice_free_sw - free resources specific to switch
2887 : : * @hw: pointer to the HW struct
2888 : : * @sw_id: switch ID returned
2889 : : * @counter_id: VEB counter ID returned
2890 : : *
2891 : : * free switch resources (SWID and VEB counter) (0x0209)
2892 : : *
2893 : : * NOTE: This function frees multiple resources. It continues
2894 : : * releasing other resources even after it encounters error.
2895 : : * The error code returned is the last error it encountered.
2896 : : */
2897 : 0 : int ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id)
2898 : : {
2899 : : struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf;
2900 : : int status, ret_status;
2901 : : u16 buf_len;
2902 : :
2903 : : buf_len = ice_struct_size(sw_buf, elem, 1);
2904 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
2905 [ # # ]: 0 : if (!sw_buf)
2906 : : return ICE_ERR_NO_MEMORY;
2907 : :
2908 : : /* Prepare buffer to free for switch ID res.
2909 : : * The number of resource entries in buffer is passed as 1 since only a
2910 : : * single switch/VEB instance is freed, and hence a single sw_id
2911 : : * is released.
2912 : : */
2913 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
2914 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID);
2915 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id);
2916 : :
2917 : 0 : ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2918 : : ice_aqc_opc_free_res, NULL);
2919 : :
2920 [ # # ]: 0 : if (ret_status)
2921 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n");
2922 : :
2923 : : /* Prepare buffer to free for VEB Counter resource */
2924 : : counter_buf = (struct ice_aqc_alloc_free_res_elem *)
2925 : 0 : ice_malloc(hw, buf_len);
2926 [ # # ]: 0 : if (!counter_buf) {
2927 : 0 : ice_free(hw, sw_buf);
2928 : 0 : return ICE_ERR_NO_MEMORY;
2929 : : }
2930 : :
2931 : : /* The number of resource entries in buffer is passed as 1 since only a
2932 : : * single switch/VEB instance is freed, and hence a single VEB counter
2933 : : * is released
2934 : : */
2935 : 0 : counter_buf->num_elems = CPU_TO_LE16(1);
2936 : 0 : counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER);
2937 : 0 : counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
2938 : :
2939 : 0 : status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len,
2940 : : ice_aqc_opc_free_res, NULL);
2941 [ # # ]: 0 : if (status) {
2942 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "VEB counter resource could not be freed\n");
2943 : : ret_status = status;
2944 : : }
2945 : :
2946 : 0 : ice_free(hw, counter_buf);
2947 : 0 : ice_free(hw, sw_buf);
2948 : 0 : return ret_status;
2949 : : }
2950 : :
2951 : : /**
2952 : : * ice_aq_add_vsi
2953 : : * @hw: pointer to the HW struct
2954 : : * @vsi_ctx: pointer to a VSI context struct
2955 : : * @cd: pointer to command details structure or NULL
2956 : : *
2957 : : * Add a VSI context to the hardware (0x0210)
2958 : : */
2959 : : int
2960 : 0 : ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
2961 : : struct ice_sq_cd *cd)
2962 : : {
2963 : : struct ice_aqc_add_update_free_vsi_resp *res;
2964 : : struct ice_aqc_add_get_update_free_vsi *cmd;
2965 : : struct ice_aq_desc desc;
2966 : : int status;
2967 : :
2968 : : cmd = &desc.params.vsi_cmd;
2969 : : res = &desc.params.add_update_free_vsi_res;
2970 : :
2971 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
2972 : :
2973 [ # # ]: 0 : if (!vsi_ctx->alloc_from_pool)
2974 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num |
2975 : : ICE_AQ_VSI_IS_VALID);
2976 : :
2977 : 0 : cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags);
2978 : :
2979 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
2980 : :
2981 : 0 : status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
2982 : : sizeof(vsi_ctx->info), cd);
2983 : :
2984 [ # # ]: 0 : if (!status) {
2985 : 0 : vsi_ctx->vsi_num = LE16_TO_CPU(res->vsi_num) & ICE_AQ_VSI_NUM_M;
2986 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(res->vsi_used);
2987 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(res->vsi_free);
2988 : : }
2989 : :
2990 : 0 : return status;
2991 : : }
2992 : :
2993 : : /**
2994 : : * ice_aq_free_vsi
2995 : : * @hw: pointer to the HW struct
2996 : : * @vsi_ctx: pointer to a VSI context struct
2997 : : * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
2998 : : * @cd: pointer to command details structure or NULL
2999 : : *
3000 : : * Free VSI context info from hardware (0x0213)
3001 : : */
3002 : : int
3003 : 0 : ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
3004 : : bool keep_vsi_alloc, struct ice_sq_cd *cd)
3005 : : {
3006 : : struct ice_aqc_add_update_free_vsi_resp *resp;
3007 : : struct ice_aqc_add_get_update_free_vsi *cmd;
3008 : : struct ice_aq_desc desc;
3009 : : int status;
3010 : :
3011 : : cmd = &desc.params.vsi_cmd;
3012 : : resp = &desc.params.add_update_free_vsi_res;
3013 : :
3014 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
3015 : :
3016 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
3017 [ # # ]: 0 : if (keep_vsi_alloc)
3018 : 0 : cmd->cmd_flags = CPU_TO_LE16(ICE_AQ_VSI_KEEP_ALLOC);
3019 : :
3020 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3021 [ # # ]: 0 : if (!status) {
3022 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
3023 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
3024 : : }
3025 : :
3026 : 0 : return status;
3027 : : }
3028 : :
3029 : : /**
3030 : : * ice_aq_update_vsi
3031 : : * @hw: pointer to the HW struct
3032 : : * @vsi_ctx: pointer to a VSI context struct
3033 : : * @cd: pointer to command details structure or NULL
3034 : : *
3035 : : * Update VSI context in the hardware (0x0211)
3036 : : */
3037 : : int
3038 : 0 : ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
3039 : : struct ice_sq_cd *cd)
3040 : : {
3041 : : struct ice_aqc_add_update_free_vsi_resp *resp;
3042 : : struct ice_aqc_add_get_update_free_vsi *cmd;
3043 : : struct ice_aq_desc desc;
3044 : : int status;
3045 : :
3046 : : cmd = &desc.params.vsi_cmd;
3047 : : resp = &desc.params.add_update_free_vsi_res;
3048 : :
3049 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
3050 : :
3051 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
3052 : :
3053 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3054 : :
3055 : 0 : status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
3056 : : sizeof(vsi_ctx->info), cd);
3057 : :
3058 [ # # ]: 0 : if (!status) {
3059 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
3060 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
3061 : : }
3062 : :
3063 : 0 : return status;
3064 : : }
3065 : :
3066 : : /**
3067 : : * ice_is_vsi_valid - check whether the VSI is valid or not
3068 : : * @hw: pointer to the HW struct
3069 : : * @vsi_handle: VSI handle
3070 : : *
3071 : : * check whether the VSI is valid or not
3072 : : */
3073 : 0 : bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
3074 : : {
3075 [ # # # # ]: 0 : return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
3076 : : }
3077 : :
3078 : : /**
3079 : : * ice_get_hw_vsi_num - return the HW VSI number
3080 : : * @hw: pointer to the HW struct
3081 : : * @vsi_handle: VSI handle
3082 : : *
3083 : : * return the HW VSI number
3084 : : * Caution: call this function only if VSI is valid (ice_is_vsi_valid)
3085 : : */
3086 : 0 : u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
3087 : : {
3088 : 0 : return hw->vsi_ctx[vsi_handle]->vsi_num;
3089 : : }
3090 : :
3091 : : /**
3092 : : * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle
3093 : : * @hw: pointer to the HW struct
3094 : : * @vsi_handle: VSI handle
3095 : : *
3096 : : * return the VSI context entry for a given VSI handle
3097 : : */
3098 : 0 : struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
3099 : : {
3100 [ # # ]: 0 : return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
3101 : : }
3102 : :
3103 : : /**
3104 : : * ice_save_vsi_ctx - save the VSI context for a given VSI handle
3105 : : * @hw: pointer to the HW struct
3106 : : * @vsi_handle: VSI handle
3107 : : * @vsi: VSI context pointer
3108 : : *
3109 : : * save the VSI context entry for a given VSI handle
3110 : : */
3111 : : static void
3112 : : ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
3113 : : {
3114 : 0 : hw->vsi_ctx[vsi_handle] = vsi;
3115 : 0 : }
3116 : :
3117 : : /**
3118 : : * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs
3119 : : * @hw: pointer to the HW struct
3120 : : * @vsi_handle: VSI handle
3121 : : */
3122 : 0 : void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
3123 : : {
3124 : : struct ice_vsi_ctx *vsi;
3125 : : u8 i;
3126 : :
3127 : 0 : vsi = ice_get_vsi_ctx(hw, vsi_handle);
3128 [ # # ]: 0 : if (!vsi)
3129 : : return;
3130 [ # # ]: 0 : ice_for_each_traffic_class(i) {
3131 [ # # ]: 0 : if (vsi->lan_q_ctx[i]) {
3132 : 0 : ice_free(hw, vsi->lan_q_ctx[i]);
3133 : 0 : vsi->lan_q_ctx[i] = NULL;
3134 : : }
3135 : : }
3136 : : }
3137 : :
3138 : : /**
3139 : : * ice_clear_vsi_ctx - clear the VSI context entry
3140 : : * @hw: pointer to the HW struct
3141 : : * @vsi_handle: VSI handle
3142 : : *
3143 : : * clear the VSI context entry
3144 : : */
3145 : 0 : static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
3146 : : {
3147 : : struct ice_vsi_ctx *vsi;
3148 : :
3149 : 0 : vsi = ice_get_vsi_ctx(hw, vsi_handle);
3150 [ # # ]: 0 : if (vsi) {
3151 : 0 : ice_clear_vsi_q_ctx(hw, vsi_handle);
3152 : 0 : ice_free(hw, vsi);
3153 : 0 : hw->vsi_ctx[vsi_handle] = NULL;
3154 : : }
3155 : 0 : }
3156 : :
3157 : : /**
3158 : : * ice_clear_all_vsi_ctx - clear all the VSI context entries
3159 : : * @hw: pointer to the HW struct
3160 : : */
3161 : 0 : void ice_clear_all_vsi_ctx(struct ice_hw *hw)
3162 : : {
3163 : : u16 i;
3164 : :
3165 [ # # ]: 0 : for (i = 0; i < ICE_MAX_VSI; i++)
3166 : 0 : ice_clear_vsi_ctx(hw, i);
3167 : 0 : }
3168 : :
3169 : : /**
3170 : : * ice_add_vsi - add VSI context to the hardware and VSI handle list
3171 : : * @hw: pointer to the HW struct
3172 : : * @vsi_handle: unique VSI handle provided by drivers
3173 : : * @vsi_ctx: pointer to a VSI context struct
3174 : : * @cd: pointer to command details structure or NULL
3175 : : *
3176 : : * Add a VSI context to the hardware also add it into the VSI handle list.
3177 : : * If this function gets called after reset for existing VSIs then update
3178 : : * with the new HW VSI number in the corresponding VSI handle list entry.
3179 : : */
3180 : : int
3181 : 0 : ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
3182 : : struct ice_sq_cd *cd)
3183 : : {
3184 : : struct ice_vsi_ctx *tmp_vsi_ctx;
3185 : : int status;
3186 : :
3187 [ # # ]: 0 : if (vsi_handle >= ICE_MAX_VSI)
3188 : : return ICE_ERR_PARAM;
3189 : 0 : status = ice_aq_add_vsi(hw, vsi_ctx, cd);
3190 [ # # ]: 0 : if (status)
3191 : : return status;
3192 : 0 : tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
3193 [ # # ]: 0 : if (!tmp_vsi_ctx) {
3194 : : /* Create a new VSI context */
3195 : : tmp_vsi_ctx = (struct ice_vsi_ctx *)
3196 : 0 : ice_malloc(hw, sizeof(*tmp_vsi_ctx));
3197 [ # # ]: 0 : if (!tmp_vsi_ctx) {
3198 : 0 : ice_aq_free_vsi(hw, vsi_ctx, false, cd);
3199 : 0 : return ICE_ERR_NO_MEMORY;
3200 : : }
3201 : 0 : *tmp_vsi_ctx = *vsi_ctx;
3202 : :
3203 : : ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
3204 : : } else {
3205 : : /* update with new HW VSI num */
3206 : 0 : tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
3207 : : }
3208 : :
3209 : : return 0;
3210 : : }
3211 : :
3212 : : /**
3213 : : * ice_free_vsi- free VSI context from hardware and VSI handle list
3214 : : * @hw: pointer to the HW struct
3215 : : * @vsi_handle: unique VSI handle
3216 : : * @vsi_ctx: pointer to a VSI context struct
3217 : : * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources
3218 : : * @cd: pointer to command details structure or NULL
3219 : : *
3220 : : * Free VSI context info from hardware as well as from VSI handle list
3221 : : */
3222 : : int
3223 : 0 : ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
3224 : : bool keep_vsi_alloc, struct ice_sq_cd *cd)
3225 : : {
3226 : : int status;
3227 : :
3228 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
3229 : : return ICE_ERR_PARAM;
3230 : 0 : vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
3231 : 0 : status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
3232 [ # # ]: 0 : if (!status)
3233 : 0 : ice_clear_vsi_ctx(hw, vsi_handle);
3234 : : return status;
3235 : : }
3236 : :
3237 : : /**
3238 : : * ice_update_vsi
3239 : : * @hw: pointer to the HW struct
3240 : : * @vsi_handle: unique VSI handle
3241 : : * @vsi_ctx: pointer to a VSI context struct
3242 : : * @cd: pointer to command details structure or NULL
3243 : : *
3244 : : * Update VSI context in the hardware
3245 : : */
3246 : : int
3247 : 0 : ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
3248 : : struct ice_sq_cd *cd)
3249 : : {
3250 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
3251 : : return ICE_ERR_PARAM;
3252 : 0 : vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
3253 : 0 : return ice_aq_update_vsi(hw, vsi_ctx, cd);
3254 : : }
3255 : :
3256 : : /**
3257 : : * ice_aq_get_vsi_params
3258 : : * @hw: pointer to the HW struct
3259 : : * @vsi_ctx: pointer to a VSI context struct
3260 : : * @cd: pointer to command details structure or NULL
3261 : : *
3262 : : * Get VSI context info from hardware (0x0212)
3263 : : */
3264 : : int
3265 : 0 : ice_aq_get_vsi_params(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
3266 : : struct ice_sq_cd *cd)
3267 : : {
3268 : : struct ice_aqc_add_get_update_free_vsi *cmd;
3269 : : struct ice_aqc_get_vsi_resp *resp;
3270 : : struct ice_aq_desc desc;
3271 : : int status;
3272 : :
3273 : : cmd = &desc.params.vsi_cmd;
3274 : : resp = &desc.params.get_vsi_resp;
3275 : :
3276 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_vsi_params);
3277 : :
3278 : 0 : cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
3279 : :
3280 : 0 : status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
3281 : : sizeof(vsi_ctx->info), cd);
3282 [ # # ]: 0 : if (!status) {
3283 : 0 : vsi_ctx->vsi_num = LE16_TO_CPU(resp->vsi_num) &
3284 : : ICE_AQ_VSI_NUM_M;
3285 : 0 : vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used);
3286 : 0 : vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free);
3287 : : }
3288 : :
3289 : 0 : return status;
3290 : : }
3291 : :
3292 : : /**
3293 : : * ice_aq_add_update_mir_rule - add/update a mirror rule
3294 : : * @hw: pointer to the HW struct
3295 : : * @rule_type: Rule Type
3296 : : * @dest_vsi: VSI number to which packets will be mirrored
3297 : : * @count: length of the list
3298 : : * @mr_buf: buffer for list of mirrored VSI numbers
3299 : : * @cd: pointer to command details structure or NULL
3300 : : * @rule_id: Rule ID
3301 : : *
3302 : : * Add/Update Mirror Rule (0x260).
3303 : : */
3304 : : int
3305 : 0 : ice_aq_add_update_mir_rule(struct ice_hw *hw, u16 rule_type, u16 dest_vsi,
3306 : : u16 count, struct ice_mir_rule_buf *mr_buf,
3307 : : struct ice_sq_cd *cd, u16 *rule_id)
3308 : : {
3309 : : struct ice_aqc_add_update_mir_rule *cmd;
3310 : : struct ice_aq_desc desc;
3311 : : __le16 *mr_list = NULL;
3312 : : u16 buf_size = 0;
3313 : : int status;
3314 : :
3315 [ # # # ]: 0 : switch (rule_type) {
3316 : 0 : case ICE_AQC_RULE_TYPE_VPORT_INGRESS:
3317 : : case ICE_AQC_RULE_TYPE_VPORT_EGRESS:
3318 : : /* Make sure count and mr_buf are set for these rule_types */
3319 [ # # ]: 0 : if (!(count && mr_buf))
3320 : : return ICE_ERR_PARAM;
3321 : :
3322 : 0 : buf_size = count * sizeof(__le16);
3323 : 0 : mr_list = (_FORCE_ __le16 *)ice_malloc(hw, buf_size);
3324 [ # # ]: 0 : if (!mr_list)
3325 : : return ICE_ERR_NO_MEMORY;
3326 : : break;
3327 : 0 : case ICE_AQC_RULE_TYPE_PPORT_INGRESS:
3328 : : case ICE_AQC_RULE_TYPE_PPORT_EGRESS:
3329 : : /* Make sure count and mr_buf are not set for these
3330 : : * rule_types
3331 : : */
3332 [ # # ]: 0 : if (count || mr_buf)
3333 : : return ICE_ERR_PARAM;
3334 : : break;
3335 : 0 : default:
3336 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Error due to unsupported rule_type %u\n", rule_type);
3337 : : return ICE_ERR_OUT_OF_RANGE;
3338 : : }
3339 : :
3340 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_update_mir_rule);
3341 : :
3342 : : /* Pre-process 'mr_buf' items for add/update of virtual port
3343 : : * ingress/egress mirroring (but not physical port ingress/egress
3344 : : * mirroring)
3345 : : */
3346 [ # # ]: 0 : if (mr_buf) {
3347 : : int i;
3348 : :
3349 [ # # ]: 0 : for (i = 0; i < count; i++) {
3350 : : u16 id;
3351 : :
3352 : 0 : id = mr_buf[i].vsi_idx & ICE_AQC_RULE_MIRRORED_VSI_M;
3353 : :
3354 : : /* Validate specified VSI number, make sure it is less
3355 : : * than ICE_MAX_VSI, if not return with error.
3356 : : */
3357 [ # # ]: 0 : if (id >= ICE_MAX_VSI) {
3358 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Error VSI index (%u) out-of-range\n",
3359 : : id);
3360 : 0 : ice_free(hw, mr_list);
3361 : 0 : return ICE_ERR_OUT_OF_RANGE;
3362 : : }
3363 : :
3364 : : /* add VSI to mirror rule */
3365 [ # # ]: 0 : if (mr_buf[i].add)
3366 : 0 : mr_list[i] =
3367 : : CPU_TO_LE16(id | ICE_AQC_RULE_ACT_M);
3368 : : else /* remove VSI from mirror rule */
3369 : 0 : mr_list[i] = CPU_TO_LE16(id);
3370 : : }
3371 : :
3372 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3373 : : }
3374 : :
3375 : : cmd = &desc.params.add_update_rule;
3376 [ # # ]: 0 : if ((*rule_id) != ICE_INVAL_MIRROR_RULE_ID)
3377 : 0 : cmd->rule_id = CPU_TO_LE16(((*rule_id) & ICE_AQC_RULE_ID_M) |
3378 : : ICE_AQC_RULE_ID_VALID_M);
3379 : 0 : cmd->rule_type = CPU_TO_LE16(rule_type & ICE_AQC_RULE_TYPE_M);
3380 : 0 : cmd->num_entries = CPU_TO_LE16(count);
3381 : 0 : cmd->dest = CPU_TO_LE16(dest_vsi);
3382 : :
3383 : 0 : status = ice_aq_send_cmd(hw, &desc, mr_list, buf_size, cd);
3384 [ # # ]: 0 : if (!status)
3385 : 0 : *rule_id = LE16_TO_CPU(cmd->rule_id) & ICE_AQC_RULE_ID_M;
3386 : :
3387 : 0 : ice_free(hw, mr_list);
3388 : :
3389 : 0 : return status;
3390 : : }
3391 : :
3392 : : /**
3393 : : * ice_aq_delete_mir_rule - delete a mirror rule
3394 : : * @hw: pointer to the HW struct
3395 : : * @rule_id: Mirror rule ID (to be deleted)
3396 : : * @keep_allocd: if set, the VSI stays part of the PF allocated res,
3397 : : * otherwise it is returned to the shared pool
3398 : : * @cd: pointer to command details structure or NULL
3399 : : *
3400 : : * Delete Mirror Rule (0x261).
3401 : : */
3402 : : int
3403 : 0 : ice_aq_delete_mir_rule(struct ice_hw *hw, u16 rule_id, bool keep_allocd,
3404 : : struct ice_sq_cd *cd)
3405 : : {
3406 : : struct ice_aqc_delete_mir_rule *cmd;
3407 : : struct ice_aq_desc desc;
3408 : :
3409 : : /* rule_id should be in the range 0...63 */
3410 [ # # ]: 0 : if (rule_id >= ICE_MAX_NUM_MIRROR_RULES)
3411 : : return ICE_ERR_OUT_OF_RANGE;
3412 : :
3413 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_del_mir_rule);
3414 : :
3415 : : cmd = &desc.params.del_rule;
3416 : 0 : rule_id |= ICE_AQC_RULE_ID_VALID_M;
3417 : 0 : cmd->rule_id = CPU_TO_LE16(rule_id);
3418 : :
3419 [ # # ]: 0 : if (keep_allocd)
3420 : 0 : cmd->flags = CPU_TO_LE16(ICE_AQC_FLAG_KEEP_ALLOCD_M);
3421 : :
3422 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3423 : : }
3424 : :
3425 : : /**
3426 : : * ice_aq_alloc_free_vsi_list
3427 : : * @hw: pointer to the HW struct
3428 : : * @vsi_list_id: VSI list ID returned or used for lookup
3429 : : * @lkup_type: switch rule filter lookup type
3430 : : * @opc: switch rules population command type - pass in the command opcode
3431 : : *
3432 : : * allocates or free a VSI list resource
3433 : : */
3434 : : static int
3435 : 0 : ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
3436 : : enum ice_sw_lkup_type lkup_type,
3437 : : enum ice_adminq_opc opc)
3438 : : {
3439 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
3440 : : struct ice_aqc_res_elem *vsi_ele;
3441 : : u16 buf_len;
3442 : : int status;
3443 : :
3444 : : buf_len = ice_struct_size(sw_buf, elem, 1);
3445 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3446 [ # # ]: 0 : if (!sw_buf)
3447 : : return ICE_ERR_NO_MEMORY;
3448 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
3449 : :
3450 : 0 : if (lkup_type == ICE_SW_LKUP_MAC ||
3451 : 0 : lkup_type == ICE_SW_LKUP_MAC_VLAN ||
3452 : 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3453 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3454 : 0 : lkup_type == ICE_SW_LKUP_PROMISC ||
3455 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3456 : 0 : lkup_type == ICE_SW_LKUP_DFLT ||
3457 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_LAST) {
3458 : 0 : sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
3459 [ # # ]: 0 : } else if (lkup_type == ICE_SW_LKUP_VLAN) {
3460 : 0 : sw_buf->res_type =
3461 : : CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
3462 : : } else {
3463 : : status = ICE_ERR_PARAM;
3464 : 0 : goto ice_aq_alloc_free_vsi_list_exit;
3465 : : }
3466 : :
3467 [ # # ]: 0 : if (opc == ice_aqc_opc_free_res)
3468 : 0 : sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(*vsi_list_id);
3469 : :
3470 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
3471 [ # # ]: 0 : if (status)
3472 : 0 : goto ice_aq_alloc_free_vsi_list_exit;
3473 : :
3474 [ # # ]: 0 : if (opc == ice_aqc_opc_alloc_res) {
3475 : : vsi_ele = &sw_buf->elem[0];
3476 : 0 : *vsi_list_id = LE16_TO_CPU(vsi_ele->e.sw_resp);
3477 : : }
3478 : :
3479 : 0 : ice_aq_alloc_free_vsi_list_exit:
3480 : 0 : ice_free(hw, sw_buf);
3481 : 0 : return status;
3482 : : }
3483 : :
3484 : : /**
3485 : : * ice_aq_set_storm_ctrl - Sets storm control configuration
3486 : : * @hw: pointer to the HW struct
3487 : : * @bcast_thresh: represents the upper threshold for broadcast storm control
3488 : : * @mcast_thresh: represents the upper threshold for multicast storm control
3489 : : * @ctl_bitmask: storm control knobs
3490 : : *
3491 : : * Sets the storm control configuration (0x0280)
3492 : : */
3493 : : int
3494 : 0 : ice_aq_set_storm_ctrl(struct ice_hw *hw, u32 bcast_thresh, u32 mcast_thresh,
3495 : : u32 ctl_bitmask)
3496 : : {
3497 : : struct ice_aqc_storm_cfg *cmd;
3498 : : struct ice_aq_desc desc;
3499 : :
3500 : : cmd = &desc.params.storm_conf;
3501 : :
3502 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_storm_cfg);
3503 : :
3504 : 0 : cmd->bcast_thresh_size = CPU_TO_LE32(bcast_thresh & ICE_AQ_THRESHOLD_M);
3505 : 0 : cmd->mcast_thresh_size = CPU_TO_LE32(mcast_thresh & ICE_AQ_THRESHOLD_M);
3506 : 0 : cmd->storm_ctrl_ctrl = CPU_TO_LE32(ctl_bitmask);
3507 : :
3508 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3509 : : }
3510 : :
3511 : : /**
3512 : : * ice_aq_get_storm_ctrl - gets storm control configuration
3513 : : * @hw: pointer to the HW struct
3514 : : * @bcast_thresh: represents the upper threshold for broadcast storm control
3515 : : * @mcast_thresh: represents the upper threshold for multicast storm control
3516 : : * @ctl_bitmask: storm control knobs
3517 : : *
3518 : : * Gets the storm control configuration (0x0281)
3519 : : */
3520 : : int
3521 : 0 : ice_aq_get_storm_ctrl(struct ice_hw *hw, u32 *bcast_thresh, u32 *mcast_thresh,
3522 : : u32 *ctl_bitmask)
3523 : : {
3524 : : struct ice_aq_desc desc;
3525 : : int status;
3526 : :
3527 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_storm_cfg);
3528 : :
3529 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL);
3530 [ # # ]: 0 : if (!status) {
3531 : : struct ice_aqc_storm_cfg *resp = &desc.params.storm_conf;
3532 : :
3533 [ # # ]: 0 : if (bcast_thresh)
3534 : 0 : *bcast_thresh = LE32_TO_CPU(resp->bcast_thresh_size) &
3535 : : ICE_AQ_THRESHOLD_M;
3536 [ # # ]: 0 : if (mcast_thresh)
3537 : 0 : *mcast_thresh = LE32_TO_CPU(resp->mcast_thresh_size) &
3538 : : ICE_AQ_THRESHOLD_M;
3539 [ # # ]: 0 : if (ctl_bitmask)
3540 : 0 : *ctl_bitmask = LE32_TO_CPU(resp->storm_ctrl_ctrl);
3541 : : }
3542 : :
3543 : 0 : return status;
3544 : : }
3545 : :
3546 : : /**
3547 : : * ice_aq_sw_rules - add/update/remove switch rules
3548 : : * @hw: pointer to the HW struct
3549 : : * @rule_list: pointer to switch rule population list
3550 : : * @rule_list_sz: total size of the rule list in bytes
3551 : : * @num_rules: number of switch rules in the rule_list
3552 : : * @opc: switch rules population command type - pass in the command opcode
3553 : : * @cd: pointer to command details structure or NULL
3554 : : *
3555 : : * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware
3556 : : */
3557 : : static int
3558 : 0 : ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
3559 : : u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
3560 : : {
3561 : : struct ice_aq_desc desc;
3562 : : int status;
3563 : :
3564 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3565 : :
3566 : 0 : if (opc != ice_aqc_opc_add_sw_rules &&
3567 [ # # ]: 0 : opc != ice_aqc_opc_update_sw_rules &&
3568 : : opc != ice_aqc_opc_remove_sw_rules)
3569 : : return ICE_ERR_PARAM;
3570 : :
3571 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, opc);
3572 : :
3573 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3574 : 0 : desc.params.sw_rules.num_rules_fltr_entry_index =
3575 : : CPU_TO_LE16(num_rules);
3576 : 0 : status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
3577 [ # # ]: 0 : if (opc != ice_aqc_opc_add_sw_rules &&
3578 [ # # ]: 0 : hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
3579 : : status = ICE_ERR_DOES_NOT_EXIST;
3580 : :
3581 : : return status;
3582 : : }
3583 : :
3584 : : /**
3585 : : * ice_aq_add_recipe - add switch recipe
3586 : : * @hw: pointer to the HW struct
3587 : : * @s_recipe_list: pointer to switch rule population list
3588 : : * @num_recipes: number of switch recipes in the list
3589 : : * @cd: pointer to command details structure or NULL
3590 : : *
3591 : : * Add(0x0290)
3592 : : */
3593 : : int
3594 : 0 : ice_aq_add_recipe(struct ice_hw *hw,
3595 : : struct ice_aqc_recipe_data_elem *s_recipe_list,
3596 : : u16 num_recipes, struct ice_sq_cd *cd)
3597 : : {
3598 : : struct ice_aqc_add_get_recipe *cmd;
3599 : : struct ice_aq_desc desc;
3600 : : u16 buf_size;
3601 : :
3602 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3603 : : cmd = &desc.params.add_get_recipe;
3604 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
3605 : :
3606 : 0 : cmd->num_sub_recipes = CPU_TO_LE16(num_recipes);
3607 : 0 : desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
3608 : :
3609 : 0 : buf_size = num_recipes * sizeof(*s_recipe_list);
3610 : :
3611 : 0 : return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3612 : : }
3613 : :
3614 : : /**
3615 : : * ice_aq_get_recipe - get switch recipe
3616 : : * @hw: pointer to the HW struct
3617 : : * @s_recipe_list: pointer to switch rule population list
3618 : : * @num_recipes: pointer to the number of recipes (input and output)
3619 : : * @recipe_root: root recipe number of recipe(s) to retrieve
3620 : : * @cd: pointer to command details structure or NULL
3621 : : *
3622 : : * Get(0x0292)
3623 : : *
3624 : : * On input, *num_recipes should equal the number of entries in s_recipe_list.
3625 : : * On output, *num_recipes will equal the number of entries returned in
3626 : : * s_recipe_list.
3627 : : *
3628 : : * The caller must supply enough space in s_recipe_list to hold all possible
3629 : : * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES.
3630 : : */
3631 : : int
3632 : 0 : ice_aq_get_recipe(struct ice_hw *hw,
3633 : : struct ice_aqc_recipe_data_elem *s_recipe_list,
3634 : : u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
3635 : : {
3636 : : struct ice_aqc_add_get_recipe *cmd;
3637 : : struct ice_aq_desc desc;
3638 : : u16 buf_size;
3639 : : int status;
3640 : :
3641 [ # # ]: 0 : if (*num_recipes != ICE_MAX_NUM_RECIPES)
3642 : : return ICE_ERR_PARAM;
3643 : :
3644 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3645 : : cmd = &desc.params.add_get_recipe;
3646 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
3647 : :
3648 : 0 : cmd->return_index = CPU_TO_LE16(recipe_root);
3649 : 0 : cmd->num_sub_recipes = 0;
3650 : :
3651 : 0 : buf_size = *num_recipes * sizeof(*s_recipe_list);
3652 : :
3653 : 0 : status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
3654 : 0 : *num_recipes = LE16_TO_CPU(cmd->num_sub_recipes);
3655 : :
3656 : 0 : return status;
3657 : : }
3658 : :
3659 : : /**
3660 : : * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx
3661 : : * @hw: pointer to the HW struct
3662 : : * @params: parameters used to update the default recipe
3663 : : *
3664 : : * This function only supports updating default recipes and it only supports
3665 : : * updating a single recipe based on the lkup_idx at a time.
3666 : : *
3667 : : * This is done as a read-modify-write operation. First, get the current recipe
3668 : : * contents based on the recipe's ID. Then modify the field vector index and
3669 : : * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update
3670 : : * the pre-existing recipe with the modifications.
3671 : : */
3672 : : int
3673 : 0 : ice_update_recipe_lkup_idx(struct ice_hw *hw,
3674 : : struct ice_update_recipe_lkup_idx_params *params)
3675 : : {
3676 : : struct ice_aqc_recipe_data_elem *rcp_list;
3677 : 0 : u16 num_recps = ICE_MAX_NUM_RECIPES;
3678 : : int status;
3679 : :
3680 : 0 : rcp_list = (struct ice_aqc_recipe_data_elem *)ice_malloc(hw, num_recps * sizeof(*rcp_list));
3681 [ # # ]: 0 : if (!rcp_list)
3682 : : return ICE_ERR_NO_MEMORY;
3683 : :
3684 : : /* read current recipe list from firmware */
3685 : 0 : rcp_list->recipe_indx = params->rid;
3686 : 0 : status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
3687 [ # # ]: 0 : if (status) {
3688 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
3689 : : params->rid, status);
3690 : 0 : goto error_out;
3691 : : }
3692 : :
3693 : : /* only modify existing recipe's lkup_idx and mask if valid, while
3694 : : * leaving all other fields the same, then update the recipe firmware
3695 : : */
3696 : 0 : rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
3697 [ # # ]: 0 : if (params->mask_valid)
3698 : 0 : rcp_list->content.mask[params->lkup_idx] =
3699 : 0 : CPU_TO_LE16(params->mask);
3700 : :
3701 [ # # ]: 0 : if (params->ignore_valid)
3702 : 0 : rcp_list->content.lkup_indx[params->lkup_idx] |=
3703 : : ICE_AQ_RECIPE_LKUP_IGNORE;
3704 : :
3705 : 0 : status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
3706 [ # # ]: 0 : if (status)
3707 [ # # # # ]: 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",
3708 : : params->rid, params->lkup_idx, params->fv_idx,
3709 : : params->mask, params->mask_valid ? "true" : "false",
3710 : : status);
3711 : :
3712 : 0 : error_out:
3713 : 0 : ice_free(hw, rcp_list);
3714 : 0 : return status;
3715 : : }
3716 : :
3717 : : /**
3718 : : * ice_aq_map_recipe_to_profile - Map recipe to packet profile
3719 : : * @hw: pointer to the HW struct
3720 : : * @profile_id: package profile ID to associate the recipe with
3721 : : * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3722 : : * @cd: pointer to command details structure or NULL
3723 : : * Recipe to profile association (0x0291)
3724 : : */
3725 : : int
3726 : 0 : ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3727 : : struct ice_sq_cd *cd)
3728 : : {
3729 : : struct ice_aqc_recipe_to_profile *cmd;
3730 : : struct ice_aq_desc desc;
3731 : :
3732 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3733 : : cmd = &desc.params.recipe_to_profile;
3734 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
3735 [ # # ]: 0 : cmd->profile_id = CPU_TO_LE16(profile_id);
3736 : : /* Set the recipe ID bit in the bitmask to let the device know which
3737 : : * profile we are associating the recipe to
3738 : : */
3739 : : ice_memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc),
3740 : : ICE_NONDMA_TO_NONDMA);
3741 : :
3742 : 0 : return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3743 : : }
3744 : :
3745 : : /**
3746 : : * ice_aq_get_recipe_to_profile - Map recipe to packet profile
3747 : : * @hw: pointer to the HW struct
3748 : : * @profile_id: package profile ID to associate the recipe with
3749 : : * @r_bitmap: Recipe bitmap filled in and need to be returned as response
3750 : : * @cd: pointer to command details structure or NULL
3751 : : * Associate profile ID with given recipe (0x0293)
3752 : : */
3753 : : int
3754 : 0 : ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
3755 : : struct ice_sq_cd *cd)
3756 : : {
3757 : : struct ice_aqc_recipe_to_profile *cmd;
3758 : : struct ice_aq_desc desc;
3759 : : int status;
3760 : :
3761 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
3762 : : cmd = &desc.params.recipe_to_profile;
3763 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
3764 : 0 : cmd->profile_id = CPU_TO_LE16(profile_id);
3765 : :
3766 : 0 : status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
3767 [ # # ]: 0 : if (!status)
3768 : : ice_memcpy(r_bitmap, cmd->recipe_assoc,
3769 : : sizeof(cmd->recipe_assoc), ICE_NONDMA_TO_NONDMA);
3770 : :
3771 : 0 : return status;
3772 : : }
3773 : :
3774 : : /**
3775 : : * ice_alloc_recipe - add recipe resource
3776 : : * @hw: pointer to the hardware structure
3777 : : * @rid: recipe ID returned as response to AQ call
3778 : : */
3779 : 0 : int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
3780 : : {
3781 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
3782 : : u16 buf_len;
3783 : : int status;
3784 : :
3785 : : buf_len = ice_struct_size(sw_buf, elem, 1);
3786 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
3787 [ # # ]: 0 : if (!sw_buf)
3788 : : return ICE_ERR_NO_MEMORY;
3789 : :
3790 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
3791 : 0 : sw_buf->res_type = CPU_TO_LE16((ICE_AQC_RES_TYPE_RECIPE <<
3792 : : ICE_AQC_RES_TYPE_S) |
3793 : : ICE_AQC_RES_TYPE_FLAG_SHARED);
3794 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
3795 : : ice_aqc_opc_alloc_res, NULL);
3796 [ # # ]: 0 : if (!status)
3797 : 0 : *rid = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
3798 : 0 : ice_free(hw, sw_buf);
3799 : :
3800 : 0 : return status;
3801 : : }
3802 : :
3803 : : /* ice_init_port_info - Initialize port_info with switch configuration data
3804 : : * @pi: pointer to port_info
3805 : : * @vsi_port_num: VSI number or port number
3806 : : * @type: Type of switch element (port or VSI)
3807 : : * @swid: switch ID of the switch the element is attached to
3808 : : * @pf_vf_num: PF or VF number
3809 : : * @is_vf: true if the element is a VF, false otherwise
3810 : : */
3811 : : static void
3812 : 0 : ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
3813 : : u16 swid, u16 pf_vf_num, bool is_vf)
3814 : : {
3815 [ # # ]: 0 : switch (type) {
3816 : 0 : case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3817 : 0 : pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
3818 : 0 : pi->sw_id = swid;
3819 : 0 : pi->pf_vf_num = pf_vf_num;
3820 : 0 : pi->is_vf = is_vf;
3821 : 0 : break;
3822 : 0 : default:
3823 [ # # ]: 0 : ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
3824 : : break;
3825 : : }
3826 : 0 : }
3827 : :
3828 : : /* ice_get_initial_sw_cfg - Get initial port and default VSI data
3829 : : * @hw: pointer to the hardware structure
3830 : : */
3831 : 0 : int ice_get_initial_sw_cfg(struct ice_hw *hw)
3832 : : {
3833 : : struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
3834 : : u8 num_total_ports;
3835 : 0 : u16 req_desc = 0;
3836 : : u16 num_elems;
3837 : : int status;
3838 : : u8 j = 0;
3839 : : u16 i;
3840 : :
3841 : : num_total_ports = 1;
3842 : :
3843 : : rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *)
3844 : 0 : ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN);
3845 : :
3846 [ # # ]: 0 : if (!rbuf)
3847 : : return ICE_ERR_NO_MEMORY;
3848 : :
3849 : : /* Multiple calls to ice_aq_get_sw_cfg may be required
3850 : : * to get all the switch configuration information. The need
3851 : : * for additional calls is indicated by ice_aq_get_sw_cfg
3852 : : * writing a non-zero value in req_desc
3853 : : */
3854 : : do {
3855 : : struct ice_aqc_get_sw_cfg_resp_elem *ele;
3856 : :
3857 : 0 : status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
3858 : : &req_desc, &num_elems, NULL);
3859 : :
3860 [ # # ]: 0 : if (status)
3861 : : break;
3862 : :
3863 [ # # ]: 0 : for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
3864 : : u16 pf_vf_num, swid, vsi_port_num;
3865 : : bool is_vf = false;
3866 : : u8 res_type;
3867 : :
3868 : 0 : vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) &
3869 : : ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
3870 : :
3871 : 0 : pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) &
3872 : : ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
3873 : :
3874 : 0 : swid = LE16_TO_CPU(ele->swid);
3875 : :
3876 [ # # ]: 0 : if (LE16_TO_CPU(ele->pf_vf_num) &
3877 : : ICE_AQC_GET_SW_CONF_RESP_IS_VF)
3878 : : is_vf = true;
3879 : :
3880 : 0 : res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >>
3881 : : ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
3882 : :
3883 [ # # # ]: 0 : switch (res_type) {
3884 : 0 : case ICE_AQC_GET_SW_CONF_RESP_VSI:
3885 [ # # ]: 0 : if (hw->fw_vsi_num != ICE_DFLT_VSI_INVAL)
3886 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "fw_vsi_num %d -> %d\n",
3887 : : hw->fw_vsi_num, vsi_port_num);
3888 : 0 : hw->fw_vsi_num = vsi_port_num;
3889 [ # # # # ]: 0 : if (hw->dcf_enabled && !is_vf)
3890 : 0 : hw->pf_id = pf_vf_num;
3891 : : break;
3892 : 0 : case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
3893 : : case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT:
3894 [ # # ]: 0 : if (j == num_total_ports) {
3895 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "more ports than expected\n");
3896 : : status = ICE_ERR_CFG;
3897 : 0 : goto out;
3898 : : }
3899 : 0 : ice_init_port_info(hw->port_info,
3900 : : vsi_port_num, res_type, swid,
3901 : : pf_vf_num, is_vf);
3902 : 0 : j++;
3903 : 0 : break;
3904 : : default:
3905 : : break;
3906 : : }
3907 : : }
3908 [ # # ]: 0 : } while (req_desc && !status);
3909 : :
3910 : 0 : out:
3911 : 0 : ice_free(hw, rbuf);
3912 : 0 : return status;
3913 : : }
3914 : :
3915 : : /**
3916 : : * ice_fill_sw_info - Helper function to populate lb_en and lan_en
3917 : : * @hw: pointer to the hardware structure
3918 : : * @fi: filter info structure to fill/update
3919 : : *
3920 : : * This helper function populates the lb_en and lan_en elements of the provided
3921 : : * ice_fltr_info struct using the switch's type and characteristics of the
3922 : : * switch rule being configured.
3923 : : */
3924 : 0 : static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
3925 : : {
3926 : 0 : if ((fi->flag & ICE_FLTR_RX) &&
3927 : : (fi->fltr_act == ICE_FWD_TO_VSI ||
3928 : : fi->fltr_act == ICE_FWD_TO_VSI_LIST) &&
3929 : : fi->lkup_type == ICE_SW_LKUP_LAST)
3930 : : fi->lan_en = true;
3931 : 0 : fi->lb_en = false;
3932 : 0 : fi->lan_en = false;
3933 [ # # ]: 0 : if ((fi->flag & ICE_FLTR_TX) &&
3934 [ # # ]: 0 : (fi->fltr_act == ICE_FWD_TO_VSI ||
3935 : : fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
3936 : : fi->fltr_act == ICE_FWD_TO_Q ||
3937 : : fi->fltr_act == ICE_FWD_TO_QGRP)) {
3938 : : /* Setting LB for prune actions will result in replicated
3939 : : * packets to the internal switch that will be dropped.
3940 : : */
3941 [ # # ]: 0 : if (fi->lkup_type != ICE_SW_LKUP_VLAN)
3942 : 0 : fi->lb_en = true;
3943 : :
3944 : : /* Set lan_en to TRUE if
3945 : : * 1. The switch is a VEB AND
3946 : : * 2
3947 : : * 2.1 The lookup is a directional lookup like ethertype,
3948 : : * promiscuous, ethertype-MAC, promiscuous-VLAN
3949 : : * and default-port OR
3950 : : * 2.2 The lookup is VLAN, OR
3951 : : * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR
3952 : : * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC.
3953 : : *
3954 : : * OR
3955 : : *
3956 : : * The switch is a VEPA.
3957 : : *
3958 : : * In all other cases, the LAN enable has to be set to false.
3959 : : */
3960 [ # # ]: 0 : if (hw->evb_veb) {
3961 [ # # ]: 0 : if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
3962 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_PROMISC ||
3963 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
3964 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
3965 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_DFLT ||
3966 [ # # ]: 0 : fi->lkup_type == ICE_SW_LKUP_VLAN ||
3967 : 0 : (fi->lkup_type == ICE_SW_LKUP_MAC &&
3968 [ # # # # ]: 0 : !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) ||
3969 : 0 : (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
3970 [ # # ]: 0 : !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr))) {
3971 [ # # ]: 0 : if (!fi->fltVeb_en)
3972 : 0 : fi->lan_en = true;
3973 : : }
3974 : : } else {
3975 : 0 : fi->lan_en = true;
3976 : : }
3977 : : }
3978 : : /* To be able to receive packets coming from the VF on the same PF,
3979 : : * unicast filter needs to be added without LB_EN bit
3980 : : */
3981 [ # # ]: 0 : if (fi->flag & ICE_FLTR_RX_LB) {
3982 : 0 : fi->lb_en = false;
3983 : 0 : fi->lan_en = true;
3984 : : }
3985 : 0 : }
3986 : :
3987 : : /**
3988 : : * ice_fill_sw_rule - Helper function to fill switch rule structure
3989 : : * @hw: pointer to the hardware structure
3990 : : * @f_info: entry containing packet forwarding information
3991 : : * @s_rule: switch rule structure to be filled in based on mac_entry
3992 : : * @opc: switch rules population command type - pass in the command opcode
3993 : : */
3994 : : static void
3995 : 0 : ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
3996 : : struct ice_sw_rule_lkup_rx_tx *s_rule,
3997 : : enum ice_adminq_opc opc)
3998 : : {
3999 : : u16 vlan_id = ICE_MAX_VLAN_ID + 1;
4000 : : u16 vlan_tpid = ICE_ETH_P_8021Q;
4001 : : void *daddr = NULL;
4002 : : u16 eth_hdr_sz;
4003 : : u8 *eth_hdr;
4004 : : u32 act = 0;
4005 : : __be16 *off;
4006 : : u8 q_rgn;
4007 : :
4008 [ # # ]: 0 : if (opc == ice_aqc_opc_remove_sw_rules) {
4009 : 0 : s_rule->act = 0;
4010 : 0 : s_rule->index = CPU_TO_LE16(f_info->fltr_rule_id);
4011 : 0 : s_rule->hdr_len = 0;
4012 : 0 : return;
4013 : : }
4014 : :
4015 : : eth_hdr_sz = sizeof(dummy_eth_header);
4016 [ # # ]: 0 : eth_hdr = s_rule->hdr_data;
4017 : :
4018 : : /* initialize the ether header with a dummy header */
4019 : : ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA);
4020 : 0 : ice_fill_sw_info(hw, f_info);
4021 : :
4022 [ # # # # : 0 : switch (f_info->fltr_act) {
# # ]
4023 : 0 : case ICE_FWD_TO_VSI:
4024 : 0 : act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
4025 : : ICE_SINGLE_ACT_VSI_ID_M;
4026 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
4027 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING |
4028 : : ICE_SINGLE_ACT_VALID_BIT;
4029 : : break;
4030 : 0 : case ICE_FWD_TO_VSI_LIST:
4031 : : act |= ICE_SINGLE_ACT_VSI_LIST;
4032 : 0 : act |= (f_info->fwd_id.vsi_list_id <<
4033 : 0 : ICE_SINGLE_ACT_VSI_LIST_ID_S) &
4034 : : ICE_SINGLE_ACT_VSI_LIST_ID_M;
4035 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
4036 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING |
4037 : : ICE_SINGLE_ACT_VALID_BIT;
4038 : : break;
4039 : 0 : case ICE_FWD_TO_Q:
4040 : : act |= ICE_SINGLE_ACT_TO_Q;
4041 : 0 : act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
4042 : : ICE_SINGLE_ACT_Q_INDEX_M;
4043 : 0 : break;
4044 : : case ICE_DROP_PACKET:
4045 : : act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
4046 : : ICE_SINGLE_ACT_VALID_BIT;
4047 : : break;
4048 : 0 : case ICE_FWD_TO_QGRP:
4049 [ # # ]: 0 : q_rgn = f_info->qgrp_size > 0 ?
4050 : 0 : (u8)ice_ilog2(f_info->qgrp_size) : 0;
4051 : : act |= ICE_SINGLE_ACT_TO_Q;
4052 : 0 : act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
4053 : : ICE_SINGLE_ACT_Q_INDEX_M;
4054 : 0 : act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
4055 : : ICE_SINGLE_ACT_Q_REGION_M;
4056 : 0 : break;
4057 : : default:
4058 : : return;
4059 : : }
4060 : :
4061 [ # # ]: 0 : if (f_info->lb_en)
4062 : 0 : act |= ICE_SINGLE_ACT_LB_ENABLE;
4063 [ # # ]: 0 : if (f_info->lan_en)
4064 : 0 : act |= ICE_SINGLE_ACT_LAN_ENABLE;
4065 : :
4066 [ # # # # : 0 : switch (f_info->lkup_type) {
# # # # ]
4067 : 0 : case ICE_SW_LKUP_MAC:
4068 : 0 : daddr = f_info->l_data.mac.mac_addr;
4069 : 0 : break;
4070 : 0 : case ICE_SW_LKUP_VLAN:
4071 : 0 : vlan_id = f_info->l_data.vlan.vlan_id;
4072 [ # # ]: 0 : if (f_info->l_data.vlan.tpid_valid)
4073 : 0 : vlan_tpid = f_info->l_data.vlan.tpid;
4074 [ # # ]: 0 : if (f_info->fltr_act == ICE_FWD_TO_VSI ||
4075 : : f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
4076 : : act |= ICE_SINGLE_ACT_PRUNE;
4077 : 0 : act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
4078 : : }
4079 : : break;
4080 : 0 : case ICE_SW_LKUP_ETHERTYPE_MAC:
4081 : 0 : daddr = f_info->l_data.ethertype_mac.mac_addr;
4082 : : /* fall-through */
4083 : 0 : case ICE_SW_LKUP_ETHERTYPE:
4084 : : off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
4085 [ # # ]: 0 : *off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype);
4086 : 0 : break;
4087 : 0 : case ICE_SW_LKUP_MAC_VLAN:
4088 : 0 : daddr = f_info->l_data.mac_vlan.mac_addr;
4089 : 0 : vlan_id = f_info->l_data.mac_vlan.vlan_id;
4090 : 0 : break;
4091 : 0 : case ICE_SW_LKUP_PROMISC_VLAN:
4092 : 0 : vlan_id = f_info->l_data.mac_vlan.vlan_id;
4093 : : /* fall-through */
4094 : 0 : case ICE_SW_LKUP_PROMISC:
4095 : 0 : daddr = f_info->l_data.mac_vlan.mac_addr;
4096 : 0 : break;
4097 : : default:
4098 : : break;
4099 : : }
4100 : :
4101 : 0 : s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ?
4102 : 0 : CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) :
4103 : : CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
4104 : :
4105 : : /* Recipe set depending on lookup type */
4106 : 0 : s_rule->recipe_id = CPU_TO_LE16(f_info->lkup_type);
4107 : 0 : s_rule->src = CPU_TO_LE16(f_info->src);
4108 : 0 : s_rule->act = CPU_TO_LE32(act);
4109 : :
4110 [ # # ]: 0 : if (daddr)
4111 : : ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN,
4112 : : ICE_NONDMA_TO_NONDMA);
4113 : :
4114 [ # # ]: 0 : if (!(vlan_id > ICE_MAX_VLAN_ID)) {
4115 : : off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
4116 [ # # ]: 0 : *off = CPU_TO_BE16(vlan_id);
4117 : : off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
4118 [ # # ]: 0 : *off = CPU_TO_BE16(vlan_tpid);
4119 : : }
4120 : :
4121 : : /* Create the switch rule with the final dummy Ethernet header */
4122 [ # # ]: 0 : if (opc != ice_aqc_opc_update_sw_rules)
4123 : 0 : s_rule->hdr_len = CPU_TO_LE16(eth_hdr_sz);
4124 : : }
4125 : :
4126 : : /**
4127 : : * ice_add_marker_act
4128 : : * @hw: pointer to the hardware structure
4129 : : * @m_ent: the management entry for which sw marker needs to be added
4130 : : * @sw_marker: sw marker to tag the Rx descriptor with
4131 : : * @l_id: large action resource ID
4132 : : *
4133 : : * Create a large action to hold software marker and update the switch rule
4134 : : * entry pointed by m_ent with newly created large action
4135 : : */
4136 : : static int
4137 : 0 : ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
4138 : : u16 sw_marker, u16 l_id)
4139 : : {
4140 : : struct ice_sw_rule_lkup_rx_tx *rx_tx;
4141 : : struct ice_sw_rule_lg_act *lg_act;
4142 : : /* For software marker we need 3 large actions
4143 : : * 1. FWD action: FWD TO VSI or VSI LIST
4144 : : * 2. GENERIC VALUE action to hold the profile ID
4145 : : * 3. GENERIC VALUE action to hold the software marker ID
4146 : : */
4147 : : const u16 num_lg_acts = 3;
4148 : : u16 lg_act_size;
4149 : : u16 rules_size;
4150 : : int status;
4151 : : u32 act;
4152 : : u16 id;
4153 : :
4154 [ # # ]: 0 : if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
4155 : : return ICE_ERR_PARAM;
4156 : :
4157 : : /* Create two back-to-back switch rules and submit them to the HW using
4158 : : * one memory buffer:
4159 : : * 1. Large Action
4160 : : * 2. Look up Tx Rx
4161 : : */
4162 : : lg_act_size = (u16)ice_struct_size(lg_act, act, num_lg_acts);
4163 : : rules_size = lg_act_size +
4164 : : ice_struct_size(rx_tx, hdr_data, DUMMY_ETH_HDR_LEN);
4165 : 0 : lg_act = (struct ice_sw_rule_lg_act *)ice_malloc(hw, rules_size);
4166 [ # # ]: 0 : if (!lg_act)
4167 : : return ICE_ERR_NO_MEMORY;
4168 : :
4169 : 0 : rx_tx = (struct ice_sw_rule_lkup_rx_tx *)((u8 *)lg_act + lg_act_size);
4170 : :
4171 : : /* Fill in the first switch rule i.e. large action */
4172 : 0 : lg_act->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
4173 : 0 : lg_act->index = CPU_TO_LE16(l_id);
4174 : 0 : lg_act->size = CPU_TO_LE16(num_lg_acts);
4175 : :
4176 : : /* First action VSI forwarding or VSI list forwarding depending on how
4177 : : * many VSIs
4178 : : */
4179 [ # # ]: 0 : id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
4180 : 0 : m_ent->fltr_info.fwd_id.hw_vsi_id;
4181 : :
4182 : : act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
4183 : 0 : act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
4184 [ # # ]: 0 : if (m_ent->vsi_count > 1)
4185 : 0 : act |= ICE_LG_ACT_VSI_LIST;
4186 : 0 : lg_act->act[0] = CPU_TO_LE32(act);
4187 : :
4188 : : /* Second action descriptor type */
4189 : : act = ICE_LG_ACT_GENERIC;
4190 : :
4191 : : act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
4192 : 0 : lg_act->act[1] = CPU_TO_LE32(act);
4193 : :
4194 : : act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
4195 : : ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
4196 : :
4197 : : /* Third action Marker value */
4198 : : act |= ICE_LG_ACT_GENERIC;
4199 : 0 : act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
4200 : : ICE_LG_ACT_GENERIC_VALUE_M;
4201 : :
4202 : 0 : lg_act->act[2] = CPU_TO_LE32(act);
4203 : :
4204 : : /* call the fill switch rule to fill the lookup Tx Rx structure */
4205 : 0 : ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
4206 : : ice_aqc_opc_update_sw_rules);
4207 : :
4208 : : /* Update the action to point to the large action ID */
4209 : 0 : rx_tx->act = CPU_TO_LE32(ICE_SINGLE_ACT_PTR |
4210 : : ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
4211 : : ICE_SINGLE_ACT_PTR_VAL_M));
4212 : :
4213 : : /* Use the filter rule ID of the previously created rule with single
4214 : : * act. Once the update happens, hardware will treat this as large
4215 : : * action
4216 : : */
4217 : 0 : rx_tx->index = CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id);
4218 : :
4219 : 0 : status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
4220 : : ice_aqc_opc_update_sw_rules, NULL);
4221 [ # # ]: 0 : if (!status) {
4222 : 0 : m_ent->lg_act_idx = l_id;
4223 : 0 : m_ent->sw_marker_id = sw_marker;
4224 : : }
4225 : :
4226 : 0 : ice_free(hw, lg_act);
4227 : 0 : return status;
4228 : : }
4229 : :
4230 : : /**
4231 : : * ice_add_counter_act - add/update filter rule with counter action
4232 : : * @hw: pointer to the hardware structure
4233 : : * @m_ent: the management entry for which counter needs to be added
4234 : : * @counter_id: VLAN counter ID returned as part of allocate resource
4235 : : * @l_id: large action resource ID
4236 : : */
4237 : : static int
4238 : 0 : ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
4239 : : u16 counter_id, u16 l_id)
4240 : : {
4241 : : struct ice_sw_rule_lkup_rx_tx *rx_tx;
4242 : : struct ice_sw_rule_lg_act *lg_act;
4243 : :
4244 : : /* 2 actions will be added while adding a large action counter */
4245 : : const int num_acts = 2;
4246 : : u16 lg_act_size;
4247 : : u16 rules_size;
4248 : : u16 f_rule_id;
4249 : : u32 act;
4250 : : int status;
4251 : : u16 id;
4252 : :
4253 [ # # ]: 0 : if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
4254 : : return ICE_ERR_PARAM;
4255 : :
4256 : : /* Create two back-to-back switch rules and submit them to the HW using
4257 : : * one memory buffer:
4258 : : * 1. Large Action
4259 : : * 2. Look up Tx Rx
4260 : : */
4261 : : lg_act_size = (u16)ice_struct_size(lg_act, act, num_acts);
4262 : : rules_size = lg_act_size +
4263 : : ice_struct_size(rx_tx, hdr_data, DUMMY_ETH_HDR_LEN);
4264 : 0 : lg_act = (struct ice_sw_rule_lg_act *)ice_malloc(hw, rules_size);
4265 [ # # ]: 0 : if (!lg_act)
4266 : : return ICE_ERR_NO_MEMORY;
4267 : :
4268 : 0 : rx_tx = (struct ice_sw_rule_lkup_rx_tx *)((u8 *)lg_act +
4269 : : lg_act_size);
4270 : :
4271 : : /* Fill in the first switch rule i.e. large action */
4272 : 0 : lg_act->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
4273 : 0 : lg_act->index = CPU_TO_LE16(l_id);
4274 : 0 : lg_act->size = CPU_TO_LE16(num_acts);
4275 : :
4276 : : /* First action VSI forwarding or VSI list forwarding depending on how
4277 : : * many VSIs
4278 : : */
4279 [ # # ]: 0 : id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
4280 : 0 : m_ent->fltr_info.fwd_id.hw_vsi_id;
4281 : :
4282 : : act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
4283 : 0 : act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) &
4284 : : ICE_LG_ACT_VSI_LIST_ID_M;
4285 [ # # ]: 0 : if (m_ent->vsi_count > 1)
4286 : 0 : act |= ICE_LG_ACT_VSI_LIST;
4287 : 0 : lg_act->act[0] = CPU_TO_LE32(act);
4288 : :
4289 : : /* Second action counter ID */
4290 : : act = ICE_LG_ACT_STAT_COUNT;
4291 : 0 : act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) &
4292 : : ICE_LG_ACT_STAT_COUNT_M;
4293 : 0 : lg_act->act[1] = CPU_TO_LE32(act);
4294 : :
4295 : : /* call the fill switch rule to fill the lookup Tx Rx structure */
4296 : 0 : ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
4297 : : ice_aqc_opc_update_sw_rules);
4298 : :
4299 : : act = ICE_SINGLE_ACT_PTR;
4300 : 0 : act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M;
4301 : 0 : rx_tx->act = CPU_TO_LE32(act);
4302 : :
4303 : : /* Use the filter rule ID of the previously created rule with single
4304 : : * act. Once the update happens, hardware will treat this as large
4305 : : * action
4306 : : */
4307 : 0 : f_rule_id = m_ent->fltr_info.fltr_rule_id;
4308 : 0 : rx_tx->index = CPU_TO_LE16(f_rule_id);
4309 : :
4310 : 0 : status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
4311 : : ice_aqc_opc_update_sw_rules, NULL);
4312 [ # # ]: 0 : if (!status) {
4313 : 0 : m_ent->lg_act_idx = l_id;
4314 : 0 : m_ent->counter_index = (u8)counter_id;
4315 : : }
4316 : :
4317 : 0 : ice_free(hw, lg_act);
4318 : 0 : return status;
4319 : : }
4320 : :
4321 : : /**
4322 : : * ice_create_vsi_list_map
4323 : : * @hw: pointer to the hardware structure
4324 : : * @vsi_handle_arr: array of VSI handles to set in the VSI mapping
4325 : : * @num_vsi: number of VSI handles in the array
4326 : : * @vsi_list_id: VSI list ID generated as part of allocate resource
4327 : : *
4328 : : * Helper function to create a new entry of VSI list ID to VSI mapping
4329 : : * using the given VSI list ID
4330 : : */
4331 : : static struct ice_vsi_list_map_info *
4332 : 0 : ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4333 : : u16 vsi_list_id)
4334 : : {
4335 : 0 : struct ice_switch_info *sw = hw->switch_info;
4336 : : struct ice_vsi_list_map_info *v_map;
4337 : : int i;
4338 : :
4339 : 0 : v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map));
4340 [ # # ]: 0 : if (!v_map)
4341 : : return NULL;
4342 : :
4343 : 0 : v_map->vsi_list_id = vsi_list_id;
4344 : 0 : v_map->ref_cnt = 1;
4345 [ # # ]: 0 : for (i = 0; i < num_vsi; i++)
4346 : 0 : ice_set_bit(vsi_handle_arr[i], v_map->vsi_map);
4347 : :
4348 [ # # ]: 0 : LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head);
4349 : 0 : return v_map;
4350 : : }
4351 : :
4352 : : /**
4353 : : * ice_update_vsi_list_rule
4354 : : * @hw: pointer to the hardware structure
4355 : : * @vsi_handle_arr: array of VSI handles to form a VSI list
4356 : : * @num_vsi: number of VSI handles in the array
4357 : : * @vsi_list_id: VSI list ID generated as part of allocate resource
4358 : : * @remove: Boolean value to indicate if this is a remove action
4359 : : * @opc: switch rules population command type - pass in the command opcode
4360 : : * @lkup_type: lookup type of the filter
4361 : : *
4362 : : * Call AQ command to add a new switch rule or update existing switch rule
4363 : : * using the given VSI list ID
4364 : : */
4365 : : static int
4366 : 0 : ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4367 : : u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
4368 : : enum ice_sw_lkup_type lkup_type)
4369 : : {
4370 : : struct ice_sw_rule_vsi_list *s_rule;
4371 : : u16 s_rule_size;
4372 : : u16 rule_type;
4373 : : int status;
4374 : : int i;
4375 : :
4376 [ # # ]: 0 : if (!num_vsi)
4377 : : return ICE_ERR_PARAM;
4378 : :
4379 : 0 : if (lkup_type == ICE_SW_LKUP_MAC ||
4380 : 0 : lkup_type == ICE_SW_LKUP_MAC_VLAN ||
4381 : 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE ||
4382 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
4383 : 0 : lkup_type == ICE_SW_LKUP_PROMISC ||
4384 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
4385 : 0 : lkup_type == ICE_SW_LKUP_DFLT ||
4386 [ # # ]: 0 : lkup_type == ICE_SW_LKUP_LAST)
4387 [ # # ]: 0 : rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
4388 : : ICE_AQC_SW_RULES_T_VSI_LIST_SET;
4389 [ # # ]: 0 : else if (lkup_type == ICE_SW_LKUP_VLAN)
4390 [ # # ]: 0 : rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
4391 : : ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
4392 : : else
4393 : : return ICE_ERR_PARAM;
4394 : :
4395 : 0 : s_rule_size = (u16)ice_struct_size(s_rule, vsi, num_vsi);
4396 : 0 : s_rule = (struct ice_sw_rule_vsi_list *)ice_malloc(hw, s_rule_size);
4397 [ # # ]: 0 : if (!s_rule)
4398 : : return ICE_ERR_NO_MEMORY;
4399 [ # # ]: 0 : for (i = 0; i < num_vsi; i++) {
4400 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
4401 : : status = ICE_ERR_PARAM;
4402 : 0 : goto exit;
4403 : : }
4404 : : /* AQ call requires hw_vsi_id(s) */
4405 : 0 : s_rule->vsi[i] =
4406 : 0 : CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
4407 : : }
4408 : :
4409 : 0 : s_rule->hdr.type = CPU_TO_LE16(rule_type);
4410 : 0 : s_rule->number_vsi = CPU_TO_LE16(num_vsi);
4411 : 0 : s_rule->index = CPU_TO_LE16(vsi_list_id);
4412 : :
4413 : 0 : status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
4414 : :
4415 : 0 : exit:
4416 : 0 : ice_free(hw, s_rule);
4417 : 0 : return status;
4418 : : }
4419 : :
4420 : : /**
4421 : : * ice_create_vsi_list_rule - Creates and populates a VSI list rule
4422 : : * @hw: pointer to the HW struct
4423 : : * @vsi_handle_arr: array of VSI handles to form a VSI list
4424 : : * @num_vsi: number of VSI handles in the array
4425 : : * @vsi_list_id: stores the ID of the VSI list to be created
4426 : : * @lkup_type: switch rule filter's lookup type
4427 : : */
4428 : : static int
4429 : 0 : ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
4430 : : u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
4431 : : {
4432 : : int status;
4433 : :
4434 : 0 : status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
4435 : : ice_aqc_opc_alloc_res);
4436 [ # # ]: 0 : if (status)
4437 : : return status;
4438 : :
4439 : : /* Update the newly created VSI list to include the specified VSIs */
4440 : 0 : return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
4441 : 0 : *vsi_list_id, false,
4442 : : ice_aqc_opc_add_sw_rules, lkup_type);
4443 : : }
4444 : :
4445 : : /**
4446 : : * ice_create_pkt_fwd_rule
4447 : : * @hw: pointer to the hardware structure
4448 : : * @recp_list: corresponding filter management list
4449 : : * @f_entry: entry containing packet forwarding information
4450 : : *
4451 : : * Create switch rule with given filter information and add an entry
4452 : : * to the corresponding filter management list to track this switch rule
4453 : : * and VSI mapping
4454 : : */
4455 : : static int
4456 : 0 : ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4457 : : struct ice_fltr_list_entry *f_entry)
4458 : : {
4459 : : struct ice_fltr_mgmt_list_entry *fm_entry;
4460 : : struct ice_sw_rule_lkup_rx_tx *s_rule;
4461 : : int status;
4462 : :
4463 : : s_rule = (struct ice_sw_rule_lkup_rx_tx *)
4464 : 0 : ice_malloc(hw, ice_struct_size(s_rule, hdr_data,
4465 : : DUMMY_ETH_HDR_LEN));
4466 [ # # ]: 0 : if (!s_rule)
4467 : : return ICE_ERR_NO_MEMORY;
4468 : : fm_entry = (struct ice_fltr_mgmt_list_entry *)
4469 : 0 : ice_malloc(hw, sizeof(*fm_entry));
4470 [ # # ]: 0 : if (!fm_entry) {
4471 : : status = ICE_ERR_NO_MEMORY;
4472 : 0 : goto ice_create_pkt_fwd_rule_exit;
4473 : : }
4474 : :
4475 : 0 : fm_entry->fltr_info = f_entry->fltr_info;
4476 : :
4477 : : /* Initialize all the fields for the management entry */
4478 : 0 : fm_entry->vsi_count = 1;
4479 : 0 : fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
4480 : 0 : fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
4481 : 0 : fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
4482 : :
4483 : 0 : ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
4484 : : ice_aqc_opc_add_sw_rules);
4485 : :
4486 : 0 : status = ice_aq_sw_rules(hw, s_rule,
4487 : : ice_struct_size(s_rule, hdr_data,
4488 : : DUMMY_ETH_HDR_LEN),
4489 : : 1, ice_aqc_opc_add_sw_rules, NULL);
4490 [ # # ]: 0 : if (status) {
4491 : 0 : ice_free(hw, fm_entry);
4492 : 0 : goto ice_create_pkt_fwd_rule_exit;
4493 : : }
4494 : :
4495 : 0 : f_entry->fltr_info.fltr_rule_id = LE16_TO_CPU(s_rule->index);
4496 : 0 : fm_entry->fltr_info.fltr_rule_id = LE16_TO_CPU(s_rule->index);
4497 : :
4498 : : /* The book keeping entries will get removed when base driver
4499 : : * calls remove filter AQ command
4500 : : */
4501 [ # # ]: 0 : LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules);
4502 : :
4503 : 0 : ice_create_pkt_fwd_rule_exit:
4504 : 0 : ice_free(hw, s_rule);
4505 : 0 : return status;
4506 : : }
4507 : :
4508 : : /**
4509 : : * ice_update_pkt_fwd_rule
4510 : : * @hw: pointer to the hardware structure
4511 : : * @f_info: filter information for switch rule
4512 : : *
4513 : : * Call AQ command to update a previously created switch rule with a
4514 : : * VSI list ID
4515 : : */
4516 : : static int
4517 : 0 : ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
4518 : : {
4519 : : struct ice_sw_rule_lkup_rx_tx *s_rule;
4520 : : int status;
4521 : :
4522 : : s_rule = (struct ice_sw_rule_lkup_rx_tx *)
4523 : 0 : ice_malloc(hw, ice_struct_size(s_rule, hdr_data,
4524 : : DUMMY_ETH_HDR_LEN));
4525 [ # # ]: 0 : if (!s_rule)
4526 : : return ICE_ERR_NO_MEMORY;
4527 : :
4528 : 0 : ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
4529 : :
4530 : 0 : s_rule->index = CPU_TO_LE16(f_info->fltr_rule_id);
4531 : :
4532 : : /* Update switch rule with new rule set to forward VSI list */
4533 : 0 : status = ice_aq_sw_rules(hw, s_rule,
4534 : : ice_struct_size(s_rule, hdr_data,
4535 : : DUMMY_ETH_HDR_LEN),
4536 : : 1, ice_aqc_opc_update_sw_rules, NULL);
4537 : :
4538 : 0 : ice_free(hw, s_rule);
4539 : 0 : return status;
4540 : : }
4541 : :
4542 : : /**
4543 : : * ice_update_sw_rule_bridge_mode
4544 : : * @hw: pointer to the HW struct
4545 : : *
4546 : : * Updates unicast switch filter rules based on VEB/VEPA mode
4547 : : */
4548 : 0 : int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
4549 : : {
4550 : : struct ice_fltr_mgmt_list_entry *fm_entry;
4551 : : struct LIST_HEAD_TYPE *rule_head;
4552 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4553 : : struct ice_switch_info *sw;
4554 : : int status = 0;
4555 : :
4556 : 0 : sw = hw->switch_info;
4557 : :
4558 : 0 : rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
4559 : : rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
4560 : :
4561 : 0 : ice_acquire_lock(rule_lock);
4562 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry,
# # ]
4563 : : list_entry) {
4564 : 0 : struct ice_fltr_info *fi = &fm_entry->fltr_info;
4565 : : u8 *addr = fi->l_data.mac.mac_addr;
4566 : :
4567 : : /* Update unicast Tx rules to reflect the selected
4568 : : * VEB/VEPA mode
4569 : : */
4570 [ # # # # ]: 0 : if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) &&
4571 [ # # ]: 0 : (fi->fltr_act == ICE_FWD_TO_VSI ||
4572 : : fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
4573 : : fi->fltr_act == ICE_FWD_TO_Q ||
4574 : : fi->fltr_act == ICE_FWD_TO_QGRP)) {
4575 : 0 : status = ice_update_pkt_fwd_rule(hw, fi);
4576 [ # # ]: 0 : if (status)
4577 : : break;
4578 : : }
4579 : : }
4580 : :
4581 : : ice_release_lock(rule_lock);
4582 : :
4583 : 0 : return status;
4584 : : }
4585 : :
4586 : : /**
4587 : : * ice_add_update_vsi_list
4588 : : * @hw: pointer to the hardware structure
4589 : : * @m_entry: pointer to current filter management list entry
4590 : : * @cur_fltr: filter information from the book keeping entry
4591 : : * @new_fltr: filter information with the new VSI to be added
4592 : : *
4593 : : * Call AQ command to add or update previously created VSI list with new VSI.
4594 : : *
4595 : : * Helper function to do book keeping associated with adding filter information
4596 : : * The algorithm to do the book keeping is described below :
4597 : : * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.)
4598 : : * if only one VSI has been added till now
4599 : : * Allocate a new VSI list and add two VSIs
4600 : : * to this list using switch rule command
4601 : : * Update the previously created switch rule with the
4602 : : * newly created VSI list ID
4603 : : * if a VSI list was previously created
4604 : : * Add the new VSI to the previously created VSI list set
4605 : : * using the update switch rule command
4606 : : */
4607 : : static int
4608 : 0 : ice_add_update_vsi_list(struct ice_hw *hw,
4609 : : struct ice_fltr_mgmt_list_entry *m_entry,
4610 : : struct ice_fltr_info *cur_fltr,
4611 : : struct ice_fltr_info *new_fltr)
4612 : : {
4613 : 0 : u16 vsi_list_id = 0;
4614 : : int status = 0;
4615 : :
4616 [ # # ]: 0 : if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
4617 : : cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
4618 : : return ICE_ERR_NOT_IMPL;
4619 : :
4620 [ # # ]: 0 : if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
4621 [ # # ]: 0 : new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
4622 : : (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
4623 : : cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
4624 : : return ICE_ERR_NOT_IMPL;
4625 : :
4626 [ # # # # ]: 0 : if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
4627 : : /* Only one entry existed in the mapping and it was not already
4628 : : * a part of a VSI list. So, create a VSI list with the old and
4629 : : * new VSIs.
4630 : : */
4631 : : struct ice_fltr_info tmp_fltr;
4632 : : u16 vsi_handle_arr[2];
4633 : :
4634 : : /* A rule already exists with the new VSI being added */
4635 [ # # ]: 0 : if (cur_fltr->vsi_handle == new_fltr->vsi_handle)
4636 : 0 : return ICE_ERR_ALREADY_EXISTS;
4637 : :
4638 : 0 : vsi_handle_arr[0] = cur_fltr->vsi_handle;
4639 : 0 : vsi_handle_arr[1] = new_fltr->vsi_handle;
4640 : 0 : status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
4641 : : &vsi_list_id,
4642 : : new_fltr->lkup_type);
4643 [ # # ]: 0 : if (status)
4644 : : return status;
4645 : :
4646 : 0 : tmp_fltr = *new_fltr;
4647 : 0 : tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
4648 : 0 : tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
4649 : 0 : tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
4650 : : /* Update the previous switch rule of "MAC forward to VSI" to
4651 : : * "MAC fwd to VSI list"
4652 : : */
4653 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
4654 [ # # ]: 0 : if (status)
4655 : : return status;
4656 : :
4657 : 0 : cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
4658 : 0 : cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
4659 : 0 : m_entry->vsi_list_info =
4660 : 0 : ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
4661 : : vsi_list_id);
4662 : :
4663 [ # # ]: 0 : if (!m_entry->vsi_list_info)
4664 : : return ICE_ERR_NO_MEMORY;
4665 : :
4666 : : /* If this entry was large action then the large action needs
4667 : : * to be updated to point to FWD to VSI list
4668 : : */
4669 [ # # ]: 0 : if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
4670 : : status =
4671 : 0 : ice_add_marker_act(hw, m_entry,
4672 : : m_entry->sw_marker_id,
4673 : 0 : m_entry->lg_act_idx);
4674 : : } else {
4675 : 0 : u16 vsi_handle = new_fltr->vsi_handle;
4676 : : enum ice_adminq_opc opcode;
4677 : :
4678 [ # # ]: 0 : if (!m_entry->vsi_list_info)
4679 : 0 : return ICE_ERR_CFG;
4680 : :
4681 : : /* A rule already exists with the new VSI being added */
4682 [ # # ]: 0 : if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
4683 : : return ICE_ERR_ALREADY_EXISTS;
4684 : :
4685 : : /* Update the previously created VSI list set with
4686 : : * the new VSI ID passed in
4687 : : */
4688 : 0 : vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
4689 : : opcode = ice_aqc_opc_update_sw_rules;
4690 : :
4691 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
4692 : : vsi_list_id, false, opcode,
4693 : : new_fltr->lkup_type);
4694 : : /* update VSI list mapping info with new VSI ID */
4695 [ # # ]: 0 : if (!status)
4696 : 0 : ice_set_bit(vsi_handle,
4697 : 0 : m_entry->vsi_list_info->vsi_map);
4698 : : }
4699 [ # # ]: 0 : if (!status)
4700 : 0 : m_entry->vsi_count++;
4701 : : return status;
4702 : : }
4703 : :
4704 : : /**
4705 : : * ice_find_rule_entry - Search a rule entry
4706 : : * @list_head: head of rule list
4707 : : * @f_info: rule information
4708 : : *
4709 : : * Helper function to search for a given rule entry
4710 : : * Returns pointer to entry storing the rule if found
4711 : : */
4712 : : static struct ice_fltr_mgmt_list_entry *
4713 : 0 : ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head,
4714 : : struct ice_fltr_info *f_info)
4715 : : {
4716 : : struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
4717 : :
4718 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
# # ]
4719 : : list_entry) {
4720 [ # # ]: 0 : if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
4721 : 0 : sizeof(f_info->l_data)) &&
4722 [ # # ]: 0 : f_info->flag == list_itr->fltr_info.flag) {
4723 : : ret = list_itr;
4724 : : break;
4725 : : }
4726 : : }
4727 : 0 : return ret;
4728 : : }
4729 : :
4730 : : /**
4731 : : * ice_find_vsi_list_entry - Search VSI list map with VSI count 1
4732 : : * @recp_list: VSI lists needs to be searched
4733 : : * @vsi_handle: VSI handle to be found in VSI list
4734 : : * @vsi_list_id: VSI list ID found containing vsi_handle
4735 : : *
4736 : : * Helper function to search a VSI list with single entry containing given VSI
4737 : : * handle element. This can be extended further to search VSI list with more
4738 : : * than 1 vsi_count. Returns pointer to VSI list entry if found.
4739 : : */
4740 : : struct ice_vsi_list_map_info *
4741 : 0 : ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle,
4742 : : u16 *vsi_list_id)
4743 : : {
4744 : : struct ice_vsi_list_map_info *map_info = NULL;
4745 : : struct LIST_HEAD_TYPE *list_head;
4746 : :
4747 : : list_head = &recp_list->filt_rules;
4748 [ # # ]: 0 : if (recp_list->adv_rule) {
4749 : : struct ice_adv_fltr_mgmt_list_entry *list_itr;
4750 : :
4751 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head,
# # ]
4752 : : ice_adv_fltr_mgmt_list_entry,
4753 : : list_entry) {
4754 [ # # ]: 0 : if (list_itr->vsi_list_info) {
4755 : : map_info = list_itr->vsi_list_info;
4756 [ # # ]: 0 : if (ice_is_bit_set(map_info->vsi_map,
4757 : : vsi_handle)) {
4758 : 0 : *vsi_list_id = map_info->vsi_list_id;
4759 : 0 : return map_info;
4760 : : }
4761 : : }
4762 : : }
4763 : : } else {
4764 : : struct ice_fltr_mgmt_list_entry *list_itr;
4765 : :
4766 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head,
# # ]
4767 : : ice_fltr_mgmt_list_entry,
4768 : : list_entry) {
4769 [ # # ]: 0 : if (list_itr->vsi_count == 1 &&
4770 [ # # ]: 0 : list_itr->vsi_list_info) {
4771 : : map_info = list_itr->vsi_list_info;
4772 [ # # ]: 0 : if (ice_is_bit_set(map_info->vsi_map,
4773 : : vsi_handle)) {
4774 : 0 : *vsi_list_id = map_info->vsi_list_id;
4775 : 0 : return map_info;
4776 : : }
4777 : : }
4778 : : }
4779 : : }
4780 : : return NULL;
4781 : : }
4782 : :
4783 : : /**
4784 : : * ice_add_rule_internal - add rule for a given lookup type
4785 : : * @hw: pointer to the hardware structure
4786 : : * @recp_list: recipe list for which rule has to be added
4787 : : * @lport: logic port number on which function add rule
4788 : : * @f_entry: structure containing MAC forwarding information
4789 : : *
4790 : : * Adds or updates the rule lists for a given recipe
4791 : : */
4792 : : static int
4793 : 0 : ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4794 : : u8 lport, struct ice_fltr_list_entry *f_entry)
4795 : : {
4796 : : struct ice_fltr_info *new_fltr, *cur_fltr;
4797 : : struct ice_fltr_mgmt_list_entry *m_entry;
4798 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4799 : : int status = 0;
4800 : :
4801 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4802 : : return ICE_ERR_PARAM;
4803 : :
4804 : : /* Load the hw_vsi_id only if the fwd action is fwd to VSI */
4805 [ # # ]: 0 : if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI)
4806 : 0 : f_entry->fltr_info.fwd_id.hw_vsi_id =
4807 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4808 : :
4809 : : rule_lock = &recp_list->filt_rule_lock;
4810 : :
4811 : 0 : ice_acquire_lock(rule_lock);
4812 : 0 : new_fltr = &f_entry->fltr_info;
4813 [ # # ]: 0 : if (new_fltr->flag & ICE_FLTR_RX)
4814 : 0 : new_fltr->src = lport;
4815 [ # # ]: 0 : else if (new_fltr->flag & (ICE_FLTR_TX | ICE_FLTR_RX_LB))
4816 : 0 : new_fltr->src =
4817 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4818 : :
4819 : 0 : m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
4820 [ # # ]: 0 : if (!m_entry) {
4821 : 0 : status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
4822 : 0 : goto exit_add_rule_internal;
4823 : : }
4824 : :
4825 : 0 : cur_fltr = &m_entry->fltr_info;
4826 : 0 : status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
4827 : :
4828 : 0 : exit_add_rule_internal:
4829 : : ice_release_lock(rule_lock);
4830 : 0 : return status;
4831 : : }
4832 : :
4833 : : /**
4834 : : * ice_remove_vsi_list_rule
4835 : : * @hw: pointer to the hardware structure
4836 : : * @vsi_list_id: VSI list ID generated as part of allocate resource
4837 : : * @lkup_type: switch rule filter lookup type
4838 : : *
4839 : : * The VSI list should be emptied before this function is called to remove the
4840 : : * VSI list.
4841 : : */
4842 : : static int
4843 : : ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
4844 : : enum ice_sw_lkup_type lkup_type)
4845 : : {
4846 : : /* Free the vsi_list resource that we allocated. It is assumed that the
4847 : : * list is empty at this point.
4848 : : */
4849 : 0 : return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
4850 : : ice_aqc_opc_free_res);
4851 : : }
4852 : :
4853 : : /**
4854 : : * ice_rem_update_vsi_list
4855 : : * @hw: pointer to the hardware structure
4856 : : * @vsi_handle: VSI handle of the VSI to remove
4857 : : * @fm_list: filter management entry for which the VSI list management needs to
4858 : : * be done
4859 : : */
4860 : : static int
4861 : 0 : ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
4862 : : struct ice_fltr_mgmt_list_entry *fm_list)
4863 : : {
4864 : : enum ice_sw_lkup_type lkup_type;
4865 : : u16 vsi_list_id;
4866 : : int status = 0;
4867 : :
4868 [ # # ]: 0 : if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
4869 [ # # ]: 0 : fm_list->vsi_count == 0)
4870 : : return ICE_ERR_PARAM;
4871 : :
4872 : : /* A rule with the VSI being removed does not exist */
4873 [ # # ]: 0 : if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
4874 : : return ICE_ERR_DOES_NOT_EXIST;
4875 : :
4876 : 0 : lkup_type = fm_list->fltr_info.lkup_type;
4877 : 0 : vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
4878 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
4879 : : ice_aqc_opc_update_sw_rules,
4880 : : lkup_type);
4881 [ # # ]: 0 : if (status)
4882 : : return status;
4883 : :
4884 : 0 : fm_list->vsi_count--;
4885 [ # # ]: 0 : ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
4886 : :
4887 [ # # # # ]: 0 : if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
4888 : 0 : struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
4889 : : struct ice_vsi_list_map_info *vsi_list_info =
4890 : : fm_list->vsi_list_info;
4891 : : u16 rem_vsi_handle;
4892 : :
4893 : 0 : rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
4894 : : ICE_MAX_VSI);
4895 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, rem_vsi_handle))
4896 : 0 : return ICE_ERR_OUT_OF_RANGE;
4897 : :
4898 : : /* Make sure VSI list is empty before removing it below */
4899 : 0 : status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
4900 : : vsi_list_id, true,
4901 : : ice_aqc_opc_update_sw_rules,
4902 : : lkup_type);
4903 [ # # ]: 0 : if (status)
4904 : : return status;
4905 : :
4906 : 0 : tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
4907 : 0 : tmp_fltr_info.fwd_id.hw_vsi_id =
4908 : 0 : ice_get_hw_vsi_num(hw, rem_vsi_handle);
4909 : 0 : tmp_fltr_info.vsi_handle = rem_vsi_handle;
4910 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
4911 [ # # ]: 0 : if (status) {
4912 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
4913 : : tmp_fltr_info.fwd_id.hw_vsi_id, status);
4914 : 0 : return status;
4915 : : }
4916 : :
4917 : 0 : fm_list->fltr_info = tmp_fltr_info;
4918 : : }
4919 : :
4920 [ # # # # : 0 : if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
# # ]
4921 [ # # ]: 0 : (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
4922 : 0 : struct ice_vsi_list_map_info *vsi_list_info =
4923 : : fm_list->vsi_list_info;
4924 : :
4925 : : /* Remove the VSI list since it is no longer used */
4926 : 0 : status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
4927 [ # # ]: 0 : if (status) {
4928 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
4929 : : vsi_list_id, status);
4930 : 0 : return status;
4931 : : }
4932 : :
4933 [ # # ]: 0 : LIST_DEL(&vsi_list_info->list_entry);
4934 : 0 : ice_free(hw, vsi_list_info);
4935 : 0 : fm_list->vsi_list_info = NULL;
4936 : : }
4937 : :
4938 : : return status;
4939 : : }
4940 : :
4941 : : /**
4942 : : * ice_remove_rule_internal - Remove a filter rule of a given type
4943 : : * @hw: pointer to the hardware structure
4944 : : * @recp_list: recipe list for which the rule needs to removed
4945 : : * @f_entry: rule entry containing filter information
4946 : : */
4947 : : static int
4948 : 0 : ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
4949 : : struct ice_fltr_list_entry *f_entry)
4950 : : {
4951 : : struct ice_fltr_mgmt_list_entry *list_elem;
4952 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
4953 : : bool remove_rule = false;
4954 : : int status = 0;
4955 : : u16 vsi_handle;
4956 : :
4957 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
4958 : : return ICE_ERR_PARAM;
4959 : 0 : f_entry->fltr_info.fwd_id.hw_vsi_id =
4960 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
4961 : :
4962 : : rule_lock = &recp_list->filt_rule_lock;
4963 : 0 : ice_acquire_lock(rule_lock);
4964 : :
4965 : 0 : list_elem = ice_find_rule_entry(&recp_list->filt_rules,
4966 : : &f_entry->fltr_info);
4967 [ # # ]: 0 : if (!list_elem) {
4968 : : status = ICE_ERR_DOES_NOT_EXIST;
4969 : 0 : goto exit;
4970 : : }
4971 : :
4972 [ # # ]: 0 : if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
4973 : : remove_rule = true;
4974 [ # # ]: 0 : } else if (!list_elem->vsi_list_info) {
4975 : : status = ICE_ERR_DOES_NOT_EXIST;
4976 : 0 : goto exit;
4977 [ # # ]: 0 : } else if (list_elem->vsi_list_info->ref_cnt > 1) {
4978 : : /* a ref_cnt > 1 indicates that the vsi_list is being
4979 : : * shared by multiple rules. Decrement the ref_cnt and
4980 : : * remove this rule, but do not modify the list, as it
4981 : : * is in-use by other rules.
4982 : : */
4983 : 0 : list_elem->vsi_list_info->ref_cnt--;
4984 : : remove_rule = true;
4985 : : } else {
4986 : : /* a ref_cnt of 1 indicates the vsi_list is only used
4987 : : * by one rule. However, the original removal request is only
4988 : : * for a single VSI. Update the vsi_list first, and only
4989 : : * remove the rule if there are no further VSIs in this list.
4990 : : */
4991 : 0 : vsi_handle = f_entry->fltr_info.vsi_handle;
4992 : 0 : status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
4993 [ # # ]: 0 : if (status)
4994 : 0 : goto exit;
4995 : : /* if VSI count goes to zero after updating the VSI list */
4996 [ # # ]: 0 : if (list_elem->vsi_count == 0)
4997 : : remove_rule = true;
4998 : : }
4999 : :
5000 : : if (remove_rule) {
5001 : : /* Remove the lookup rule */
5002 : : struct ice_sw_rule_lkup_rx_tx *s_rule;
5003 : :
5004 : : s_rule = (struct ice_sw_rule_lkup_rx_tx *)
5005 : 0 : ice_malloc(hw, ice_struct_size(s_rule, hdr_data, 0));
5006 [ # # ]: 0 : if (!s_rule) {
5007 : : status = ICE_ERR_NO_MEMORY;
5008 : 0 : goto exit;
5009 : : }
5010 : :
5011 : : ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
5012 : : ice_aqc_opc_remove_sw_rules);
5013 : :
5014 : 0 : status = ice_aq_sw_rules(hw, s_rule,
5015 : : ice_struct_size(s_rule, hdr_data, 0),
5016 : : 1, ice_aqc_opc_remove_sw_rules, NULL);
5017 : :
5018 : : /* Remove a book keeping from the list */
5019 : 0 : ice_free(hw, s_rule);
5020 : :
5021 [ # # ]: 0 : if (status)
5022 : 0 : goto exit;
5023 : :
5024 [ # # ]: 0 : LIST_DEL(&list_elem->list_entry);
5025 : 0 : ice_free(hw, list_elem);
5026 : : }
5027 : 0 : exit:
5028 : : ice_release_lock(rule_lock);
5029 : 0 : return status;
5030 : : }
5031 : :
5032 : : /**
5033 : : * ice_aq_get_res_alloc - get allocated resources
5034 : : * @hw: pointer to the HW struct
5035 : : * @num_entries: pointer to u16 to store the number of resource entries returned
5036 : : * @buf: pointer to buffer
5037 : : * @buf_size: size of buf
5038 : : * @cd: pointer to command details structure or NULL
5039 : : *
5040 : : * The caller-supplied buffer must be large enough to store the resource
5041 : : * information for all resource types. Each resource type is an
5042 : : * ice_aqc_get_res_resp_elem structure.
5043 : : */
5044 : : int
5045 : 0 : ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries,
5046 : : struct ice_aqc_get_res_resp_elem *buf, u16 buf_size,
5047 : : struct ice_sq_cd *cd)
5048 : : {
5049 : : struct ice_aqc_get_res_alloc *resp;
5050 : : struct ice_aq_desc desc;
5051 : : int status;
5052 : :
5053 [ # # ]: 0 : if (!buf)
5054 : : return ICE_ERR_BAD_PTR;
5055 : :
5056 [ # # ]: 0 : if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN)
5057 : : return ICE_ERR_INVAL_SIZE;
5058 : :
5059 : : resp = &desc.params.get_res;
5060 : :
5061 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc);
5062 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
5063 : :
5064 [ # # ]: 0 : if (!status && num_entries)
5065 : 0 : *num_entries = LE16_TO_CPU(resp->resp_elem_num);
5066 : :
5067 : : return status;
5068 : : }
5069 : :
5070 : : /**
5071 : : * ice_aq_get_res_descs - get allocated resource descriptors
5072 : : * @hw: pointer to the hardware structure
5073 : : * @num_entries: number of resource entries in buffer
5074 : : * @buf: structure to hold response data buffer
5075 : : * @buf_size: size of buffer
5076 : : * @res_type: resource type
5077 : : * @res_shared: is resource shared
5078 : : * @desc_id: input - first desc ID to start; output - next desc ID
5079 : : * @cd: pointer to command details structure or NULL
5080 : : */
5081 : : int
5082 : 0 : ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries,
5083 : : struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type,
5084 : : bool res_shared, u16 *desc_id, struct ice_sq_cd *cd)
5085 : : {
5086 : : struct ice_aqc_get_allocd_res_desc *cmd;
5087 : : struct ice_aq_desc desc;
5088 : : int status;
5089 : :
5090 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
5091 : :
5092 : : cmd = &desc.params.get_res_desc;
5093 : :
5094 [ # # ]: 0 : if (!buf)
5095 : : return ICE_ERR_PARAM;
5096 : :
5097 [ # # ]: 0 : if (buf_size != (num_entries * sizeof(*buf)))
5098 : : return ICE_ERR_PARAM;
5099 : :
5100 : 0 : ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc);
5101 : :
5102 [ # # ]: 0 : cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) &
5103 : : ICE_AQC_RES_TYPE_M) | (res_shared ?
5104 : : ICE_AQC_RES_TYPE_FLAG_SHARED : 0));
5105 : 0 : cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id);
5106 : :
5107 : 0 : status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
5108 [ # # ]: 0 : if (!status)
5109 : 0 : *desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc);
5110 : :
5111 : : return status;
5112 : : }
5113 : :
5114 : : /**
5115 : : * ice_add_mac_rule - Add a MAC address based filter rule
5116 : : * @hw: pointer to the hardware structure
5117 : : * @m_list: list of MAC addresses and forwarding information
5118 : : * @sw: pointer to switch info struct for which function add rule
5119 : : * @lport: logic port number on which function add rule
5120 : : *
5121 : : * IMPORTANT: When the umac_shared flag is set to false and m_list has
5122 : : * multiple unicast addresses, the function assumes that all the
5123 : : * addresses are unique in a given add_mac call. It doesn't
5124 : : * check for duplicates in this case, removing duplicates from a given
5125 : : * list should be taken care of in the caller of this function.
5126 : : */
5127 : : static int
5128 : 0 : ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5129 : : struct ice_switch_info *sw, u8 lport)
5130 : : {
5131 : 0 : struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC];
5132 : : struct ice_sw_rule_lkup_rx_tx *s_rule, *r_iter;
5133 : : struct ice_fltr_list_entry *m_list_itr;
5134 : : struct LIST_HEAD_TYPE *rule_head;
5135 : : u16 total_elem_left, s_rule_size;
5136 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5137 : : u16 num_unicast = 0;
5138 : : int status = 0;
5139 : : u8 elem_sent;
5140 : :
5141 : : s_rule = NULL;
5142 : : rule_lock = &recp_list->filt_rule_lock;
5143 : 0 : rule_head = &recp_list->filt_rules;
5144 : :
5145 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
# # ]
5146 : : list_entry) {
5147 : : u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
5148 : : u16 vsi_handle;
5149 : : u16 hw_vsi_id;
5150 : :
5151 : 0 : m_list_itr->fltr_info.flag = ICE_FLTR_TX;
5152 : 0 : vsi_handle = m_list_itr->fltr_info.vsi_handle;
5153 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5154 : : return ICE_ERR_PARAM;
5155 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5156 [ # # ]: 0 : if (m_list_itr->fltr_info.fltr_act == ICE_FWD_TO_VSI)
5157 : 0 : m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
5158 : : /* update the src in case it is VSI num */
5159 [ # # ]: 0 : if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
5160 : : return ICE_ERR_PARAM;
5161 : 0 : m_list_itr->fltr_info.src = hw_vsi_id;
5162 [ # # ]: 0 : if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
5163 [ # # # # : 0 : IS_ZERO_ETHER_ADDR(add))
# # ]
5164 : : return ICE_ERR_PARAM;
5165 [ # # # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(add) && !hw->umac_shared) {
5166 : : /* Don't overwrite the unicast address */
5167 : 0 : ice_acquire_lock(rule_lock);
5168 [ # # ]: 0 : if (ice_find_rule_entry(rule_head,
5169 : : &m_list_itr->fltr_info)) {
5170 : : ice_release_lock(rule_lock);
5171 : 0 : continue;
5172 : : }
5173 : : ice_release_lock(rule_lock);
5174 : 0 : num_unicast++;
5175 [ # # ]: 0 : } else if (IS_MULTICAST_ETHER_ADDR(add) ||
5176 [ # # ]: 0 : (IS_UNICAST_ETHER_ADDR(add) && hw->umac_shared)) {
5177 : 0 : m_list_itr->status =
5178 : 0 : ice_add_rule_internal(hw, recp_list, lport,
5179 : : m_list_itr);
5180 [ # # ]: 0 : if (m_list_itr->status)
5181 : 0 : return m_list_itr->status;
5182 : : }
5183 : : }
5184 : :
5185 : 0 : ice_acquire_lock(rule_lock);
5186 : : /* Exit if no suitable entries were found for adding bulk switch rule */
5187 [ # # ]: 0 : if (!num_unicast) {
5188 : : status = 0;
5189 : 0 : goto ice_add_mac_exit;
5190 : : }
5191 : :
5192 : : /* Allocate switch rule buffer for the bulk update for unicast */
5193 : : s_rule_size = ice_struct_size(s_rule, hdr_data, DUMMY_ETH_HDR_LEN);
5194 : : s_rule = (struct ice_sw_rule_lkup_rx_tx *)
5195 : 0 : ice_calloc(hw, num_unicast, s_rule_size);
5196 [ # # ]: 0 : if (!s_rule) {
5197 : : status = ICE_ERR_NO_MEMORY;
5198 : 0 : goto ice_add_mac_exit;
5199 : : }
5200 : :
5201 : : r_iter = s_rule;
5202 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
# # ]
5203 : : list_entry) {
5204 : : struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
5205 : : u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
5206 : :
5207 [ # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
5208 : 0 : ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
5209 : : ice_aqc_opc_add_sw_rules);
5210 : 0 : r_iter = (struct ice_sw_rule_lkup_rx_tx *)
5211 : : ((u8 *)r_iter + s_rule_size);
5212 : : }
5213 : : }
5214 : :
5215 : : /* Call AQ bulk switch rule update for all unicast addresses */
5216 : : r_iter = s_rule;
5217 : : /* Call AQ switch rule in AQ_MAX chunk */
5218 [ # # ]: 0 : for (total_elem_left = num_unicast; total_elem_left > 0;
5219 : 0 : total_elem_left -= elem_sent) {
5220 : : struct ice_sw_rule_lkup_rx_tx *entry = r_iter;
5221 : :
5222 : 0 : elem_sent = MIN_T(u8, total_elem_left,
5223 : : (ICE_AQ_MAX_BUF_LEN / s_rule_size));
5224 : 0 : status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
5225 : : elem_sent, ice_aqc_opc_add_sw_rules,
5226 : : NULL);
5227 [ # # ]: 0 : if (status)
5228 : 0 : goto ice_add_mac_exit;
5229 : 0 : r_iter = (struct ice_sw_rule_lkup_rx_tx *)
5230 : 0 : ((u8 *)r_iter + (elem_sent * s_rule_size));
5231 : : }
5232 : :
5233 : : /* Fill up rule ID based on the value returned from FW */
5234 : : r_iter = s_rule;
5235 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry,
# # ]
5236 : : list_entry) {
5237 : : struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
5238 : : u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
5239 : : struct ice_fltr_mgmt_list_entry *fm_entry;
5240 : :
5241 [ # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(mac_addr)) {
5242 : 0 : f_info->fltr_rule_id =
5243 : 0 : LE16_TO_CPU(r_iter->index);
5244 : 0 : f_info->fltr_act = ICE_FWD_TO_VSI;
5245 : : /* Create an entry to track this MAC address */
5246 : : fm_entry = (struct ice_fltr_mgmt_list_entry *)
5247 : 0 : ice_malloc(hw, sizeof(*fm_entry));
5248 [ # # ]: 0 : if (!fm_entry) {
5249 : : status = ICE_ERR_NO_MEMORY;
5250 : 0 : goto ice_add_mac_exit;
5251 : : }
5252 : 0 : fm_entry->fltr_info = *f_info;
5253 : 0 : fm_entry->vsi_count = 1;
5254 : : /* The book keeping entries will get removed when
5255 : : * base driver calls remove filter AQ command
5256 : : */
5257 : :
5258 [ # # ]: 0 : LIST_ADD(&fm_entry->list_entry, rule_head);
5259 : 0 : r_iter = (struct ice_sw_rule_lkup_rx_tx *)
5260 : : ((u8 *)r_iter + s_rule_size);
5261 : : }
5262 : : }
5263 : :
5264 : 0 : ice_add_mac_exit:
5265 : : ice_release_lock(rule_lock);
5266 [ # # ]: 0 : if (s_rule)
5267 : 0 : ice_free(hw, s_rule);
5268 : : return status;
5269 : : }
5270 : :
5271 : : /**
5272 : : * ice_add_mac - Add a MAC address based filter rule
5273 : : * @hw: pointer to the hardware structure
5274 : : * @m_list: list of MAC addresses and forwarding information
5275 : : *
5276 : : * Function add MAC rule for logical port from HW struct
5277 : : */
5278 : 0 : int ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5279 : : {
5280 [ # # ]: 0 : if (!m_list || !hw)
5281 : : return ICE_ERR_PARAM;
5282 : :
5283 : 0 : return ice_add_mac_rule(hw, m_list, hw->switch_info,
5284 : 0 : hw->port_info->lport);
5285 : : }
5286 : :
5287 : : /**
5288 : : * ice_add_vlan_internal - Add one VLAN based filter rule
5289 : : * @hw: pointer to the hardware structure
5290 : : * @recp_list: recipe list for which rule has to be added
5291 : : * @f_entry: filter entry containing one VLAN information
5292 : : */
5293 : : static int
5294 : 0 : ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list,
5295 : : struct ice_fltr_list_entry *f_entry)
5296 : : {
5297 : : struct ice_fltr_mgmt_list_entry *v_list_itr;
5298 : : struct ice_fltr_info *new_fltr, *cur_fltr;
5299 : : enum ice_sw_lkup_type lkup_type;
5300 : 0 : u16 vsi_list_id = 0, vsi_handle;
5301 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5302 : : int status = 0;
5303 : :
5304 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
5305 : : return ICE_ERR_PARAM;
5306 : :
5307 : 0 : f_entry->fltr_info.fwd_id.hw_vsi_id =
5308 : 0 : ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
5309 : 0 : new_fltr = &f_entry->fltr_info;
5310 : :
5311 : : /* VLAN ID should only be 12 bits */
5312 [ # # ]: 0 : if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
5313 : : return ICE_ERR_PARAM;
5314 : :
5315 [ # # ]: 0 : if (new_fltr->src_id != ICE_SRC_ID_VSI)
5316 : : return ICE_ERR_PARAM;
5317 : :
5318 : 0 : new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
5319 : 0 : lkup_type = new_fltr->lkup_type;
5320 : 0 : vsi_handle = new_fltr->vsi_handle;
5321 : : rule_lock = &recp_list->filt_rule_lock;
5322 : 0 : ice_acquire_lock(rule_lock);
5323 : 0 : v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr);
5324 [ # # ]: 0 : if (!v_list_itr) {
5325 : : struct ice_vsi_list_map_info *map_info = NULL;
5326 : :
5327 [ # # ]: 0 : if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
5328 : : /* All VLAN pruning rules use a VSI list. Check if
5329 : : * there is already a VSI list containing VSI that we
5330 : : * want to add. If found, use the same vsi_list_id for
5331 : : * this new VLAN rule or else create a new list.
5332 : : */
5333 : 0 : map_info = ice_find_vsi_list_entry(recp_list,
5334 : : vsi_handle,
5335 : : &vsi_list_id);
5336 [ # # ]: 0 : if (!map_info) {
5337 : 0 : status = ice_create_vsi_list_rule(hw,
5338 : : &vsi_handle,
5339 : : 1,
5340 : : &vsi_list_id,
5341 : : lkup_type);
5342 [ # # ]: 0 : if (status)
5343 : 0 : goto exit;
5344 : : }
5345 : : /* Convert the action to forwarding to a VSI list. */
5346 : 0 : new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
5347 : 0 : new_fltr->fwd_id.vsi_list_id = vsi_list_id;
5348 : : }
5349 : :
5350 : 0 : status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry);
5351 [ # # ]: 0 : if (!status) {
5352 : 0 : v_list_itr = ice_find_rule_entry(&recp_list->filt_rules,
5353 : : new_fltr);
5354 [ # # ]: 0 : if (!v_list_itr) {
5355 : : status = ICE_ERR_DOES_NOT_EXIST;
5356 : 0 : goto exit;
5357 : : }
5358 : : /* reuse VSI list for new rule and increment ref_cnt */
5359 [ # # ]: 0 : if (map_info) {
5360 : 0 : v_list_itr->vsi_list_info = map_info;
5361 : 0 : map_info->ref_cnt++;
5362 : : } else {
5363 : 0 : v_list_itr->vsi_list_info =
5364 : 0 : ice_create_vsi_list_map(hw, &vsi_handle,
5365 : : 1, vsi_list_id);
5366 : : }
5367 : : }
5368 [ # # ]: 0 : } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
5369 : : /* Update existing VSI list to add new VSI ID only if it used
5370 : : * by one VLAN rule.
5371 : : */
5372 : 0 : cur_fltr = &v_list_itr->fltr_info;
5373 : 0 : status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
5374 : : new_fltr);
5375 : : } else {
5376 : : /* If VLAN rule exists and VSI list being used by this rule is
5377 : : * referenced by more than 1 VLAN rule. Then create a new VSI
5378 : : * list appending previous VSI with new VSI and update existing
5379 : : * VLAN rule to point to new VSI list ID
5380 : : */
5381 : : struct ice_fltr_info tmp_fltr;
5382 : : u16 vsi_handle_arr[2];
5383 : : u16 cur_handle;
5384 : :
5385 : : /* Current implementation only supports reusing VSI list with
5386 : : * one VSI count. We should never hit below condition
5387 : : */
5388 [ # # # # ]: 0 : if (v_list_itr->vsi_count > 1 &&
5389 : : v_list_itr->vsi_list_info->ref_cnt > 1) {
5390 [ # # ]: 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");
5391 : : status = ICE_ERR_CFG;
5392 : 0 : goto exit;
5393 : : }
5394 : :
5395 : : cur_handle =
5396 : 0 : ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map,
5397 : : ICE_MAX_VSI);
5398 : :
5399 : : /* A rule already exists with the new VSI being added */
5400 [ # # ]: 0 : if (cur_handle == vsi_handle) {
5401 : : status = ICE_ERR_ALREADY_EXISTS;
5402 : 0 : goto exit;
5403 : : }
5404 : :
5405 : 0 : vsi_handle_arr[0] = cur_handle;
5406 : 0 : vsi_handle_arr[1] = vsi_handle;
5407 : 0 : status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
5408 : : &vsi_list_id, lkup_type);
5409 [ # # ]: 0 : if (status)
5410 : 0 : goto exit;
5411 : :
5412 : 0 : tmp_fltr = v_list_itr->fltr_info;
5413 : : tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
5414 : 0 : tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
5415 : 0 : tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
5416 : : /* Update the previous switch rule to a new VSI list which
5417 : : * includes current VSI that is requested
5418 : : */
5419 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
5420 [ # # ]: 0 : if (status)
5421 : 0 : goto exit;
5422 : :
5423 : : /* before overriding VSI list map info. decrement ref_cnt of
5424 : : * previous VSI list
5425 : : */
5426 : 0 : v_list_itr->vsi_list_info->ref_cnt--;
5427 : :
5428 : : /* now update to newly created list */
5429 : 0 : v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
5430 : 0 : v_list_itr->vsi_list_info =
5431 : 0 : ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
5432 : : vsi_list_id);
5433 : 0 : v_list_itr->vsi_count++;
5434 : : }
5435 : :
5436 : 0 : exit:
5437 : : ice_release_lock(rule_lock);
5438 : 0 : return status;
5439 : : }
5440 : :
5441 : : /**
5442 : : * ice_add_vlan_rule - Add VLAN based filter rule
5443 : : * @hw: pointer to the hardware structure
5444 : : * @v_list: list of VLAN entries and forwarding information
5445 : : * @sw: pointer to switch info struct for which function add rule
5446 : : */
5447 : : static int
5448 : 0 : ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5449 : : struct ice_switch_info *sw)
5450 : : {
5451 : : struct ice_fltr_list_entry *v_list_itr;
5452 : : struct ice_sw_recipe *recp_list;
5453 : :
5454 : 0 : recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN];
5455 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry,
# # ]
5456 : : list_entry) {
5457 [ # # ]: 0 : if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
5458 : : return ICE_ERR_PARAM;
5459 : 0 : v_list_itr->fltr_info.flag = ICE_FLTR_TX;
5460 : 0 : v_list_itr->status = ice_add_vlan_internal(hw, recp_list,
5461 : : v_list_itr);
5462 [ # # ]: 0 : if (v_list_itr->status)
5463 : 0 : return v_list_itr->status;
5464 : : }
5465 : : return 0;
5466 : : }
5467 : :
5468 : : /**
5469 : : * ice_add_vlan - Add a VLAN based filter rule
5470 : : * @hw: pointer to the hardware structure
5471 : : * @v_list: list of VLAN and forwarding information
5472 : : *
5473 : : * Function add VLAN rule for logical port from HW struct
5474 : : */
5475 : 0 : int ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
5476 : : {
5477 [ # # ]: 0 : if (!v_list || !hw)
5478 : : return ICE_ERR_PARAM;
5479 : :
5480 : 0 : return ice_add_vlan_rule(hw, v_list, hw->switch_info);
5481 : : }
5482 : :
5483 : : /**
5484 : : * ice_add_mac_vlan_rule - Add MAC and VLAN pair based filter rule
5485 : : * @hw: pointer to the hardware structure
5486 : : * @mv_list: list of MAC and VLAN filters
5487 : : * @sw: pointer to switch info struct for which function add rule
5488 : : * @lport: logic port number on which function add rule
5489 : : *
5490 : : * If the VSI on which the MAC-VLAN pair has to be added has Rx and Tx VLAN
5491 : : * pruning bits enabled, then it is the responsibility of the caller to make
5492 : : * sure to add a VLAN only filter on the same VSI. Packets belonging to that
5493 : : * VLAN won't be received on that VSI otherwise.
5494 : : */
5495 : : static int
5496 : 0 : ice_add_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list,
5497 : : struct ice_switch_info *sw, u8 lport)
5498 : : {
5499 : : struct ice_fltr_list_entry *mv_list_itr;
5500 : : struct ice_sw_recipe *recp_list;
5501 : :
5502 [ # # ]: 0 : if (!mv_list || !hw)
5503 : : return ICE_ERR_PARAM;
5504 : :
5505 : 0 : recp_list = &sw->recp_list[ICE_SW_LKUP_MAC_VLAN];
5506 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(mv_list_itr, mv_list, ice_fltr_list_entry,
# # ]
5507 : : list_entry) {
5508 : 0 : enum ice_sw_lkup_type l_type =
5509 : : mv_list_itr->fltr_info.lkup_type;
5510 : :
5511 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_MAC_VLAN)
5512 : : return ICE_ERR_PARAM;
5513 : 0 : mv_list_itr->fltr_info.flag = ICE_FLTR_TX;
5514 : 0 : mv_list_itr->status =
5515 : 0 : ice_add_rule_internal(hw, recp_list, lport,
5516 : : mv_list_itr);
5517 [ # # ]: 0 : if (mv_list_itr->status)
5518 : 0 : return mv_list_itr->status;
5519 : : }
5520 : : return 0;
5521 : : }
5522 : :
5523 : : /**
5524 : : * ice_add_mac_vlan - Add a MAC VLAN address based filter rule
5525 : : * @hw: pointer to the hardware structure
5526 : : * @mv_list: list of MAC VLAN addresses and forwarding information
5527 : : *
5528 : : * Function add MAC VLAN rule for logical port from HW struct
5529 : : */
5530 : : int
5531 : 0 : ice_add_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
5532 : : {
5533 [ # # ]: 0 : if (!mv_list || !hw)
5534 : : return ICE_ERR_PARAM;
5535 : :
5536 : 0 : return ice_add_mac_vlan_rule(hw, mv_list, hw->switch_info,
5537 : 0 : hw->port_info->lport);
5538 : : }
5539 : :
5540 : : /**
5541 : : * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule
5542 : : * @hw: pointer to the hardware structure
5543 : : * @em_list: list of ether type MAC filter, MAC is optional
5544 : : * @sw: pointer to switch info struct for which function add rule
5545 : : * @lport: logic port number on which function add rule
5546 : : *
5547 : : * This function requires the caller to populate the entries in
5548 : : * the filter list with the necessary fields (including flags to
5549 : : * indicate Tx or Rx rules).
5550 : : */
5551 : : static int
5552 : 0 : ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5553 : : struct ice_switch_info *sw, u8 lport)
5554 : : {
5555 : : struct ice_fltr_list_entry *em_list_itr;
5556 : :
5557 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry,
# # ]
5558 : : list_entry) {
5559 : : struct ice_sw_recipe *recp_list;
5560 : : enum ice_sw_lkup_type l_type;
5561 : :
5562 : 0 : l_type = em_list_itr->fltr_info.lkup_type;
5563 : 0 : recp_list = &sw->recp_list[l_type];
5564 : :
5565 : 0 : if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5566 [ # # ]: 0 : l_type != ICE_SW_LKUP_ETHERTYPE)
5567 : : return ICE_ERR_PARAM;
5568 : :
5569 : 0 : em_list_itr->status = ice_add_rule_internal(hw, recp_list,
5570 : : lport,
5571 : : em_list_itr);
5572 [ # # ]: 0 : if (em_list_itr->status)
5573 : 0 : return em_list_itr->status;
5574 : : }
5575 : : return 0;
5576 : : }
5577 : :
5578 : : /**
5579 : : * ice_add_eth_mac - Add a ethertype based filter rule
5580 : : * @hw: pointer to the hardware structure
5581 : : * @em_list: list of ethertype and forwarding information
5582 : : *
5583 : : * Function add ethertype rule for logical port from HW struct
5584 : : */
5585 : : int
5586 : 0 : ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5587 : : {
5588 [ # # ]: 0 : if (!em_list || !hw)
5589 : : return ICE_ERR_PARAM;
5590 : :
5591 : 0 : return ice_add_eth_mac_rule(hw, em_list, hw->switch_info,
5592 : 0 : hw->port_info->lport);
5593 : : }
5594 : :
5595 : : /**
5596 : : * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule
5597 : : * @hw: pointer to the hardware structure
5598 : : * @em_list: list of ethertype or ethertype MAC entries
5599 : : * @sw: pointer to switch info struct for which function add rule
5600 : : */
5601 : : static int
5602 : 0 : ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list,
5603 : : struct ice_switch_info *sw)
5604 : : {
5605 : : struct ice_fltr_list_entry *em_list_itr, *tmp;
5606 : :
5607 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry,
# # # # #
# ]
5608 : : list_entry) {
5609 : : struct ice_sw_recipe *recp_list;
5610 : : enum ice_sw_lkup_type l_type;
5611 : :
5612 : 0 : l_type = em_list_itr->fltr_info.lkup_type;
5613 : :
5614 : 0 : if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
5615 [ # # ]: 0 : l_type != ICE_SW_LKUP_ETHERTYPE)
5616 : : return ICE_ERR_PARAM;
5617 : :
5618 : 0 : recp_list = &sw->recp_list[l_type];
5619 : 0 : em_list_itr->status = ice_remove_rule_internal(hw, recp_list,
5620 : : em_list_itr);
5621 [ # # ]: 0 : if (em_list_itr->status)
5622 : 0 : return em_list_itr->status;
5623 : : }
5624 : : return 0;
5625 : : }
5626 : :
5627 : : /**
5628 : : * ice_remove_eth_mac - remove a ethertype based filter rule
5629 : : * @hw: pointer to the hardware structure
5630 : : * @em_list: list of ethertype and forwarding information
5631 : : *
5632 : : */
5633 : : int
5634 : 0 : ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list)
5635 : : {
5636 [ # # ]: 0 : if (!em_list || !hw)
5637 : : return ICE_ERR_PARAM;
5638 : :
5639 : 0 : return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info);
5640 : : }
5641 : :
5642 : : /**
5643 : : * ice_get_lg_act_aqc_res_type - get resource type for a large action
5644 : : * @res_type: resource type to be filled in case of function success
5645 : : * @num_acts: number of actions to hold with a large action entry
5646 : : *
5647 : : * Get resource type for a large action depending on the number
5648 : : * of single actions that it contains.
5649 : : */
5650 : : static int
5651 : : ice_get_lg_act_aqc_res_type(u16 *res_type, int num_acts)
5652 : : {
5653 : : if (!res_type)
5654 : : return ICE_ERR_BAD_PTR;
5655 : :
5656 : : /* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1.
5657 : : * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3.
5658 : : * If num_acts is greater than 2, then use
5659 : : * ICE_AQC_RES_TYPE_WIDE_TABLE_4.
5660 : : * The num_acts cannot be equal to 0 or greater than 4.
5661 : : */
5662 : : switch (num_acts) {
5663 : : case 1:
5664 : : *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_1;
5665 : : break;
5666 : : case 2:
5667 : : *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_2;
5668 : : break;
5669 : : case 3:
5670 : : case 4:
5671 : : *res_type = ICE_AQC_RES_TYPE_WIDE_TABLE_4;
5672 : : break;
5673 : : default:
5674 : : return ICE_ERR_PARAM;
5675 : : }
5676 : :
5677 : : return 0;
5678 : : }
5679 : :
5680 : : /**
5681 : : * ice_alloc_res_lg_act - add large action resource
5682 : : * @hw: pointer to the hardware structure
5683 : : * @l_id: large action ID to fill it in
5684 : : * @num_acts: number of actions to hold with a large action entry
5685 : : */
5686 : : static int
5687 : 0 : ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts)
5688 : : {
5689 : : struct ice_aqc_alloc_free_res_elem *sw_buf;
5690 : : u16 buf_len, res_type;
5691 : : int status;
5692 : :
5693 [ # # ]: 0 : if (!l_id)
5694 : : return ICE_ERR_BAD_PTR;
5695 : :
5696 : : status = ice_get_lg_act_aqc_res_type(&res_type, num_acts);
5697 : : if (status)
5698 : : return status;
5699 : :
5700 : : /* Allocate resource for large action */
5701 : : buf_len = ice_struct_size(sw_buf, elem, 1);
5702 : 0 : sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
5703 [ # # ]: 0 : if (!sw_buf)
5704 : : return ICE_ERR_NO_MEMORY;
5705 : :
5706 : 0 : sw_buf->res_type = CPU_TO_LE16(res_type);
5707 : 0 : sw_buf->num_elems = CPU_TO_LE16(1);
5708 : :
5709 : 0 : status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
5710 : : ice_aqc_opc_alloc_res, NULL);
5711 [ # # ]: 0 : if (!status)
5712 : 0 : *l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp);
5713 : :
5714 : 0 : ice_free(hw, sw_buf);
5715 : :
5716 : 0 : return status;
5717 : : }
5718 : :
5719 : : /**
5720 : : * ice_rem_sw_rule_info
5721 : : * @hw: pointer to the hardware structure
5722 : : * @rule_head: pointer to the switch list structure that we want to delete
5723 : : */
5724 : : static void
5725 : 0 : ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5726 : : {
5727 [ # # ]: 0 : if (!LIST_EMPTY(rule_head)) {
5728 : : struct ice_fltr_mgmt_list_entry *entry;
5729 : : struct ice_fltr_mgmt_list_entry *tmp;
5730 : :
5731 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head,
# # # # #
# ]
5732 : : ice_fltr_mgmt_list_entry, list_entry) {
5733 [ # # ]: 0 : LIST_DEL(&entry->list_entry);
5734 : 0 : ice_free(hw, entry);
5735 : : }
5736 : : }
5737 : 0 : }
5738 : :
5739 : : /**
5740 : : * ice_rem_adv_rule_info
5741 : : * @hw: pointer to the hardware structure
5742 : : * @rule_head: pointer to the switch list structure that we want to delete
5743 : : */
5744 : : static void
5745 : 0 : ice_rem_adv_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head)
5746 : : {
5747 : : struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
5748 : : struct ice_adv_fltr_mgmt_list_entry *lst_itr;
5749 : :
5750 [ # # ]: 0 : if (LIST_EMPTY(rule_head))
5751 : : return;
5752 : :
5753 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry, rule_head,
# # # # ]
5754 : : ice_adv_fltr_mgmt_list_entry, list_entry) {
5755 [ # # ]: 0 : LIST_DEL(&lst_itr->list_entry);
5756 : 0 : ice_free(hw, lst_itr->lkups);
5757 : 0 : ice_free(hw, lst_itr);
5758 : : }
5759 : : }
5760 : :
5761 : : /**
5762 : : * ice_rem_all_sw_rules_info
5763 : : * @hw: pointer to the hardware structure
5764 : : */
5765 : 0 : void ice_rem_all_sw_rules_info(struct ice_hw *hw)
5766 : : {
5767 : 0 : struct ice_switch_info *sw = hw->switch_info;
5768 : : u8 i;
5769 : :
5770 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
5771 : : struct LIST_HEAD_TYPE *rule_head;
5772 : :
5773 : 0 : rule_head = &sw->recp_list[i].filt_rules;
5774 [ # # ]: 0 : if (!sw->recp_list[i].adv_rule)
5775 : 0 : ice_rem_sw_rule_info(hw, rule_head);
5776 : : else
5777 : 0 : ice_rem_adv_rule_info(hw, rule_head);
5778 [ # # ]: 0 : if (sw->recp_list[i].adv_rule &&
5779 [ # # ]: 0 : LIST_EMPTY(&sw->recp_list[i].filt_rules))
5780 : 0 : sw->recp_list[i].adv_rule = false;
5781 : : }
5782 : 0 : }
5783 : :
5784 : : /**
5785 : : * ice_cfg_dflt_vsi - change state of VSI to set/clear default
5786 : : * @pi: pointer to the port_info structure
5787 : : * @vsi_handle: VSI handle to set as default
5788 : : * @set: true to add the above mentioned switch rule, false to remove it
5789 : : * @direction: ICE_FLTR_RX or ICE_FLTR_TX
5790 : : *
5791 : : * add filter rule to set/unset given VSI as default VSI for the switch
5792 : : * (represented by swid)
5793 : : */
5794 : : int
5795 : 0 : ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
5796 : : u8 direction)
5797 : : {
5798 : : struct ice_fltr_list_entry f_list_entry;
5799 : : struct ice_sw_recipe *recp_list = NULL;
5800 : : struct ice_fltr_info f_info;
5801 : 0 : struct ice_hw *hw = pi->hw;
5802 : 0 : u8 lport = pi->lport;
5803 : : u16 hw_vsi_id;
5804 : : int status;
5805 : :
5806 : 0 : recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
5807 : :
5808 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5809 : : return ICE_ERR_PARAM;
5810 : :
5811 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
5812 : :
5813 : : ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM);
5814 : :
5815 : 0 : f_info.lkup_type = ICE_SW_LKUP_DFLT;
5816 : 0 : f_info.flag = direction;
5817 : : f_info.fltr_act = ICE_FWD_TO_VSI;
5818 : 0 : f_info.fwd_id.hw_vsi_id = hw_vsi_id;
5819 : 0 : f_info.vsi_handle = vsi_handle;
5820 : :
5821 [ # # ]: 0 : if (f_info.flag & ICE_FLTR_RX) {
5822 : 0 : f_info.src = pi->lport;
5823 : 0 : f_info.src_id = ICE_SRC_ID_LPORT;
5824 [ # # ]: 0 : } else if (f_info.flag & ICE_FLTR_TX) {
5825 : 0 : f_info.src_id = ICE_SRC_ID_VSI;
5826 : 0 : f_info.src = hw_vsi_id;
5827 : : }
5828 : 0 : f_list_entry.fltr_info = f_info;
5829 : :
5830 [ # # ]: 0 : if (set)
5831 : 0 : status = ice_add_rule_internal(hw, recp_list, lport,
5832 : : &f_list_entry);
5833 : : else
5834 : 0 : status = ice_remove_rule_internal(hw, recp_list,
5835 : : &f_list_entry);
5836 : :
5837 : : return status;
5838 : : }
5839 : :
5840 : : /**
5841 : : * ice_check_if_dflt_vsi - check if VSI is default VSI
5842 : : * @pi: pointer to the port_info structure
5843 : : * @vsi_handle: vsi handle to check for in filter list
5844 : : * @rule_exists: indicates if there are any VSI's in the rule list
5845 : : *
5846 : : * checks if the VSI is in a default VSI list, and also indicates
5847 : : * if the default VSI list is empty
5848 : : */
5849 : 0 : bool ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
5850 : : bool *rule_exists)
5851 : : {
5852 : : struct ice_fltr_mgmt_list_entry *fm_entry;
5853 : : struct LIST_HEAD_TYPE *rule_head;
5854 : : struct ice_sw_recipe *recp_list;
5855 : : struct ice_lock *rule_lock;
5856 : : bool ret = false;
5857 : 0 : recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
5858 : : rule_lock = &recp_list->filt_rule_lock;
5859 : : rule_head = &recp_list->filt_rules;
5860 : :
5861 : 0 : ice_acquire_lock(rule_lock);
5862 : :
5863 [ # # # # ]: 0 : if (rule_exists && !LIST_EMPTY(rule_head))
5864 : 0 : *rule_exists = true;
5865 : :
5866 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fm_entry, rule_head,
# # ]
5867 : : ice_fltr_mgmt_list_entry, list_entry) {
5868 : 0 : if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
5869 : : ret = true;
5870 : : break;
5871 : : }
5872 : : }
5873 : :
5874 : : ice_release_lock(rule_lock);
5875 : 0 : return ret;
5876 : : }
5877 : :
5878 : : /**
5879 : : * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry
5880 : : * @list_head: head of rule list
5881 : : * @f_info: rule information
5882 : : *
5883 : : * Helper function to search for a unicast rule entry - this is to be used
5884 : : * to remove unicast MAC filter that is not shared with other VSIs on the
5885 : : * PF switch.
5886 : : *
5887 : : * Returns pointer to entry storing the rule if found
5888 : : */
5889 : : static struct ice_fltr_mgmt_list_entry *
5890 : 0 : ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head,
5891 : : struct ice_fltr_info *f_info)
5892 : : {
5893 : : struct ice_fltr_mgmt_list_entry *list_itr;
5894 : :
5895 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry,
# # ]
5896 : : list_entry) {
5897 [ # # ]: 0 : if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
5898 : 0 : sizeof(f_info->l_data)) &&
5899 : 0 : f_info->fwd_id.hw_vsi_id ==
5900 [ # # ]: 0 : list_itr->fltr_info.fwd_id.hw_vsi_id &&
5901 [ # # ]: 0 : f_info->flag == list_itr->fltr_info.flag)
5902 : 0 : return list_itr;
5903 : : }
5904 : : return NULL;
5905 : : }
5906 : :
5907 : : /**
5908 : : * ice_remove_mac_rule - remove a MAC based filter rule
5909 : : * @hw: pointer to the hardware structure
5910 : : * @m_list: list of MAC addresses and forwarding information
5911 : : * @recp_list: list from which function remove MAC address
5912 : : *
5913 : : * This function removes either a MAC filter rule or a specific VSI from a
5914 : : * VSI list for a multicast MAC address.
5915 : : *
5916 : : * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by
5917 : : * ice_add_mac. Caller should be aware that this call will only work if all
5918 : : * the entries passed into m_list were added previously. It will not attempt to
5919 : : * do a partial remove of entries that were found.
5920 : : */
5921 : : static int
5922 : 0 : ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list,
5923 : : struct ice_sw_recipe *recp_list)
5924 : : {
5925 : : struct ice_fltr_list_entry *list_itr, *tmp;
5926 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
5927 : :
5928 [ # # ]: 0 : if (!m_list)
5929 : : return ICE_ERR_PARAM;
5930 : :
5931 : : rule_lock = &recp_list->filt_rule_lock;
5932 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry,
# # # # #
# ]
5933 : : list_entry) {
5934 : 0 : enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
5935 : : u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
5936 : : u16 vsi_handle;
5937 : :
5938 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_MAC)
5939 : : return ICE_ERR_PARAM;
5940 : :
5941 : 0 : vsi_handle = list_itr->fltr_info.vsi_handle;
5942 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
5943 : : return ICE_ERR_PARAM;
5944 : :
5945 : 0 : list_itr->fltr_info.fwd_id.hw_vsi_id =
5946 : 0 : ice_get_hw_vsi_num(hw, vsi_handle);
5947 [ # # # # ]: 0 : if (IS_UNICAST_ETHER_ADDR(add) && !hw->umac_shared) {
5948 : : /* Don't remove the unicast address that belongs to
5949 : : * another VSI on the switch, since it is not being
5950 : : * shared...
5951 : : */
5952 : 0 : ice_acquire_lock(rule_lock);
5953 [ # # ]: 0 : if (!ice_find_ucast_rule_entry(&recp_list->filt_rules,
5954 : : &list_itr->fltr_info)) {
5955 : : ice_release_lock(rule_lock);
5956 : 0 : return ICE_ERR_DOES_NOT_EXIST;
5957 : : }
5958 : : ice_release_lock(rule_lock);
5959 : : }
5960 : 0 : list_itr->status = ice_remove_rule_internal(hw, recp_list,
5961 : : list_itr);
5962 [ # # ]: 0 : if (list_itr->status)
5963 : 0 : return list_itr->status;
5964 : : }
5965 : : return 0;
5966 : : }
5967 : :
5968 : : /**
5969 : : * ice_remove_mac - remove a MAC address based filter rule
5970 : : * @hw: pointer to the hardware structure
5971 : : * @m_list: list of MAC addresses and forwarding information
5972 : : *
5973 : : */
5974 : 0 : int ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list)
5975 : : {
5976 : : struct ice_sw_recipe *recp_list;
5977 : :
5978 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
5979 : 0 : return ice_remove_mac_rule(hw, m_list, recp_list);
5980 : : }
5981 : :
5982 : : /**
5983 : : * ice_remove_vlan_rule - Remove VLAN based filter rule
5984 : : * @hw: pointer to the hardware structure
5985 : : * @v_list: list of VLAN entries and forwarding information
5986 : : * @recp_list: list from which function remove VLAN
5987 : : */
5988 : : static int
5989 : 0 : ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
5990 : : struct ice_sw_recipe *recp_list)
5991 : : {
5992 : : struct ice_fltr_list_entry *v_list_itr, *tmp;
5993 : :
5994 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
# # # # #
# ]
5995 : : list_entry) {
5996 : 0 : enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
5997 : :
5998 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_VLAN)
5999 : : return ICE_ERR_PARAM;
6000 : 0 : v_list_itr->status = ice_remove_rule_internal(hw, recp_list,
6001 : : v_list_itr);
6002 [ # # ]: 0 : if (v_list_itr->status)
6003 : 0 : return v_list_itr->status;
6004 : : }
6005 : : return 0;
6006 : : }
6007 : :
6008 : : /**
6009 : : * ice_remove_vlan - remove a VLAN address based filter rule
6010 : : * @hw: pointer to the hardware structure
6011 : : * @v_list: list of VLAN and forwarding information
6012 : : *
6013 : : */
6014 : : int
6015 : 0 : ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list)
6016 : : {
6017 : : struct ice_sw_recipe *recp_list;
6018 : :
6019 [ # # ]: 0 : if (!v_list || !hw)
6020 : : return ICE_ERR_PARAM;
6021 : :
6022 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN];
6023 : 0 : return ice_remove_vlan_rule(hw, v_list, recp_list);
6024 : : }
6025 : :
6026 : : /**
6027 : : * ice_remove_mac_vlan_rule - Remove MAC VLAN based filter rule
6028 : : * @hw: pointer to the hardware structure
6029 : : * @v_list: list of MAC VLAN entries and forwarding information
6030 : : * @recp_list: list from which function remove MAC VLAN
6031 : : */
6032 : : static int
6033 : 0 : ice_remove_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list,
6034 : : struct ice_sw_recipe *recp_list)
6035 : : {
6036 : : struct ice_fltr_list_entry *v_list_itr, *tmp;
6037 : :
6038 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
6039 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
# # # # #
# ]
6040 : : list_entry) {
6041 : 0 : enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
6042 : :
6043 [ # # ]: 0 : if (l_type != ICE_SW_LKUP_MAC_VLAN)
6044 : : return ICE_ERR_PARAM;
6045 : 0 : v_list_itr->status =
6046 : 0 : ice_remove_rule_internal(hw, recp_list,
6047 : : v_list_itr);
6048 [ # # ]: 0 : if (v_list_itr->status)
6049 : 0 : return v_list_itr->status;
6050 : : }
6051 : : return 0;
6052 : : }
6053 : :
6054 : : /**
6055 : : * ice_remove_mac_vlan - remove a MAC VLAN address based filter rule
6056 : : * @hw: pointer to the hardware structure
6057 : : * @mv_list: list of MAC VLAN and forwarding information
6058 : : */
6059 : : int
6060 : 0 : ice_remove_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list)
6061 : : {
6062 : : struct ice_sw_recipe *recp_list;
6063 : :
6064 [ # # ]: 0 : if (!mv_list || !hw)
6065 : : return ICE_ERR_PARAM;
6066 : :
6067 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN];
6068 : 0 : return ice_remove_mac_vlan_rule(hw, mv_list, recp_list);
6069 : : }
6070 : :
6071 : : /**
6072 : : * ice_vsi_uses_fltr - Determine if given VSI uses specified filter
6073 : : * @fm_entry: filter entry to inspect
6074 : : * @vsi_handle: VSI handle to compare with filter info
6075 : : */
6076 : : static bool
6077 : : ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
6078 : : {
6079 : 0 : return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
6080 [ # # # # : 0 : fm_entry->fltr_info.vsi_handle == vsi_handle) ||
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
6081 : 0 : (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
6082 [ # # # # : 0 : fm_entry->vsi_list_info &&
# # # # #
# # # # #
# # ]
6083 [ # # # # : 0 : (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map,
# # # # ]
6084 : : vsi_handle))));
6085 : : }
6086 : :
6087 : : /**
6088 : : * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list
6089 : : * @hw: pointer to the hardware structure
6090 : : * @vsi_handle: VSI handle to remove filters from
6091 : : * @vsi_list_head: pointer to the list to add entry to
6092 : : * @fi: pointer to fltr_info of filter entry to copy & add
6093 : : *
6094 : : * Helper function, used when creating a list of filters to remove from
6095 : : * a specific VSI. The entry added to vsi_list_head is a COPY of the
6096 : : * original filter entry, with the exception of fltr_info.fltr_act and
6097 : : * fltr_info.fwd_id fields. These are set such that later logic can
6098 : : * extract which VSI to remove the fltr from, and pass on that information.
6099 : : */
6100 : : static int
6101 : 0 : ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
6102 : : struct LIST_HEAD_TYPE *vsi_list_head,
6103 : : struct ice_fltr_info *fi)
6104 : : {
6105 : : struct ice_fltr_list_entry *tmp;
6106 : :
6107 : : /* this memory is freed up in the caller function
6108 : : * once filters for this VSI are removed
6109 : : */
6110 : 0 : tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp));
6111 [ # # ]: 0 : if (!tmp)
6112 : : return ICE_ERR_NO_MEMORY;
6113 : :
6114 : 0 : tmp->fltr_info = *fi;
6115 : :
6116 : : /* Overwrite these fields to indicate which VSI to remove filter from,
6117 : : * so find and remove logic can extract the information from the
6118 : : * list entries. Note that original entries will still have proper
6119 : : * values.
6120 : : */
6121 : 0 : tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
6122 : 0 : tmp->fltr_info.vsi_handle = vsi_handle;
6123 : 0 : tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6124 : :
6125 [ # # ]: 0 : LIST_ADD(&tmp->list_entry, vsi_list_head);
6126 : :
6127 : 0 : return 0;
6128 : : }
6129 : :
6130 : : /**
6131 : : * ice_add_to_vsi_fltr_list - Add VSI filters to the list
6132 : : * @hw: pointer to the hardware structure
6133 : : * @vsi_handle: VSI handle to remove filters from
6134 : : * @lkup_list_head: pointer to the list that has certain lookup type filters
6135 : : * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle
6136 : : *
6137 : : * Locates all filters in lkup_list_head that are used by the given VSI,
6138 : : * and adds COPIES of those entries to vsi_list_head (intended to be used
6139 : : * to remove the listed filters).
6140 : : * Note that this means all entries in vsi_list_head must be explicitly
6141 : : * deallocated by the caller when done with list.
6142 : : */
6143 : : static int
6144 : 0 : ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
6145 : : struct LIST_HEAD_TYPE *lkup_list_head,
6146 : : struct LIST_HEAD_TYPE *vsi_list_head)
6147 : : {
6148 : : struct ice_fltr_mgmt_list_entry *fm_entry;
6149 : : int status = 0;
6150 : :
6151 : : /* check to make sure VSI ID is valid and within boundary */
6152 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
6153 : : return ICE_ERR_PARAM;
6154 : :
6155 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head,
# # ]
6156 : : ice_fltr_mgmt_list_entry, list_entry) {
6157 [ # # ]: 0 : if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
6158 : 0 : continue;
6159 : :
6160 : 0 : status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
6161 : : vsi_list_head,
6162 : : &fm_entry->fltr_info);
6163 [ # # ]: 0 : if (status)
6164 : 0 : return status;
6165 : : }
6166 : : return status;
6167 : : }
6168 : :
6169 : : /**
6170 : : * ice_determine_promisc_mask
6171 : : * @fi: filter info to parse
6172 : : * @promisc_mask: pointer to mask to be filled in
6173 : : *
6174 : : * Helper function to determine which ICE_PROMISC_ mask corresponds
6175 : : * to given filter into.
6176 : : */
6177 : 0 : static void ice_determine_promisc_mask(struct ice_fltr_info *fi,
6178 : : ice_bitmap_t *promisc_mask)
6179 : : {
6180 [ # # ]: 0 : u16 vid = fi->l_data.mac_vlan.vlan_id;
6181 : : u8 *macaddr = fi->l_data.mac.mac_addr;
6182 : : bool is_rx_lb_fltr = false;
6183 : : bool is_tx_fltr = false;
6184 : :
6185 : : ice_zero_bitmap(promisc_mask, ICE_PROMISC_MAX);
6186 : :
6187 [ # # ]: 0 : if (fi->flag == ICE_FLTR_TX)
6188 : : is_tx_fltr = true;
6189 [ # # ]: 0 : if (fi->flag == ICE_FLTR_RX_LB)
6190 : : is_rx_lb_fltr = true;
6191 : :
6192 [ # # ]: 0 : if (IS_BROADCAST_ETHER_ADDR(macaddr)) {
6193 [ # # ]: 0 : ice_set_bit(is_tx_fltr ? ICE_PROMISC_BCAST_TX
6194 : : : ICE_PROMISC_BCAST_RX, promisc_mask);
6195 [ # # ]: 0 : } else if (IS_MULTICAST_ETHER_ADDR(macaddr)) {
6196 [ # # ]: 0 : ice_set_bit(is_tx_fltr ? ICE_PROMISC_MCAST_TX
6197 : : : ICE_PROMISC_MCAST_RX, promisc_mask);
6198 : : } else if (IS_UNICAST_ETHER_ADDR(macaddr)) {
6199 [ # # ]: 0 : if (is_tx_fltr)
6200 : : ice_set_bit(ICE_PROMISC_UCAST_TX, promisc_mask);
6201 [ # # ]: 0 : else if (is_rx_lb_fltr)
6202 : : ice_set_bit(ICE_PROMISC_UCAST_RX_LB, promisc_mask);
6203 : : else
6204 : : ice_set_bit(ICE_PROMISC_UCAST_RX, promisc_mask);
6205 : : }
6206 : :
6207 [ # # ]: 0 : if (vid) {
6208 [ # # ]: 0 : ice_set_bit(is_tx_fltr ? ICE_PROMISC_VLAN_TX
6209 : : : ICE_PROMISC_VLAN_RX, promisc_mask);
6210 : : }
6211 : 0 : }
6212 : :
6213 : : /**
6214 : : * _ice_get_vsi_promisc - get promiscuous mode of given VSI
6215 : : * @hw: pointer to the hardware structure
6216 : : * @vsi_handle: VSI handle to retrieve info from
6217 : : * @promisc_mask: pointer to mask to be filled in
6218 : : * @vid: VLAN ID of promisc VLAN VSI
6219 : : * @sw: pointer to switch info struct for which function add rule
6220 : : * @lkup: switch rule filter lookup type
6221 : : */
6222 : : static int
6223 : 0 : _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6224 : : ice_bitmap_t *promisc_mask, u16 *vid,
6225 : : struct ice_switch_info *sw, enum ice_sw_lkup_type lkup)
6226 : : {
6227 : : ice_declare_bitmap(fltr_promisc_mask, ICE_PROMISC_MAX);
6228 : : struct ice_fltr_mgmt_list_entry *itr;
6229 : : struct LIST_HEAD_TYPE *rule_head;
6230 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6231 : :
6232 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle) ||
6233 [ # # ]: 0 : (lkup != ICE_SW_LKUP_PROMISC && lkup != ICE_SW_LKUP_PROMISC_VLAN))
6234 : : return ICE_ERR_PARAM;
6235 : :
6236 : 0 : *vid = 0;
6237 : 0 : rule_head = &sw->recp_list[lkup].filt_rules;
6238 : : rule_lock = &sw->recp_list[lkup].filt_rule_lock;
6239 : :
6240 : : ice_zero_bitmap(promisc_mask, ICE_PROMISC_MAX);
6241 : :
6242 : 0 : ice_acquire_lock(rule_lock);
6243 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(itr, rule_head,
# # ]
6244 : : ice_fltr_mgmt_list_entry, list_entry) {
6245 : : /* Continue if this filter doesn't apply to this VSI or the
6246 : : * VSI ID is not in the VSI map for this filter
6247 : : */
6248 [ # # ]: 0 : if (!ice_vsi_uses_fltr(itr, vsi_handle))
6249 : 0 : continue;
6250 : :
6251 : 0 : ice_determine_promisc_mask(&itr->fltr_info, fltr_promisc_mask);
6252 : 0 : ice_or_bitmap(promisc_mask, promisc_mask, fltr_promisc_mask,
6253 : : ICE_PROMISC_MAX);
6254 : : }
6255 : : ice_release_lock(rule_lock);
6256 : :
6257 : 0 : return 0;
6258 : : }
6259 : :
6260 : : /**
6261 : : * ice_get_vsi_promisc - get promiscuous mode of given VSI
6262 : : * @hw: pointer to the hardware structure
6263 : : * @vsi_handle: VSI handle to retrieve info from
6264 : : * @promisc_mask: pointer to mask to be filled in
6265 : : * @vid: VLAN ID of promisc VLAN VSI
6266 : : */
6267 : : int
6268 : 0 : ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6269 : : ice_bitmap_t *promisc_mask, u16 *vid)
6270 : : {
6271 [ # # # # ]: 0 : if (!vid || !promisc_mask || !hw)
6272 : : return ICE_ERR_PARAM;
6273 : :
6274 : 0 : return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
6275 : : vid, hw->switch_info, ICE_SW_LKUP_PROMISC);
6276 : : }
6277 : :
6278 : : /**
6279 : : * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI
6280 : : * @hw: pointer to the hardware structure
6281 : : * @vsi_handle: VSI handle to retrieve info from
6282 : : * @promisc_mask: pointer to mask to be filled in
6283 : : * @vid: VLAN ID of promisc VLAN VSI
6284 : : */
6285 : : int
6286 : 0 : ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle,
6287 : : ice_bitmap_t *promisc_mask, u16 *vid)
6288 : : {
6289 [ # # # # ]: 0 : if (!hw || !promisc_mask || !vid)
6290 : : return ICE_ERR_PARAM;
6291 : :
6292 : 0 : return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask,
6293 : : vid, hw->switch_info,
6294 : : ICE_SW_LKUP_PROMISC_VLAN);
6295 : : }
6296 : :
6297 : : /**
6298 : : * ice_remove_promisc - Remove promisc based filter rules
6299 : : * @hw: pointer to the hardware structure
6300 : : * @recp_id: recipe ID for which the rule needs to removed
6301 : : * @v_list: list of promisc entries
6302 : : */
6303 : : static int
6304 : 0 : ice_remove_promisc(struct ice_hw *hw, u8 recp_id,
6305 : : struct LIST_HEAD_TYPE *v_list)
6306 : : {
6307 : : struct ice_fltr_list_entry *v_list_itr, *tmp;
6308 : : struct ice_sw_recipe *recp_list;
6309 : :
6310 : 0 : recp_list = &hw->switch_info->recp_list[recp_id];
6311 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry,
# # # # #
# ]
6312 : : list_entry) {
6313 : 0 : v_list_itr->status =
6314 : 0 : ice_remove_rule_internal(hw, recp_list, v_list_itr);
6315 [ # # ]: 0 : if (v_list_itr->status)
6316 : 0 : return v_list_itr->status;
6317 : : }
6318 : : return 0;
6319 : : }
6320 : :
6321 : : /**
6322 : : * _ice_clear_vsi_promisc - clear specified promiscuous mode(s)
6323 : : * @hw: pointer to the hardware structure
6324 : : * @vsi_handle: VSI handle to clear mode
6325 : : * @promisc_mask: pointer to mask of promiscuous config bits to clear
6326 : : * @vid: VLAN ID to clear VLAN promiscuous
6327 : : * @sw: pointer to switch info struct for which function add rule
6328 : : */
6329 : : static int
6330 : 0 : _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6331 : : ice_bitmap_t *promisc_mask, u16 vid,
6332 : : struct ice_switch_info *sw)
6333 : : {
6334 : : ice_declare_bitmap(compl_promisc_mask, ICE_PROMISC_MAX);
6335 : : ice_declare_bitmap(fltr_promisc_mask, ICE_PROMISC_MAX);
6336 : : struct ice_fltr_list_entry *fm_entry, *tmp;
6337 : : struct LIST_HEAD_TYPE remove_list_head;
6338 : : struct ice_fltr_mgmt_list_entry *itr;
6339 : : struct LIST_HEAD_TYPE *rule_head;
6340 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6341 : : int status = 0;
6342 : : u8 recipe_id;
6343 : :
6344 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
6345 : : return ICE_ERR_PARAM;
6346 : :
6347 [ # # # # ]: 0 : if (ice_is_bit_set(promisc_mask, ICE_PROMISC_VLAN_RX) &&
6348 : : ice_is_bit_set(promisc_mask, ICE_PROMISC_VLAN_TX))
6349 : : recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
6350 : : else
6351 : : recipe_id = ICE_SW_LKUP_PROMISC;
6352 : :
6353 : 0 : rule_head = &sw->recp_list[recipe_id].filt_rules;
6354 : : rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
6355 : :
6356 : 0 : INIT_LIST_HEAD(&remove_list_head);
6357 : :
6358 : 0 : ice_acquire_lock(rule_lock);
6359 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(itr, rule_head,
# # ]
6360 : : ice_fltr_mgmt_list_entry, list_entry) {
6361 : : struct ice_fltr_info *fltr_info;
6362 : : ice_zero_bitmap(compl_promisc_mask, ICE_PROMISC_MAX);
6363 : :
6364 [ # # ]: 0 : if (!ice_vsi_uses_fltr(itr, vsi_handle))
6365 : 0 : continue;
6366 : 0 : fltr_info = &itr->fltr_info;
6367 : :
6368 [ # # ]: 0 : if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
6369 [ # # ]: 0 : vid != fltr_info->l_data.mac_vlan.vlan_id)
6370 : 0 : continue;
6371 : :
6372 : 0 : ice_determine_promisc_mask(fltr_info, fltr_promisc_mask);
6373 : 0 : ice_andnot_bitmap(compl_promisc_mask, fltr_promisc_mask,
6374 : : promisc_mask, ICE_PROMISC_MAX);
6375 : :
6376 : : /* Skip if filter is not completely specified by given mask */
6377 [ # # ]: 0 : if (ice_is_any_bit_set(compl_promisc_mask, ICE_PROMISC_MAX))
6378 : 0 : continue;
6379 : :
6380 : 0 : status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
6381 : : &remove_list_head,
6382 : : fltr_info);
6383 [ # # ]: 0 : if (status) {
6384 : : ice_release_lock(rule_lock);
6385 : 0 : goto free_fltr_list;
6386 : : }
6387 : : }
6388 : : ice_release_lock(rule_lock);
6389 : :
6390 : 0 : status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
6391 : :
6392 : 0 : free_fltr_list:
6393 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
# # # # #
# ]
6394 : : ice_fltr_list_entry, list_entry) {
6395 [ # # ]: 0 : LIST_DEL(&fm_entry->list_entry);
6396 : 0 : ice_free(hw, fm_entry);
6397 : : }
6398 : :
6399 : : return status;
6400 : : }
6401 : :
6402 : : /**
6403 : : * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI
6404 : : * @hw: pointer to the hardware structure
6405 : : * @vsi_handle: VSI handle to clear mode
6406 : : * @promisc_mask: pointer to mask of promiscuous config bits to clear
6407 : : * @vid: VLAN ID to clear VLAN promiscuous
6408 : : */
6409 : : int
6410 : 0 : ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6411 : : ice_bitmap_t *promisc_mask, u16 vid)
6412 : : {
6413 [ # # ]: 0 : if (!hw || !promisc_mask)
6414 : : return ICE_ERR_PARAM;
6415 : :
6416 : 0 : return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask,
6417 : : vid, hw->switch_info);
6418 : : }
6419 : :
6420 : : /**
6421 : : * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
6422 : : * @hw: pointer to the hardware structure
6423 : : * @vsi_handle: VSI handle to configure
6424 : : * @promisc_mask: pointer to mask of promiscuous config bits
6425 : : * @vid: VLAN ID to set VLAN promiscuous
6426 : : * @lport: logical port number to configure promisc mode
6427 : : * @sw: pointer to switch info struct for which function add rule
6428 : : */
6429 : : static int
6430 : 0 : _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6431 : : ice_bitmap_t *promisc_mask, u16 vid, u8 lport,
6432 : : struct ice_switch_info *sw)
6433 : : {
6434 : : enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
6435 : : ice_declare_bitmap(p_mask, ICE_PROMISC_MAX);
6436 : : struct ice_fltr_list_entry f_list_entry;
6437 : : bool is_tx_fltr, is_rx_lb_fltr;
6438 : : struct ice_fltr_info new_fltr;
6439 : : int status = 0;
6440 : : u16 hw_vsi_id;
6441 : : int pkt_type;
6442 : : u8 recipe_id;
6443 : :
6444 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6445 : :
6446 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
6447 : : return ICE_ERR_PARAM;
6448 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6449 : :
6450 : : ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM);
6451 : :
6452 : : /* Do not modify original bitmap */
6453 : 0 : ice_cp_bitmap(p_mask, promisc_mask, ICE_PROMISC_MAX);
6454 : :
6455 [ # # # # ]: 0 : if (ice_is_bit_set(p_mask, ICE_PROMISC_VLAN_RX) &&
6456 : : ice_is_bit_set(p_mask, ICE_PROMISC_VLAN_TX)) {
6457 : 0 : new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
6458 : 0 : new_fltr.l_data.mac_vlan.vlan_id = vid;
6459 : 0 : recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
6460 : : } else {
6461 : 0 : new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
6462 : : recipe_id = ICE_SW_LKUP_PROMISC;
6463 : : }
6464 : :
6465 : : /* Separate filters must be set for each direction/packet type
6466 : : * combination, so we will loop over the mask value, store the
6467 : : * individual type, and clear it out in the input mask as it
6468 : : * is found.
6469 : : */
6470 [ # # ]: 0 : while (ice_is_any_bit_set(p_mask, ICE_PROMISC_MAX)) {
6471 : : struct ice_sw_recipe *recp_list;
6472 : : u8 *mac_addr;
6473 : :
6474 : : pkt_type = 0;
6475 : : is_tx_fltr = false;
6476 : : is_rx_lb_fltr = false;
6477 : :
6478 : : if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_RX,
6479 : : p_mask)) {
6480 : : pkt_type = UCAST_FLTR;
6481 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_TX,
6482 : : p_mask)) {
6483 : : pkt_type = UCAST_FLTR;
6484 : : is_tx_fltr = true;
6485 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_MCAST_RX,
6486 : : p_mask)) {
6487 : : pkt_type = MCAST_FLTR;
6488 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_MCAST_TX,
6489 : : p_mask)) {
6490 : : pkt_type = MCAST_FLTR;
6491 : : is_tx_fltr = true;
6492 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_BCAST_RX,
6493 : : p_mask)) {
6494 : : pkt_type = BCAST_FLTR;
6495 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_BCAST_TX,
6496 : : p_mask)) {
6497 : : pkt_type = BCAST_FLTR;
6498 : : is_tx_fltr = true;
6499 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_UCAST_RX_LB,
6500 : : p_mask)) {
6501 : : pkt_type = UCAST_FLTR;
6502 : : is_rx_lb_fltr = true;
6503 : : }
6504 : :
6505 : : /* Check for VLAN promiscuous flag */
6506 [ # # ]: 0 : if (ice_is_bit_set(p_mask, ICE_PROMISC_VLAN_RX)) {
6507 : : ice_clear_bit(ICE_PROMISC_VLAN_RX, p_mask);
6508 : : } else if (ice_test_and_clear_bit(ICE_PROMISC_VLAN_TX,
6509 : : p_mask)) {
6510 : : is_tx_fltr = true;
6511 : : }
6512 : : /* Set filter DA based on packet type */
6513 : : mac_addr = new_fltr.l_data.mac.mac_addr;
6514 [ # # ]: 0 : if (pkt_type == BCAST_FLTR) {
6515 : : ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM);
6516 [ # # ]: 0 : } else if (pkt_type == MCAST_FLTR ||
6517 : : pkt_type == UCAST_FLTR) {
6518 : : /* Use the dummy ether header DA */
6519 : : ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN,
6520 : : ICE_NONDMA_TO_NONDMA);
6521 [ # # ]: 0 : if (pkt_type == MCAST_FLTR)
6522 : 0 : mac_addr[0] |= 0x1; /* Set multicast bit */
6523 : : }
6524 : :
6525 : : /* Need to reset this to zero for all iterations */
6526 : : new_fltr.flag = 0;
6527 [ # # ]: 0 : if (is_tx_fltr) {
6528 : 0 : new_fltr.flag |= ICE_FLTR_TX;
6529 : 0 : new_fltr.src = hw_vsi_id;
6530 [ # # ]: 0 : } else if (is_rx_lb_fltr) {
6531 : 0 : new_fltr.flag |= ICE_FLTR_RX_LB;
6532 : 0 : new_fltr.src = hw_vsi_id;
6533 : : } else {
6534 : 0 : new_fltr.flag |= ICE_FLTR_RX;
6535 : 0 : new_fltr.src = lport;
6536 : : }
6537 : :
6538 : 0 : new_fltr.fltr_act = ICE_FWD_TO_VSI;
6539 : 0 : new_fltr.vsi_handle = vsi_handle;
6540 : 0 : new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
6541 : 0 : f_list_entry.fltr_info = new_fltr;
6542 : 0 : recp_list = &sw->recp_list[recipe_id];
6543 : :
6544 : 0 : status = ice_add_rule_internal(hw, recp_list, lport,
6545 : : &f_list_entry);
6546 [ # # ]: 0 : if (status)
6547 : 0 : goto set_promisc_exit;
6548 : : }
6549 : :
6550 : 0 : set_promisc_exit:
6551 : : return status;
6552 : : }
6553 : :
6554 : : /**
6555 : : * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s)
6556 : : * @hw: pointer to the hardware structure
6557 : : * @vsi_handle: VSI handle to configure
6558 : : * @promisc_mask: pointer to mask of promiscuous config bits
6559 : : * @vid: VLAN ID to set VLAN promiscuous
6560 : : */
6561 : : int
6562 : 0 : ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6563 : : ice_bitmap_t *promisc_mask, u16 vid)
6564 : : {
6565 [ # # ]: 0 : if (!hw || !promisc_mask)
6566 : : return ICE_ERR_PARAM;
6567 : :
6568 : 0 : return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid,
6569 : 0 : hw->port_info->lport,
6570 : : hw->switch_info);
6571 : : }
6572 : :
6573 : : /**
6574 : : * _ice_set_vlan_vsi_promisc
6575 : : * @hw: pointer to the hardware structure
6576 : : * @vsi_handle: VSI handle to configure
6577 : : * @promisc_mask: pointer to mask of promiscuous config bits
6578 : : * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6579 : : * @lport: logical port number to configure promisc mode
6580 : : * @sw: pointer to switch info struct for which function add rule
6581 : : *
6582 : : * Configure VSI with all associated VLANs to given promiscuous mode(s)
6583 : : */
6584 : : static int
6585 : 0 : _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6586 : : ice_bitmap_t *promisc_mask, bool rm_vlan_promisc,
6587 : : u8 lport, struct ice_switch_info *sw)
6588 : : {
6589 : : struct ice_fltr_list_entry *list_itr, *tmp;
6590 : : struct LIST_HEAD_TYPE vsi_list_head;
6591 : : struct LIST_HEAD_TYPE *vlan_head;
6592 : : struct ice_lock *vlan_lock; /* Lock to protect filter rule list */
6593 : : int status;
6594 : : u16 vlan_id;
6595 : :
6596 : 0 : INIT_LIST_HEAD(&vsi_list_head);
6597 : 0 : vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
6598 : 0 : vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
6599 : 0 : ice_acquire_lock(vlan_lock);
6600 : 0 : status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
6601 : : &vsi_list_head);
6602 : : ice_release_lock(vlan_lock);
6603 [ # # ]: 0 : if (status)
6604 : 0 : goto free_fltr_list;
6605 : :
6606 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry,
# # ]
6607 : : list_entry) {
6608 : : /* Avoid enabling or disabling vlan zero twice when in double
6609 : : * vlan mode
6610 : : */
6611 [ # # ]: 0 : if (ice_is_dvm_ena(hw) &&
6612 [ # # ]: 0 : list_itr->fltr_info.l_data.vlan.tpid == 0)
6613 : 0 : continue;
6614 : :
6615 : 0 : vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
6616 [ # # ]: 0 : if (rm_vlan_promisc)
6617 : 0 : status = _ice_clear_vsi_promisc(hw, vsi_handle,
6618 : : promisc_mask,
6619 : : vlan_id, sw);
6620 : : else
6621 : 0 : status = _ice_set_vsi_promisc(hw, vsi_handle,
6622 : : promisc_mask, vlan_id,
6623 : : lport, sw);
6624 [ # # ]: 0 : if (status && status != ICE_ERR_ALREADY_EXISTS)
6625 : : break;
6626 : : }
6627 : :
6628 : 0 : free_fltr_list:
6629 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head,
# # # # #
# ]
6630 : : ice_fltr_list_entry, list_entry) {
6631 [ # # ]: 0 : LIST_DEL(&list_itr->list_entry);
6632 : 0 : ice_free(hw, list_itr);
6633 : : }
6634 : 0 : return status;
6635 : : }
6636 : :
6637 : : /**
6638 : : * ice_set_vlan_vsi_promisc
6639 : : * @hw: pointer to the hardware structure
6640 : : * @vsi_handle: VSI handle to configure
6641 : : * @promisc_mask: mask of promiscuous config bits
6642 : : * @rm_vlan_promisc: Clear VLANs VSI promisc mode
6643 : : *
6644 : : * Configure VSI with all associated VLANs to given promiscuous mode(s)
6645 : : */
6646 : : int
6647 : 0 : ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle,
6648 : : ice_bitmap_t *promisc_mask, bool rm_vlan_promisc)
6649 : : {
6650 [ # # ]: 0 : if (!hw || !promisc_mask)
6651 : : return ICE_ERR_PARAM;
6652 : :
6653 : 0 : return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask,
6654 : 0 : rm_vlan_promisc, hw->port_info->lport,
6655 : : hw->switch_info);
6656 : : }
6657 : :
6658 : : /**
6659 : : * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI
6660 : : * @hw: pointer to the hardware structure
6661 : : * @vsi_handle: VSI handle to remove filters from
6662 : : * @recp_list: recipe list from which function remove fltr
6663 : : * @lkup: switch rule filter lookup type
6664 : : */
6665 : : static void
6666 : 0 : ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
6667 : : struct ice_sw_recipe *recp_list,
6668 : : enum ice_sw_lkup_type lkup)
6669 : : {
6670 : : struct ice_fltr_list_entry *fm_entry;
6671 : : struct LIST_HEAD_TYPE remove_list_head;
6672 : : struct LIST_HEAD_TYPE *rule_head;
6673 : : struct ice_fltr_list_entry *tmp;
6674 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6675 : : int status;
6676 : :
6677 : 0 : INIT_LIST_HEAD(&remove_list_head);
6678 : 0 : rule_lock = &recp_list[lkup].filt_rule_lock;
6679 : 0 : rule_head = &recp_list[lkup].filt_rules;
6680 : 0 : ice_acquire_lock(rule_lock);
6681 : 0 : status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
6682 : : &remove_list_head);
6683 : : ice_release_lock(rule_lock);
6684 [ # # ]: 0 : if (status)
6685 : 0 : goto free_fltr_list;
6686 : :
6687 [ # # # # : 0 : switch (lkup) {
# # # # ]
6688 : 0 : case ICE_SW_LKUP_MAC:
6689 : 0 : ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]);
6690 : 0 : break;
6691 : 0 : case ICE_SW_LKUP_VLAN:
6692 : 0 : ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]);
6693 : 0 : break;
6694 : 0 : case ICE_SW_LKUP_PROMISC:
6695 : : case ICE_SW_LKUP_PROMISC_VLAN:
6696 : 0 : ice_remove_promisc(hw, (u8)lkup, &remove_list_head);
6697 : 0 : break;
6698 : 0 : case ICE_SW_LKUP_MAC_VLAN:
6699 : 0 : ice_remove_mac_vlan(hw, &remove_list_head);
6700 : 0 : break;
6701 : 0 : case ICE_SW_LKUP_ETHERTYPE:
6702 : : case ICE_SW_LKUP_ETHERTYPE_MAC:
6703 : 0 : ice_remove_eth_mac(hw, &remove_list_head);
6704 : 0 : break;
6705 : 0 : case ICE_SW_LKUP_DFLT:
6706 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n");
6707 : : break;
6708 : 0 : case ICE_SW_LKUP_LAST:
6709 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n");
6710 : : break;
6711 : : }
6712 : :
6713 : 0 : free_fltr_list:
6714 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head,
# # # # #
# ]
6715 : : ice_fltr_list_entry, list_entry) {
6716 [ # # ]: 0 : LIST_DEL(&fm_entry->list_entry);
6717 : 0 : ice_free(hw, fm_entry);
6718 : : }
6719 : 0 : }
6720 : :
6721 : : /**
6722 : : * ice_remove_vsi_fltr_rule - Remove all filters for a VSI
6723 : : * @hw: pointer to the hardware structure
6724 : : * @vsi_handle: VSI handle to remove filters from
6725 : : * @sw: pointer to switch info struct
6726 : : */
6727 : : static void
6728 : 0 : ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle,
6729 : : struct ice_switch_info *sw)
6730 : : {
6731 [ # # ]: 0 : ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__);
6732 : :
6733 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6734 : : sw->recp_list, ICE_SW_LKUP_MAC);
6735 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6736 : : sw->recp_list, ICE_SW_LKUP_MAC_VLAN);
6737 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6738 : : sw->recp_list, ICE_SW_LKUP_PROMISC);
6739 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6740 : : sw->recp_list, ICE_SW_LKUP_VLAN);
6741 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6742 : : sw->recp_list, ICE_SW_LKUP_DFLT);
6743 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6744 : : sw->recp_list, ICE_SW_LKUP_ETHERTYPE);
6745 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6746 : : sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC);
6747 : 0 : ice_remove_vsi_lkup_fltr(hw, vsi_handle,
6748 : : sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN);
6749 : 0 : }
6750 : :
6751 : : /**
6752 : : * ice_remove_vsi_fltr - Remove all filters for a VSI
6753 : : * @hw: pointer to the hardware structure
6754 : : * @vsi_handle: VSI handle to remove filters from
6755 : : */
6756 : 0 : void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
6757 : : {
6758 : 0 : ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info);
6759 : 0 : }
6760 : :
6761 : : /**
6762 : : * ice_alloc_res_cntr - allocating resource counter
6763 : : * @hw: pointer to the hardware structure
6764 : : * @type: type of resource
6765 : : * @alloc_shared: if set it is shared else dedicated
6766 : : * @num_items: number of entries requested for FD resource type
6767 : : * @counter_id: counter index returned by AQ call
6768 : : */
6769 : : int
6770 : 0 : ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6771 : : u16 *counter_id)
6772 : : {
6773 : : struct ice_aqc_alloc_free_res_elem *buf;
6774 : : u16 buf_len;
6775 : : int status;
6776 : :
6777 : : /* Allocate resource */
6778 : : buf_len = ice_struct_size(buf, elem, 1);
6779 : 0 : buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6780 [ # # ]: 0 : if (!buf)
6781 : : return ICE_ERR_NO_MEMORY;
6782 : :
6783 : 0 : buf->num_elems = CPU_TO_LE16(num_items);
6784 : 0 : buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6785 : : ICE_AQC_RES_TYPE_M) | alloc_shared);
6786 : :
6787 : 0 : status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6788 : : ice_aqc_opc_alloc_res, NULL);
6789 [ # # ]: 0 : if (status)
6790 : 0 : goto exit;
6791 : :
6792 : 0 : *counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp);
6793 : :
6794 : 0 : exit:
6795 : 0 : ice_free(hw, buf);
6796 : 0 : return status;
6797 : : }
6798 : :
6799 : : /**
6800 : : * ice_free_res_cntr - free resource counter
6801 : : * @hw: pointer to the hardware structure
6802 : : * @type: type of resource
6803 : : * @alloc_shared: if set it is shared else dedicated
6804 : : * @num_items: number of entries to be freed for FD resource type
6805 : : * @counter_id: counter ID resource which needs to be freed
6806 : : */
6807 : : int
6808 : 0 : ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
6809 : : u16 counter_id)
6810 : : {
6811 : : struct ice_aqc_alloc_free_res_elem *buf;
6812 : : u16 buf_len;
6813 : : int status;
6814 : :
6815 : : /* Free resource */
6816 : : buf_len = ice_struct_size(buf, elem, 1);
6817 : 0 : buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len);
6818 [ # # ]: 0 : if (!buf)
6819 : : return ICE_ERR_NO_MEMORY;
6820 : :
6821 : 0 : buf->num_elems = CPU_TO_LE16(num_items);
6822 : 0 : buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) &
6823 : : ICE_AQC_RES_TYPE_M) | alloc_shared);
6824 : 0 : buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id);
6825 : :
6826 : 0 : status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
6827 : : ice_aqc_opc_free_res, NULL);
6828 [ # # ]: 0 : if (status)
6829 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
6830 : :
6831 : 0 : ice_free(hw, buf);
6832 : 0 : return status;
6833 : : }
6834 : :
6835 : : /**
6836 : : * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type
6837 : : * @hw: pointer to the hardware structure
6838 : : * @counter_id: returns counter index
6839 : : */
6840 : 0 : int ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id)
6841 : : {
6842 : 0 : return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6843 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6844 : : counter_id);
6845 : : }
6846 : :
6847 : : /**
6848 : : * ice_free_vlan_res_counter - Free counter resource for VLAN type
6849 : : * @hw: pointer to the hardware structure
6850 : : * @counter_id: counter index to be freed
6851 : : */
6852 : 0 : int ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id)
6853 : : {
6854 : 0 : return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER,
6855 : : ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1,
6856 : : counter_id);
6857 : : }
6858 : :
6859 : : /**
6860 : : * ice_add_mac_with_sw_marker - add filter with sw marker
6861 : : * @hw: pointer to the hardware structure
6862 : : * @f_info: filter info structure containing the MAC filter information
6863 : : * @sw_marker: sw marker to tag the Rx descriptor with
6864 : : */
6865 : : int
6866 : 0 : ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info,
6867 : : u16 sw_marker)
6868 : : {
6869 : : struct ice_fltr_mgmt_list_entry *m_entry;
6870 : : struct ice_fltr_list_entry fl_info;
6871 : : struct ice_sw_recipe *recp_list;
6872 : : struct LIST_HEAD_TYPE l_head;
6873 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6874 : : bool entry_exists;
6875 : : u16 lg_act_id;
6876 : : int ret;
6877 : :
6878 [ # # ]: 0 : if (f_info->fltr_act != ICE_FWD_TO_VSI)
6879 : : return ICE_ERR_PARAM;
6880 : :
6881 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6882 : : return ICE_ERR_PARAM;
6883 : :
6884 [ # # ]: 0 : if (sw_marker == ICE_INVAL_SW_MARKER_ID)
6885 : : return ICE_ERR_PARAM;
6886 : :
6887 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6888 : : return ICE_ERR_PARAM;
6889 : 0 : f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6890 : :
6891 : : /* Add filter if it doesn't exist so then the adding of large
6892 : : * action always results in update
6893 : : */
6894 : :
6895 : : INIT_LIST_HEAD(&l_head);
6896 : 0 : fl_info.fltr_info = *f_info;
6897 : 0 : LIST_ADD(&fl_info.list_entry, &l_head);
6898 : :
6899 : : entry_exists = false;
6900 : 0 : ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6901 : 0 : hw->port_info->lport);
6902 [ # # ]: 0 : if (ret == ICE_ERR_ALREADY_EXISTS)
6903 : : entry_exists = true;
6904 [ # # ]: 0 : else if (ret)
6905 : : return ret;
6906 : :
6907 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6908 : : rule_lock = &recp_list->filt_rule_lock;
6909 : 0 : ice_acquire_lock(rule_lock);
6910 : : /* Get the book keeping entry for the filter */
6911 : 0 : m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
6912 [ # # ]: 0 : if (!m_entry)
6913 : 0 : goto exit_error;
6914 : :
6915 : : /* If counter action was enabled for this rule then don't enable
6916 : : * sw marker large action
6917 : : */
6918 [ # # ]: 0 : if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
6919 : : ret = ICE_ERR_PARAM;
6920 : 0 : goto exit_error;
6921 : : }
6922 : :
6923 : : /* if same marker was added before */
6924 [ # # ]: 0 : if (m_entry->sw_marker_id == sw_marker) {
6925 : : ret = ICE_ERR_ALREADY_EXISTS;
6926 : 0 : goto exit_error;
6927 : : }
6928 : :
6929 : : /* Allocate a hardware table entry to hold large act. Three actions
6930 : : * for marker based large action
6931 : : */
6932 : 0 : ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3);
6933 [ # # ]: 0 : if (ret)
6934 : 0 : goto exit_error;
6935 : :
6936 [ # # ]: 0 : if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
6937 : 0 : goto exit_error;
6938 : :
6939 : : /* Update the switch rule to add the marker action */
6940 : 0 : ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id);
6941 [ # # ]: 0 : if (!ret) {
6942 : : ice_release_lock(rule_lock);
6943 : 0 : return ret;
6944 : : }
6945 : :
6946 : 0 : exit_error:
6947 : : ice_release_lock(rule_lock);
6948 : : /* only remove entry if it did not exist previously */
6949 [ # # ]: 0 : if (!entry_exists)
6950 : 0 : ret = ice_remove_mac(hw, &l_head);
6951 : :
6952 : : return ret;
6953 : : }
6954 : :
6955 : : /**
6956 : : * ice_add_mac_with_counter - add filter with counter enabled
6957 : : * @hw: pointer to the hardware structure
6958 : : * @f_info: pointer to filter info structure containing the MAC filter
6959 : : * information
6960 : : */
6961 : : int
6962 : 0 : ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info)
6963 : : {
6964 : : struct ice_fltr_mgmt_list_entry *m_entry;
6965 : : struct ice_fltr_list_entry fl_info;
6966 : : struct ice_sw_recipe *recp_list;
6967 : : struct LIST_HEAD_TYPE l_head;
6968 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
6969 : : bool entry_exist;
6970 : : u16 counter_id;
6971 : : u16 lg_act_id;
6972 : : int ret;
6973 : :
6974 [ # # ]: 0 : if (f_info->fltr_act != ICE_FWD_TO_VSI)
6975 : : return ICE_ERR_PARAM;
6976 : :
6977 [ # # ]: 0 : if (f_info->lkup_type != ICE_SW_LKUP_MAC)
6978 : : return ICE_ERR_PARAM;
6979 : :
6980 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, f_info->vsi_handle))
6981 : : return ICE_ERR_PARAM;
6982 : 0 : f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle);
6983 : 0 : recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC];
6984 : :
6985 : : entry_exist = false;
6986 : :
6987 : : rule_lock = &recp_list->filt_rule_lock;
6988 : :
6989 : : /* Add filter if it doesn't exist so then the adding of large
6990 : : * action always results in update
6991 : : */
6992 : : INIT_LIST_HEAD(&l_head);
6993 : :
6994 : 0 : fl_info.fltr_info = *f_info;
6995 : 0 : LIST_ADD(&fl_info.list_entry, &l_head);
6996 : :
6997 : 0 : ret = ice_add_mac_rule(hw, &l_head, hw->switch_info,
6998 : 0 : hw->port_info->lport);
6999 [ # # ]: 0 : if (ret == ICE_ERR_ALREADY_EXISTS)
7000 : : entry_exist = true;
7001 [ # # ]: 0 : else if (ret)
7002 : : return ret;
7003 : :
7004 : 0 : ice_acquire_lock(rule_lock);
7005 : 0 : m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info);
7006 [ # # ]: 0 : if (!m_entry) {
7007 : : ret = ICE_ERR_BAD_PTR;
7008 : 0 : goto exit_error;
7009 : : }
7010 : :
7011 : : /* Don't enable counter for a filter for which sw marker was enabled */
7012 [ # # ]: 0 : if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) {
7013 : : ret = ICE_ERR_PARAM;
7014 : 0 : goto exit_error;
7015 : : }
7016 : :
7017 : : /* If a counter was already enabled then don't need to add again */
7018 [ # # ]: 0 : if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) {
7019 : : ret = ICE_ERR_ALREADY_EXISTS;
7020 : 0 : goto exit_error;
7021 : : }
7022 : :
7023 : : /* Allocate a hardware table entry to VLAN counter */
7024 : 0 : ret = ice_alloc_vlan_res_counter(hw, &counter_id);
7025 [ # # ]: 0 : if (ret)
7026 : 0 : goto exit_error;
7027 : :
7028 : : /* Allocate a hardware table entry to hold large act. Two actions for
7029 : : * counter based large action
7030 : : */
7031 : 0 : ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2);
7032 [ # # ]: 0 : if (ret)
7033 : 0 : goto exit_error;
7034 : :
7035 [ # # ]: 0 : if (lg_act_id == ICE_INVAL_LG_ACT_INDEX)
7036 : 0 : goto exit_error;
7037 : :
7038 : : /* Update the switch rule to add the counter action */
7039 : 0 : ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id);
7040 [ # # ]: 0 : if (!ret) {
7041 : : ice_release_lock(rule_lock);
7042 : 0 : return ret;
7043 : : }
7044 : :
7045 : 0 : exit_error:
7046 : : ice_release_lock(rule_lock);
7047 : : /* only remove entry if it did not exist previously */
7048 [ # # ]: 0 : if (!entry_exist)
7049 : 0 : ret = ice_remove_mac(hw, &l_head);
7050 : :
7051 : : return ret;
7052 : : }
7053 : :
7054 : : /* This is mapping table entry that maps every word within a given protocol
7055 : : * structure to the real byte offset as per the specification of that
7056 : : * protocol header.
7057 : : * for example dst address is 3 words in ethertype header and corresponding
7058 : : * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8
7059 : : * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a
7060 : : * matching entry describing its field. This needs to be updated if new
7061 : : * structure is added to that union.
7062 : : */
7063 : : static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
7064 : : { ICE_MAC_OFOS, { 0, 2, 4, 6, 8, 10, 12 } },
7065 : : { ICE_MAC_IL, { 0, 2, 4, 6, 8, 10, 12 } },
7066 : : { ICE_ETYPE_OL, { 0 } },
7067 : : { ICE_ETYPE_IL, { 0 } },
7068 : : { ICE_VLAN_OFOS, { 2, 0 } },
7069 : : { ICE_IPV4_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
7070 : : { ICE_IPV4_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
7071 : : { ICE_IPV6_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
7072 : : 26, 28, 30, 32, 34, 36, 38 } },
7073 : : { ICE_IPV6_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
7074 : : 26, 28, 30, 32, 34, 36, 38 } },
7075 : : { ICE_TCP_IL, { 0, 2 } },
7076 : : { ICE_UDP_OF, { 0, 2 } },
7077 : : { ICE_UDP_ILOS, { 0, 2 } },
7078 : : { ICE_SCTP_IL, { 0, 2 } },
7079 : : { ICE_VXLAN, { 8, 10, 12, 14 } },
7080 : : { ICE_GENEVE, { 8, 10, 12, 14 } },
7081 : : { ICE_VXLAN_GPE, { 8, 10, 12, 14 } },
7082 : : { ICE_NVGRE, { 0, 2, 4, 6 } },
7083 : : { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
7084 : : { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } },
7085 : : { ICE_PPPOE, { 0, 2, 4, 6 } },
7086 : : { ICE_PFCP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
7087 : : { ICE_L2TPV3, { 0, 2, 4, 6, 8, 10 } },
7088 : : { ICE_ESP, { 0, 2, 4, 6 } },
7089 : : { ICE_AH, { 0, 2, 4, 6, 8, 10 } },
7090 : : { ICE_NAT_T, { 8, 10, 12, 14 } },
7091 : : { ICE_VLAN_EX, { 2, 0 } },
7092 : : { ICE_VLAN_IN, { 2, 0 } },
7093 : : };
7094 : :
7095 : : /* The following table describes preferred grouping of recipes.
7096 : : * If a recipe that needs to be programmed is a superset or matches one of the
7097 : : * following combinations, then the recipe needs to be chained as per the
7098 : : * following policy.
7099 : : */
7100 : :
7101 : : static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
7102 : : { ICE_MAC_OFOS, ICE_MAC_OFOS_HW },
7103 : : { ICE_MAC_IL, ICE_MAC_IL_HW },
7104 : : { ICE_ETYPE_OL, ICE_ETYPE_OL_HW },
7105 : : { ICE_ETYPE_IL, ICE_ETYPE_IL_HW },
7106 : : { ICE_VLAN_OFOS, ICE_VLAN_OL_HW },
7107 : : { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW },
7108 : : { ICE_IPV4_IL, ICE_IPV4_IL_HW },
7109 : : { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW },
7110 : : { ICE_IPV6_IL, ICE_IPV6_IL_HW },
7111 : : { ICE_TCP_IL, ICE_TCP_IL_HW },
7112 : : { ICE_UDP_OF, ICE_UDP_OF_HW },
7113 : : { ICE_UDP_ILOS, ICE_UDP_ILOS_HW },
7114 : : { ICE_SCTP_IL, ICE_SCTP_IL_HW },
7115 : : { ICE_VXLAN, ICE_UDP_OF_HW },
7116 : : { ICE_GENEVE, ICE_UDP_OF_HW },
7117 : : { ICE_VXLAN_GPE, ICE_UDP_OF_HW },
7118 : : { ICE_NVGRE, ICE_GRE_OF_HW },
7119 : : { ICE_GTP, ICE_UDP_OF_HW },
7120 : : { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
7121 : : { ICE_PPPOE, ICE_PPPOE_HW },
7122 : : { ICE_PFCP, ICE_UDP_ILOS_HW },
7123 : : { ICE_L2TPV3, ICE_L2TPV3_HW },
7124 : : { ICE_ESP, ICE_ESP_HW },
7125 : : { ICE_AH, ICE_AH_HW },
7126 : : { ICE_NAT_T, ICE_UDP_ILOS_HW },
7127 : : { ICE_VLAN_EX, ICE_VLAN_OF_HW },
7128 : : { ICE_VLAN_IN, ICE_VLAN_OL_HW },
7129 : : { ICE_FLG_DIR, ICE_META_DATA_ID_HW},
7130 : : };
7131 : :
7132 : : /*
7133 : : * ice_find_recp - find a recipe
7134 : : * @hw: pointer to the hardware structure
7135 : : * @lkup_exts: extension sequence to match
7136 : : *
7137 : : * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found.
7138 : : */
7139 : 0 : static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
7140 : : enum ice_sw_tunnel_type tun_type, u32 priority)
7141 : : {
7142 : 0 : bool refresh_required = true;
7143 : : struct ice_sw_recipe *recp;
7144 : : u8 i;
7145 : :
7146 : : /* Walk through existing recipes to find a match */
7147 : 0 : recp = hw->switch_info->recp_list;
7148 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
7149 : : /* If recipe was not created for this ID, in SW bookkeeping,
7150 : : * check if FW has an entry for this recipe. If the FW has an
7151 : : * entry update it in our SW bookkeeping and continue with the
7152 : : * matching.
7153 : : */
7154 [ # # ]: 0 : if (!recp[i].recp_created)
7155 [ # # ]: 0 : if (ice_get_recp_frm_fw(hw,
7156 : 0 : hw->switch_info->recp_list, i,
7157 : : &refresh_required))
7158 : 0 : continue;
7159 : :
7160 : : /* Skip inverse action recipes */
7161 [ # # # # ]: 0 : if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
7162 : : ICE_AQ_RECIPE_ACT_INV_ACT)
7163 : 0 : continue;
7164 : :
7165 : : /* if number of words we are looking for match */
7166 [ # # ]: 0 : if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
7167 : 0 : struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
7168 : 0 : struct ice_fv_word *be = lkup_exts->fv_words;
7169 : 0 : u16 *cr = recp[i].lkup_exts.field_mask;
7170 : 0 : u16 *de = lkup_exts->field_mask;
7171 : : bool found = true;
7172 : : u8 pe, qr;
7173 : :
7174 : : /* ar, cr, and qr are related to the recipe words, while
7175 : : * be, de, and pe are related to the lookup words
7176 : : */
7177 [ # # ]: 0 : for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
7178 [ # # ]: 0 : for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
7179 : 0 : qr++) {
7180 [ # # ]: 0 : if (ar[qr].off == be[pe].off &&
7181 [ # # ]: 0 : ar[qr].prot_id == be[pe].prot_id &&
7182 [ # # ]: 0 : cr[qr] == de[pe])
7183 : : /* Found the "pe"th word in the
7184 : : * given recipe
7185 : : */
7186 : : break;
7187 : : }
7188 : : /* After walking through all the words in the
7189 : : * "i"th recipe if "p"th word was not found then
7190 : : * this recipe is not what we are looking for.
7191 : : * So break out from this loop and try the next
7192 : : * recipe
7193 : : */
7194 [ # # ]: 0 : if (qr >= recp[i].lkup_exts.n_val_words) {
7195 : : found = false;
7196 : : break;
7197 : : }
7198 : : }
7199 : : /* If for "i"th recipe the found was never set to false
7200 : : * then it means we found our match
7201 : : */
7202 [ # # # # ]: 0 : if (found && priority == recp[i].priority) {
7203 [ # # # # ]: 0 : if (tun_type == recp[i].tun_type ||
7204 : : (recp[i].tun_type == ICE_SW_TUN_UDP &&
7205 : 0 : (tun_type == ICE_SW_TUN_VXLAN_GPE ||
7206 [ # # ]: 0 : tun_type == ICE_SW_TUN_VXLAN ||
7207 : : tun_type == ICE_SW_TUN_GENEVE ||
7208 : : tun_type == ICE_SW_TUN_GENEVE_VLAN ||
7209 : : tun_type == ICE_SW_TUN_VXLAN_VLAN)))
7210 : 0 : return i; /* Return the recipe ID */
7211 : : }
7212 : : }
7213 : : }
7214 : : return ICE_MAX_NUM_RECIPES;
7215 : : }
7216 : :
7217 : : /**
7218 : : * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl
7219 : : *
7220 : : * As protocol id for outer vlan is different in dvm and svm, if dvm is
7221 : : * supported protocol array record for outer vlan has to be modified to
7222 : : * reflect the value proper for DVM.
7223 : : */
7224 : 0 : void ice_change_proto_id_to_dvm(void)
7225 : : {
7226 : : u8 i;
7227 : :
7228 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
7229 [ # # ]: 0 : if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
7230 [ # # ]: 0 : ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
7231 : 0 : ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
7232 : 0 : }
7233 : :
7234 : : /**
7235 : : * ice_prot_type_to_id - get protocol ID from protocol type
7236 : : * @type: protocol type
7237 : : * @id: pointer to variable that will receive the ID
7238 : : *
7239 : : * Returns true if found, false otherwise
7240 : : */
7241 : : static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
7242 : : {
7243 : : u8 i;
7244 : :
7245 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
7246 [ # # ]: 0 : if (ice_prot_id_tbl[i].type == type) {
7247 : : *id = ice_prot_id_tbl[i].protocol_id;
7248 : : return true;
7249 : : }
7250 : : return false;
7251 : : }
7252 : :
7253 : : /**
7254 : : * ice_fill_valid_words - count valid words
7255 : : * @rule: advanced rule with lookup information
7256 : : * @lkup_exts: byte offset extractions of the words that are valid
7257 : : *
7258 : : * calculate valid words in a lookup rule using mask value
7259 : : */
7260 : : static u8
7261 : 0 : ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
7262 : : struct ice_prot_lkup_ext *lkup_exts)
7263 : : {
7264 : : u8 j, word, prot_id, ret_val;
7265 : :
7266 : 0 : if (!ice_prot_type_to_id(rule->type, &prot_id))
7267 : : return 0;
7268 : :
7269 : 0 : word = lkup_exts->n_val_words;
7270 : :
7271 [ # # ]: 0 : for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
7272 [ # # # # ]: 0 : if (((u16 *)&rule->m_u)[j] &&
7273 : : (size_t)rule->type < ARRAY_SIZE(ice_prot_ext)) {
7274 : : /* No more space to accommodate */
7275 [ # # ]: 0 : if (word >= ICE_MAX_CHAIN_WORDS)
7276 : : return 0;
7277 : 0 : lkup_exts->fv_words[word].off =
7278 : 0 : ice_prot_ext[rule->type].offs[j];
7279 : 0 : lkup_exts->fv_words[word].prot_id =
7280 : 0 : ice_prot_id_tbl[rule->type].protocol_id;
7281 : 0 : lkup_exts->field_mask[word] =
7282 [ # # ]: 0 : BE16_TO_CPU(((_FORCE_ __be16 *)&rule->m_u)[j]);
7283 : 0 : word++;
7284 : : }
7285 : :
7286 : 0 : ret_val = word - lkup_exts->n_val_words;
7287 : 0 : lkup_exts->n_val_words = word;
7288 : :
7289 : 0 : return ret_val;
7290 : : }
7291 : :
7292 : : /**
7293 : : * ice_create_first_fit_recp_def - Create a recipe grouping
7294 : : * @hw: pointer to the hardware structure
7295 : : * @lkup_exts: an array of protocol header extractions
7296 : : * @rg_list: pointer to a list that stores new recipe groups
7297 : : * @recp_cnt: pointer to a variable that stores returned number of recipe groups
7298 : : *
7299 : : * Using first fit algorithm, take all the words that are still not done
7300 : : * and start grouping them in 4-word groups. Each group makes up one
7301 : : * recipe.
7302 : : */
7303 : : static int
7304 : 0 : ice_create_first_fit_recp_def(struct ice_hw *hw,
7305 : : struct ice_prot_lkup_ext *lkup_exts,
7306 : : struct LIST_HEAD_TYPE *rg_list,
7307 : : u8 *recp_cnt)
7308 : : {
7309 : : struct ice_pref_recipe_group *grp = NULL;
7310 : : u8 j;
7311 : :
7312 : 0 : *recp_cnt = 0;
7313 : :
7314 [ # # ]: 0 : if (!lkup_exts->n_val_words) {
7315 : : struct ice_recp_grp_entry *entry;
7316 : :
7317 : : entry = (struct ice_recp_grp_entry *)
7318 : 0 : ice_malloc(hw, sizeof(*entry));
7319 [ # # ]: 0 : if (!entry)
7320 : : return ICE_ERR_NO_MEMORY;
7321 [ # # ]: 0 : LIST_ADD(&entry->l_entry, rg_list);
7322 : 0 : grp = &entry->r_group;
7323 : 0 : (*recp_cnt)++;
7324 : 0 : grp->n_val_pairs = 0;
7325 : : }
7326 : :
7327 : : /* Walk through every word in the rule to check if it is not done. If so
7328 : : * then this word needs to be part of a new recipe.
7329 : : */
7330 [ # # ]: 0 : for (j = 0; j < lkup_exts->n_val_words; j++)
7331 [ # # ]: 0 : if (!ice_is_bit_set(lkup_exts->done, j)) {
7332 [ # # ]: 0 : if (!grp ||
7333 [ # # ]: 0 : grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
7334 : : struct ice_recp_grp_entry *entry;
7335 : :
7336 : : entry = (struct ice_recp_grp_entry *)
7337 : 0 : ice_malloc(hw, sizeof(*entry));
7338 [ # # ]: 0 : if (!entry)
7339 : : return ICE_ERR_NO_MEMORY;
7340 [ # # ]: 0 : LIST_ADD(&entry->l_entry, rg_list);
7341 : 0 : grp = &entry->r_group;
7342 : 0 : (*recp_cnt)++;
7343 : : }
7344 : :
7345 [ # # ]: 0 : if (grp->n_val_pairs < ICE_NUM_WORDS_RECIPE) {
7346 : 0 : grp->pairs[grp->n_val_pairs].prot_id =
7347 : 0 : lkup_exts->fv_words[j].prot_id;
7348 : 0 : grp->pairs[grp->n_val_pairs].off =
7349 : 0 : lkup_exts->fv_words[j].off;
7350 : 0 : grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
7351 : 0 : grp->n_val_pairs++;
7352 : : }
7353 : : }
7354 : :
7355 : : return 0;
7356 : : }
7357 : :
7358 : : /**
7359 : : * ice_fill_fv_word_index - fill in the field vector indices for a recipe group
7360 : : * @hw: pointer to the hardware structure
7361 : : * @fv_list: field vector with the extraction sequence information
7362 : : * @rg_list: recipe groupings with protocol-offset pairs
7363 : : *
7364 : : * Helper function to fill in the field vector indices for protocol-offset
7365 : : * pairs. These indexes are then ultimately programmed into a recipe.
7366 : : */
7367 : : static int
7368 : 0 : ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list,
7369 : : struct LIST_HEAD_TYPE *rg_list)
7370 : : {
7371 : : struct ice_sw_fv_list_entry *fv;
7372 : : struct ice_recp_grp_entry *rg;
7373 : : struct ice_fv_word *fv_ext;
7374 : :
7375 [ # # ]: 0 : if (LIST_EMPTY(fv_list))
7376 : : return 0;
7377 : :
7378 : : fv = LIST_FIRST_ENTRY(fv_list, struct ice_sw_fv_list_entry, list_entry);
7379 : 0 : fv_ext = fv->fv_ptr->ew;
7380 : :
7381 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(rg, rg_list, ice_recp_grp_entry, l_entry) {
# # ]
7382 : : u8 i;
7383 : :
7384 [ # # ]: 0 : for (i = 0; i < rg->r_group.n_val_pairs; i++) {
7385 : : struct ice_fv_word *pr;
7386 : : bool found = false;
7387 : : u16 mask;
7388 : : u8 j;
7389 : :
7390 : 0 : pr = &rg->r_group.pairs[i];
7391 : 0 : mask = rg->r_group.mask[i];
7392 : :
7393 [ # # ]: 0 : for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
7394 [ # # ]: 0 : if (fv_ext[j].prot_id == pr->prot_id &&
7395 [ # # ]: 0 : fv_ext[j].off == pr->off) {
7396 : : found = true;
7397 : :
7398 : : /* Store index of field vector */
7399 : 0 : rg->fv_idx[i] = j;
7400 : 0 : rg->fv_mask[i] = mask;
7401 : : break;
7402 : : }
7403 : :
7404 : : /* Protocol/offset could not be found, caller gave an
7405 : : * invalid pair
7406 : : */
7407 : : if (!found)
7408 : : return ICE_ERR_PARAM;
7409 : : }
7410 : : }
7411 : :
7412 : : return 0;
7413 : : }
7414 : :
7415 : : /**
7416 : : * ice_find_free_recp_res_idx - find free result indexes for recipe
7417 : : * @hw: pointer to hardware structure
7418 : : * @profiles: bitmap of profiles that will be associated with the new recipe
7419 : : * @free_idx: pointer to variable to receive the free index bitmap
7420 : : *
7421 : : * The algorithm used here is:
7422 : : * 1. When creating a new recipe, create a set P which contains all
7423 : : * Profiles that will be associated with our new recipe
7424 : : *
7425 : : * 2. For each Profile p in set P:
7426 : : * a. Add all recipes associated with Profile p into set R
7427 : : * b. Optional : PossibleIndexes &= profile[p].possibleIndexes
7428 : : * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF]
7429 : : * i. Or just assume they all have the same possible indexes:
7430 : : * 44, 45, 46, 47
7431 : : * i.e., PossibleIndexes = 0x0000F00000000000
7432 : : *
7433 : : * 3. For each Recipe r in set R:
7434 : : * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes
7435 : : * b. FreeIndexes = UsedIndexes ^ PossibleIndexes
7436 : : *
7437 : : * FreeIndexes will contain the bits indicating the indexes free for use,
7438 : : * then the code needs to update the recipe[r].used_result_idx_bits to
7439 : : * indicate which indexes were selected for use by this recipe.
7440 : : */
7441 : : static u16
7442 : 0 : ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles,
7443 : : ice_bitmap_t *free_idx)
7444 : : {
7445 : : ice_declare_bitmap(possible_idx, ICE_MAX_FV_WORDS);
7446 : : ice_declare_bitmap(recipes, ICE_MAX_NUM_RECIPES);
7447 : : ice_declare_bitmap(used_idx, ICE_MAX_FV_WORDS);
7448 : : u16 bit;
7449 : :
7450 : : ice_zero_bitmap(possible_idx, ICE_MAX_FV_WORDS);
7451 : : ice_zero_bitmap(recipes, ICE_MAX_NUM_RECIPES);
7452 : : ice_zero_bitmap(used_idx, ICE_MAX_FV_WORDS);
7453 : : ice_zero_bitmap(free_idx, ICE_MAX_FV_WORDS);
7454 : :
7455 : : ice_bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS);
7456 : :
7457 : : /* For each profile we are going to associate the recipe with, add the
7458 : : * recipes that are associated with that profile. This will give us
7459 : : * the set of recipes that our recipe may collide with. Also, determine
7460 : : * what possible result indexes are usable given this set of profiles.
7461 : : */
7462 [ # # ]: 0 : ice_for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
7463 : 0 : ice_or_bitmap(recipes, recipes, profile_to_recipe[bit],
7464 : : ICE_MAX_NUM_RECIPES);
7465 : 0 : ice_and_bitmap(possible_idx, possible_idx,
7466 : 0 : hw->switch_info->prof_res_bm[bit],
7467 : : ICE_MAX_FV_WORDS);
7468 : : }
7469 : :
7470 : : /* For each recipe that our new recipe may collide with, determine
7471 : : * which indexes have been used.
7472 : : */
7473 [ # # ]: 0 : ice_for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
7474 : 0 : ice_or_bitmap(used_idx, used_idx,
7475 : 0 : hw->switch_info->recp_list[bit].res_idxs,
7476 : : ICE_MAX_FV_WORDS);
7477 : :
7478 : 0 : ice_xor_bitmap(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
7479 : :
7480 : : /* return number of free indexes */
7481 : 0 : return ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS);
7482 : : }
7483 : :
7484 : : static void ice_set_recipe_index(unsigned long idx, u8 *bitmap)
7485 : : {
7486 : 0 : u32 byte = idx / BITS_PER_BYTE;
7487 : 0 : u32 bit = idx % BITS_PER_BYTE;
7488 : :
7489 : 0 : if (byte >= 8)
7490 : : return;
7491 : :
7492 : 0 : bitmap[byte] |= 1 << bit;
7493 : : }
7494 : :
7495 : : /**
7496 : : * ice_add_sw_recipe - function to call AQ calls to create switch recipe
7497 : : * @hw: pointer to hardware structure
7498 : : * @rm: recipe management list entry
7499 : : * @profiles: bitmap of profiles that will be associated.
7500 : : */
7501 : : static int
7502 : 0 : ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
7503 : : ice_bitmap_t *profiles)
7504 : : {
7505 : : ice_declare_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
7506 : : struct ice_aqc_recipe_data_elem *tmp;
7507 : : struct ice_aqc_recipe_data_elem *buf;
7508 : : struct ice_recp_grp_entry *entry;
7509 : : u16 free_res_idx;
7510 : : u16 recipe_count;
7511 : : u8 chain_idx;
7512 : : u8 recps = 0;
7513 : : int status;
7514 : :
7515 : : /* When more than one recipe are required, another recipe is needed to
7516 : : * chain them together. Matching a tunnel metadata ID takes up one of
7517 : : * the match fields in the chaining recipe reducing the number of
7518 : : * chained recipes by one.
7519 : : */
7520 : : /* check number of free result indices */
7521 : : ice_zero_bitmap(result_idx_bm, ICE_MAX_FV_WORDS);
7522 : 0 : free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
7523 : :
7524 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
7525 : : free_res_idx, rm->n_grp_count);
7526 : :
7527 [ # # ]: 0 : if (rm->n_grp_count > 1) {
7528 [ # # ]: 0 : if (rm->n_grp_count > free_res_idx)
7529 : : return ICE_ERR_MAX_LIMIT;
7530 : :
7531 : 0 : rm->n_grp_count++;
7532 : : }
7533 : :
7534 [ # # ]: 0 : if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
7535 : : return ICE_ERR_MAX_LIMIT;
7536 : :
7537 : 0 : tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw,
7538 : : ICE_MAX_NUM_RECIPES,
7539 : : sizeof(*tmp));
7540 [ # # ]: 0 : if (!tmp)
7541 : : return ICE_ERR_NO_MEMORY;
7542 : :
7543 : : buf = (struct ice_aqc_recipe_data_elem *)
7544 : 0 : ice_calloc(hw, rm->n_grp_count, sizeof(*buf));
7545 [ # # ]: 0 : if (!buf) {
7546 : : status = ICE_ERR_NO_MEMORY;
7547 : 0 : goto err_mem;
7548 : : }
7549 : :
7550 : 0 : ice_zero_bitmap(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
7551 : 0 : recipe_count = ICE_MAX_NUM_RECIPES;
7552 : 0 : status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
7553 : : NULL);
7554 [ # # # # ]: 0 : if (status || recipe_count == 0)
7555 : 0 : goto err_unroll;
7556 : :
7557 : : /* Allocate the recipe resources, and configure them according to the
7558 : : * match fields from protocol headers and extracted field vectors.
7559 : : */
7560 : 0 : chain_idx = (u8)ice_find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
7561 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7562 : : u8 i;
7563 : :
7564 : 0 : status = ice_alloc_recipe(hw, &entry->rid);
7565 [ # # ]: 0 : if (status)
7566 : 0 : goto err_unroll;
7567 : :
7568 : : /* Clear the result index of the located recipe, as this will be
7569 : : * updated, if needed, later in the recipe creation process.
7570 : : */
7571 : 0 : tmp[0].content.result_indx = 0;
7572 : :
7573 : 0 : buf[recps] = tmp[0];
7574 : 0 : buf[recps].recipe_indx = (u8)entry->rid;
7575 : : /* if the recipe is a non-root recipe RID should be programmed
7576 : : * as 0 for the rules to be applied correctly.
7577 : : */
7578 : 0 : buf[recps].content.rid = 0;
7579 : 0 : ice_memset(&buf[recps].content.lkup_indx, 0,
7580 : : sizeof(buf[recps].content.lkup_indx),
7581 : : ICE_NONDMA_MEM);
7582 : :
7583 : : /* All recipes use look-up index 0 to match switch ID. */
7584 : : buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7585 : 0 : buf[recps].content.mask[0] =
7586 : : CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7587 : : /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask
7588 : : * to be 0
7589 : : */
7590 [ # # ]: 0 : for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7591 : 0 : buf[recps].content.lkup_indx[i] = 0x80;
7592 : 0 : buf[recps].content.mask[i] = 0;
7593 : : }
7594 : :
7595 [ # # ]: 0 : for (i = 0; i < entry->r_group.n_val_pairs; i++) {
7596 : 0 : buf[recps].content.lkup_indx[i + 1] =
7597 : 0 : (u8)entry->fv_idx[i];
7598 : 0 : buf[recps].content.mask[i + 1] =
7599 : 0 : CPU_TO_LE16(entry->fv_mask[i]);
7600 : : }
7601 : :
7602 [ # # ]: 0 : if (rm->n_grp_count > 1) {
7603 : : /* Checks to see if there really is a valid result index
7604 : : * that can be used.
7605 : : */
7606 [ # # ]: 0 : if (chain_idx >= ICE_MAX_FV_WORDS) {
7607 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
7608 : : status = ICE_ERR_MAX_LIMIT;
7609 : 0 : goto err_unroll;
7610 : : }
7611 : :
7612 : 0 : entry->chain_idx = chain_idx;
7613 : 0 : buf[recps].content.result_indx =
7614 : 0 : ICE_AQ_RECIPE_RESULT_EN |
7615 : 0 : ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
7616 : : ICE_AQ_RECIPE_RESULT_DATA_M);
7617 : : ice_clear_bit(chain_idx, result_idx_bm);
7618 : 0 : chain_idx = (u8)ice_find_first_bit(result_idx_bm,
7619 : : ICE_MAX_FV_WORDS);
7620 : : }
7621 : :
7622 : : /* fill recipe dependencies */
7623 [ # # ]: 0 : ice_memset(buf[recps].recipe_bitmap, 0,
7624 : : sizeof(buf[recps].recipe_bitmap), ICE_NONDMA_MEM);
7625 [ # # ]: 0 : ice_set_recipe_index(buf[recps].recipe_indx,
7626 : : buf[recps].recipe_bitmap);
7627 : 0 : buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7628 [ # # ]: 0 : recps++;
7629 : : }
7630 : :
7631 [ # # ]: 0 : if (rm->n_grp_count == 1) {
7632 [ # # ]: 0 : rm->root_rid = buf[0].recipe_indx;
7633 : : ice_set_bit(buf[0].recipe_indx, rm->r_bitmap);
7634 : 0 : buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
7635 : : if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
7636 [ # # ]: 0 : ice_memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
7637 : : sizeof(buf[0].recipe_bitmap),
7638 : : ICE_NONDMA_TO_NONDMA);
7639 : : } else {
7640 : : status = ICE_ERR_BAD_PTR;
7641 : : goto err_unroll;
7642 : : }
7643 : : /* Applicable only for ROOT_RECIPE, set the fwd_priority for
7644 : : * the recipe which is getting created if specified
7645 : : * by user. Usually any advanced switch filter, which results
7646 : : * into new extraction sequence, ended up creating a new recipe
7647 : : * of type ROOT and usually recipes are associated with profiles
7648 : : * Switch rule referreing newly created recipe, needs to have
7649 : : * either/or 'fwd' or 'join' priority, otherwise switch rule
7650 : : * evaluation will not happen correctly. In other words, if
7651 : : * switch rule to be evaluated on priority basis, then recipe
7652 : : * needs to have priority, otherwise it will be evaluated last.
7653 : : */
7654 : 0 : buf[0].content.act_ctrl_fwd_priority = rm->priority;
7655 : : } else {
7656 : : struct ice_recp_grp_entry *last_chain_entry;
7657 : : u16 rid, i;
7658 : :
7659 : : /* Allocate the last recipe that will chain the outcomes of the
7660 : : * other recipes together
7661 : : */
7662 : 0 : status = ice_alloc_recipe(hw, &rid);
7663 [ # # ]: 0 : if (status)
7664 : 0 : goto err_unroll;
7665 : :
7666 : 0 : buf[recps].recipe_indx = (u8)rid;
7667 : : buf[recps].content.rid = (u8)rid;
7668 : 0 : buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
7669 : : /* the new entry created should also be part of rg_list to
7670 : : * make sure we have complete recipe
7671 : : */
7672 : 0 : last_chain_entry = (struct ice_recp_grp_entry *)ice_malloc(hw,
7673 : : sizeof(*last_chain_entry));
7674 [ # # ]: 0 : if (!last_chain_entry) {
7675 : : status = ICE_ERR_NO_MEMORY;
7676 : 0 : goto err_unroll;
7677 : : }
7678 : 0 : last_chain_entry->rid = rid;
7679 : 0 : ice_memset(&buf[recps].content.lkup_indx, 0,
7680 : : sizeof(buf[recps].content.lkup_indx),
7681 : : ICE_NONDMA_MEM);
7682 : : /* All recipes use look-up index 0 to match switch ID. */
7683 : : buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
7684 : 0 : buf[recps].content.mask[0] =
7685 : : CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK);
7686 [ # # ]: 0 : for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
7687 : 0 : buf[recps].content.lkup_indx[i] =
7688 : : ICE_AQ_RECIPE_LKUP_IGNORE;
7689 : 0 : buf[recps].content.mask[i] = 0;
7690 : : }
7691 : :
7692 : : i = 1;
7693 : : /* update r_bitmap with the recp that is used for chaining */
7694 : : ice_set_bit(rid, rm->r_bitmap);
7695 : : /* this is the recipe that chains all the other recipes so it
7696 : : * should not have a chaining ID to indicate the same
7697 : : */
7698 : 0 : last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
7699 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry,
# # ]
7700 : : l_entry) {
7701 : 0 : buf[recps].content.lkup_indx[i] = entry->chain_idx;
7702 : 0 : buf[recps].content.mask[i++] = CPU_TO_LE16(0xFFFF);
7703 [ # # ]: 0 : ice_set_bit(entry->rid, rm->r_bitmap);
7704 : : }
7705 [ # # ]: 0 : LIST_ADD(&last_chain_entry->l_entry, &rm->rg_list);
7706 : : if (sizeof(buf[recps].recipe_bitmap) >=
7707 : : sizeof(rm->r_bitmap)) {
7708 [ # # ]: 0 : ice_memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
7709 : : sizeof(buf[recps].recipe_bitmap),
7710 : : ICE_NONDMA_TO_NONDMA);
7711 : : } else {
7712 : : status = ICE_ERR_BAD_PTR;
7713 : : goto err_unroll;
7714 : : }
7715 : 0 : buf[recps].content.act_ctrl_fwd_priority = rm->priority;
7716 : :
7717 : : recps++;
7718 : 0 : rm->root_rid = (u8)rid;
7719 : : }
7720 : 0 : status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
7721 [ # # ]: 0 : if (status)
7722 : 0 : goto err_unroll;
7723 : :
7724 : 0 : status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
7725 : 0 : ice_release_change_lock(hw);
7726 [ # # ]: 0 : if (status)
7727 : 0 : goto err_unroll;
7728 : :
7729 : : /* Every recipe that just got created add it to the recipe
7730 : : * book keeping list
7731 : : */
7732 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) {
7733 : 0 : struct ice_switch_info *sw = hw->switch_info;
7734 : : bool is_root, idx_found = false;
7735 : : struct ice_sw_recipe *recp;
7736 : : u16 idx, buf_idx = 0;
7737 : :
7738 : : /* find buffer index for copying some data */
7739 [ # # ]: 0 : for (idx = 0; idx < rm->n_grp_count; idx++)
7740 [ # # ]: 0 : if (buf[idx].recipe_indx == entry->rid) {
7741 : : buf_idx = idx;
7742 : : idx_found = true;
7743 : : }
7744 : :
7745 [ # # ]: 0 : if (!idx_found) {
7746 : : status = ICE_ERR_OUT_OF_RANGE;
7747 : 0 : goto err_unroll;
7748 : : }
7749 : :
7750 : 0 : recp = &sw->recp_list[entry->rid];
7751 : 0 : is_root = (rm->root_rid == entry->rid);
7752 : 0 : recp->is_root = is_root;
7753 : :
7754 : 0 : recp->root_rid = (u8)entry->rid;
7755 [ # # # # ]: 0 : recp->big_recp = (is_root && rm->n_grp_count > 1);
7756 : :
7757 [ # # ]: 0 : ice_memcpy(&recp->ext_words, entry->r_group.pairs,
7758 : : entry->r_group.n_val_pairs *
7759 : : sizeof(struct ice_fv_word),
7760 : : ICE_NONDMA_TO_NONDMA);
7761 : :
7762 [ # # ]: 0 : ice_memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
7763 : : sizeof(recp->r_bitmap), ICE_NONDMA_TO_NONDMA);
7764 : :
7765 : : /* Copy non-result fv index values and masks to recipe. This
7766 : : * call will also update the result recipe bitmask.
7767 : : */
7768 : : ice_collect_result_idx(&buf[buf_idx], recp);
7769 : :
7770 : : /* for non-root recipes, also copy to the root, this allows
7771 : : * easier matching of a complete chained recipe
7772 : : */
7773 [ # # ]: 0 : if (!is_root)
7774 : 0 : ice_collect_result_idx(&buf[buf_idx],
7775 [ # # ]: 0 : &sw->recp_list[rm->root_rid]);
7776 : :
7777 : 0 : recp->n_ext_words = entry->r_group.n_val_pairs;
7778 : 0 : recp->chain_idx = entry->chain_idx;
7779 : 0 : recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
7780 : 0 : recp->n_grp_count = rm->n_grp_count;
7781 : 0 : recp->tun_type = rm->tun_type;
7782 [ # # ]: 0 : recp->recp_created = true;
7783 : : }
7784 : 0 : rm->root_buf = buf;
7785 : 0 : ice_free(hw, tmp);
7786 : 0 : return status;
7787 : :
7788 : 0 : err_unroll:
7789 : 0 : err_mem:
7790 : 0 : ice_free(hw, tmp);
7791 : 0 : ice_free(hw, buf);
7792 : 0 : return status;
7793 : : }
7794 : :
7795 : : /**
7796 : : * ice_create_recipe_group - creates recipe group
7797 : : * @hw: pointer to hardware structure
7798 : : * @rm: recipe management list entry
7799 : : * @lkup_exts: lookup elements
7800 : : */
7801 : : static int
7802 : 0 : ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
7803 : : struct ice_prot_lkup_ext *lkup_exts)
7804 : : {
7805 : 0 : u8 recp_count = 0;
7806 : : int status;
7807 : :
7808 : 0 : rm->n_grp_count = 0;
7809 : :
7810 : : /* Create recipes for words that are marked not done by packing them
7811 : : * as best fit.
7812 : : */
7813 : 0 : status = ice_create_first_fit_recp_def(hw, lkup_exts,
7814 : : &rm->rg_list, &recp_count);
7815 [ # # ]: 0 : if (!status) {
7816 : 0 : rm->n_grp_count += recp_count;
7817 : 0 : rm->n_ext_words = lkup_exts->n_val_words;
7818 [ # # ]: 0 : ice_memcpy(&rm->ext_words, lkup_exts->fv_words,
7819 : : sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA);
7820 [ # # ]: 0 : ice_memcpy(rm->word_masks, lkup_exts->field_mask,
7821 : : sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA);
7822 : : }
7823 : :
7824 : 0 : return status;
7825 : : }
7826 : :
7827 : : /**
7828 : : * ice_tun_type_match_word - determine if tun type needs a match mask
7829 : : * @rinfo: other information regarding the rule e.g. priority and action info
7830 : : * @off: offset of packet flag
7831 : : * @mask: mask to be used for the tunnel
7832 : : */
7833 : : static bool
7834 : 0 : ice_tun_type_match_word(struct ice_adv_rule_info *rinfo, u16 *off, u16 *mask)
7835 : : {
7836 [ # # # # ]: 0 : switch (rinfo->tun_type) {
7837 : 0 : case ICE_SW_TUN_VXLAN_GPE:
7838 : : case ICE_SW_TUN_GENEVE:
7839 : : case ICE_SW_TUN_VXLAN:
7840 : : case ICE_SW_TUN_NVGRE:
7841 : : case ICE_SW_TUN_UDP:
7842 : : case ICE_ALL_TUNNELS:
7843 : : case ICE_SW_TUN_AND_NON_TUN_QINQ:
7844 : : case ICE_NON_TUN_QINQ:
7845 : : case ICE_SW_TUN_PPPOE_QINQ:
7846 : : case ICE_SW_TUN_PPPOE_PAY_QINQ:
7847 : : case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7848 : : case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7849 : 0 : *mask = ICE_TUN_FLAG_MASK;
7850 : 0 : *off = ICE_TUN_FLAG_MDID_OFF(1);
7851 : 0 : return true;
7852 : :
7853 : 0 : case ICE_SW_TUN_AND_NON_TUN:
7854 [ # # ]: 0 : if (rinfo->add_dir_lkup) {
7855 : 0 : *mask = ICE_DIR_FLAG_MASK;
7856 : 0 : *off = ICE_TUN_FLAG_MDID_OFF(0);
7857 : 0 : return true;
7858 : : }
7859 : 0 : *mask = 0;
7860 : 0 : *off = 0;
7861 : 0 : return false;
7862 : :
7863 : 0 : case ICE_SW_TUN_GENEVE_VLAN:
7864 : : case ICE_SW_TUN_VXLAN_VLAN:
7865 : 0 : *mask = ICE_TUN_FLAG_MASK & ~(ICE_TUN_FLAG_VLAN_MASK |
7866 : : ICE_TUN_FLAG_IN_VLAN_MASK);
7867 : 0 : *off = ICE_TUN_FLAG_MDID_OFF(1);
7868 : 0 : return true;
7869 : :
7870 : 0 : default:
7871 : 0 : *mask = 0;
7872 : 0 : *off = 0;
7873 : 0 : return false;
7874 : : }
7875 : : }
7876 : :
7877 : : /**
7878 : : * ice_add_special_words - Add words that are not protocols, such as metadata
7879 : : * @rinfo: other information regarding the rule e.g. priority and action info
7880 : : * @lkup_exts: lookup word structure
7881 : : * @dvm_ena: is double VLAN mode enabled
7882 : : */
7883 : : static int
7884 : 0 : ice_add_special_words(struct ice_adv_rule_info *rinfo,
7885 : : struct ice_prot_lkup_ext *lkup_exts, bool dvm_ena)
7886 : : {
7887 : : u16 mask;
7888 : : u16 off;
7889 : :
7890 : : /* If this is a tunneled packet, then add recipe index to match the
7891 : : * tunnel bit in the packet metadata flags. If this is a tun_and_non_tun
7892 : : * packet, then add recipe index to match the direction bit in the flag.
7893 : : */
7894 [ # # ]: 0 : if (ice_tun_type_match_word(rinfo, &off, &mask)) {
7895 [ # # ]: 0 : if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7896 : 0 : u8 word = lkup_exts->n_val_words++;
7897 : :
7898 : 0 : lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7899 : 0 : lkup_exts->fv_words[word].off = off;
7900 : 0 : lkup_exts->field_mask[word] = mask;
7901 : : } else {
7902 : : return ICE_ERR_MAX_LIMIT;
7903 : : }
7904 : : }
7905 : :
7906 [ # # # # ]: 0 : if (rinfo->vlan_type != 0 && dvm_ena) {
7907 [ # # ]: 0 : if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
7908 : 0 : u8 word = lkup_exts->n_val_words++;
7909 : :
7910 : 0 : lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
7911 : 0 : lkup_exts->fv_words[word].off = ICE_VLAN_FLAG_MDID_OFF;
7912 : 0 : lkup_exts->field_mask[word] =
7913 : : ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK;
7914 : : } else {
7915 : : return ICE_ERR_MAX_LIMIT;
7916 : : }
7917 : : }
7918 : :
7919 : : return 0;
7920 : : }
7921 : :
7922 : : /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
7923 : : * @hw: pointer to hardware structure
7924 : : * @rinfo: other information regarding the rule e.g. priority and action info
7925 : : * @bm: pointer to memory for returning the bitmap of field vectors
7926 : : */
7927 : : static void
7928 [ # # # # : 0 : ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
7929 : : ice_bitmap_t *bm)
7930 : : {
7931 : : enum ice_prof_type prof_type;
7932 : :
7933 : : ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
7934 : :
7935 [ # # # # : 0 : switch (rinfo->tun_type) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
7936 : : case ICE_NON_TUN:
7937 : : case ICE_NON_TUN_QINQ:
7938 : : prof_type = ICE_PROF_NON_TUN;
7939 : : break;
7940 : 0 : case ICE_ALL_TUNNELS:
7941 : : prof_type = ICE_PROF_TUN_ALL;
7942 : 0 : break;
7943 : 0 : case ICE_SW_TUN_VXLAN_GPE:
7944 : : case ICE_SW_TUN_GENEVE:
7945 : : case ICE_SW_TUN_GENEVE_VLAN:
7946 : : case ICE_SW_TUN_VXLAN:
7947 : : case ICE_SW_TUN_VXLAN_VLAN:
7948 : : case ICE_SW_TUN_UDP:
7949 : : case ICE_SW_TUN_GTP:
7950 : : prof_type = ICE_PROF_TUN_UDP;
7951 : 0 : break;
7952 : 0 : case ICE_SW_TUN_NVGRE:
7953 : : prof_type = ICE_PROF_TUN_GRE;
7954 : 0 : break;
7955 : : case ICE_SW_IPV4_TCP:
7956 : : ice_set_bit(ICE_PROFID_IPV4_TCP, bm);
7957 : : return;
7958 : : case ICE_SW_IPV4_UDP:
7959 : : ice_set_bit(ICE_PROFID_IPV4_UDP, bm);
7960 : : return;
7961 : : case ICE_SW_IPV6_TCP:
7962 : : ice_set_bit(ICE_PROFID_IPV6_TCP, bm);
7963 : : return;
7964 : : case ICE_SW_IPV6_UDP:
7965 : : ice_set_bit(ICE_PROFID_IPV6_UDP, bm);
7966 : : return;
7967 : 0 : case ICE_SW_TUN_PPPOE:
7968 : : case ICE_SW_TUN_PPPOE_QINQ:
7969 : : prof_type = ICE_PROF_TUN_PPPOE;
7970 : 0 : break;
7971 : : case ICE_SW_TUN_PPPOE_PAY:
7972 : : case ICE_SW_TUN_PPPOE_PAY_QINQ:
7973 : : ice_set_bit(ICE_PROFID_PPPOE_PAY, bm);
7974 : : return;
7975 : : case ICE_SW_TUN_PPPOE_IPV4:
7976 : : case ICE_SW_TUN_PPPOE_IPV4_QINQ:
7977 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_OTHER, bm);
7978 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7979 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7980 : : return;
7981 : : case ICE_SW_TUN_PPPOE_IPV4_TCP:
7982 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm);
7983 : : return;
7984 : : case ICE_SW_TUN_PPPOE_IPV4_UDP:
7985 : : ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm);
7986 : : return;
7987 : : case ICE_SW_TUN_PPPOE_IPV6:
7988 : : case ICE_SW_TUN_PPPOE_IPV6_QINQ:
7989 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_OTHER, bm);
7990 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7991 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7992 : : return;
7993 : : case ICE_SW_TUN_PPPOE_IPV6_TCP:
7994 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm);
7995 : : return;
7996 : : case ICE_SW_TUN_PPPOE_IPV6_UDP:
7997 : : ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm);
7998 : : return;
7999 : : case ICE_SW_TUN_PROFID_IPV6_ESP:
8000 : : case ICE_SW_TUN_IPV6_ESP:
8001 : : ice_set_bit(ICE_PROFID_IPV6_ESP, bm);
8002 : : return;
8003 : : case ICE_SW_TUN_PROFID_IPV6_AH:
8004 : : case ICE_SW_TUN_IPV6_AH:
8005 : : ice_set_bit(ICE_PROFID_IPV6_AH, bm);
8006 : : return;
8007 : : case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
8008 : : case ICE_SW_TUN_IPV6_L2TPV3:
8009 : : ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm);
8010 : : return;
8011 : : case ICE_SW_TUN_PROFID_IPV6_NAT_T:
8012 : : case ICE_SW_TUN_IPV6_NAT_T:
8013 : : ice_set_bit(ICE_PROFID_IPV6_NAT_T, bm);
8014 : : return;
8015 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
8016 : : ice_set_bit(ICE_PROFID_IPV4_PFCP_NODE, bm);
8017 : : return;
8018 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
8019 : : ice_set_bit(ICE_PROFID_IPV4_PFCP_SESSION, bm);
8020 : : return;
8021 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
8022 : : ice_set_bit(ICE_PROFID_IPV6_PFCP_NODE, bm);
8023 : : return;
8024 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
8025 : : ice_set_bit(ICE_PROFID_IPV6_PFCP_SESSION, bm);
8026 : : return;
8027 : : case ICE_SW_TUN_IPV4_NAT_T:
8028 : : ice_set_bit(ICE_PROFID_IPV4_NAT_T, bm);
8029 : : return;
8030 : : case ICE_SW_TUN_IPV4_L2TPV3:
8031 : : ice_set_bit(ICE_PROFID_MAC_IPV4_L2TPV3, bm);
8032 : : return;
8033 : : case ICE_SW_TUN_IPV4_ESP:
8034 : : ice_set_bit(ICE_PROFID_IPV4_ESP, bm);
8035 : : return;
8036 : : case ICE_SW_TUN_IPV4_AH:
8037 : : ice_set_bit(ICE_PROFID_IPV4_AH, bm);
8038 : : return;
8039 : : case ICE_SW_TUN_IPV4_GTPU_NO_PAY:
8040 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_TEID, bm);
8041 : : return;
8042 : : case ICE_SW_TUN_IPV6_GTPU_NO_PAY:
8043 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_TEID, bm);
8044 : : return;
8045 : : case ICE_SW_TUN_IPV4_GTPU_IPV4:
8046 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_OTHER, bm);
8047 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
8048 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
8049 : : return;
8050 : : case ICE_SW_TUN_IPV4_GTPU_IPV4_UDP:
8051 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm);
8052 : : return;
8053 : : case ICE_SW_TUN_IPV4_GTPU_IPV4_TCP:
8054 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm);
8055 : : return;
8056 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV4:
8057 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, bm);
8058 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
8059 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
8060 : : return;
8061 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP:
8062 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm);
8063 : : return;
8064 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP:
8065 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm);
8066 : : return;
8067 : : case ICE_SW_TUN_IPV6_GTPU_IPV4:
8068 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_OTHER, bm);
8069 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
8070 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
8071 : : return;
8072 : : case ICE_SW_TUN_IPV6_GTPU_IPV4_UDP:
8073 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm);
8074 : : return;
8075 : : case ICE_SW_TUN_IPV6_GTPU_IPV4_TCP:
8076 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm);
8077 : : return;
8078 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV4:
8079 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, bm);
8080 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
8081 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
8082 : : return;
8083 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP:
8084 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm);
8085 : : return;
8086 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP:
8087 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm);
8088 : : return;
8089 : : case ICE_SW_TUN_IPV4_GTPU_IPV6:
8090 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_OTHER, bm);
8091 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
8092 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
8093 : : return;
8094 : : case ICE_SW_TUN_IPV4_GTPU_IPV6_UDP:
8095 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm);
8096 : : return;
8097 : : case ICE_SW_TUN_IPV4_GTPU_IPV6_TCP:
8098 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm);
8099 : : return;
8100 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV6:
8101 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, bm);
8102 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
8103 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
8104 : : return;
8105 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP:
8106 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm);
8107 : : return;
8108 : : case ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP:
8109 : : ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm);
8110 : : return;
8111 : : case ICE_SW_TUN_IPV6_GTPU_IPV6:
8112 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_OTHER, bm);
8113 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
8114 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
8115 : : return;
8116 : : case ICE_SW_TUN_IPV6_GTPU_IPV6_UDP:
8117 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm);
8118 : : return;
8119 : : case ICE_SW_TUN_IPV6_GTPU_IPV6_TCP:
8120 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm);
8121 : : return;
8122 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV6:
8123 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, bm);
8124 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
8125 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
8126 : : return;
8127 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP:
8128 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm);
8129 : : return;
8130 : : case ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP:
8131 : : ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm);
8132 : : return;
8133 : 0 : case ICE_SW_TUN_AND_NON_TUN:
8134 : : case ICE_SW_TUN_AND_NON_TUN_QINQ:
8135 : : default:
8136 : : prof_type = ICE_PROF_ALL;
8137 : 0 : break;
8138 : : }
8139 : :
8140 : 0 : ice_get_sw_fv_bitmap(hw, prof_type, bm);
8141 : : }
8142 : :
8143 : : /**
8144 : : * ice_is_prof_rule - determine if rule type is a profile rule
8145 : : * @type: the rule type
8146 : : *
8147 : : * if the rule type is a profile rule, that means that there no field value
8148 : : * match required, in this case just a profile hit is required.
8149 : : */
8150 : 0 : bool ice_is_prof_rule(enum ice_sw_tunnel_type type)
8151 : : {
8152 [ # # ]: 0 : switch (type) {
8153 : : case ICE_SW_TUN_AND_NON_TUN:
8154 : : case ICE_SW_TUN_PROFID_IPV6_ESP:
8155 : : case ICE_SW_TUN_PROFID_IPV6_AH:
8156 : : case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3:
8157 : : case ICE_SW_TUN_PROFID_IPV6_NAT_T:
8158 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE:
8159 : : case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION:
8160 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE:
8161 : : case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION:
8162 : : return true;
8163 : : default:
8164 : : break;
8165 : : }
8166 : :
8167 : 0 : return false;
8168 : : }
8169 : :
8170 : : /**
8171 : : * ice_add_adv_recipe - Add an advanced recipe that is not part of the default
8172 : : * @hw: pointer to hardware structure
8173 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
8174 : : * structure per protocol header
8175 : : * @lkups_cnt: number of protocols
8176 : : * @rinfo: other information regarding the rule e.g. priority and action info
8177 : : * @rid: return the recipe ID of the recipe created
8178 : : */
8179 : : int
8180 : 0 : ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
8181 : : u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
8182 : : {
8183 : : ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES);
8184 : : ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES);
8185 : : struct ice_prot_lkup_ext *lkup_exts;
8186 : : struct ice_recp_grp_entry *r_entry;
8187 : : struct ice_sw_fv_list_entry *fvit;
8188 : : struct ice_recp_grp_entry *r_tmp;
8189 : : struct ice_sw_fv_list_entry *tmp;
8190 : : struct ice_sw_recipe *rm;
8191 : : u8 i;
8192 : : int status = ICE_SUCCESS;
8193 : : u16 cnt;
8194 : :
8195 [ # # # # ]: 0 : if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt)
8196 : : return ICE_ERR_PARAM;
8197 : :
8198 : : lkup_exts = (struct ice_prot_lkup_ext *)
8199 : 0 : ice_malloc(hw, sizeof(*lkup_exts));
8200 [ # # ]: 0 : if (!lkup_exts)
8201 : : return ICE_ERR_NO_MEMORY;
8202 : :
8203 : : /* Determine the number of words to be matched and if it exceeds a
8204 : : * recipe's restrictions
8205 : : */
8206 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
8207 : : u16 count;
8208 : :
8209 [ # # ]: 0 : if (lkups[i].type >= ICE_PROTOCOL_LAST) {
8210 : : status = ICE_ERR_CFG;
8211 : 0 : goto err_free_lkup_exts;
8212 : : }
8213 : :
8214 : 0 : count = ice_fill_valid_words(&lkups[i], lkup_exts);
8215 [ # # ]: 0 : if (!count) {
8216 : : status = ICE_ERR_CFG;
8217 : 0 : goto err_free_lkup_exts;
8218 : : }
8219 : : }
8220 : :
8221 : 0 : rm = (struct ice_sw_recipe *)ice_malloc(hw, sizeof(*rm));
8222 [ # # ]: 0 : if (!rm) {
8223 : : status = ICE_ERR_NO_MEMORY;
8224 : 0 : goto err_free_lkup_exts;
8225 : : }
8226 : :
8227 : : /* Get field vectors that contain fields extracted from all the protocol
8228 : : * headers being programmed.
8229 : : */
8230 : 0 : INIT_LIST_HEAD(&rm->fv_list);
8231 : 0 : INIT_LIST_HEAD(&rm->rg_list);
8232 : :
8233 : : /* Get bitmap of field vectors (profiles) that are compatible with the
8234 : : * rule request; only these will be searched in the subsequent call to
8235 : : * ice_get_sw_fv_list.
8236 : : */
8237 : 0 : ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
8238 : :
8239 : 0 : status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
8240 [ # # ]: 0 : if (status)
8241 : 0 : goto err_unroll;
8242 : :
8243 : : /* Create any special protocol/offset pairs, such as looking at tunnel
8244 : : * bits by extracting metadata
8245 : : */
8246 : 0 : status = ice_add_special_words(rinfo, lkup_exts, ice_is_dvm_ena(hw));
8247 [ # # ]: 0 : if (status)
8248 : 0 : goto err_free_lkup_exts;
8249 : :
8250 : : /* Group match words into recipes using preferred recipe grouping
8251 : : * criteria.
8252 : : */
8253 : 0 : status = ice_create_recipe_group(hw, rm, lkup_exts);
8254 [ # # ]: 0 : if (status)
8255 : 0 : goto err_unroll;
8256 : :
8257 : : /* set the recipe priority if specified */
8258 : 0 : rm->priority = (u8)rinfo->priority;
8259 : :
8260 : : /* Find offsets from the field vector. Pick the first one for all the
8261 : : * recipes.
8262 : : */
8263 : 0 : status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
8264 [ # # ]: 0 : if (status)
8265 : 0 : goto err_unroll;
8266 : :
8267 : : /* An empty FV list means to use all the profiles returned in the
8268 : : * profile bitmap
8269 : : */
8270 [ # # ]: 0 : if (LIST_EMPTY(&rm->fv_list)) {
8271 : : u16 j;
8272 : :
8273 [ # # ]: 0 : ice_for_each_set_bit(j, fv_bitmap, ICE_MAX_NUM_PROFILES) {
8274 : : struct ice_sw_fv_list_entry *fvl;
8275 : :
8276 : : fvl = (struct ice_sw_fv_list_entry *)
8277 : 0 : ice_malloc(hw, sizeof(*fvl));
8278 [ # # ]: 0 : if (!fvl)
8279 : 0 : goto err_unroll;
8280 : 0 : fvl->fv_ptr = NULL;
8281 : 0 : fvl->profile_id = j;
8282 [ # # ]: 0 : LIST_ADD(&fvl->list_entry, &rm->fv_list);
8283 : : }
8284 : : }
8285 : :
8286 : : /* get bitmap of all profiles the recipe will be associated with */
8287 : : ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES);
8288 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
# # ]
8289 : : list_entry) {
8290 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
8291 [ # # ]: 0 : ice_set_bit((u16)fvit->profile_id, profiles);
8292 : : }
8293 : :
8294 : : /* Look for a recipe which matches our requested fv / mask list */
8295 : 0 : *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type, rinfo->priority);
8296 [ # # ]: 0 : if (*rid < ICE_MAX_NUM_RECIPES)
8297 : : /* Success if found a recipe that match the existing criteria */
8298 : 0 : goto err_unroll;
8299 : :
8300 : 0 : rm->tun_type = rinfo->tun_type;
8301 : : /* Recipe we need does not exist, add a recipe */
8302 : 0 : status = ice_add_sw_recipe(hw, rm, profiles);
8303 [ # # ]: 0 : if (status)
8304 : 0 : goto err_unroll;
8305 : :
8306 : : /* Associate all the recipes created with all the profiles in the
8307 : : * common field vector.
8308 : : */
8309 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry,
# # ]
8310 : : list_entry) {
8311 : : ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES);
8312 : : u16 j;
8313 : :
8314 : 0 : status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
8315 : : (u8 *)r_bitmap, NULL);
8316 [ # # ]: 0 : if (status)
8317 : 0 : goto err_unroll;
8318 : :
8319 : 0 : ice_or_bitmap(r_bitmap, r_bitmap, rm->r_bitmap,
8320 : : ICE_MAX_NUM_RECIPES);
8321 : 0 : status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
8322 [ # # ]: 0 : if (status)
8323 : 0 : goto err_unroll;
8324 : :
8325 : 0 : status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
8326 : : (u8 *)r_bitmap,
8327 : : NULL);
8328 : 0 : ice_release_change_lock(hw);
8329 : :
8330 [ # # ]: 0 : if (status)
8331 : 0 : goto err_unroll;
8332 : :
8333 : : /* Update profile to recipe bitmap array */
8334 : 0 : ice_cp_bitmap(profile_to_recipe[fvit->profile_id], r_bitmap,
8335 : : ICE_MAX_NUM_RECIPES);
8336 : :
8337 : : /* Update recipe to profile bitmap array */
8338 [ # # ]: 0 : ice_for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
8339 : 0 : ice_set_bit((u16)fvit->profile_id,
8340 : 0 : recipe_to_profile[j]);
8341 : : }
8342 : :
8343 : 0 : *rid = rm->root_rid;
8344 [ # # ]: 0 : ice_memcpy(&hw->switch_info->recp_list[*rid].lkup_exts,
8345 : : lkup_exts, sizeof(*lkup_exts), ICE_NONDMA_TO_NONDMA);
8346 : 0 : err_unroll:
8347 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(r_entry, r_tmp, &rm->rg_list,
# # # # #
# ]
8348 : : ice_recp_grp_entry, l_entry) {
8349 [ # # ]: 0 : LIST_DEL(&r_entry->l_entry);
8350 : 0 : ice_free(hw, r_entry);
8351 : : }
8352 : :
8353 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(fvit, tmp, &rm->fv_list, ice_sw_fv_list_entry,
# # # # #
# ]
8354 : : list_entry) {
8355 [ # # ]: 0 : LIST_DEL(&fvit->list_entry);
8356 : 0 : ice_free(hw, fvit);
8357 : : }
8358 : :
8359 [ # # ]: 0 : if (rm->root_buf)
8360 : 0 : ice_free(hw, rm->root_buf);
8361 : :
8362 : 0 : ice_free(hw, rm);
8363 : :
8364 : 0 : err_free_lkup_exts:
8365 : 0 : ice_free(hw, lkup_exts);
8366 : :
8367 : 0 : return status;
8368 : : }
8369 : :
8370 : : /**
8371 : : * ice_find_dummy_packet - find dummy packet by tunnel type
8372 : : *
8373 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
8374 : : * structure per protocol header
8375 : : * @lkups_cnt: number of protocols
8376 : : * @tun_type: tunnel type from the match criteria
8377 : : * @pkt: dummy packet to fill according to filter match criteria
8378 : : * @pkt_len: packet length of dummy packet
8379 : : * @offsets: pointer to receive the pointer to the offsets for the packet
8380 : : */
8381 : : void
8382 : 0 : ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8383 : : enum ice_sw_tunnel_type tun_type, const u8 **pkt,
8384 : : u16 *pkt_len,
8385 : : const struct ice_dummy_pkt_offsets **offsets)
8386 : : {
8387 : : bool tcp = false, udp = false, outer_ipv6 = false, vlan = false;
8388 : : bool inner_ipv6 = false, pppoe = false;
8389 : : bool cvlan = false;
8390 : : bool gre = false, mpls = false;
8391 : : u16 i;
8392 : :
8393 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
8394 [ # # ]: 0 : if (lkups[i].type == ICE_UDP_ILOS)
8395 : : udp = true;
8396 : : else if (lkups[i].type == ICE_TCP_IL)
8397 : : tcp = true;
8398 : : else if (lkups[i].type == ICE_IPV6_OFOS)
8399 : : outer_ipv6 = true;
8400 : : else if (lkups[i].type == ICE_VLAN_OFOS ||
8401 : : lkups[i].type == ICE_VLAN_EX)
8402 : : vlan = true;
8403 : :
8404 : : else if (lkups[i].type == ICE_VLAN_IN)
8405 : : cvlan = true;
8406 : 0 : else if (lkups[i].type == ICE_ETYPE_OL &&
8407 [ # # ]: 0 : lkups[i].h_u.ethertype.ethtype_id ==
8408 : 0 : CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
8409 [ # # ]: 0 : lkups[i].m_u.ethertype.ethtype_id ==
8410 : : CPU_TO_BE16(0xFFFF))
8411 : : outer_ipv6 = true;
8412 [ # # ]: 0 : else if (lkups[i].type == ICE_ETYPE_IL &&
8413 [ # # ]: 0 : lkups[i].h_u.ethertype.ethtype_id ==
8414 : 0 : CPU_TO_BE16(ICE_IPV6_ETHER_ID) &&
8415 [ # # ]: 0 : lkups[i].m_u.ethertype.ethtype_id ==
8416 : : CPU_TO_BE16(0xFFFF))
8417 : : inner_ipv6 = true;
8418 [ # # ]: 0 : else if (lkups[i].type == ICE_PPPOE) {
8419 : : pppoe = true;
8420 [ # # ]: 0 : if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
8421 : 0 : CPU_TO_BE16(ICE_PPP_IPV6_PROTO_ID) &&
8422 [ # # ]: 0 : lkups[i].m_u.pppoe_hdr.ppp_prot_id ==
8423 : : CPU_TO_BE16(0xFFFF))
8424 : : outer_ipv6 = true;
8425 : : }
8426 [ # # ]: 0 : else if (lkups[i].type == ICE_IPV4_OFOS &&
8427 [ # # ]: 0 : lkups[i].h_u.ipv4_hdr.protocol ==
8428 : 0 : ICE_IPV4_NVGRE_PROTO_ID &&
8429 [ # # ]: 0 : lkups[i].m_u.ipv4_hdr.protocol ==
8430 : : 0xFF)
8431 : : gre = true;
8432 [ # # ]: 0 : else if (lkups[i].type == ICE_IPV4_IL &&
8433 [ # # ]: 0 : lkups[i].h_u.ipv4_hdr.protocol ==
8434 : 0 : ICE_TCP_PROTO_ID &&
8435 [ # # ]: 0 : lkups[i].m_u.ipv4_hdr.protocol ==
8436 : : 0xFF)
8437 : : tcp = true;
8438 [ # # ]: 0 : else if (lkups[i].type == ICE_ETYPE_OL &&
8439 [ # # ]: 0 : lkups[i].h_u.ethertype.ethtype_id ==
8440 : 0 : CPU_TO_BE16(ICE_MPLS_ETHER_ID) &&
8441 [ # # ]: 0 : lkups[i].m_u.ethertype.ethtype_id == 0xFFFF)
8442 : : mpls = true;
8443 : : }
8444 : :
8445 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
8446 : : tun_type == ICE_NON_TUN_QINQ) {
8447 [ # # ]: 0 : if (outer_ipv6) {
8448 [ # # ]: 0 : if (tcp) {
8449 : 0 : *pkt = dummy_qinq_ipv6_tcp_pkt;
8450 : 0 : *pkt_len = sizeof(dummy_qinq_ipv6_tcp_pkt);
8451 : 0 : *offsets = dummy_qinq_ipv6_tcp_packet_offsets;
8452 : 0 : return;
8453 : : }
8454 : :
8455 [ # # ]: 0 : if (udp) {
8456 : 0 : *pkt = dummy_qinq_ipv6_udp_pkt;
8457 : 0 : *pkt_len = sizeof(dummy_qinq_ipv6_udp_pkt);
8458 : 0 : *offsets = dummy_qinq_ipv6_udp_packet_offsets;
8459 : 0 : return;
8460 : : }
8461 : :
8462 : 0 : *pkt = dummy_qinq_ipv6_pkt;
8463 : 0 : *pkt_len = sizeof(dummy_qinq_ipv6_pkt);
8464 : 0 : *offsets = dummy_qinq_ipv6_packet_offsets;
8465 : 0 : return;
8466 : : } else {
8467 [ # # ]: 0 : if (tcp) {
8468 : 0 : *pkt = dummy_qinq_ipv4_tcp_pkt;
8469 : 0 : *pkt_len = sizeof(dummy_qinq_ipv4_tcp_pkt);
8470 : 0 : *offsets = dummy_qinq_ipv4_tcp_packet_offsets;
8471 : 0 : return;
8472 : : }
8473 : :
8474 [ # # ]: 0 : if (udp) {
8475 : 0 : *pkt = dummy_qinq_ipv4_udp_pkt;
8476 : 0 : *pkt_len = sizeof(dummy_qinq_ipv4_udp_pkt);
8477 : 0 : *offsets = dummy_qinq_ipv4_udp_packet_offsets;
8478 : 0 : return;
8479 : : }
8480 : :
8481 : 0 : *pkt = dummy_qinq_ipv4_pkt;
8482 : 0 : *pkt_len = sizeof(dummy_qinq_ipv4_pkt);
8483 : 0 : *offsets = dummy_qinq_ipv4_packet_offsets;
8484 : 0 : return;
8485 : : }
8486 : : }
8487 : :
8488 : : if (tun_type == ICE_SW_IPV4_TCP) {
8489 : 0 : *pkt = dummy_tcp_packet;
8490 : 0 : *pkt_len = sizeof(dummy_tcp_packet);
8491 : 0 : *offsets = dummy_tcp_packet_offsets;
8492 : 0 : return;
8493 : : }
8494 : :
8495 : : if (tun_type == ICE_SW_IPV4_UDP) {
8496 : 0 : *pkt = dummy_udp_packet;
8497 : 0 : *pkt_len = sizeof(dummy_udp_packet);
8498 : 0 : *offsets = dummy_udp_packet_offsets;
8499 : 0 : return;
8500 : : }
8501 : :
8502 : : if (tun_type == ICE_SW_IPV6_TCP) {
8503 : 0 : *pkt = dummy_tcp_ipv6_packet;
8504 : 0 : *pkt_len = sizeof(dummy_tcp_ipv6_packet);
8505 : 0 : *offsets = dummy_tcp_ipv6_packet_offsets;
8506 : 0 : return;
8507 : : }
8508 : :
8509 : : if (tun_type == ICE_SW_IPV6_UDP) {
8510 : 0 : *pkt = dummy_udp_ipv6_packet;
8511 : 0 : *pkt_len = sizeof(dummy_udp_ipv6_packet);
8512 : 0 : *offsets = dummy_udp_ipv6_packet_offsets;
8513 : 0 : return;
8514 : : }
8515 : :
8516 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6_QINQ) {
8517 : 0 : *pkt = dummy_qinq_pppoe_ipv6_packet;
8518 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
8519 : 0 : *offsets = dummy_qinq_pppoe_packet_ipv6_offsets;
8520 : 0 : return;
8521 : : } else if (tun_type == ICE_SW_TUN_PPPOE_IPV4_QINQ) {
8522 : 0 : *pkt = dummy_qinq_pppoe_ipv4_pkt;
8523 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
8524 : 0 : *offsets = dummy_qinq_pppoe_ipv4_packet_offsets;
8525 : 0 : return;
8526 [ # # ]: 0 : } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ && outer_ipv6) {
8527 : 0 : *pkt = dummy_qinq_pppoe_ipv6_packet;
8528 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet);
8529 : 0 : *offsets = dummy_qinq_pppoe_packet_offsets;
8530 : 0 : return;
8531 [ # # # # : 0 : } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ ||
# # # # #
# # # # #
# # # # #
# # # # #
# ]
8532 : : tun_type == ICE_SW_TUN_PPPOE_PAY_QINQ) {
8533 : 0 : *pkt = dummy_qinq_pppoe_ipv4_pkt;
8534 : 0 : *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt);
8535 : 0 : *offsets = dummy_qinq_pppoe_packet_offsets;
8536 : 0 : return;
8537 : : }
8538 : :
8539 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_NO_PAY) {
8540 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_packet;
8541 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
8542 : 0 : *offsets = dummy_ipv4_gtp_no_pay_packet_offsets;
8543 : 0 : return;
8544 : : } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_NO_PAY) {
8545 : 0 : *pkt = dummy_ipv6_gtp_packet;
8546 : 0 : *pkt_len = sizeof(dummy_ipv6_gtp_packet);
8547 : 0 : *offsets = dummy_ipv6_gtp_no_pay_packet_offsets;
8548 : 0 : return;
8549 : : }
8550 : :
8551 : : if (tun_type == ICE_SW_TUN_IPV4_ESP) {
8552 : 0 : *pkt = dummy_ipv4_esp_pkt;
8553 : 0 : *pkt_len = sizeof(dummy_ipv4_esp_pkt);
8554 : 0 : *offsets = dummy_ipv4_esp_packet_offsets;
8555 : 0 : return;
8556 : : }
8557 : :
8558 : : if (tun_type == ICE_SW_TUN_IPV6_ESP) {
8559 : 0 : *pkt = dummy_ipv6_esp_pkt;
8560 : 0 : *pkt_len = sizeof(dummy_ipv6_esp_pkt);
8561 : 0 : *offsets = dummy_ipv6_esp_packet_offsets;
8562 : 0 : return;
8563 : : }
8564 : :
8565 : : if (tun_type == ICE_SW_TUN_IPV4_AH) {
8566 : 0 : *pkt = dummy_ipv4_ah_pkt;
8567 : 0 : *pkt_len = sizeof(dummy_ipv4_ah_pkt);
8568 : 0 : *offsets = dummy_ipv4_ah_packet_offsets;
8569 : 0 : return;
8570 : : }
8571 : :
8572 : : if (tun_type == ICE_SW_TUN_IPV6_AH) {
8573 : 0 : *pkt = dummy_ipv6_ah_pkt;
8574 : 0 : *pkt_len = sizeof(dummy_ipv6_ah_pkt);
8575 : 0 : *offsets = dummy_ipv6_ah_packet_offsets;
8576 : 0 : return;
8577 : : }
8578 : :
8579 : : if (tun_type == ICE_SW_TUN_IPV4_NAT_T) {
8580 : 0 : *pkt = dummy_ipv4_nat_pkt;
8581 : 0 : *pkt_len = sizeof(dummy_ipv4_nat_pkt);
8582 : 0 : *offsets = dummy_ipv4_nat_packet_offsets;
8583 : 0 : return;
8584 : : }
8585 : :
8586 : : if (tun_type == ICE_SW_TUN_IPV6_NAT_T) {
8587 : 0 : *pkt = dummy_ipv6_nat_pkt;
8588 : 0 : *pkt_len = sizeof(dummy_ipv6_nat_pkt);
8589 : 0 : *offsets = dummy_ipv6_nat_packet_offsets;
8590 : 0 : return;
8591 : : }
8592 : :
8593 : : if (tun_type == ICE_SW_TUN_IPV4_L2TPV3) {
8594 : 0 : *pkt = dummy_ipv4_l2tpv3_pkt;
8595 : 0 : *pkt_len = sizeof(dummy_ipv4_l2tpv3_pkt);
8596 : 0 : *offsets = dummy_ipv4_l2tpv3_packet_offsets;
8597 : 0 : return;
8598 : : }
8599 : :
8600 : : if (tun_type == ICE_SW_TUN_IPV6_L2TPV3) {
8601 : 0 : *pkt = dummy_ipv6_l2tpv3_pkt;
8602 : 0 : *pkt_len = sizeof(dummy_ipv6_l2tpv3_pkt);
8603 : 0 : *offsets = dummy_ipv6_l2tpv3_packet_offsets;
8604 : 0 : return;
8605 : : }
8606 : :
8607 : : if (tun_type == ICE_SW_TUN_GTP) {
8608 : 0 : *pkt = dummy_udp_gtp_packet;
8609 : 0 : *pkt_len = sizeof(dummy_udp_gtp_packet);
8610 : 0 : *offsets = dummy_udp_gtp_packet_offsets;
8611 : 0 : return;
8612 : : }
8613 : :
8614 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4 ||
8615 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4) {
8616 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_packet;
8617 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet);
8618 : 0 : *offsets = dummy_ipv4_gtpu_ipv4_packet_offsets;
8619 : 0 : return;
8620 : : }
8621 : :
8622 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4_UDP ||
8623 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4_UDP) {
8624 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_udp_packet;
8625 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_udp_packet);
8626 : 0 : *offsets = dummy_ipv4_gtpu_ipv4_udp_packet_offsets;
8627 : 0 : return;
8628 : : }
8629 : :
8630 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4_TCP ||
8631 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV4_TCP) {
8632 : 0 : *pkt = dummy_ipv4_gtpu_ipv4_tcp_packet;
8633 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_tcp_packet);
8634 : 0 : *offsets = dummy_ipv4_gtpu_ipv4_tcp_packet_offsets;
8635 : 0 : return;
8636 : : }
8637 : :
8638 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6 ||
8639 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6) {
8640 : 0 : *pkt = dummy_ipv4_gtpu_ipv6_packet;
8641 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_packet);
8642 : 0 : *offsets = dummy_ipv4_gtpu_ipv6_packet_offsets;
8643 : 0 : return;
8644 : : }
8645 : :
8646 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6_UDP ||
8647 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6_UDP) {
8648 : 0 : *pkt = dummy_ipv4_gtpu_ipv6_udp_packet;
8649 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_udp_packet);
8650 : 0 : *offsets = dummy_ipv4_gtpu_ipv6_udp_packet_offsets;
8651 : 0 : return;
8652 : : }
8653 : :
8654 : : if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6_TCP ||
8655 : : tun_type == ICE_SW_TUN_IPV4_GTPU_EH_IPV6_TCP) {
8656 : 0 : *pkt = dummy_ipv4_gtpu_ipv6_tcp_packet;
8657 : 0 : *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_tcp_packet);
8658 : 0 : *offsets = dummy_ipv4_gtpu_ipv6_tcp_packet_offsets;
8659 : 0 : return;
8660 : : }
8661 : :
8662 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4 ||
8663 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4) {
8664 : 0 : *pkt = dummy_ipv6_gtpu_ipv4_packet;
8665 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_packet);
8666 : 0 : *offsets = dummy_ipv6_gtpu_ipv4_packet_offsets;
8667 : 0 : return;
8668 : : }
8669 : :
8670 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4_UDP ||
8671 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4_UDP) {
8672 : 0 : *pkt = dummy_ipv6_gtpu_ipv4_udp_packet;
8673 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_udp_packet);
8674 : 0 : *offsets = dummy_ipv6_gtpu_ipv4_udp_packet_offsets;
8675 : 0 : return;
8676 : : }
8677 : :
8678 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4_TCP ||
8679 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV4_TCP) {
8680 : 0 : *pkt = dummy_ipv6_gtpu_ipv4_tcp_packet;
8681 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_tcp_packet);
8682 : 0 : *offsets = dummy_ipv6_gtpu_ipv4_tcp_packet_offsets;
8683 : 0 : return;
8684 : : }
8685 : :
8686 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6 ||
8687 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6) {
8688 : 0 : *pkt = dummy_ipv6_gtpu_ipv6_packet;
8689 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet);
8690 : 0 : *offsets = dummy_ipv6_gtpu_ipv6_packet_offsets;
8691 : 0 : return;
8692 : : }
8693 : :
8694 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6_UDP ||
8695 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6_UDP) {
8696 : 0 : *pkt = dummy_ipv6_gtpu_ipv6_udp_packet;
8697 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_udp_packet);
8698 : 0 : *offsets = dummy_ipv6_gtpu_ipv6_udp_packet_offsets;
8699 : 0 : return;
8700 : : }
8701 : :
8702 : : if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6_TCP ||
8703 : : tun_type == ICE_SW_TUN_IPV6_GTPU_EH_IPV6_TCP) {
8704 : 0 : *pkt = dummy_ipv6_gtpu_ipv6_tcp_packet;
8705 : 0 : *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_tcp_packet);
8706 : 0 : *offsets = dummy_ipv6_gtpu_ipv6_tcp_packet_offsets;
8707 : 0 : return;
8708 : : }
8709 : :
8710 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_PPPOE && outer_ipv6) {
8711 : 0 : *pkt = dummy_pppoe_ipv6_packet;
8712 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
8713 : 0 : *offsets = dummy_pppoe_packet_offsets;
8714 : 0 : return;
8715 [ # # # # : 0 : } else if (tun_type == ICE_SW_TUN_PPPOE ||
# # # #
# ]
8716 : : tun_type == ICE_SW_TUN_PPPOE_PAY) {
8717 : 0 : *pkt = dummy_pppoe_ipv4_packet;
8718 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
8719 : 0 : *offsets = dummy_pppoe_packet_offsets;
8720 : 0 : return;
8721 : : }
8722 : :
8723 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV4) {
8724 : 0 : *pkt = dummy_pppoe_ipv4_packet;
8725 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_packet);
8726 : 0 : *offsets = dummy_pppoe_packet_ipv4_offsets;
8727 : 0 : return;
8728 : : }
8729 : :
8730 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV4_TCP) {
8731 : 0 : *pkt = dummy_pppoe_ipv4_tcp_packet;
8732 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
8733 : 0 : *offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
8734 : 0 : return;
8735 : : }
8736 : :
8737 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV4_UDP) {
8738 : 0 : *pkt = dummy_pppoe_ipv4_udp_packet;
8739 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
8740 : 0 : *offsets = dummy_pppoe_ipv4_udp_packet_offsets;
8741 : 0 : return;
8742 : : }
8743 : :
8744 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6) {
8745 : 0 : *pkt = dummy_pppoe_ipv6_packet;
8746 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_packet);
8747 : 0 : *offsets = dummy_pppoe_packet_ipv6_offsets;
8748 : 0 : return;
8749 : : }
8750 : :
8751 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6_TCP) {
8752 : 0 : *pkt = dummy_pppoe_ipv6_tcp_packet;
8753 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
8754 : 0 : *offsets = dummy_pppoe_ipv6_tcp_packet_offsets;
8755 : 0 : return;
8756 : : }
8757 : :
8758 : : if (tun_type == ICE_SW_TUN_PPPOE_IPV6_UDP) {
8759 : 0 : *pkt = dummy_pppoe_ipv6_udp_packet;
8760 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
8761 : 0 : *offsets = dummy_pppoe_ipv6_udp_packet_offsets;
8762 : 0 : return;
8763 : : }
8764 : :
8765 : : if (tun_type == ICE_ALL_TUNNELS) {
8766 : 0 : *pkt = dummy_gre_udp_packet;
8767 : 0 : *pkt_len = sizeof(dummy_gre_udp_packet);
8768 : 0 : *offsets = dummy_gre_udp_packet_offsets;
8769 : 0 : return;
8770 : : }
8771 : :
8772 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_NVGRE || gre) {
8773 [ # # ]: 0 : if (tcp && inner_ipv6) {
8774 : 0 : *pkt = dummy_gre_ipv6_tcp_packet;
8775 : 0 : *pkt_len = sizeof(dummy_gre_ipv6_tcp_packet);
8776 : 0 : *offsets = dummy_gre_ipv6_tcp_packet_offsets;
8777 : 0 : return;
8778 : : }
8779 : :
8780 [ # # ]: 0 : if (tcp) {
8781 : 0 : *pkt = dummy_gre_tcp_packet;
8782 : 0 : *pkt_len = sizeof(dummy_gre_tcp_packet);
8783 : 0 : *offsets = dummy_gre_tcp_packet_offsets;
8784 : 0 : return;
8785 : : }
8786 : :
8787 [ # # ]: 0 : if (inner_ipv6) {
8788 : 0 : *pkt = dummy_gre_ipv6_udp_packet;
8789 : 0 : *pkt_len = sizeof(dummy_gre_ipv6_udp_packet);
8790 : 0 : *offsets = dummy_gre_ipv6_udp_packet_offsets;
8791 : 0 : return;
8792 : : }
8793 : :
8794 : 0 : *pkt = dummy_gre_udp_packet;
8795 : 0 : *pkt_len = sizeof(dummy_gre_udp_packet);
8796 : 0 : *offsets = dummy_gre_udp_packet_offsets;
8797 : 0 : return;
8798 : : }
8799 : :
8800 [ # # ]: 0 : if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE ||
8801 [ # # ]: 0 : tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP ||
8802 : 0 : tun_type == ICE_SW_TUN_GENEVE_VLAN ||
8803 [ # # ]: 0 : tun_type == ICE_SW_TUN_VXLAN_VLAN) {
8804 [ # # ]: 0 : if (tcp && inner_ipv6) {
8805 : 0 : *pkt = dummy_udp_tun_ipv6_tcp_packet;
8806 : 0 : *pkt_len = sizeof(dummy_udp_tun_ipv6_tcp_packet);
8807 : 0 : *offsets = dummy_udp_tun_ipv6_tcp_packet_offsets;
8808 : 0 : return;
8809 : : }
8810 : :
8811 [ # # ]: 0 : if (tcp) {
8812 : 0 : *pkt = dummy_udp_tun_tcp_packet;
8813 : 0 : *pkt_len = sizeof(dummy_udp_tun_tcp_packet);
8814 : 0 : *offsets = dummy_udp_tun_tcp_packet_offsets;
8815 : 0 : return;
8816 : : }
8817 : :
8818 [ # # ]: 0 : if (inner_ipv6) {
8819 : 0 : *pkt = dummy_udp_tun_ipv6_udp_packet;
8820 : 0 : *pkt_len = sizeof(dummy_udp_tun_ipv6_udp_packet);
8821 : 0 : *offsets = dummy_udp_tun_ipv6_udp_packet_offsets;
8822 : 0 : return;
8823 : : }
8824 : :
8825 : 0 : *pkt = dummy_udp_tun_udp_packet;
8826 : 0 : *pkt_len = sizeof(dummy_udp_tun_udp_packet);
8827 : 0 : *offsets = dummy_udp_tun_udp_packet_offsets;
8828 : 0 : return;
8829 : : }
8830 : :
8831 [ # # ]: 0 : if (udp && !outer_ipv6) {
8832 [ # # ]: 0 : if (vlan) {
8833 : 0 : *pkt = dummy_vlan_udp_packet;
8834 : 0 : *pkt_len = sizeof(dummy_vlan_udp_packet);
8835 : 0 : *offsets = dummy_vlan_udp_packet_offsets;
8836 : 0 : return;
8837 [ # # ]: 0 : } else if (pppoe) {
8838 : 0 : *pkt = dummy_pppoe_ipv4_udp_packet;
8839 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet);
8840 : 0 : *offsets = dummy_pppoe_ipv4_udp_packet_offsets;
8841 : 0 : return;
8842 : : }
8843 : 0 : *pkt = dummy_udp_packet;
8844 : 0 : *pkt_len = sizeof(dummy_udp_packet);
8845 : 0 : *offsets = dummy_udp_packet_offsets;
8846 : 0 : return;
8847 [ # # ]: 0 : } else if (udp && outer_ipv6) {
8848 [ # # ]: 0 : if (vlan) {
8849 : 0 : *pkt = dummy_vlan_udp_ipv6_packet;
8850 : 0 : *pkt_len = sizeof(dummy_vlan_udp_ipv6_packet);
8851 : 0 : *offsets = dummy_vlan_udp_ipv6_packet_offsets;
8852 : 0 : return;
8853 [ # # ]: 0 : } else if (pppoe) {
8854 : 0 : *pkt = dummy_pppoe_ipv6_udp_packet;
8855 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet);
8856 : 0 : *offsets = dummy_pppoe_ipv6_udp_packet_offsets;
8857 : 0 : return;
8858 : : }
8859 : 0 : *pkt = dummy_udp_ipv6_packet;
8860 : 0 : *pkt_len = sizeof(dummy_udp_ipv6_packet);
8861 : 0 : *offsets = dummy_udp_ipv6_packet_offsets;
8862 : 0 : return;
8863 [ # # # # ]: 0 : } else if ((tcp && outer_ipv6) || outer_ipv6) {
8864 [ # # ]: 0 : if (vlan) {
8865 : 0 : *pkt = dummy_vlan_tcp_ipv6_packet;
8866 : 0 : *pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet);
8867 : 0 : *offsets = dummy_vlan_tcp_ipv6_packet_offsets;
8868 : 0 : return;
8869 [ # # ]: 0 : } else if (pppoe) {
8870 : 0 : *pkt = dummy_pppoe_ipv6_tcp_packet;
8871 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet);
8872 : 0 : *offsets = dummy_pppoe_ipv6_tcp_packet_offsets;
8873 : 0 : return;
8874 : : }
8875 : 0 : *pkt = dummy_tcp_ipv6_packet;
8876 : 0 : *pkt_len = sizeof(dummy_tcp_ipv6_packet);
8877 : 0 : *offsets = dummy_tcp_ipv6_packet_offsets;
8878 : 0 : return;
8879 : : }
8880 : :
8881 [ # # ]: 0 : if (vlan) {
8882 : 0 : *pkt = dummy_vlan_tcp_packet;
8883 : 0 : *pkt_len = sizeof(dummy_vlan_tcp_packet);
8884 : 0 : *offsets = dummy_vlan_tcp_packet_offsets;
8885 [ # # ]: 0 : } else if (pppoe) {
8886 : 0 : *pkt = dummy_pppoe_ipv4_tcp_packet;
8887 : 0 : *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet);
8888 : 0 : *offsets = dummy_pppoe_ipv4_tcp_packet_offsets;
8889 : 0 : return;
8890 [ # # ]: 0 : } else if (mpls) {
8891 : 0 : *pkt = dummy_mpls_packet;
8892 : 0 : *pkt_len = sizeof(dummy_mpls_packet);
8893 : 0 : *offsets = dummy_mpls_packet_offsets;
8894 : : } else {
8895 : 0 : *pkt = dummy_tcp_packet;
8896 : 0 : *pkt_len = sizeof(dummy_tcp_packet);
8897 : 0 : *offsets = dummy_tcp_packet_offsets;
8898 : : }
8899 : : }
8900 : :
8901 : : /**
8902 : : * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria
8903 : : *
8904 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
8905 : : * structure per protocol header
8906 : : * @lkups_cnt: number of protocols
8907 : : * @s_rule: stores rule information from the match criteria
8908 : : * @dummy_pkt: dummy packet to fill according to filter match criteria
8909 : : * @pkt_len: packet length of dummy packet
8910 : : * @offsets: offset info for the dummy packet
8911 : : */
8912 : : int
8913 : 0 : ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
8914 : : struct ice_sw_rule_lkup_rx_tx *s_rule,
8915 : : const u8 *dummy_pkt, u16 pkt_len,
8916 : : const struct ice_dummy_pkt_offsets *offsets)
8917 : : {
8918 : : u8 *pkt;
8919 : : u16 i;
8920 : :
8921 : : /* Start with a packet with a pre-defined/dummy content. Then, fill
8922 : : * in the header values to be looked up or matched.
8923 : : */
8924 : 0 : pkt = s_rule->hdr_data;
8925 : :
8926 [ # # ]: 0 : ice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA);
8927 : :
8928 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
8929 : : enum ice_protocol_type type;
8930 : : u16 offset = 0, len = 0, j;
8931 : : bool found = false;
8932 : :
8933 : : /* find the start of this layer; it should be found since this
8934 : : * was already checked when search for the dummy packet
8935 : : */
8936 : 0 : type = lkups[i].type;
8937 [ # # ]: 0 : for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
8938 [ # # ]: 0 : if (type == offsets[j].type) {
8939 : 0 : offset = offsets[j].offset;
8940 : : found = true;
8941 : 0 : break;
8942 : : }
8943 : : }
8944 : : /* this should never happen in a correct calling sequence */
8945 [ # # ]: 0 : if (!found)
8946 : : return ICE_ERR_PARAM;
8947 : :
8948 [ # # # # : 0 : switch (lkups[i].type) {
# # # # #
# # # #
# ]
8949 : : case ICE_MAC_OFOS:
8950 : : case ICE_MAC_IL:
8951 : : len = sizeof(struct ice_ether_hdr);
8952 : : break;
8953 : 0 : case ICE_ETYPE_OL:
8954 : : case ICE_ETYPE_IL:
8955 : : len = sizeof(struct ice_ethtype_hdr);
8956 : 0 : break;
8957 : 0 : case ICE_VLAN_OFOS:
8958 : : case ICE_VLAN_EX:
8959 : : case ICE_VLAN_IN:
8960 : : len = sizeof(struct ice_vlan_hdr);
8961 : 0 : break;
8962 : 0 : case ICE_IPV4_OFOS:
8963 : : case ICE_IPV4_IL:
8964 : : len = sizeof(struct ice_ipv4_hdr);
8965 : 0 : break;
8966 : 0 : case ICE_IPV6_OFOS:
8967 : : case ICE_IPV6_IL:
8968 : : len = sizeof(struct ice_ipv6_hdr);
8969 : 0 : break;
8970 : 0 : case ICE_TCP_IL:
8971 : : case ICE_UDP_OF:
8972 : : case ICE_UDP_ILOS:
8973 : : len = sizeof(struct ice_l4_hdr);
8974 : 0 : break;
8975 : : case ICE_SCTP_IL:
8976 : : len = sizeof(struct ice_sctp_hdr);
8977 : : break;
8978 : 0 : case ICE_NVGRE:
8979 : : len = sizeof(struct ice_nvgre);
8980 : 0 : break;
8981 : 0 : case ICE_VXLAN:
8982 : : case ICE_GENEVE:
8983 : : case ICE_VXLAN_GPE:
8984 : : len = sizeof(struct ice_udp_tnl_hdr);
8985 : 0 : break;
8986 : 0 : case ICE_ESP:
8987 : : len = sizeof(struct ice_esp_hdr);
8988 : 0 : break;
8989 : 0 : case ICE_NAT_T:
8990 : : len = sizeof(struct ice_nat_t_hdr);
8991 : 0 : break;
8992 : : case ICE_AH:
8993 : : len = sizeof(struct ice_ah_hdr);
8994 : : break;
8995 : 0 : case ICE_GTP_NO_PAY:
8996 : : case ICE_GTP:
8997 : : len = sizeof(struct ice_udp_gtp_hdr);
8998 : 0 : break;
8999 : 0 : case ICE_PPPOE:
9000 : : len = sizeof(struct ice_pppoe_hdr);
9001 : 0 : break;
9002 : 0 : case ICE_L2TPV3:
9003 : : len = sizeof(struct ice_l2tpv3_sess_hdr);
9004 : 0 : break;
9005 : : default:
9006 : : return ICE_ERR_PARAM;
9007 : : }
9008 : :
9009 : : /* the length should be a word multiple */
9010 : : if (len % ICE_BYTES_PER_WORD)
9011 : : return ICE_ERR_CFG;
9012 : :
9013 : : /* We have the offset to the header start, the length, the
9014 : : * caller's header values and mask. Use this information to
9015 : : * copy the data into the dummy packet appropriately based on
9016 : : * the mask. Note that we need to only write the bits as
9017 : : * indicated by the mask to make sure we don't improperly write
9018 : : * over any significant packet data.
9019 : : */
9020 [ # # ]: 0 : for (j = 0; j < len / sizeof(u16); j++)
9021 [ # # ]: 0 : if (((u16 *)&lkups[i].m_u)[j])
9022 : 0 : ((u16 *)(pkt + offset))[j] =
9023 : 0 : (((u16 *)(pkt + offset))[j] &
9024 : 0 : ~((u16 *)&lkups[i].m_u)[j]) |
9025 : 0 : (((u16 *)&lkups[i].h_u)[j] &
9026 : : ((u16 *)&lkups[i].m_u)[j]);
9027 : : }
9028 : :
9029 : 0 : s_rule->hdr_len = CPU_TO_LE16(pkt_len);
9030 : :
9031 : 0 : return 0;
9032 : : }
9033 : :
9034 : : /**
9035 : : * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
9036 : : * @hw: pointer to the hardware structure
9037 : : * @tun_type: tunnel type
9038 : : * @pkt: dummy packet to fill in
9039 : : * @offsets: offset info for the dummy packet
9040 : : */
9041 : : static int
9042 : 0 : ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
9043 : : u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
9044 : : {
9045 : : u16 open_port, i;
9046 : :
9047 [ # # # ]: 0 : switch (tun_type) {
9048 : 0 : case ICE_SW_TUN_AND_NON_TUN:
9049 : : case ICE_SW_TUN_VXLAN_GPE:
9050 : : case ICE_SW_TUN_VXLAN:
9051 : : case ICE_SW_TUN_VXLAN_VLAN:
9052 : : case ICE_SW_TUN_UDP:
9053 [ # # ]: 0 : if (!ice_get_open_tunnel_port(hw, TNL_VXLAN, &open_port))
9054 : : return ICE_ERR_CFG;
9055 : : break;
9056 : 0 : case ICE_SW_TUN_GENEVE:
9057 : : case ICE_SW_TUN_GENEVE_VLAN:
9058 [ # # ]: 0 : if (!ice_get_open_tunnel_port(hw, TNL_GENEVE, &open_port))
9059 : : return ICE_ERR_CFG;
9060 : : break;
9061 : : default:
9062 : : /* Nothing needs to be done for this tunnel type */
9063 : : return 0;
9064 : : }
9065 : :
9066 : : /* Find the outer UDP protocol header and insert the port number */
9067 [ # # ]: 0 : for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
9068 [ # # ]: 0 : if (offsets[i].type == ICE_UDP_OF) {
9069 : : struct ice_l4_hdr *hdr;
9070 : : u16 offset;
9071 : :
9072 : 0 : offset = offsets[i].offset;
9073 : 0 : hdr = (struct ice_l4_hdr *)&pkt[offset];
9074 [ # # ]: 0 : hdr->dst_port = CPU_TO_BE16(open_port);
9075 : :
9076 : 0 : return 0;
9077 : : }
9078 : : }
9079 : :
9080 : : return ICE_ERR_CFG;
9081 : : }
9082 : :
9083 : : /**
9084 : : * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type
9085 : : * @vlan_type: VLAN tag type
9086 : : * @pkt: dummy packet to fill in
9087 : : * @offsets: offset info for the dummy packet
9088 : : */
9089 : : static int
9090 : 0 : ice_fill_adv_packet_vlan(u16 vlan_type, u8 *pkt,
9091 : : const struct ice_dummy_pkt_offsets *offsets)
9092 : : {
9093 : : u16 i;
9094 : :
9095 : : /* Find VLAN header and insert VLAN TPID */
9096 [ # # ]: 0 : for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
9097 [ # # ]: 0 : if (offsets[i].type == ICE_VLAN_OFOS ||
9098 : : offsets[i].type == ICE_VLAN_EX) {
9099 : : struct ice_vlan_hdr *hdr;
9100 : : u16 offset;
9101 : :
9102 : 0 : offset = offsets[i].offset;
9103 : 0 : hdr = (struct ice_vlan_hdr *)&pkt[offset];
9104 [ # # ]: 0 : hdr->type = CPU_TO_BE16(vlan_type);
9105 : :
9106 : 0 : return 0;
9107 : : }
9108 : : }
9109 : :
9110 : : return ICE_ERR_CFG;
9111 : : }
9112 : :
9113 : : /**
9114 : : * ice_find_adv_rule_entry - Search a rule entry
9115 : : * @hw: pointer to the hardware structure
9116 : : * @lkups: lookup elements or match criteria for the advanced recipe, one
9117 : : * structure per protocol header
9118 : : * @lkups_cnt: number of protocols
9119 : : * @recp_id: recipe ID for which we are finding the rule
9120 : : * @rinfo: other information regarding the rule e.g. priority and action info
9121 : : *
9122 : : * Helper function to search for a given advance rule entry
9123 : : * Returns pointer to entry storing the rule if found
9124 : : */
9125 : : struct ice_adv_fltr_mgmt_list_entry *
9126 : 0 : ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
9127 : : u16 lkups_cnt, u16 recp_id,
9128 : : struct ice_adv_rule_info *rinfo)
9129 : : {
9130 : : struct ice_adv_fltr_mgmt_list_entry *list_itr;
9131 : 0 : struct ice_switch_info *sw = hw->switch_info;
9132 : : int i;
9133 : :
9134 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, &sw->recp_list[recp_id].filt_rules,
# # ]
9135 : : ice_adv_fltr_mgmt_list_entry, list_entry) {
9136 : : bool lkups_matched = true;
9137 : :
9138 [ # # ]: 0 : if (lkups_cnt != list_itr->lkups_cnt)
9139 : 0 : continue;
9140 [ # # ]: 0 : for (i = 0; i < list_itr->lkups_cnt; i++)
9141 [ # # ]: 0 : if (memcmp(&list_itr->lkups[i], &lkups[i],
9142 : : sizeof(*lkups))) {
9143 : : lkups_matched = false;
9144 : : break;
9145 : : }
9146 [ # # ]: 0 : if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
9147 [ # # ]: 0 : rinfo->tun_type == list_itr->rule_info.tun_type &&
9148 [ # # # # ]: 0 : rinfo->vlan_type == list_itr->rule_info.vlan_type &&
9149 : : lkups_matched)
9150 : 0 : return list_itr;
9151 : : }
9152 : : return NULL;
9153 : : }
9154 : :
9155 : : /**
9156 : : * ice_adv_add_update_vsi_list
9157 : : * @hw: pointer to the hardware structure
9158 : : * @m_entry: pointer to current adv filter management list entry
9159 : : * @cur_fltr: filter information from the book keeping entry
9160 : : * @new_fltr: filter information with the new VSI to be added
9161 : : *
9162 : : * Call AQ command to add or update previously created VSI list with new VSI.
9163 : : *
9164 : : * Helper function to do book keeping associated with adding filter information
9165 : : * The algorithm to do the booking keeping is described below :
9166 : : * When a VSI needs to subscribe to a given advanced filter
9167 : : * if only one VSI has been added till now
9168 : : * Allocate a new VSI list and add two VSIs
9169 : : * to this list using switch rule command
9170 : : * Update the previously created switch rule with the
9171 : : * newly created VSI list ID
9172 : : * if a VSI list was previously created
9173 : : * Add the new VSI to the previously created VSI list set
9174 : : * using the update switch rule command
9175 : : */
9176 : : int
9177 : 0 : ice_adv_add_update_vsi_list(struct ice_hw *hw,
9178 : : struct ice_adv_fltr_mgmt_list_entry *m_entry,
9179 : : struct ice_adv_rule_info *cur_fltr,
9180 : : struct ice_adv_rule_info *new_fltr)
9181 : : {
9182 : 0 : u16 vsi_list_id = 0;
9183 : : int status;
9184 : :
9185 : 0 : if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
9186 [ # # ]: 0 : cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
9187 : : cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
9188 : : return ICE_ERR_NOT_IMPL;
9189 : :
9190 [ # # ]: 0 : if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
9191 [ # # ]: 0 : new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
9192 : : (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
9193 : : cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
9194 : : return ICE_ERR_NOT_IMPL;
9195 : :
9196 [ # # # # ]: 0 : if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
9197 : : /* Only one entry existed in the mapping and it was not already
9198 : : * a part of a VSI list. So, create a VSI list with the old and
9199 : : * new VSIs.
9200 : : */
9201 : : struct ice_fltr_info tmp_fltr;
9202 : : u16 vsi_handle_arr[2];
9203 : :
9204 : : /* A rule already exists with the new VSI being added */
9205 [ # # ]: 0 : if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
9206 : : new_fltr->sw_act.fwd_id.hw_vsi_id)
9207 : 0 : return ICE_ERR_ALREADY_EXISTS;
9208 : :
9209 : 0 : vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
9210 : 0 : vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
9211 : 0 : status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
9212 : : &vsi_list_id,
9213 : : ICE_SW_LKUP_LAST);
9214 [ # # ]: 0 : if (status)
9215 : : return status;
9216 : :
9217 : : ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
9218 : 0 : tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
9219 : 0 : tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
9220 : 0 : tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
9221 : 0 : tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
9222 : 0 : tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
9223 : :
9224 : : /* Update the previous switch rule of "forward to VSI" to
9225 : : * "fwd to VSI list"
9226 : : */
9227 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
9228 [ # # ]: 0 : if (status)
9229 : : return status;
9230 : :
9231 : 0 : cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
9232 : 0 : cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
9233 : 0 : m_entry->vsi_list_info =
9234 : 0 : ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
9235 : : vsi_list_id);
9236 : : } else {
9237 : 0 : u16 vsi_handle = new_fltr->sw_act.vsi_handle;
9238 : :
9239 [ # # ]: 0 : if (!m_entry->vsi_list_info)
9240 : 0 : return ICE_ERR_CFG;
9241 : :
9242 : : /* A rule already exists with the new VSI being added */
9243 [ # # ]: 0 : if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle))
9244 : : return ICE_ERR_ALREADY_EXISTS;
9245 : :
9246 : : /* Update the previously created VSI list set with
9247 : : * the new VSI ID passed in
9248 : : */
9249 : 0 : vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
9250 : :
9251 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
9252 : : vsi_list_id, false,
9253 : : ice_aqc_opc_update_sw_rules,
9254 : : ICE_SW_LKUP_LAST);
9255 : : /* update VSI list mapping info with new VSI ID */
9256 [ # # ]: 0 : if (!status)
9257 : 0 : ice_set_bit(vsi_handle,
9258 : 0 : m_entry->vsi_list_info->vsi_map);
9259 : : }
9260 [ # # ]: 0 : if (!status)
9261 : 0 : m_entry->vsi_count++;
9262 : : return status;
9263 : : }
9264 : :
9265 : : /**
9266 : : * ice_set_lg_action_entry
9267 : : * @act_type: large action type is defined in struct ice_sw_rule_lg_act
9268 : : * @lg_act_entry: large action entry content
9269 : : *
9270 : : * Helper function to set large action entry. Each entry represents a single
9271 : : * action and up to 4 actions can be chained.
9272 : : */
9273 : : static u32
9274 : 0 : ice_set_lg_action_entry(u8 act_type, union lg_act_entry *lg_entry)
9275 : : {
9276 : 0 : u32 act = act_type;
9277 : :
9278 [ # # # # : 0 : switch (act_type) {
# # # ]
9279 : 0 : case ICE_LG_ACT_VSI_FORWARDING:
9280 : 0 : act |= ICE_LG_ACT_VALID_BIT;
9281 : 0 : act |= (lg_entry->vsi_fwd.vsi_list <<
9282 : 0 : ICE_LG_ACT_VSI_LIST_ID_S) &
9283 : : ICE_LG_ACT_VSI_LIST_ID_M;
9284 : 0 : break;
9285 : 0 : case ICE_LG_ACT_TO_Q:
9286 : 0 : act |= ICE_LG_ACT_Q_PRIORITY_SET;
9287 : 0 : act |= (lg_entry->to_q.q_idx << ICE_LG_ACT_Q_INDEX_S) &
9288 : : ICE_LG_ACT_Q_INDEX_M;
9289 : 0 : act |= (lg_entry->to_q.q_region_sz << ICE_LG_ACT_Q_REGION_S) &
9290 : : ICE_LG_ACT_Q_REGION_M;
9291 : 0 : act |= (lg_entry->to_q.q_pri << ICE_LG_ACT_Q_REGION_S) &
9292 : : ICE_LG_ACT_Q_REGION_M;
9293 : 0 : break;
9294 : 0 : case ICE_LG_ACT_PRUNE:
9295 : 0 : act |= (lg_entry->prune.vsi_list << ICE_LG_ACT_VSI_LIST_ID_S) &
9296 : : ICE_LG_ACT_VSI_LIST_ID_M;
9297 : :
9298 [ # # ]: 0 : if (lg_entry->prune.egr)
9299 : 0 : act |= ICE_LG_ACT_EGRESS;
9300 [ # # ]: 0 : if (lg_entry->prune.ing)
9301 : 0 : act |= ICE_LG_ACT_INGRESS;
9302 [ # # ]: 0 : if (lg_entry->prune.prune_t)
9303 : 0 : act |= ICE_LG_ACT_PRUNET;
9304 : : break;
9305 : 0 : case ICE_LG_OTHER_ACT_MIRROR:
9306 : 0 : act |= (lg_entry->mirror.mirror_vsi <<
9307 : 0 : ICE_LG_ACT_MIRROR_VSI_ID_S) &
9308 : : ICE_LG_ACT_MIRROR_VSI_ID_M;
9309 : 0 : break;
9310 : 0 : case ICE_LG_ACT_GENERIC:
9311 : 0 : act |= (lg_entry->generic_act.generic_value <<
9312 : 0 : ICE_LG_ACT_GENERIC_VALUE_S) &
9313 : : ICE_LG_ACT_GENERIC_VALUE_M;
9314 : 0 : act |= (lg_entry->generic_act.offset <<
9315 : 0 : ICE_LG_ACT_GENERIC_OFFSET_S) &
9316 : : ICE_LG_ACT_GENERIC_OFFSET_M;
9317 : 0 : act |= (lg_entry->generic_act.priority <<
9318 : 0 : ICE_LG_ACT_GENERIC_PRIORITY_S) &
9319 : : ICE_LG_ACT_GENERIC_PRIORITY_M;
9320 : 0 : break;
9321 : 0 : case ICE_LG_ACT_STAT_COUNT:
9322 : 0 : act |= (lg_entry->statistics.counter_idx <<
9323 : 0 : ICE_LG_ACT_STAT_COUNT_S) &
9324 : : ICE_LG_ACT_STAT_COUNT_M;
9325 : 0 : break;
9326 : : }
9327 : :
9328 : 0 : return act;
9329 : : }
9330 : :
9331 : : /**
9332 : : * ice_fill_sw_marker_lg_act
9333 : : * @hw: pointer to the hardware structure
9334 : : * @sw_marker: sw marker to tag the Rx descriptor with
9335 : : * @l_id: large action resource ID
9336 : : * @lkup_rule_sz: lookup rule size
9337 : : * @lg_act_size: large action rule size
9338 : : * @num_lg_acts: number of actions to hold with a large action entry
9339 : : * @s_rule: switch lookup rule structure
9340 : : *
9341 : : * Fill a large action to hold software marker and link the lookup rule
9342 : : * with an action pointing to this larger action
9343 : : */
9344 : : static struct ice_sw_rule_lg_act *
9345 : 0 : ice_fill_sw_marker_lg_act(struct ice_hw *hw, u32 sw_marker, u16 l_id,
9346 : : u16 lkup_rule_sz, u16 lg_act_size, u16 num_lg_acts,
9347 : : struct ice_sw_rule_lkup_rx_tx *s_rule)
9348 : : {
9349 : : struct ice_sw_rule_lkup_rx_tx *rx_tx;
9350 : : const u16 offset_generic_md_word_0 = 0;
9351 : : const u16 offset_generic_md_word_1 = 1;
9352 : : struct ice_sw_rule_lg_act *lg_act;
9353 : : union lg_act_entry lg_e_lo;
9354 : : union lg_act_entry lg_e_hi;
9355 : : const u8 priority = 0x3;
9356 : : u16 rules_size;
9357 : : u32 act;
9358 : :
9359 : : /* For software marker we need 2 large actions for 32 bit mark id */
9360 : 0 : rules_size = lg_act_size + lkup_rule_sz;
9361 : 0 : lg_act = (struct ice_sw_rule_lg_act *)ice_malloc(hw, rules_size);
9362 [ # # ]: 0 : if (!lg_act)
9363 : : return NULL;
9364 : :
9365 : 0 : rx_tx = (struct ice_sw_rule_lkup_rx_tx *)((u8 *)lg_act + lg_act_size);
9366 : :
9367 [ # # ]: 0 : ice_memcpy(rx_tx, s_rule, lkup_rule_sz, ICE_NONDMA_TO_NONDMA);
9368 : 0 : ice_free(hw, s_rule);
9369 : : s_rule = NULL;
9370 : :
9371 : 0 : lg_act->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT);
9372 : 0 : lg_act->index = CPU_TO_LE16(l_id);
9373 : 0 : lg_act->size = CPU_TO_LE16(num_lg_acts);
9374 : :
9375 : : /* GENERIC VALUE action to hold the software marker ID low 16 bits */
9376 : : /* and set in meta data index 4 by default. */
9377 : 0 : lg_e_lo.generic_act.generic_value = (u16)(sw_marker & 0xFFFF);
9378 : 0 : lg_e_lo.generic_act.offset = offset_generic_md_word_0;
9379 : 0 : lg_e_lo.generic_act.priority = priority;
9380 : 0 : act = ice_set_lg_action_entry(ICE_LG_ACT_GENERIC, &lg_e_lo);
9381 : 0 : lg_act->act[0] = CPU_TO_LE32(act);
9382 : :
9383 [ # # ]: 0 : if (num_lg_acts == 1)
9384 : : return lg_act;
9385 : :
9386 : : /* This is a 32 bits marker id, chain a new entry to set higher 16 bits
9387 : : * and set in meta data index 5 by default.
9388 : : */
9389 : 0 : lg_e_hi.generic_act.generic_value = (u16)((sw_marker >> 16) & 0xFFFF);
9390 : 0 : lg_e_hi.generic_act.offset = offset_generic_md_word_1;
9391 : 0 : lg_e_hi.generic_act.priority = priority;
9392 : 0 : act = ice_set_lg_action_entry(ICE_LG_ACT_GENERIC, &lg_e_hi);
9393 : 0 : lg_act->act[1] = CPU_TO_LE32(act);
9394 : :
9395 : 0 : return lg_act;
9396 : : }
9397 : :
9398 : : /**
9399 : : * ice_add_adv_rule - helper function to create an advanced switch rule
9400 : : * @hw: pointer to the hardware structure
9401 : : * @lkups: information on the words that needs to be looked up. All words
9402 : : * together makes one recipe
9403 : : * @lkups_cnt: num of entries in the lkups array
9404 : : * @rinfo: other information related to the rule that needs to be programmed
9405 : : * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be
9406 : : * ignored is case of error.
9407 : : *
9408 : : * This function can program only 1 rule at a time. The lkups is used to
9409 : : * describe the all the words that forms the "lookup" portion of the recipe.
9410 : : * These words can span multiple protocols. Callers to this function need to
9411 : : * pass in a list of protocol headers with lookup information along and mask
9412 : : * that determines which words are valid from the given protocol header.
9413 : : * rinfo describes other information related to this rule such as forwarding
9414 : : * IDs, priority of this rule, etc.
9415 : : */
9416 : : int
9417 : 0 : ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
9418 : : u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
9419 : : struct ice_rule_query_data *added_entry)
9420 : : {
9421 : : struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
9422 : 0 : u16 lg_act_sz, lg_act_id = ICE_INVAL_LG_ACT_INDEX;
9423 : 0 : u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle;
9424 : : const struct ice_dummy_pkt_offsets *pkt_offsets;
9425 : : struct ice_sw_rule_lg_act *lg_rule = NULL;
9426 : : struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
9427 : : struct ice_sw_rule_lkup_rx_tx *rx_tx;
9428 : : struct LIST_HEAD_TYPE *rule_head;
9429 : : struct ice_switch_info *sw;
9430 : : u16 nb_lg_acts_mark = 1;
9431 : 0 : const u8 *pkt = NULL;
9432 : : u8 num_rules = 1;
9433 : : bool prof_rule;
9434 : : u16 word_cnt;
9435 : : u32 act = 0;
9436 : : int status;
9437 : : u8 q_rgn;
9438 : :
9439 : : /* Initialize profile to result index bitmap */
9440 [ # # ]: 0 : if (!hw->switch_info->prof_res_bm_init) {
9441 : 0 : hw->switch_info->prof_res_bm_init = 1;
9442 : 0 : ice_init_prof_result_bm(hw);
9443 : : }
9444 : :
9445 : 0 : prof_rule = ice_is_prof_rule(rinfo->tun_type);
9446 [ # # ]: 0 : if (!prof_rule && !lkups_cnt)
9447 : : return ICE_ERR_PARAM;
9448 : :
9449 : : /* get # of words we need to match */
9450 : : word_cnt = 0;
9451 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
9452 : : u16 j, *ptr;
9453 : :
9454 : 0 : ptr = (u16 *)&lkups[i].m_u;
9455 [ # # ]: 0 : for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++)
9456 [ # # ]: 0 : if (ptr[j] != 0)
9457 : 0 : word_cnt++;
9458 : : }
9459 : :
9460 [ # # ]: 0 : if (prof_rule) {
9461 [ # # ]: 0 : if (word_cnt > ICE_MAX_CHAIN_WORDS)
9462 : : return ICE_ERR_PARAM;
9463 : : } else {
9464 [ # # ]: 0 : if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS)
9465 : : return ICE_ERR_PARAM;
9466 : : }
9467 : :
9468 : : /* make sure that we can locate a dummy packet */
9469 : 0 : ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
9470 : : &pkt_offsets);
9471 [ # # ]: 0 : if (!pkt) {
9472 : : status = ICE_ERR_PARAM;
9473 : 0 : goto err_ice_add_adv_rule;
9474 : : }
9475 : :
9476 [ # # # # ]: 0 : if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
9477 [ # # ]: 0 : rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
9478 [ # # ]: 0 : rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
9479 : : rinfo->sw_act.fltr_act == ICE_SET_MARK ||
9480 : : rinfo->sw_act.fltr_act == ICE_DROP_PACKET))
9481 : : return ICE_ERR_CFG;
9482 : :
9483 : 0 : vsi_handle = rinfo->sw_act.vsi_handle;
9484 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
9485 : : return ICE_ERR_PARAM;
9486 : :
9487 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
9488 : 0 : rinfo->sw_act.fwd_id.hw_vsi_id =
9489 : 0 : ice_get_hw_vsi_num(hw, vsi_handle);
9490 [ # # ]: 0 : if (rinfo->sw_act.flag & ICE_FLTR_TX)
9491 : 0 : rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
9492 : :
9493 : 0 : status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
9494 [ # # ]: 0 : if (status)
9495 : : return status;
9496 : 0 : m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
9497 [ # # ]: 0 : if (m_entry) {
9498 : : /* we have to add VSI to VSI_LIST and increment vsi_count.
9499 : : * Also Update VSI list so that we can change forwarding rule
9500 : : * if the rule already exists, we will check if it exists with
9501 : : * same vsi_id, if not then add it to the VSI list if it already
9502 : : * exists if not then create a VSI list and add the existing VSI
9503 : : * ID and the new VSI ID to the list
9504 : : * We will add that VSI to the list
9505 : : */
9506 : 0 : status = ice_adv_add_update_vsi_list(hw, m_entry,
9507 : : &m_entry->rule_info,
9508 : : rinfo);
9509 [ # # ]: 0 : if (added_entry) {
9510 : 0 : added_entry->rid = rid;
9511 : 0 : added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
9512 : 0 : added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
9513 : : }
9514 : 0 : return status;
9515 : : }
9516 : 0 : rule_buf_sz = ice_struct_size(s_rule, hdr_data, 0) + pkt_len;
9517 : 0 : s_rule = (struct ice_sw_rule_lkup_rx_tx *)ice_malloc(hw, rule_buf_sz);
9518 [ # # ]: 0 : if (!s_rule)
9519 : : return ICE_ERR_NO_MEMORY;
9520 [ # # ]: 0 : if (!rinfo->flags_info.act_valid)
9521 : : act |= ICE_SINGLE_ACT_LAN_ENABLE;
9522 : : else
9523 : 0 : act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
9524 : : ICE_SINGLE_ACT_LB_ENABLE);
9525 : :
9526 [ # # # # : 0 : switch (rinfo->sw_act.fltr_act) {
# # ]
9527 : 0 : case ICE_FWD_TO_VSI:
9528 : 0 : act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
9529 : 0 : ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
9530 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
9531 : 0 : break;
9532 : 0 : case ICE_FWD_TO_Q:
9533 : 0 : act |= ICE_SINGLE_ACT_TO_Q;
9534 : 0 : act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
9535 : : ICE_SINGLE_ACT_Q_INDEX_M;
9536 : 0 : break;
9537 : 0 : case ICE_FWD_TO_QGRP:
9538 [ # # ]: 0 : q_rgn = rinfo->sw_act.qgrp_size > 0 ?
9539 : 0 : (u8)ice_ilog2(rinfo->sw_act.qgrp_size) : 0;
9540 : 0 : act |= ICE_SINGLE_ACT_TO_Q;
9541 : 0 : act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
9542 : : ICE_SINGLE_ACT_Q_INDEX_M;
9543 : 0 : act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
9544 : : ICE_SINGLE_ACT_Q_REGION_M;
9545 : 0 : break;
9546 : 0 : case ICE_SET_MARK:
9547 [ # # ]: 0 : if (rinfo->sw_act.markid > 0xFFFF)
9548 : : nb_lg_acts_mark += 1;
9549 : : /* Allocate a hardware table entry to hold large act. */
9550 : 0 : status = ice_alloc_res_lg_act(hw, &lg_act_id, nb_lg_acts_mark);
9551 [ # # # # ]: 0 : if (status || lg_act_id == ICE_INVAL_LG_ACT_INDEX)
9552 : : return ICE_ERR_NO_MEMORY;
9553 : :
9554 : : act = ICE_SINGLE_ACT_PTR;
9555 : 0 : act |= (lg_act_id << ICE_SINGLE_ACT_PTR_VAL_S) &
9556 : : ICE_SINGLE_ACT_PTR_VAL_M;
9557 : 0 : act |= ICE_SINGLE_ACT_PTR_BIT;
9558 : 0 : break;
9559 : 0 : case ICE_DROP_PACKET:
9560 : 0 : act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
9561 : : ICE_SINGLE_ACT_VALID_BIT;
9562 : 0 : break;
9563 : 0 : default:
9564 : : status = ICE_ERR_CFG;
9565 : 0 : goto err_ice_add_adv_rule;
9566 : : }
9567 : :
9568 : : /* Set the rule LOOKUP type based on caller specified 'Rx'
9569 : : * instead of hardcoding it to be either LOOKUP_TX/RX
9570 : : *
9571 : : * for 'Rx' set the source to be the port number
9572 : : * for 'Tx' set the source to be the source HW VSI number (determined
9573 : : * by caller)
9574 : : */
9575 [ # # ]: 0 : if (rinfo->rx) {
9576 : 0 : s_rule->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX);
9577 : 0 : s_rule->src = CPU_TO_LE16(hw->port_info->lport);
9578 : : } else {
9579 : 0 : s_rule->hdr.type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX);
9580 : 0 : s_rule->src = CPU_TO_LE16(rinfo->sw_act.src);
9581 : : }
9582 : :
9583 : 0 : s_rule->recipe_id = CPU_TO_LE16(rid);
9584 : 0 : s_rule->act = CPU_TO_LE32(act);
9585 : :
9586 : 0 : status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt,
9587 : : pkt_len, pkt_offsets);
9588 [ # # ]: 0 : if (status)
9589 : 0 : goto err_ice_add_adv_rule;
9590 : :
9591 [ # # ]: 0 : if (rinfo->tun_type != ICE_NON_TUN &&
9592 : : rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
9593 : 0 : status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
9594 : 0 : s_rule->hdr_data,
9595 : : pkt_offsets);
9596 [ # # ]: 0 : if (status)
9597 : 0 : goto err_ice_add_adv_rule;
9598 : : }
9599 : :
9600 [ # # # # ]: 0 : if (rinfo->vlan_type != 0 && ice_is_dvm_ena(hw)) {
9601 : 0 : status = ice_fill_adv_packet_vlan(rinfo->vlan_type,
9602 : 0 : s_rule->hdr_data,
9603 : : pkt_offsets);
9604 [ # # ]: 0 : if (status)
9605 : 0 : goto err_ice_add_adv_rule;
9606 : : }
9607 : :
9608 : : rx_tx = s_rule;
9609 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_SET_MARK) {
9610 : 0 : lg_act_sz = (u16)ice_struct_size(lg_rule, act, nb_lg_acts_mark);
9611 : 0 : lg_rule = ice_fill_sw_marker_lg_act(hw, rinfo->sw_act.markid,
9612 : : lg_act_id, rule_buf_sz,
9613 : : lg_act_sz, nb_lg_acts_mark,
9614 : : s_rule);
9615 [ # # ]: 0 : if (!lg_rule)
9616 : 0 : goto err_ice_add_adv_rule;
9617 : :
9618 : : s_rule = (struct ice_sw_rule_lkup_rx_tx *)lg_rule;
9619 : 0 : rule_buf_sz += lg_act_sz;
9620 : : num_rules += 1;
9621 : 0 : rx_tx = (struct ice_sw_rule_lkup_rx_tx *)
9622 : : ((u8 *)s_rule + lg_act_sz);
9623 : : }
9624 : :
9625 : 0 : status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
9626 : : rule_buf_sz, num_rules,
9627 : : ice_aqc_opc_add_sw_rules, NULL);
9628 [ # # ]: 0 : if (status)
9629 : 0 : goto err_ice_add_adv_rule;
9630 : : adv_fltr = (struct ice_adv_fltr_mgmt_list_entry *)
9631 : 0 : ice_malloc(hw, sizeof(struct ice_adv_fltr_mgmt_list_entry));
9632 [ # # ]: 0 : if (!adv_fltr) {
9633 : : status = ICE_ERR_NO_MEMORY;
9634 : 0 : goto err_ice_add_adv_rule;
9635 : : }
9636 : :
9637 [ # # ]: 0 : if (lkups_cnt) {
9638 : 0 : adv_fltr->lkups = (struct ice_adv_lkup_elem *)
9639 : 0 : ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups),
9640 : : ICE_NONDMA_TO_NONDMA);
9641 : : } else {
9642 : 0 : adv_fltr->lkups = NULL;
9643 : : }
9644 : :
9645 [ # # # # ]: 0 : if (!adv_fltr->lkups && !prof_rule) {
9646 : : status = ICE_ERR_NO_MEMORY;
9647 : 0 : goto err_ice_add_adv_rule;
9648 : : }
9649 : :
9650 : 0 : adv_fltr->lkups_cnt = lkups_cnt;
9651 : 0 : adv_fltr->rule_info = *rinfo;
9652 : 0 : adv_fltr->rule_info.fltr_rule_id =
9653 : 0 : LE16_TO_CPU(rx_tx->index);
9654 : 0 : adv_fltr->rule_info.lg_id = LE16_TO_CPU(lg_act_id);
9655 : 0 : sw = hw->switch_info;
9656 : 0 : sw->recp_list[rid].adv_rule = true;
9657 : : rule_head = &sw->recp_list[rid].filt_rules;
9658 : :
9659 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
9660 : 0 : adv_fltr->vsi_count = 1;
9661 : :
9662 : : /* Add rule entry to book keeping list */
9663 [ # # ]: 0 : LIST_ADD(&adv_fltr->list_entry, rule_head);
9664 [ # # ]: 0 : if (added_entry) {
9665 : 0 : added_entry->rid = rid;
9666 : 0 : added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
9667 : 0 : added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
9668 : : }
9669 : 0 : err_ice_add_adv_rule:
9670 [ # # # # ]: 0 : if (status && rinfo->sw_act.fltr_act == ICE_SET_MARK)
9671 : 0 : ice_free_sw_marker_lg(hw, lg_act_id, rinfo->sw_act.markid);
9672 : :
9673 [ # # ]: 0 : if (status && adv_fltr) {
9674 : 0 : ice_free(hw, adv_fltr->lkups);
9675 : 0 : ice_free(hw, adv_fltr);
9676 : : }
9677 : :
9678 : 0 : ice_free(hw, s_rule);
9679 : :
9680 : 0 : return status;
9681 : : }
9682 : :
9683 : : /**
9684 : : * ice_adv_rem_update_vsi_list
9685 : : * @hw: pointer to the hardware structure
9686 : : * @vsi_handle: VSI handle of the VSI to remove
9687 : : * @fm_list: filter management entry for which the VSI list management needs to
9688 : : * be done
9689 : : */
9690 : : static int
9691 : 0 : ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
9692 : : struct ice_adv_fltr_mgmt_list_entry *fm_list)
9693 : : {
9694 : : struct ice_vsi_list_map_info *vsi_list_info;
9695 : : enum ice_sw_lkup_type lkup_type;
9696 : : u16 vsi_list_id;
9697 : : int status;
9698 : :
9699 [ # # ]: 0 : if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
9700 [ # # ]: 0 : fm_list->vsi_count == 0)
9701 : : return ICE_ERR_PARAM;
9702 : :
9703 : : /* A rule with the VSI being removed does not exist */
9704 [ # # ]: 0 : if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle))
9705 : : return ICE_ERR_DOES_NOT_EXIST;
9706 : :
9707 : : lkup_type = ICE_SW_LKUP_LAST;
9708 : 0 : vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
9709 : 0 : status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
9710 : : ice_aqc_opc_update_sw_rules,
9711 : : lkup_type);
9712 [ # # ]: 0 : if (status)
9713 : : return status;
9714 : :
9715 : 0 : fm_list->vsi_count--;
9716 [ # # ]: 0 : ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
9717 : : vsi_list_info = fm_list->vsi_list_info;
9718 [ # # ]: 0 : if (fm_list->vsi_count == 1) {
9719 : : struct ice_fltr_info tmp_fltr;
9720 : : u16 rem_vsi_handle;
9721 : :
9722 : 0 : rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map,
9723 : : ICE_MAX_VSI);
9724 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, rem_vsi_handle))
9725 : 0 : return ICE_ERR_OUT_OF_RANGE;
9726 : :
9727 : : /* Make sure VSI list is empty before removing it below */
9728 : 0 : status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
9729 : : vsi_list_id, true,
9730 : : ice_aqc_opc_update_sw_rules,
9731 : : lkup_type);
9732 [ # # ]: 0 : if (status)
9733 : : return status;
9734 : :
9735 : : ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM);
9736 : 0 : tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
9737 : 0 : tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
9738 : 0 : fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
9739 : : tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
9740 : 0 : tmp_fltr.fwd_id.hw_vsi_id =
9741 : 0 : ice_get_hw_vsi_num(hw, rem_vsi_handle);
9742 : 0 : fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
9743 : 0 : ice_get_hw_vsi_num(hw, rem_vsi_handle);
9744 : 0 : fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
9745 : :
9746 : : /* Update the previous switch rule of "MAC forward to VSI" to
9747 : : * "MAC fwd to VSI list"
9748 : : */
9749 : 0 : status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
9750 [ # # ]: 0 : if (status) {
9751 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
9752 : : tmp_fltr.fwd_id.hw_vsi_id, status);
9753 : 0 : return status;
9754 : : }
9755 : 0 : fm_list->vsi_list_info->ref_cnt--;
9756 : :
9757 : : /* Remove the VSI list since it is no longer used */
9758 : 0 : status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
9759 [ # # ]: 0 : if (status) {
9760 [ # # ]: 0 : ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
9761 : : vsi_list_id, status);
9762 : 0 : return status;
9763 : : }
9764 : :
9765 [ # # ]: 0 : LIST_DEL(&vsi_list_info->list_entry);
9766 : 0 : ice_free(hw, vsi_list_info);
9767 : 0 : fm_list->vsi_list_info = NULL;
9768 : : }
9769 : :
9770 : : return status;
9771 : : }
9772 : :
9773 : : /**
9774 : : * ice_rem_adv_rule - removes existing advanced switch rule
9775 : : * @hw: pointer to the hardware structure
9776 : : * @lkups: information on the words that needs to be looked up. All words
9777 : : * together makes one recipe
9778 : : * @lkups_cnt: num of entries in the lkups array
9779 : : * @rinfo: Its the pointer to the rule information for the rule
9780 : : *
9781 : : * This function can be used to remove 1 rule at a time. The lkups is
9782 : : * used to describe all the words that forms the "lookup" portion of the
9783 : : * rule. These words can span multiple protocols. Callers to this function
9784 : : * need to pass in a list of protocol headers with lookup information along
9785 : : * and mask that determines which words are valid from the given protocol
9786 : : * header. rinfo describes other information related to this rule such as
9787 : : * forwarding IDs, priority of this rule, etc.
9788 : : */
9789 : : int
9790 : 0 : ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
9791 : : u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
9792 : : {
9793 : : struct ice_adv_fltr_mgmt_list_entry *list_elem;
9794 : : struct ice_prot_lkup_ext lkup_exts;
9795 : : bool remove_rule = false;
9796 : : struct ice_lock *rule_lock; /* Lock to protect filter rule list */
9797 : : u16 i, rid, vsi_handle;
9798 : : bool is_add = false;
9799 : : int status = ICE_SUCCESS;
9800 : :
9801 : : ice_memset(&lkup_exts, 0, sizeof(lkup_exts), ICE_NONDMA_MEM);
9802 [ # # ]: 0 : for (i = 0; i < lkups_cnt; i++) {
9803 : : u16 count;
9804 : :
9805 [ # # ]: 0 : if (lkups[i].type >= ICE_PROTOCOL_LAST)
9806 : : return ICE_ERR_CFG;
9807 : :
9808 : 0 : count = ice_fill_valid_words(&lkups[i], &lkup_exts);
9809 [ # # ]: 0 : if (!count)
9810 : : return ICE_ERR_CFG;
9811 : : }
9812 : :
9813 : : /* Create any special protocol/offset pairs, such as looking at tunnel
9814 : : * bits by extracting metadata
9815 : : */
9816 : 0 : status = ice_add_special_words(rinfo, &lkup_exts, ice_is_dvm_ena(hw));
9817 [ # # ]: 0 : if (status)
9818 : : return status;
9819 : :
9820 : 0 : rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type, rinfo->priority);
9821 : : /* If did not find a recipe that match the existing criteria */
9822 [ # # ]: 0 : if (rid == ICE_MAX_NUM_RECIPES)
9823 : : return ICE_ERR_PARAM;
9824 : :
9825 : 0 : rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
9826 : 0 : list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
9827 : : /* the rule is already removed */
9828 [ # # ]: 0 : if (!list_elem)
9829 : : return ICE_SUCCESS;
9830 : 0 : ice_acquire_lock(rule_lock);
9831 [ # # ]: 0 : if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
9832 : : remove_rule = true;
9833 [ # # ]: 0 : } else if (list_elem->vsi_count > 1) {
9834 : : remove_rule = false;
9835 : 0 : vsi_handle = rinfo->sw_act.vsi_handle;
9836 : 0 : status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
9837 : : } else {
9838 : 0 : vsi_handle = rinfo->sw_act.vsi_handle;
9839 : 0 : status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
9840 [ # # ]: 0 : if (status) {
9841 : : ice_release_lock(rule_lock);
9842 : 0 : return status;
9843 : : }
9844 [ # # ]: 0 : if (list_elem->vsi_count == 0)
9845 : : remove_rule = true;
9846 : : }
9847 : : ice_release_lock(rule_lock);
9848 [ # # ]: 0 : if (remove_rule) {
9849 : : struct ice_sw_rule_lkup_rx_tx *s_rule;
9850 : : u16 rule_buf_sz;
9851 : :
9852 [ # # ]: 0 : if (rinfo->sw_act.fltr_act == ICE_SET_MARK)
9853 : 0 : ice_free_sw_marker_lg(hw, list_elem->rule_info.lg_id,
9854 : : rinfo->sw_act.markid);
9855 : : rule_buf_sz = ice_struct_size(s_rule, hdr_data, 0);
9856 : : s_rule = (struct ice_sw_rule_lkup_rx_tx *)
9857 : 0 : ice_malloc(hw, rule_buf_sz);
9858 [ # # ]: 0 : if (!s_rule)
9859 : : return ICE_ERR_NO_MEMORY;
9860 : 0 : s_rule->act = 0;
9861 : 0 : s_rule->index = CPU_TO_LE16(list_elem->rule_info.fltr_rule_id);
9862 : 0 : s_rule->hdr_len = 0;
9863 : 0 : status = ice_aq_sw_rules(hw, s_rule, rule_buf_sz, 1,
9864 : : ice_aqc_opc_remove_sw_rules, NULL);
9865 [ # # ]: 0 : if (status == ICE_SUCCESS || status == ICE_ERR_DOES_NOT_EXIST) {
9866 : 0 : struct ice_switch_info *sw = hw->switch_info;
9867 : :
9868 : : ice_acquire_lock(rule_lock);
9869 [ # # ]: 0 : LIST_DEL(&list_elem->list_entry);
9870 : 0 : ice_free(hw, list_elem->lkups);
9871 : 0 : ice_free(hw, list_elem);
9872 : : ice_release_lock(rule_lock);
9873 [ # # ]: 0 : if (LIST_EMPTY(&sw->recp_list[rid].filt_rules))
9874 : 0 : sw->recp_list[rid].adv_rule = false;
9875 : : }
9876 : 0 : ice_free(hw, s_rule);
9877 : : }
9878 : : return status;
9879 : : }
9880 : :
9881 : : /**
9882 : : * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID
9883 : : * @hw: pointer to the hardware structure
9884 : : * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID
9885 : : *
9886 : : * This function is used to remove 1 rule at a time. The removal is based on
9887 : : * the remove_entry parameter. This function will remove rule for a given
9888 : : * vsi_handle with a given rule_id which is passed as parameter in remove_entry
9889 : : */
9890 : : int
9891 : 0 : ice_rem_adv_rule_by_id(struct ice_hw *hw,
9892 : : struct ice_rule_query_data *remove_entry)
9893 : : {
9894 : : struct ice_adv_fltr_mgmt_list_entry *list_itr;
9895 : : struct LIST_HEAD_TYPE *list_head;
9896 : : struct ice_adv_rule_info rinfo;
9897 : : struct ice_switch_info *sw;
9898 : :
9899 : 0 : sw = hw->switch_info;
9900 [ # # ]: 0 : if (!sw->recp_list[remove_entry->rid].recp_created)
9901 : : return ICE_ERR_PARAM;
9902 : : list_head = &sw->recp_list[remove_entry->rid].filt_rules;
9903 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_adv_fltr_mgmt_list_entry,
# # ]
9904 : : list_entry) {
9905 : 0 : if (list_itr->rule_info.fltr_rule_id ==
9906 [ # # ]: 0 : remove_entry->rule_id) {
9907 : 0 : rinfo = list_itr->rule_info;
9908 : 0 : rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
9909 : 0 : return ice_rem_adv_rule(hw, list_itr->lkups,
9910 : 0 : list_itr->lkups_cnt, &rinfo);
9911 : : }
9912 : : }
9913 : : /* either list is empty or unable to find rule */
9914 : : return ICE_ERR_DOES_NOT_EXIST;
9915 : : }
9916 : :
9917 : : /**
9918 : : * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a
9919 : : * given VSI handle
9920 : : * @hw: pointer to the hardware structure
9921 : : * @vsi_handle: VSI handle for which we are supposed to remove all the rules.
9922 : : *
9923 : : * This function is used to remove all the rules for a given VSI and as soon
9924 : : * as removing a rule fails, it will return immediately with the error code,
9925 : : * else it will return 0.
9926 : : */
9927 : 0 : int ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
9928 : : {
9929 : : struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
9930 : : struct ice_vsi_list_map_info *map_info;
9931 : : struct ice_adv_rule_info rinfo;
9932 : : struct LIST_HEAD_TYPE *list_head;
9933 : : struct ice_switch_info *sw;
9934 : : int status;
9935 : : u8 rid;
9936 : :
9937 : 0 : sw = hw->switch_info;
9938 [ # # ]: 0 : for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
9939 [ # # ]: 0 : if (!sw->recp_list[rid].recp_created)
9940 : 0 : continue;
9941 [ # # ]: 0 : if (!sw->recp_list[rid].adv_rule)
9942 : 0 : continue;
9943 : :
9944 : : list_head = &sw->recp_list[rid].filt_rules;
9945 [ # # # # : 0 : LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp_entry, list_head,
# # # # #
# ]
9946 : : ice_adv_fltr_mgmt_list_entry,
9947 : : list_entry) {
9948 : 0 : rinfo = list_itr->rule_info;
9949 : :
9950 [ # # ]: 0 : if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
9951 : 0 : map_info = list_itr->vsi_list_info;
9952 [ # # ]: 0 : if (!map_info)
9953 : 0 : continue;
9954 : :
9955 [ # # ]: 0 : if (!ice_is_bit_set(map_info->vsi_map,
9956 : : vsi_handle))
9957 : 0 : continue;
9958 [ # # ]: 0 : } else if (rinfo.sw_act.vsi_handle != vsi_handle) {
9959 : 0 : continue;
9960 : : }
9961 : :
9962 : 0 : rinfo.sw_act.vsi_handle = vsi_handle;
9963 : 0 : status = ice_rem_adv_rule(hw, list_itr->lkups,
9964 : 0 : list_itr->lkups_cnt, &rinfo);
9965 : :
9966 [ # # ]: 0 : if (status)
9967 : 0 : return status;
9968 : : }
9969 : : }
9970 : : return ICE_SUCCESS;
9971 : : }
9972 : :
9973 : : /**
9974 : : * ice_replay_fltr - Replay all the filters stored by a specific list head
9975 : : * @hw: pointer to the hardware structure
9976 : : * @list_head: list for which filters needs to be replayed
9977 : : * @recp_id: Recipe ID for which rules need to be replayed
9978 : : */
9979 : : static int
9980 : 0 : ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head)
9981 : : {
9982 : : struct ice_fltr_mgmt_list_entry *itr;
9983 : : struct ice_sw_recipe *recp_list;
9984 : 0 : u8 lport = hw->port_info->lport;
9985 : : struct LIST_HEAD_TYPE l_head;
9986 : : int status = 0;
9987 : :
9988 [ # # ]: 0 : if (LIST_EMPTY(list_head))
9989 : : return status;
9990 : :
9991 : 0 : recp_list = &hw->switch_info->recp_list[recp_id];
9992 : : /* Move entries from the given list_head to a temporary l_head so that
9993 : : * they can be replayed. Otherwise when trying to re-add the same
9994 : : * filter, the function will return already exists
9995 : : */
9996 : 0 : LIST_REPLACE_INIT(list_head, &l_head);
9997 : :
9998 : : /* Mark the given list_head empty by reinitializing it so filters
9999 : : * could be added again by *handler
10000 : : */
10001 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry,
10002 : : list_entry) {
10003 : : struct ice_fltr_list_entry f_entry;
10004 : : u16 vsi_handle;
10005 : :
10006 : 0 : f_entry.fltr_info = itr->fltr_info;
10007 [ # # # # ]: 0 : if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) {
10008 : 0 : status = ice_add_rule_internal(hw, recp_list, lport,
10009 : : &f_entry);
10010 [ # # ]: 0 : if (status)
10011 : 0 : goto end;
10012 : 0 : continue;
10013 : : }
10014 : :
10015 : : /* Add a filter per VSI separately */
10016 [ # # ]: 0 : ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map,
10017 : : ICE_MAX_VSI) {
10018 [ # # ]: 0 : if (!ice_is_vsi_valid(hw, vsi_handle))
10019 : : break;
10020 : :
10021 : 0 : ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
10022 : 0 : f_entry.fltr_info.vsi_handle = vsi_handle;
10023 : 0 : f_entry.fltr_info.fwd_id.hw_vsi_id =
10024 : 0 : ice_get_hw_vsi_num(hw, vsi_handle);
10025 : 0 : f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
10026 [ # # ]: 0 : if (recp_id == ICE_SW_LKUP_VLAN)
10027 : 0 : status = ice_add_vlan_internal(hw, recp_list,
10028 : : &f_entry);
10029 : : else
10030 : 0 : status = ice_add_rule_internal(hw, recp_list,
10031 : : lport,
10032 : : &f_entry);
10033 [ # # ]: 0 : if (status)
10034 : 0 : goto end;
10035 : : }
10036 : : }
10037 : 0 : end:
10038 : : /* Clear the filter management list */
10039 : 0 : ice_rem_sw_rule_info(hw, &l_head);
10040 : 0 : return status;
10041 : : }
10042 : :
10043 : : /**
10044 : : * ice_replay_all_fltr - replay all filters stored in bookkeeping lists
10045 : : * @hw: pointer to the hardware structure
10046 : : *
10047 : : * NOTE: This function does not clean up partially added filters on error.
10048 : : * It is up to caller of the function to issue a reset or fail early.
10049 : : */
10050 : 0 : int ice_replay_all_fltr(struct ice_hw *hw)
10051 : : {
10052 : 0 : struct ice_switch_info *sw = hw->switch_info;
10053 : : int status = ICE_SUCCESS;
10054 : : u8 i;
10055 : :
10056 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
10057 : 0 : struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules;
10058 : :
10059 : 0 : status = ice_replay_fltr(hw, i, head);
10060 [ # # ]: 0 : if (status != ICE_SUCCESS)
10061 : 0 : return status;
10062 : : }
10063 : : return status;
10064 : : }
10065 : :
10066 : : /**
10067 : : * ice_replay_vsi_fltr - Replay filters for requested VSI
10068 : : * @hw: pointer to the hardware structure
10069 : : * @pi: pointer to port information structure
10070 : : * @sw: pointer to switch info struct for which function replays filters
10071 : : * @vsi_handle: driver VSI handle
10072 : : * @recp_id: Recipe ID for which rules need to be replayed
10073 : : * @list_head: list for which filters need to be replayed
10074 : : *
10075 : : * Replays the filter of recipe recp_id for a VSI represented via vsi_handle.
10076 : : * It is required to pass valid VSI handle.
10077 : : */
10078 : : static int
10079 : 0 : ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi,
10080 : : struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id,
10081 : : struct LIST_HEAD_TYPE *list_head)
10082 : : {
10083 : : struct ice_fltr_mgmt_list_entry *itr;
10084 : : struct ice_sw_recipe *recp_list;
10085 : : int status = 0;
10086 : : u16 hw_vsi_id;
10087 : :
10088 [ # # ]: 0 : if (LIST_EMPTY(list_head))
10089 : : return status;
10090 : 0 : recp_list = &sw->recp_list[recp_id];
10091 : 0 : hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
10092 : :
10093 [ # # # # : 0 : LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry,
# # ]
10094 : : list_entry) {
10095 : : struct ice_fltr_list_entry f_entry;
10096 : :
10097 : 0 : f_entry.fltr_info = itr->fltr_info;
10098 [ # # # # ]: 0 : if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
10099 [ # # ]: 0 : itr->fltr_info.vsi_handle == vsi_handle) {
10100 : : /* update the src in case it is VSI num */
10101 [ # # ]: 0 : if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
10102 : 0 : f_entry.fltr_info.src = hw_vsi_id;
10103 : 0 : status = ice_add_rule_internal(hw, recp_list,
10104 : 0 : pi->lport,
10105 : : &f_entry);
10106 [ # # ]: 0 : if (status)
10107 : 0 : goto end;
10108 : 0 : continue;
10109 : : }
10110 [ # # # # ]: 0 : if (!itr->vsi_list_info ||
10111 [ # # ]: 0 : !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle))
10112 : 0 : continue;
10113 : 0 : f_entry.fltr_info.vsi_handle = vsi_handle;
10114 : 0 : f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
10115 : : /* update the src in case it is VSI num */
10116 [ # # ]: 0 : if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
10117 : 0 : f_entry.fltr_info.src = hw_vsi_id;
10118 [ # # ]: 0 : if (recp_id == ICE_SW_LKUP_VLAN)
10119 : 0 : status = ice_add_vlan_internal(hw, recp_list, &f_entry);
10120 : : else
10121 : 0 : status = ice_add_rule_internal(hw, recp_list,
10122 : 0 : pi->lport,
10123 : : &f_entry);
10124 [ # # ]: 0 : if (status)
10125 : 0 : goto end;
10126 : : }
10127 : 0 : end:
10128 : : return status;
10129 : : }
10130 : :
10131 : : /**
10132 : : * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI
10133 : : * @hw: pointer to the hardware structure
10134 : : * @vsi_handle: driver VSI handle
10135 : : * @list_head: list for which filters need to be replayed
10136 : : *
10137 : : * Replay the advanced rule for the given VSI.
10138 : : */
10139 : : static int
10140 : 0 : ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
10141 : : struct LIST_HEAD_TYPE *list_head)
10142 : : {
10143 : 0 : struct ice_rule_query_data added_entry = { 0 };
10144 : : struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
10145 : : int status = 0;
10146 : :
10147 [ # # ]: 0 : if (LIST_EMPTY(list_head))
10148 : : return status;
10149 [ # # # # ]: 0 : LIST_FOR_EACH_ENTRY(adv_fltr, list_head, ice_adv_fltr_mgmt_list_entry,
10150 : : list_entry) {
10151 : 0 : struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
10152 : 0 : u16 lk_cnt = adv_fltr->lkups_cnt;
10153 : :
10154 [ # # ]: 0 : if (vsi_handle != rinfo->sw_act.vsi_handle)
10155 : 0 : continue;
10156 : 0 : status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
10157 : : &added_entry);
10158 [ # # ]: 0 : if (status)
10159 : : break;
10160 : : }
10161 : : return status;
10162 : : }
10163 : :
10164 : : /**
10165 : : * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists
10166 : : * @hw: pointer to the hardware structure
10167 : : * @pi: pointer to port information structure
10168 : : * @vsi_handle: driver VSI handle
10169 : : *
10170 : : * Replays filters for requested VSI via vsi_handle.
10171 : : */
10172 : : int
10173 : 0 : ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi,
10174 : : u16 vsi_handle)
10175 : : {
10176 : : struct ice_switch_info *sw = NULL;
10177 : : int status;
10178 : : u8 i;
10179 : :
10180 : 0 : sw = hw->switch_info;
10181 : :
10182 : : /* Update the recipes that were created */
10183 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
10184 : : struct LIST_HEAD_TYPE *head;
10185 : :
10186 : 0 : head = &sw->recp_list[i].filt_replay_rules;
10187 [ # # ]: 0 : if (!sw->recp_list[i].adv_rule)
10188 : 0 : status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i,
10189 : : head);
10190 : : else
10191 : 0 : status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
10192 [ # # ]: 0 : if (status)
10193 : 0 : return status;
10194 : : }
10195 : :
10196 : : return 0;
10197 : : }
10198 : :
10199 : : /**
10200 : : * ice_rm_sw_replay_rule_info - helper function to delete filter replay rules
10201 : : * @hw: pointer to the HW struct
10202 : : * @sw: pointer to switch info struct for which function removes filters
10203 : : *
10204 : : * Deletes the filter replay rules for given switch
10205 : : */
10206 : 0 : void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw)
10207 : : {
10208 : : u8 i;
10209 : :
10210 [ # # ]: 0 : if (!sw)
10211 : : return;
10212 : :
10213 [ # # ]: 0 : for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
10214 [ # # ]: 0 : if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) {
10215 : : struct LIST_HEAD_TYPE *l_head;
10216 : :
10217 : 0 : l_head = &sw->recp_list[i].filt_replay_rules;
10218 [ # # ]: 0 : if (!sw->recp_list[i].adv_rule)
10219 : 0 : ice_rem_sw_rule_info(hw, l_head);
10220 : : else
10221 : 0 : ice_rem_adv_rule_info(hw, l_head);
10222 : : }
10223 : : }
10224 : : }
10225 : :
10226 : : /**
10227 : : * ice_rm_all_sw_replay_rule_info - deletes filter replay rules
10228 : : * @hw: pointer to the HW struct
10229 : : *
10230 : : * Deletes the filter replay rules.
10231 : : */
10232 : 0 : void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
10233 : : {
10234 : 0 : ice_rm_sw_replay_rule_info(hw, hw->switch_info);
10235 : 0 : }
|