1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* Microchip Sparx5 Switch driver VCAP debugFS implementation |
3 | * |
4 | * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. |
5 | */ |
6 | |
7 | #include <linux/types.h> |
8 | #include <linux/list.h> |
9 | |
10 | #include "sparx5_vcap_debugfs.h" |
11 | #include "sparx5_main_regs.h" |
12 | #include "sparx5_main.h" |
13 | #include "sparx5_vcap_impl.h" |
14 | #include "sparx5_vcap_ag_api.h" |
15 | |
16 | static const char *sparx5_vcap_is0_etype_str(u32 value) |
17 | { |
18 | switch (value) { |
19 | case VCAP_IS0_PS_ETYPE_DEFAULT: |
20 | return "default" ; |
21 | case VCAP_IS0_PS_ETYPE_NORMAL_7TUPLE: |
22 | return "normal_7tuple" ; |
23 | case VCAP_IS0_PS_ETYPE_NORMAL_5TUPLE_IP4: |
24 | return "normal_5tuple_ip4" ; |
25 | case VCAP_IS0_PS_ETYPE_MLL: |
26 | return "mll" ; |
27 | case VCAP_IS0_PS_ETYPE_LL_FULL: |
28 | return "ll_full" ; |
29 | case VCAP_IS0_PS_ETYPE_PURE_5TUPLE_IP4: |
30 | return "pure_5tuple_ip4" ; |
31 | case VCAP_IS0_PS_ETYPE_ETAG: |
32 | return "etag" ; |
33 | case VCAP_IS0_PS_ETYPE_NO_LOOKUP: |
34 | return "no lookup" ; |
35 | default: |
36 | return "unknown" ; |
37 | } |
38 | } |
39 | |
40 | static const char *sparx5_vcap_is0_mpls_str(u32 value) |
41 | { |
42 | switch (value) { |
43 | case VCAP_IS0_PS_MPLS_FOLLOW_ETYPE: |
44 | return "follow_etype" ; |
45 | case VCAP_IS0_PS_MPLS_NORMAL_7TUPLE: |
46 | return "normal_7tuple" ; |
47 | case VCAP_IS0_PS_MPLS_NORMAL_5TUPLE_IP4: |
48 | return "normal_5tuple_ip4" ; |
49 | case VCAP_IS0_PS_MPLS_MLL: |
50 | return "mll" ; |
51 | case VCAP_IS0_PS_MPLS_LL_FULL: |
52 | return "ll_full" ; |
53 | case VCAP_IS0_PS_MPLS_PURE_5TUPLE_IP4: |
54 | return "pure_5tuple_ip4" ; |
55 | case VCAP_IS0_PS_MPLS_ETAG: |
56 | return "etag" ; |
57 | case VCAP_IS0_PS_MPLS_NO_LOOKUP: |
58 | return "no lookup" ; |
59 | default: |
60 | return "unknown" ; |
61 | } |
62 | } |
63 | |
64 | static const char *sparx5_vcap_is0_mlbs_str(u32 value) |
65 | { |
66 | switch (value) { |
67 | case VCAP_IS0_PS_MLBS_FOLLOW_ETYPE: |
68 | return "follow_etype" ; |
69 | case VCAP_IS0_PS_MLBS_NO_LOOKUP: |
70 | return "no lookup" ; |
71 | default: |
72 | return "unknown" ; |
73 | } |
74 | } |
75 | |
76 | static void sparx5_vcap_is0_port_keys(struct sparx5 *sparx5, |
77 | struct vcap_admin *admin, |
78 | struct sparx5_port *port, |
79 | struct vcap_output_print *out) |
80 | { |
81 | int lookup; |
82 | u32 value, val; |
83 | |
84 | out->prf(out->dst, " port[%02d] (%s): " , port->portno, |
85 | netdev_name(dev: port->ndev)); |
86 | for (lookup = 0; lookup < admin->lookups; ++lookup) { |
87 | out->prf(out->dst, "\n Lookup %d: " , lookup); |
88 | |
89 | /* Get lookup state */ |
90 | value = spx5_rd(sparx5, |
91 | ANA_CL_ADV_CL_CFG(port->portno, lookup)); |
92 | out->prf(out->dst, "\n state: " ); |
93 | if (ANA_CL_ADV_CL_CFG_LOOKUP_ENA_GET(value)) |
94 | out->prf(out->dst, "on" ); |
95 | else |
96 | out->prf(out->dst, "off" ); |
97 | val = ANA_CL_ADV_CL_CFG_ETYPE_CLM_KEY_SEL_GET(value); |
98 | out->prf(out->dst, "\n etype: %s" , |
99 | sparx5_vcap_is0_etype_str(value: val)); |
100 | val = ANA_CL_ADV_CL_CFG_IP4_CLM_KEY_SEL_GET(value); |
101 | out->prf(out->dst, "\n ipv4: %s" , |
102 | sparx5_vcap_is0_etype_str(value: val)); |
103 | val = ANA_CL_ADV_CL_CFG_IP6_CLM_KEY_SEL_GET(value); |
104 | out->prf(out->dst, "\n ipv6: %s" , |
105 | sparx5_vcap_is0_etype_str(value: val)); |
106 | val = ANA_CL_ADV_CL_CFG_MPLS_UC_CLM_KEY_SEL_GET(value); |
107 | out->prf(out->dst, "\n mpls_uc: %s" , |
108 | sparx5_vcap_is0_mpls_str(value: val)); |
109 | val = ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_GET(value); |
110 | out->prf(out->dst, "\n mpls_mc: %s" , |
111 | sparx5_vcap_is0_mpls_str(value: val)); |
112 | val = ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_GET(value); |
113 | out->prf(out->dst, "\n mlbs: %s" , |
114 | sparx5_vcap_is0_mlbs_str(value: val)); |
115 | } |
116 | out->prf(out->dst, "\n" ); |
117 | } |
118 | |
119 | static void sparx5_vcap_is2_port_keys(struct sparx5 *sparx5, |
120 | struct vcap_admin *admin, |
121 | struct sparx5_port *port, |
122 | struct vcap_output_print *out) |
123 | { |
124 | int lookup; |
125 | u32 value; |
126 | |
127 | out->prf(out->dst, " port[%02d] (%s): " , port->portno, |
128 | netdev_name(dev: port->ndev)); |
129 | for (lookup = 0; lookup < admin->lookups; ++lookup) { |
130 | out->prf(out->dst, "\n Lookup %d: " , lookup); |
131 | |
132 | /* Get lookup state */ |
133 | value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_CFG(port->portno)); |
134 | out->prf(out->dst, "\n state: " ); |
135 | if (ANA_ACL_VCAP_S2_CFG_SEC_ENA_GET(value) & BIT(lookup)) |
136 | out->prf(out->dst, "on" ); |
137 | else |
138 | out->prf(out->dst, "off" ); |
139 | |
140 | /* Get key selection state */ |
141 | value = spx5_rd(sparx5, |
142 | ANA_ACL_VCAP_S2_KEY_SEL(port->portno, lookup)); |
143 | |
144 | out->prf(out->dst, "\n noneth: " ); |
145 | switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) { |
146 | case VCAP_IS2_PS_NONETH_MAC_ETYPE: |
147 | out->prf(out->dst, "mac_etype" ); |
148 | break; |
149 | case VCAP_IS2_PS_NONETH_CUSTOM_1: |
150 | out->prf(out->dst, "custom1" ); |
151 | break; |
152 | case VCAP_IS2_PS_NONETH_CUSTOM_2: |
153 | out->prf(out->dst, "custom2" ); |
154 | break; |
155 | case VCAP_IS2_PS_NONETH_NO_LOOKUP: |
156 | out->prf(out->dst, "none" ); |
157 | break; |
158 | } |
159 | out->prf(out->dst, "\n ipv4_mc: " ); |
160 | switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) { |
161 | case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE: |
162 | out->prf(out->dst, "mac_etype" ); |
163 | break; |
164 | case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER: |
165 | out->prf(out->dst, "ip4_tcp_udp ip4_other" ); |
166 | break; |
167 | case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE: |
168 | out->prf(out->dst, "ip_7tuple" ); |
169 | break; |
170 | case VCAP_IS2_PS_IPV4_MC_IP4_VID: |
171 | out->prf(out->dst, "ip4_vid" ); |
172 | break; |
173 | } |
174 | out->prf(out->dst, "\n ipv4_uc: " ); |
175 | switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) { |
176 | case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE: |
177 | out->prf(out->dst, "mac_etype" ); |
178 | break; |
179 | case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER: |
180 | out->prf(out->dst, "ip4_tcp_udp ip4_other" ); |
181 | break; |
182 | case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE: |
183 | out->prf(out->dst, "ip_7tuple" ); |
184 | break; |
185 | } |
186 | out->prf(out->dst, "\n ipv6_mc: " ); |
187 | switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) { |
188 | case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE: |
189 | out->prf(out->dst, "mac_etype" ); |
190 | break; |
191 | case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE: |
192 | out->prf(out->dst, "ip_7tuple" ); |
193 | break; |
194 | case VCAP_IS2_PS_IPV6_MC_IP6_VID: |
195 | out->prf(out->dst, "ip6_vid" ); |
196 | break; |
197 | case VCAP_IS2_PS_IPV6_MC_IP6_STD: |
198 | out->prf(out->dst, "ip6_std" ); |
199 | break; |
200 | case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER: |
201 | out->prf(out->dst, "ip4_tcp_udp ip4_other" ); |
202 | break; |
203 | } |
204 | out->prf(out->dst, "\n ipv6_uc: " ); |
205 | switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) { |
206 | case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE: |
207 | out->prf(out->dst, "mac_etype" ); |
208 | break; |
209 | case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE: |
210 | out->prf(out->dst, "ip_7tuple" ); |
211 | break; |
212 | case VCAP_IS2_PS_IPV6_UC_IP6_STD: |
213 | out->prf(out->dst, "ip6_std" ); |
214 | break; |
215 | case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER: |
216 | out->prf(out->dst, "ip4_tcp_udp ip4_other" ); |
217 | break; |
218 | } |
219 | out->prf(out->dst, "\n arp: " ); |
220 | switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) { |
221 | case VCAP_IS2_PS_ARP_MAC_ETYPE: |
222 | out->prf(out->dst, "mac_etype" ); |
223 | break; |
224 | case VCAP_IS2_PS_ARP_ARP: |
225 | out->prf(out->dst, "arp" ); |
226 | break; |
227 | } |
228 | } |
229 | out->prf(out->dst, "\n" ); |
230 | } |
231 | |
232 | static void sparx5_vcap_is2_port_stickies(struct sparx5 *sparx5, |
233 | struct vcap_admin *admin, |
234 | struct vcap_output_print *out) |
235 | { |
236 | int lookup; |
237 | u32 value; |
238 | |
239 | out->prf(out->dst, " Sticky bits: " ); |
240 | for (lookup = 0; lookup < admin->lookups; ++lookup) { |
241 | out->prf(out->dst, "\n Lookup %d: " , lookup); |
242 | /* Get lookup sticky bits */ |
243 | value = spx5_rd(sparx5, ANA_ACL_SEC_LOOKUP_STICKY(lookup)); |
244 | |
245 | if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_CLM_STICKY_GET(value)) |
246 | out->prf(out->dst, " sel_clm" ); |
247 | if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_IRLEG_STICKY_GET(value)) |
248 | out->prf(out->dst, " sel_irleg" ); |
249 | if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_ERLEG_STICKY_GET(value)) |
250 | out->prf(out->dst, " sel_erleg" ); |
251 | if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_PORT_STICKY_GET(value)) |
252 | out->prf(out->dst, " sel_port" ); |
253 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_CUSTOM2_STICKY_GET(value)) |
254 | out->prf(out->dst, " custom2" ); |
255 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_CUSTOM1_STICKY_GET(value)) |
256 | out->prf(out->dst, " custom1" ); |
257 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_OAM_STICKY_GET(value)) |
258 | out->prf(out->dst, " oam" ); |
259 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_VID_STICKY_GET(value)) |
260 | out->prf(out->dst, " ip6_vid" ); |
261 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_STD_STICKY_GET(value)) |
262 | out->prf(out->dst, " ip6_std" ); |
263 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_TCPUDP_STICKY_GET(value)) |
264 | out->prf(out->dst, " ip6_tcpudp" ); |
265 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP_7TUPLE_STICKY_GET(value)) |
266 | out->prf(out->dst, " ip_7tuple" ); |
267 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_VID_STICKY_GET(value)) |
268 | out->prf(out->dst, " ip4_vid" ); |
269 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_TCPUDP_STICKY_GET(value)) |
270 | out->prf(out->dst, " ip4_tcpudp" ); |
271 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_OTHER_STICKY_GET(value)) |
272 | out->prf(out->dst, " ip4_other" ); |
273 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_ARP_STICKY_GET(value)) |
274 | out->prf(out->dst, " arp" ); |
275 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_SNAP_STICKY_GET(value)) |
276 | out->prf(out->dst, " mac_snap" ); |
277 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_LLC_STICKY_GET(value)) |
278 | out->prf(out->dst, " mac_llc" ); |
279 | if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_ETYPE_STICKY_GET(value)) |
280 | out->prf(out->dst, " mac_etype" ); |
281 | /* Clear stickies */ |
282 | spx5_wr(val: value, sparx5, ANA_ACL_SEC_LOOKUP_STICKY(lookup)); |
283 | } |
284 | out->prf(out->dst, "\n" ); |
285 | } |
286 | |
287 | static void sparx5_vcap_es0_port_keys(struct sparx5 *sparx5, |
288 | struct vcap_admin *admin, |
289 | struct sparx5_port *port, |
290 | struct vcap_output_print *out) |
291 | { |
292 | u32 value; |
293 | |
294 | out->prf(out->dst, " port[%02d] (%s): " , port->portno, |
295 | netdev_name(dev: port->ndev)); |
296 | out->prf(out->dst, "\n Lookup 0: " ); |
297 | |
298 | /* Get lookup state */ |
299 | value = spx5_rd(sparx5, REW_ES0_CTRL); |
300 | out->prf(out->dst, "\n state: " ); |
301 | if (REW_ES0_CTRL_ES0_LU_ENA_GET(value)) |
302 | out->prf(out->dst, "on" ); |
303 | else |
304 | out->prf(out->dst, "off" ); |
305 | |
306 | out->prf(out->dst, "\n keyset: " ); |
307 | value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(port->portno)); |
308 | switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) { |
309 | case VCAP_ES0_PS_NORMAL_SELECTION: |
310 | out->prf(out->dst, "normal" ); |
311 | break; |
312 | case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS: |
313 | out->prf(out->dst, "isdx" ); |
314 | break; |
315 | case VCAP_ES0_PS_FORCE_VID_LOOKUPS: |
316 | out->prf(out->dst, "vid" ); |
317 | break; |
318 | case VCAP_ES0_PS_RESERVED: |
319 | out->prf(out->dst, "reserved" ); |
320 | break; |
321 | } |
322 | out->prf(out->dst, "\n" ); |
323 | } |
324 | |
325 | static void sparx5_vcap_es2_port_keys(struct sparx5 *sparx5, |
326 | struct vcap_admin *admin, |
327 | struct sparx5_port *port, |
328 | struct vcap_output_print *out) |
329 | { |
330 | int lookup; |
331 | u32 value; |
332 | |
333 | out->prf(out->dst, " port[%02d] (%s): " , port->portno, |
334 | netdev_name(dev: port->ndev)); |
335 | for (lookup = 0; lookup < admin->lookups; ++lookup) { |
336 | out->prf(out->dst, "\n Lookup %d: " , lookup); |
337 | |
338 | /* Get lookup state */ |
339 | value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(port->portno, |
340 | lookup)); |
341 | out->prf(out->dst, "\n state: " ); |
342 | if (EACL_VCAP_ES2_KEY_SEL_KEY_ENA_GET(value)) |
343 | out->prf(out->dst, "on" ); |
344 | else |
345 | out->prf(out->dst, "off" ); |
346 | |
347 | out->prf(out->dst, "\n arp: " ); |
348 | switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) { |
349 | case VCAP_ES2_PS_ARP_MAC_ETYPE: |
350 | out->prf(out->dst, "mac_etype" ); |
351 | break; |
352 | case VCAP_ES2_PS_ARP_ARP: |
353 | out->prf(out->dst, "arp" ); |
354 | break; |
355 | } |
356 | out->prf(out->dst, "\n ipv4: " ); |
357 | switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) { |
358 | case VCAP_ES2_PS_IPV4_MAC_ETYPE: |
359 | out->prf(out->dst, "mac_etype" ); |
360 | break; |
361 | case VCAP_ES2_PS_IPV4_IP_7TUPLE: |
362 | out->prf(out->dst, "ip_7tuple" ); |
363 | break; |
364 | case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID: |
365 | out->prf(out->dst, "ip4_tcp_udp ip4_vid" ); |
366 | break; |
367 | case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER: |
368 | out->prf(out->dst, "ip4_tcp_udp ip4_other" ); |
369 | break; |
370 | case VCAP_ES2_PS_IPV4_IP4_VID: |
371 | out->prf(out->dst, "ip4_vid" ); |
372 | break; |
373 | case VCAP_ES2_PS_IPV4_IP4_OTHER: |
374 | out->prf(out->dst, "ip4_other" ); |
375 | break; |
376 | } |
377 | out->prf(out->dst, "\n ipv6: " ); |
378 | switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) { |
379 | case VCAP_ES2_PS_IPV6_MAC_ETYPE: |
380 | out->prf(out->dst, "mac_etype" ); |
381 | break; |
382 | case VCAP_ES2_PS_IPV6_IP_7TUPLE: |
383 | out->prf(out->dst, "ip_7tuple" ); |
384 | break; |
385 | case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID: |
386 | out->prf(out->dst, "ip_7tuple ip6_vid" ); |
387 | break; |
388 | case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD: |
389 | out->prf(out->dst, "ip_7tuple ip6_std" ); |
390 | break; |
391 | case VCAP_ES2_PS_IPV6_IP6_VID: |
392 | out->prf(out->dst, "ip6_vid" ); |
393 | break; |
394 | case VCAP_ES2_PS_IPV6_IP6_STD: |
395 | out->prf(out->dst, "ip6_std" ); |
396 | break; |
397 | case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE: |
398 | out->prf(out->dst, "ip4_downgrade" ); |
399 | break; |
400 | } |
401 | } |
402 | out->prf(out->dst, "\n" ); |
403 | } |
404 | |
405 | static void sparx5_vcap_es2_port_stickies(struct sparx5 *sparx5, |
406 | struct vcap_admin *admin, |
407 | struct vcap_output_print *out) |
408 | { |
409 | int lookup; |
410 | u32 value; |
411 | |
412 | out->prf(out->dst, " Sticky bits: " ); |
413 | for (lookup = 0; lookup < admin->lookups; ++lookup) { |
414 | value = spx5_rd(sparx5, EACL_SEC_LOOKUP_STICKY(lookup)); |
415 | out->prf(out->dst, "\n Lookup %d: " , lookup); |
416 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP_7TUPLE_STICKY_GET(value)) |
417 | out->prf(out->dst, " ip_7tuple" ); |
418 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_VID_STICKY_GET(value)) |
419 | out->prf(out->dst, " ip6_vid" ); |
420 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_STD_STICKY_GET(value)) |
421 | out->prf(out->dst, " ip6_std" ); |
422 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_TCPUDP_STICKY_GET(value)) |
423 | out->prf(out->dst, " ip4_tcp_udp" ); |
424 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_VID_STICKY_GET(value)) |
425 | out->prf(out->dst, " ip4_vid" ); |
426 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_OTHER_STICKY_GET(value)) |
427 | out->prf(out->dst, " ip4_other" ); |
428 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_ARP_STICKY_GET(value)) |
429 | out->prf(out->dst, " arp" ); |
430 | if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_ETYPE_STICKY_GET(value)) |
431 | out->prf(out->dst, " mac_etype" ); |
432 | /* Clear stickies */ |
433 | spx5_wr(val: value, sparx5, EACL_SEC_LOOKUP_STICKY(lookup)); |
434 | } |
435 | out->prf(out->dst, "\n" ); |
436 | } |
437 | |
438 | /* Provide port information via a callback interface */ |
439 | int sparx5_port_info(struct net_device *ndev, |
440 | struct vcap_admin *admin, |
441 | struct vcap_output_print *out) |
442 | { |
443 | struct sparx5_port *port = netdev_priv(dev: ndev); |
444 | struct sparx5 *sparx5 = port->sparx5; |
445 | const struct vcap_info *vcap; |
446 | struct vcap_control *vctrl; |
447 | |
448 | vctrl = sparx5->vcap_ctrl; |
449 | vcap = &vctrl->vcaps[admin->vtype]; |
450 | out->prf(out->dst, "%s:\n" , vcap->name); |
451 | switch (admin->vtype) { |
452 | case VCAP_TYPE_IS0: |
453 | sparx5_vcap_is0_port_keys(sparx5, admin, port, out); |
454 | break; |
455 | case VCAP_TYPE_IS2: |
456 | sparx5_vcap_is2_port_keys(sparx5, admin, port, out); |
457 | sparx5_vcap_is2_port_stickies(sparx5, admin, out); |
458 | break; |
459 | case VCAP_TYPE_ES0: |
460 | sparx5_vcap_es0_port_keys(sparx5, admin, port, out); |
461 | break; |
462 | case VCAP_TYPE_ES2: |
463 | sparx5_vcap_es2_port_keys(sparx5, admin, port, out); |
464 | sparx5_vcap_es2_port_stickies(sparx5, admin, out); |
465 | break; |
466 | default: |
467 | out->prf(out->dst, " no info\n" ); |
468 | break; |
469 | } |
470 | return 0; |
471 | } |
472 | |