]> Git Repo - J-linux.git/blob - drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c
Merge tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy...
[J-linux.git] / drivers / net / ethernet / microchip / sparx5 / sparx5_vcap_debugfs.c
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(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(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(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(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(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(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(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(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(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(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(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(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(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 }
This page took 0.054852 seconds and 4 git commands to generate.