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 void sparx5_vcap_port_keys(struct sparx5 *sparx5, 17 struct vcap_admin *admin, 18 struct sparx5_port *port, 19 struct vcap_output_print *out) 20 { 21 int lookup; 22 u32 value; 23 24 out->prf(out->dst, " port[%02d] (%s): ", port->portno, 25 netdev_name(port->ndev)); 26 for (lookup = 0; lookup < admin->lookups; ++lookup) { 27 out->prf(out->dst, "\n Lookup %d: ", lookup); 28 29 /* Get lookup state */ 30 value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_CFG(port->portno)); 31 out->prf(out->dst, "\n state: "); 32 if (ANA_ACL_VCAP_S2_CFG_SEC_ENA_GET(value)) 33 out->prf(out->dst, "on"); 34 else 35 out->prf(out->dst, "off"); 36 37 /* Get key selection state */ 38 value = spx5_rd(sparx5, 39 ANA_ACL_VCAP_S2_KEY_SEL(port->portno, lookup)); 40 41 out->prf(out->dst, "\n noneth: "); 42 switch (ANA_ACL_VCAP_S2_KEY_SEL_NON_ETH_KEY_SEL_GET(value)) { 43 case VCAP_IS2_PS_NONETH_MAC_ETYPE: 44 out->prf(out->dst, "mac_etype"); 45 break; 46 case VCAP_IS2_PS_NONETH_CUSTOM_1: 47 out->prf(out->dst, "custom1"); 48 break; 49 case VCAP_IS2_PS_NONETH_CUSTOM_2: 50 out->prf(out->dst, "custom2"); 51 break; 52 case VCAP_IS2_PS_NONETH_NO_LOOKUP: 53 out->prf(out->dst, "none"); 54 break; 55 } 56 out->prf(out->dst, "\n ipv4_mc: "); 57 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_MC_KEY_SEL_GET(value)) { 58 case VCAP_IS2_PS_IPV4_MC_MAC_ETYPE: 59 out->prf(out->dst, "mac_etype"); 60 break; 61 case VCAP_IS2_PS_IPV4_MC_IP4_TCP_UDP_OTHER: 62 out->prf(out->dst, "ip4_tcp_udp ip4_other"); 63 break; 64 case VCAP_IS2_PS_IPV4_MC_IP_7TUPLE: 65 out->prf(out->dst, "ip_7tuple"); 66 break; 67 case VCAP_IS2_PS_IPV4_MC_IP4_VID: 68 out->prf(out->dst, "ip4_vid"); 69 break; 70 } 71 out->prf(out->dst, "\n ipv4_uc: "); 72 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP4_UC_KEY_SEL_GET(value)) { 73 case VCAP_IS2_PS_IPV4_UC_MAC_ETYPE: 74 out->prf(out->dst, "mac_etype"); 75 break; 76 case VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER: 77 out->prf(out->dst, "ip4_tcp_udp ip4_other"); 78 break; 79 case VCAP_IS2_PS_IPV4_UC_IP_7TUPLE: 80 out->prf(out->dst, "ip_7tuple"); 81 break; 82 } 83 out->prf(out->dst, "\n ipv6_mc: "); 84 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_MC_KEY_SEL_GET(value)) { 85 case VCAP_IS2_PS_IPV6_MC_MAC_ETYPE: 86 out->prf(out->dst, "mac_etype"); 87 break; 88 case VCAP_IS2_PS_IPV6_MC_IP_7TUPLE: 89 out->prf(out->dst, "ip_7tuple"); 90 break; 91 case VCAP_IS2_PS_IPV6_MC_IP6_VID: 92 out->prf(out->dst, "ip6_vid"); 93 break; 94 case VCAP_IS2_PS_IPV6_MC_IP6_STD: 95 out->prf(out->dst, "ip6_std"); 96 break; 97 case VCAP_IS2_PS_IPV6_MC_IP4_TCP_UDP_OTHER: 98 out->prf(out->dst, "ip4_tcp_udp ipv4_other"); 99 break; 100 } 101 out->prf(out->dst, "\n ipv6_uc: "); 102 switch (ANA_ACL_VCAP_S2_KEY_SEL_IP6_UC_KEY_SEL_GET(value)) { 103 case VCAP_IS2_PS_IPV6_UC_MAC_ETYPE: 104 out->prf(out->dst, "mac_etype"); 105 break; 106 case VCAP_IS2_PS_IPV6_UC_IP_7TUPLE: 107 out->prf(out->dst, "ip_7tuple"); 108 break; 109 case VCAP_IS2_PS_IPV6_UC_IP6_STD: 110 out->prf(out->dst, "ip6_std"); 111 break; 112 case VCAP_IS2_PS_IPV6_UC_IP4_TCP_UDP_OTHER: 113 out->prf(out->dst, "ip4_tcp_udp ip4_other"); 114 break; 115 } 116 out->prf(out->dst, "\n arp: "); 117 switch (ANA_ACL_VCAP_S2_KEY_SEL_ARP_KEY_SEL_GET(value)) { 118 case VCAP_IS2_PS_ARP_MAC_ETYPE: 119 out->prf(out->dst, "mac_etype"); 120 break; 121 case VCAP_IS2_PS_ARP_ARP: 122 out->prf(out->dst, "arp"); 123 break; 124 } 125 } 126 out->prf(out->dst, "\n"); 127 } 128 129 static void sparx5_vcap_port_stickies(struct sparx5 *sparx5, 130 struct vcap_admin *admin, 131 struct vcap_output_print *out) 132 { 133 int lookup; 134 u32 value; 135 136 out->prf(out->dst, " Sticky bits: "); 137 for (lookup = 0; lookup < admin->lookups; ++lookup) { 138 out->prf(out->dst, "\n Lookup %d: ", lookup); 139 /* Get lookup sticky bits */ 140 value = spx5_rd(sparx5, ANA_ACL_SEC_LOOKUP_STICKY(lookup)); 141 142 if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_CLM_STICKY_GET(value)) 143 out->prf(out->dst, " sel_clm"); 144 if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_IRLEG_STICKY_GET(value)) 145 out->prf(out->dst, " sel_irleg"); 146 if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_ERLEG_STICKY_GET(value)) 147 out->prf(out->dst, " sel_erleg"); 148 if (ANA_ACL_SEC_LOOKUP_STICKY_KEY_SEL_PORT_STICKY_GET(value)) 149 out->prf(out->dst, " sel_port"); 150 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_CUSTOM2_STICKY_GET(value)) 151 out->prf(out->dst, " custom2"); 152 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_CUSTOM1_STICKY_GET(value)) 153 out->prf(out->dst, " custom1"); 154 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_OAM_STICKY_GET(value)) 155 out->prf(out->dst, " oam"); 156 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_VID_STICKY_GET(value)) 157 out->prf(out->dst, " ip6_vid"); 158 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_STD_STICKY_GET(value)) 159 out->prf(out->dst, " ip6_std"); 160 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_TCPUDP_STICKY_GET(value)) 161 out->prf(out->dst, " ip6_tcpudp"); 162 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP_7TUPLE_STICKY_GET(value)) 163 out->prf(out->dst, " ip_7tuple"); 164 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_VID_STICKY_GET(value)) 165 out->prf(out->dst, " ip4_vid"); 166 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_TCPUDP_STICKY_GET(value)) 167 out->prf(out->dst, " ip4_tcpudp"); 168 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_OTHER_STICKY_GET(value)) 169 out->prf(out->dst, " ip4_other"); 170 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_ARP_STICKY_GET(value)) 171 out->prf(out->dst, " arp"); 172 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_SNAP_STICKY_GET(value)) 173 out->prf(out->dst, " mac_snap"); 174 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_LLC_STICKY_GET(value)) 175 out->prf(out->dst, " mac_llc"); 176 if (ANA_ACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_ETYPE_STICKY_GET(value)) 177 out->prf(out->dst, " mac_etype"); 178 /* Clear stickies */ 179 spx5_wr(value, sparx5, ANA_ACL_SEC_LOOKUP_STICKY(lookup)); 180 } 181 out->prf(out->dst, "\n"); 182 } 183 184 /* Provide port information via a callback interface */ 185 int sparx5_port_info(struct net_device *ndev, 186 struct vcap_admin *admin, 187 struct vcap_output_print *out) 188 { 189 struct sparx5_port *port = netdev_priv(ndev); 190 struct sparx5 *sparx5 = port->sparx5; 191 const struct vcap_info *vcap; 192 struct vcap_control *vctrl; 193 194 vctrl = sparx5->vcap_ctrl; 195 vcap = &vctrl->vcaps[admin->vtype]; 196 out->prf(out->dst, "%s:\n", vcap->name); 197 sparx5_vcap_port_keys(sparx5, admin, port, out); 198 sparx5_vcap_port_stickies(sparx5, admin, out); 199 return 0; 200 } 201