summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c')
-rw-r--r--drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c
new file mode 100644
index 000000000000..b91e05ffe2f4
--- /dev/null
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_debugfs.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Microchip Sparx5 Switch driver VCAP debugFS implementation
+ *
+ * Copyright (c) 2022 Microchip Technology Inc. and its subsidiaries.
+ */
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include "sparx5_vcap_debugfs.h"
+#include "sparx5_main_regs.h"
+#include "sparx5_main.h"
+#include "sparx5_vcap_impl.h"
+#include "sparx5_vcap_ag_api.h"
+
+static void sparx5_vcap_port_keys(struct sparx5 *sparx5,
+ struct vcap_admin *admin,
+ struct sparx5_port *port,
+ struct vcap_output_print *out)
+{
+ int lookup;
+ u32 value;
+
+ out->prf(out->dst, " port[%02d] (%s): ", port->portno,
+ netdev_name(port->ndev));
+ for (lookup = 0; lookup < admin->lookups; ++lookup) {
+ out->prf(out->dst, "\n Lookup %d: ", lookup);
+
+ /* Get lookup state */
+ value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_CFG(port->portno));
+ out->prf(out->dst, "\n state: ");
+ if (ANA_ACL_VCAP_S2_CFG_SEC_ENA_GET(value))
+ out->prf(out->dst, "on");
+ else
+ out->prf(out->dst, "off");
+
+ /* Get key selection state */
+ value = spx5_rd(sparx5,
+ ANA_ACL_VCAP_S2_KEY_SEL(port->portno, lookup));
+
+ out->prf(out->dst, "\n noneth: ");
+ switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) {
+ case VCAP_IS2_PS_NONETH_MAC_ETYPE:
+ out->prf(out->dst, "mac_etype");
+ break;
+ case VCAP_IS2_PS_NONETH_CUSTOM_1:
+ out->prf(out->dst, "custom1");
+ break;
+ case VCAP_IS2_PS_NONETH_CUSTOM_2:
+ out->prf(out->dst, "custom2");
+ break;
+ case VCAP_IS2_PS_NONETH_NO_LOOKUP:
+ out->prf(out->dst, "none");
+ break;
+ }
+ out->prf(out->dst, "\n ipv4_mc: ");
+ switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) {
+ case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE:
+ out->prf(out->dst, "mac_etype");
+ break;
+ case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER:
+ out->prf(out->dst, "ip4_tcp_udp ip4_other");
+ break;
+ case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE:
+ out->prf(out->dst, "ip_7tuple");
+ break;
+ case VCAP_IS2_PS_IPV4_MC_IP4_VID:
+ out->prf(out->dst, "ip4_vid");
+ break;
+ }
+ out->prf(out->dst, "\n ipv4_uc: ");
+ switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) {
+ case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE:
+ out->prf(out->dst, "mac_etype");
+ break;
+ case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER:
+ out->prf(out->dst, "ip4_tcp_udp ip4_other");
+ break;
+ case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE:
+ out->prf(out->dst, "ip_7tuple");
+ break;
+ }
+ out->prf(out->dst, "\n ipv6_mc: ");
+ switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) {
+ case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE:
+ out->prf(out->dst, "mac_etype");
+ break;
+ case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE:
+ out->prf(out->dst, "ip_7tuple");
+ break;
+ case VCAP_IS2_PS_IPV6_MC_IP6_VID:
+ out->prf(out->dst, "ip6_vid");
+ break;
+ case VCAP_IS2_PS_IPV6_MC_IP6_STD:
+ out->prf(out->dst, "ip6_std");
+ break;
+ case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER:
+ out->prf(out->dst, "ip4_tcp_udp ipv4_other");
+ break;
+ }
+ out->prf(out->dst, "\n ipv6_uc: ");
+ switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) {
+ case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE:
+ out->prf(out->dst, "mac_etype");
+ break;
+ case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE:
+ out->prf(out->dst, "ip_7tuple");
+ break;
+ case VCAP_IS2_PS_IPV6_UC_IP6_STD:
+ out->prf(out->dst, "ip6_std");
+ break;
+ case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER:
+ out->prf(out->dst, "ip4_tcp_udp ip4_other");
+ break;
+ }
+ out->prf(out->dst, "\n arp: ");
+ switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
+ case VCAP_IS2_PS_ARP_MAC_ETYPE:
+ out->prf(out->dst, "mac_etype");
+ break;
+ case VCAP_IS2_PS_ARP_ARP:
+ out->prf(out->dst, "arp");
+ break;
+ }
+ }
+ out->prf(out->dst, "\n");
+}
+
+static void sparx5_vcap_port_stickies(struct sparx5 *sparx5,
+ struct vcap_admin *admin,
+ struct vcap_output_print *out)
+{
+ int lookup;
+ u32 value;
+
+ out->prf(out->dst, " Sticky bits: ");
+ for (lookup = 0; lookup < admin->lookups; ++lookup) {
+ out->prf(out->dst, "\n Lookup %d: ", lookup);
+ /* Get lookup sticky bits */
+ value = spx5_rd(sparx5, ANA_ACL_SEC_LOOKUP_STICKY(lookup));
+
+ if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_CLM_STICKY_GET(value))
+ out->prf(out->dst, " sel_clm");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_IRLEG_STICKY_GET(value))
+ out->prf(out->dst, " sel_irleg");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_ERLEG_STICKY_GET(value))
+ out->prf(out->dst, " sel_erleg");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_PORT_STICKY_GET(value))
+ out->prf(out->dst, " sel_port");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_CUSTOM2_STICKY_GET(value))
+ out->prf(out->dst, " custom2");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_CUSTOM1_STICKY_GET(value))
+ out->prf(out->dst, " custom1");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_OAM_STICKY_GET(value))
+ out->prf(out->dst, " oam");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_VID_STICKY_GET(value))
+ out->prf(out->dst, " ip6_vid");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_STD_STICKY_GET(value))
+ out->prf(out->dst, " ip6_std");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_TCPUDP_STICKY_GET(value))
+ out->prf(out->dst, " ip6_tcpudp");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP_7TUPLE_STICKY_GET(value))
+ out->prf(out->dst, " ip_7tuple");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_VID_STICKY_GET(value))
+ out->prf(out->dst, " ip4_vid");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_TCPUDP_STICKY_GET(value))
+ out->prf(out->dst, " ip4_tcpudp");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_OTHER_STICKY_GET(value))
+ out->prf(out->dst, " ip4_other");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_ARP_STICKY_GET(value))
+ out->prf(out->dst, " arp");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_SNAP_STICKY_GET(value))
+ out->prf(out->dst, " mac_snap");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_LLC_STICKY_GET(value))
+ out->prf(out->dst, " mac_llc");
+ if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_ETYPE_STICKY_GET(value))
+ out->prf(out->dst, " mac_etype");
+ /* Clear stickies */
+ spx5_wr(value, sparx5, ANA_ACL_SEC_LOOKUP_STICKY(lookup));
+ }
+ out->prf(out->dst, "\n");
+}
+
+/* Provide port information via a callback interface */
+int sparx5_port_info(struct net_device *ndev,
+ struct vcap_admin *admin,
+ struct vcap_output_print *out)
+{
+ struct sparx5_port *port = netdev_priv(ndev);
+ struct sparx5 *sparx5 = port->sparx5;
+ const struct vcap_info *vcap;
+ struct vcap_control *vctrl;
+
+ vctrl = sparx5->vcap_ctrl;
+ vcap = &vctrl->vcaps[admin->vtype];
+ out->prf(out->dst, "%s:\n", vcap->name);
+ sparx5_vcap_port_keys(sparx5, admin, port, out);
+ sparx5_vcap_port_stickies(sparx5, admin, out);
+ return 0;
+}