debugfs.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/debugfs.h>
  3. #include <linux/kernel.h>
  4. #include <asm/mach-rtl838x/mach-rtl83xx.h>
  5. #include "rtl83xx.h"
  6. #define RTL838X_DRIVER_NAME "rtl838x"
  7. #define RTL8380_LED_GLB_CTRL (0xA000)
  8. #define RTL8380_LED_MODE_SEL (0x1004)
  9. #define RTL8380_LED_MODE_CTRL (0xA004)
  10. #define RTL8380_LED_P_EN_CTRL (0xA008)
  11. #define RTL8380_LED_SW_CTRL (0xA00C)
  12. #define RTL8380_LED0_SW_P_EN_CTRL (0xA010)
  13. #define RTL8380_LED1_SW_P_EN_CTRL (0xA014)
  14. #define RTL8380_LED2_SW_P_EN_CTRL (0xA018)
  15. #define RTL8380_LED_SW_P_CTRL(p) (0xA01C + (((p) << 2)))
  16. #define RTL8390_LED_GLB_CTRL (0x00E4)
  17. #define RTL8390_LED_SET_2_3_CTRL (0x00E8)
  18. #define RTL8390_LED_SET_0_1_CTRL (0x00EC)
  19. #define RTL8390_LED_COPR_SET_SEL_CTRL(p) (0x00F0 + (((p >> 4) << 2)))
  20. #define RTL8390_LED_FIB_SET_SEL_CTRL(p) (0x0100 + (((p >> 4) << 2)))
  21. #define RTL8390_LED_COPR_PMASK_CTRL(p) (0x0110 + (((p >> 5) << 2)))
  22. #define RTL8390_LED_FIB_PMASK_CTRL(p) (0x00118 + (((p >> 5) << 2)))
  23. #define RTL8390_LED_COMBO_CTRL(p) (0x0120 + (((p >> 5) << 2)))
  24. #define RTL8390_LED_SW_CTRL (0x0128)
  25. #define RTL8390_LED_SW_P_EN_CTRL(p) (0x012C + (((p / 10) << 2)))
  26. #define RTL8390_LED_SW_P_CTRL(p) (0x0144 + (((p) << 2)))
  27. #define RTL838X_MIR_QID_CTRL(grp) (0xAD44 + (((grp) << 2)))
  28. #define RTL838X_MIR_RSPAN_VLAN_CTRL(grp) (0xA340 + (((grp) << 2)))
  29. #define RTL838X_MIR_RSPAN_VLAN_CTRL_MAC(grp) (0xAA70 + (((grp) << 2)))
  30. #define RTL838X_MIR_RSPAN_TX_CTRL (0xA350)
  31. #define RTL838X_MIR_RSPAN_TX_TAG_RM_CTRL (0xAA80)
  32. #define RTL838X_MIR_RSPAN_TX_TAG_EN_CTRL (0xAA84)
  33. #define RTL839X_MIR_RSPAN_VLAN_CTRL(grp) (0xA340 + (((grp) << 2)))
  34. #define RTL839X_MIR_RSPAN_TX_CTRL (0x69b0)
  35. #define RTL839X_MIR_RSPAN_TX_TAG_RM_CTRL (0x2550)
  36. #define RTL839X_MIR_RSPAN_TX_TAG_EN_CTRL (0x2554)
  37. #define RTL839X_MIR_SAMPLE_RATE_CTRL (0x2558)
  38. #define RTL838X_STAT_PRVTE_DROP_COUNTERS (0x6A00)
  39. #define RTL839X_STAT_PRVTE_DROP_COUNTERS (0x3E00)
  40. #define RTL930X_STAT_PRVTE_DROP_COUNTERS (0xB5B8)
  41. #define RTL931X_STAT_PRVTE_DROP_COUNTERS (0xd800)
  42. int rtl83xx_port_get_stp_state(struct rtl838x_switch_priv *priv, int port);
  43. void rtl83xx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
  44. void rtl83xx_fast_age(struct dsa_switch *ds, int port);
  45. u32 rtl838x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
  46. u32 rtl839x_get_egress_rate(struct rtl838x_switch_priv *priv, int port);
  47. int rtl838x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
  48. int rtl839x_set_egress_rate(struct rtl838x_switch_priv *priv, int port, u32 rate);
  49. const char *rtl838x_drop_cntr[] = {
  50. "ALE_TX_GOOD_PKTS", "MAC_RX_DROP", "ACL_FWD_DROP", "HW_ATTACK_PREVENTION_DROP",
  51. "RMA_DROP", "VLAN_IGR_FLTR_DROP", "INNER_OUTER_CFI_EQUAL_1_DROP", "PORT_MOVE_DROP",
  52. "NEW_SA_DROP", "MAC_LIMIT_SYS_DROP", "MAC_LIMIT_VLAN_DROP", "MAC_LIMIT_PORT_DROP",
  53. "SWITCH_MAC_DROP", "ROUTING_EXCEPTION_DROP", "DA_LKMISS_DROP", "RSPAN_DROP",
  54. "ACL_LKMISS_DROP", "ACL_DROP", "INBW_DROP", "IGR_METER_DROP",
  55. "ACCEPT_FRAME_TYPE_DROP", "STP_IGR_DROP", "INVALID_SA_DROP", "SA_BLOCKING_DROP",
  56. "DA_BLOCKING_DROP", "L2_INVALID_DPM_DROP", "MCST_INVALID_DPM_DROP", "RX_FLOW_CONTROL_DROP",
  57. "STORM_SPPRS_DROP", "LALS_DROP", "VLAN_EGR_FILTER_DROP", "STP_EGR_DROP",
  58. "SRC_PORT_FILTER_DROP", "PORT_ISOLATION_DROP", "ACL_FLTR_DROP", "MIRROR_FLTR_DROP",
  59. "TX_MAX_DROP", "LINK_DOWN_DROP", "FLOW_CONTROL_DROP", "BRIDGE .1d discards"
  60. };
  61. const char *rtl839x_drop_cntr[] = {
  62. "ALE_TX_GOOD_PKTS", "ERROR_PKTS", "EGR_ACL_DROP", "EGR_METER_DROP",
  63. "OAM", "CFM" "VLAN_IGR_FLTR", "VLAN_ERR",
  64. "INNER_OUTER_CFI_EQUAL_1", "VLAN_TAG_FORMAT", "SRC_PORT_SPENDING_TREE", "INBW",
  65. "RMA", "HW_ATTACK_PREVENTION", "PROTO_STORM", "MCAST_SA",
  66. "IGR_ACL_DROP", "IGR_METER_DROP", "DFLT_ACTION_FOR_MISS_ACL_AND_C2SC", "NEW_SA",
  67. "PORT_MOVE", "SA_BLOCKING", "ROUTING_EXCEPTION", "SRC_PORT_SPENDING_TREE_NON_FWDING",
  68. "MAC_LIMIT", "UNKNOW_STORM", "MISS_DROP", "CPU_MAC_DROP",
  69. "DA_BLOCKING", "SRC_PORT_FILTER_BEFORE_EGR_ACL", "VLAN_EGR_FILTER", "SPANNING_TRE",
  70. "PORT_ISOLATION", "OAM_EGRESS_DROP", "MIRROR_ISOLATION", "MAX_LEN_BEFORE_EGR_ACL",
  71. "SRC_PORT_FILTER_BEFORE_MIRROR", "MAX_LEN_BEFORE_MIRROR", "SPECIAL_CONGEST_BEFORE_MIRROR",
  72. "LINK_STATUS_BEFORE_MIRROR",
  73. "WRED_BEFORE_MIRROR", "MAX_LEN_AFTER_MIRROR", "SPECIAL_CONGEST_AFTER_MIRROR",
  74. "LINK_STATUS_AFTER_MIRROR",
  75. "WRED_AFTER_MIRROR"
  76. };
  77. const char *rtl930x_drop_cntr[] = {
  78. "OAM_PARSER", "UC_RPF", "DEI_CFI", "MAC_IP_SUBNET_BASED_VLAN", "VLAN_IGR_FILTER",
  79. "L2_UC_MC", "IPV_IP6_MC_BRIDGE", "PTP", "USER_DEF_0_3", "RESERVED",
  80. "RESERVED1", "RESERVED2", "BPDU_RMA", "LACP", "LLDP",
  81. "EAPOL", "XX_RMA", "L3_IPUC_NON_IP", "IP4_IP6_HEADER_ERROR", "L3_BAD_IP",
  82. "L3_DIP_DMAC_MISMATCH", "IP4_IP_OPTION", "IP_UC_MC_ROUTING_LOOK_UP_MISS", "L3_DST_NULL_INTF",
  83. "L3_PBR_NULL_INTF",
  84. "HOST_NULL_INTF", "ROUTE_NULL_INTF", "BRIDGING_ACTION", "ROUTING_ACTION", "IPMC_RPF",
  85. "L2_NEXTHOP_AGE_OUT", "L3_UC_TTL_FAIL", "L3_MC_TTL_FAIL", "L3_UC_MTU_FAIL", "L3_MC_MTU_FAIL",
  86. "L3_UC_ICMP_REDIR", "IP6_MLD_OTHER_ACT", "ND", "IP_MC_RESERVED", "IP6_HBH",
  87. "INVALID_SA", "L2_HASH_FULL", "NEW_SA", "PORT_MOVE_FORBID", "STATIC_PORT_MOVING",
  88. "DYNMIC_PORT_MOVING", "L3_CRC", "MAC_LIMIT", "ATTACK_PREVENT", "ACL_FWD_ACTION",
  89. "OAMPDU", "OAM_MUX", "TRUNK_FILTER", "ACL_DROP", "IGR_BW",
  90. "ACL_METER", "VLAN_ACCEPT_FRAME_TYPE", "MSTP_SRC_DROP_DISABLED_BLOCKING", "SA_BLOCK", "DA_BLOCK",
  91. "STORM_CONTROL", "VLAN_EGR_FILTER", "MSTP_DESTINATION_DROP", "SRC_PORT_FILTER", "PORT_ISOLATION",
  92. "TX_MAX_FRAME_SIZE", "EGR_LINK_STATUS", "MAC_TX_DISABLE", "MAC_PAUSE_FRAME", "MAC_RX_DROP",
  93. "MIRROR_ISOLATE", "RX_FC", "EGR_QUEUE", "HSM_RUNOUT", "ROUTING_DISABLE", "INVALID_L2_NEXTHOP_ENTRY",
  94. "L3_MC_SRC_FLT", "CPUTAG_FLT", "FWD_PMSK_NULL", "IPUC_ROUTING_LOOKUP_MISS", "MY_DEV_DROP",
  95. "STACK_NONUC_BLOCKING_PMSK", "STACK_PORT_NOT_FOUND", "ACL_LOOPBACK_DROP", "IP6_ROUTING_EXT_HEADER"
  96. };
  97. const char *rtl931x_drop_cntr[] = {
  98. "ALE_RX_GOOD_PKTS", "RX_MAX_FRAME_SIZE", "MAC_RX_DROP", "OPENFLOW_IP_MPLS_TTL", "OPENFLOW_TBL_MISS",
  99. "IGR_BW", "SPECIAL_CONGEST", "EGR_QUEUE", "RESERVED", "EGR_LINK_STATUS", "STACK_UCAST_NONUCAST_TTL", // 10
  100. "STACK_NONUC_BLOCKING_PMSK", "L2_CRC", "SRC_PORT_FILTER", "PARSER_PACKET_TOO_LONG", "PARSER_MALFORM_PACKET",
  101. "MPLS_OVER_2_LBL", "EACL_METER", "IACL_METER", "PROTO_STORM", "INVALID_CAPWAP_HEADER", // 20
  102. "MAC_IP_SUBNET_BASED_VLAN", "OAM_PARSER", "UC_MC_RPF", "IP_MAC_BINDING_MATCH_MISMATCH", "SA_BLOCK",
  103. "TUNNEL_IP_ADDRESS_CHECK", "EACL_DROP", "IACL_DROP", "ATTACK_PREVENT", "SYSTEM_PORT_LIMIT_LEARN", // 30,
  104. "OAMPDU", "CCM_RX", "CFM_UNKNOWN_TYPE", "LBM_LBR_LTM_LTR", "Y_1731", "VLAN_LIMIT_LEARN",
  105. "VLAN_ACCEPT_FRAME_TYPE", "CFI_1", "STATIC_DYNAMIC_PORT_MOVING", "PORT_MOVE_FORBID", // 40
  106. "L3_CRC", "BPDU_PTP_LLDP_EAPOL_RMA", "MSTP_SRC_DROP_DISABLED_BLOCKING", "INVALID_SA", "NEW_SA",
  107. "VLAN_IGR_FILTER", "IGR_VLAN_CONVERT", "GRATUITOUS_ARP", "MSTP_SRC_DROP", "L2_HASH_FULL", // 50
  108. "MPLS_UNKNOWN_LBL", "L3_IPUC_NON_IP", "TTL", "MTU", "ICMP_REDIRECT", "STORM_CONTROL", "L3_DIP_DMAC_MISMATCH",
  109. "IP4_IP_OPTION", "IP6_HBH_EXT_HEADER", "IP4_IP6_HEADER_ERROR", // 60
  110. "ROUTING_IP_ADDR_CHECK", "ROUTING_EXCEPTION", "DA_BLOCK", "OAM_MUX", "PORT_ISOLATION", "VLAN_EGR_FILTER",
  111. "MIRROR_ISOLATE", "MSTP_DESTINATION_DROP", "L2_MC_BRIDGE", "IP_UC_MC_ROUTING_LOOK_UP_MISS", // 70
  112. "L2_UC", "L2_MC", "IP4_MC", "IP6_MC", "L3_UC_MC_ROUTE", "UNKNOWN_L2_UC_FLPM", "BC_FLPM",
  113. "VLAN_PRO_UNKNOWN_L2_MC_FLPM", "VLAN_PRO_UNKNOWN_IP4_MC_FLPM", "VLAN_PROFILE_UNKNOWN_IP6_MC_FLPM" // 80,
  114. };
  115. static ssize_t rtl838x_common_read(char __user *buffer, size_t count,
  116. loff_t *ppos, unsigned int value)
  117. {
  118. char *buf;
  119. ssize_t len;
  120. if (*ppos != 0)
  121. return 0;
  122. buf = kasprintf(GFP_KERNEL, "0x%08x\n", value);
  123. if (!buf)
  124. return -ENOMEM;
  125. if (count < strlen(buf)) {
  126. kfree(buf);
  127. return -ENOSPC;
  128. }
  129. len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
  130. kfree(buf);
  131. return len;
  132. }
  133. static ssize_t rtl838x_common_write(const char __user *buffer, size_t count,
  134. loff_t *ppos, unsigned int *value)
  135. {
  136. char b[32];
  137. ssize_t len;
  138. int ret;
  139. if (*ppos != 0)
  140. return -EINVAL;
  141. if (count >= sizeof(b))
  142. return -ENOSPC;
  143. len = simple_write_to_buffer(b, sizeof(b) - 1, ppos,
  144. buffer, count);
  145. if (len < 0)
  146. return len;
  147. b[len] = '\0';
  148. ret = kstrtouint(b, 16, value);
  149. if (ret)
  150. return -EIO;
  151. return len;
  152. }
  153. static ssize_t stp_state_read(struct file *filp, char __user *buffer, size_t count,
  154. loff_t *ppos)
  155. {
  156. struct rtl838x_port *p = filp->private_data;
  157. struct dsa_switch *ds = p->dp->ds;
  158. int value = rtl83xx_port_get_stp_state(ds->priv, p->dp->index);
  159. if (value < 0)
  160. return -EINVAL;
  161. return rtl838x_common_read(buffer, count, ppos, (u32)value);
  162. }
  163. static ssize_t stp_state_write(struct file *filp, const char __user *buffer,
  164. size_t count, loff_t *ppos)
  165. {
  166. struct rtl838x_port *p = filp->private_data;
  167. u32 value;
  168. size_t res = rtl838x_common_write(buffer, count, ppos, &value);
  169. if (res < 0)
  170. return res;
  171. rtl83xx_port_stp_state_set(p->dp->ds, p->dp->index, (u8)value);
  172. return res;
  173. }
  174. static const struct file_operations stp_state_fops = {
  175. .owner = THIS_MODULE,
  176. .open = simple_open,
  177. .read = stp_state_read,
  178. .write = stp_state_write,
  179. };
  180. static ssize_t drop_counter_read(struct file *filp, char __user *buffer, size_t count,
  181. loff_t *ppos)
  182. {
  183. struct rtl838x_switch_priv *priv = filp->private_data;
  184. int i;
  185. const char **d;
  186. u32 v;
  187. char *buf;
  188. int n = 0, len, offset;
  189. int num;
  190. switch (priv->family_id) {
  191. case RTL8380_FAMILY_ID:
  192. d = rtl838x_drop_cntr;
  193. offset = RTL838X_STAT_PRVTE_DROP_COUNTERS;
  194. num = 40;
  195. break;
  196. case RTL8390_FAMILY_ID:
  197. d = rtl839x_drop_cntr;
  198. offset = RTL839X_STAT_PRVTE_DROP_COUNTERS;
  199. num = 45;
  200. break;
  201. case RTL9300_FAMILY_ID:
  202. d = rtl930x_drop_cntr;
  203. offset = RTL930X_STAT_PRVTE_DROP_COUNTERS;
  204. num = 85;
  205. break;
  206. case RTL9310_FAMILY_ID:
  207. d = rtl931x_drop_cntr;
  208. offset = RTL931X_STAT_PRVTE_DROP_COUNTERS;
  209. num = 81;
  210. break;
  211. }
  212. buf = kmalloc(30 * num, GFP_KERNEL);
  213. if (!buf)
  214. return -ENOMEM;
  215. for (i = 0; i < num; i++) {
  216. v = sw_r32(offset + (i << 2)) & 0xffff;
  217. n += sprintf(buf + n, "%s: %d\n", d[i], v);
  218. }
  219. if (count < strlen(buf)) {
  220. kfree(buf);
  221. return -ENOSPC;
  222. }
  223. len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
  224. kfree(buf);
  225. return len;
  226. }
  227. static const struct file_operations drop_counter_fops = {
  228. .owner = THIS_MODULE,
  229. .open = simple_open,
  230. .read = drop_counter_read,
  231. };
  232. static ssize_t age_out_read(struct file *filp, char __user *buffer, size_t count,
  233. loff_t *ppos)
  234. {
  235. struct rtl838x_port *p = filp->private_data;
  236. struct dsa_switch *ds = p->dp->ds;
  237. struct rtl838x_switch_priv *priv = ds->priv;
  238. int value = sw_r32(priv->r->l2_port_aging_out);
  239. if (value < 0)
  240. return -EINVAL;
  241. return rtl838x_common_read(buffer, count, ppos, (u32)value);
  242. }
  243. static ssize_t age_out_write(struct file *filp, const char __user *buffer,
  244. size_t count, loff_t *ppos)
  245. {
  246. struct rtl838x_port *p = filp->private_data;
  247. u32 value;
  248. size_t res = rtl838x_common_write(buffer, count, ppos, &value);
  249. if (res < 0)
  250. return res;
  251. rtl83xx_fast_age(p->dp->ds, p->dp->index);
  252. return res;
  253. }
  254. static const struct file_operations age_out_fops = {
  255. .owner = THIS_MODULE,
  256. .open = simple_open,
  257. .read = age_out_read,
  258. .write = age_out_write,
  259. };
  260. static ssize_t port_egress_rate_read(struct file *filp, char __user *buffer, size_t count,
  261. loff_t *ppos)
  262. {
  263. struct rtl838x_port *p = filp->private_data;
  264. struct dsa_switch *ds = p->dp->ds;
  265. struct rtl838x_switch_priv *priv = ds->priv;
  266. int value;
  267. if (priv->family_id == RTL8380_FAMILY_ID)
  268. value = rtl838x_get_egress_rate(priv, p->dp->index);
  269. else
  270. value = rtl839x_get_egress_rate(priv, p->dp->index);
  271. if (value < 0)
  272. return -EINVAL;
  273. return rtl838x_common_read(buffer, count, ppos, (u32)value);
  274. }
  275. static ssize_t port_egress_rate_write(struct file *filp, const char __user *buffer,
  276. size_t count, loff_t *ppos)
  277. {
  278. struct rtl838x_port *p = filp->private_data;
  279. struct dsa_switch *ds = p->dp->ds;
  280. struct rtl838x_switch_priv *priv = ds->priv;
  281. u32 value;
  282. size_t res = rtl838x_common_write(buffer, count, ppos, &value);
  283. if (res < 0)
  284. return res;
  285. if (priv->family_id == RTL8380_FAMILY_ID)
  286. rtl838x_set_egress_rate(priv, p->dp->index, value);
  287. else
  288. rtl839x_set_egress_rate(priv, p->dp->index, value);
  289. return res;
  290. }
  291. static const struct file_operations port_egress_fops = {
  292. .owner = THIS_MODULE,
  293. .open = simple_open,
  294. .read = port_egress_rate_read,
  295. .write = port_egress_rate_write,
  296. };
  297. static const struct debugfs_reg32 port_ctrl_regs[] = {
  298. { .name = "port_isolation", .offset = RTL838X_PORT_ISO_CTRL(0), },
  299. { .name = "mac_force_mode", .offset = RTL838X_MAC_FORCE_MODE_CTRL, },
  300. };
  301. void rtl838x_dbgfs_cleanup(struct rtl838x_switch_priv *priv)
  302. {
  303. debugfs_remove_recursive(priv->dbgfs_dir);
  304. // kfree(priv->dbgfs_entries);
  305. }
  306. static int rtl838x_dbgfs_port_init(struct dentry *parent, struct rtl838x_switch_priv *priv,
  307. int port)
  308. {
  309. struct dentry *port_dir;
  310. struct debugfs_regset32 *port_ctrl_regset;
  311. port_dir = debugfs_create_dir(priv->ports[port].dp->name, parent);
  312. if (priv->family_id == RTL8380_FAMILY_ID) {
  313. debugfs_create_x32("storm_rate_uc", 0644, port_dir,
  314. (u32 *)(RTL838X_SW_BASE + RTL838X_STORM_CTRL_PORT_UC(port)));
  315. debugfs_create_x32("storm_rate_mc", 0644, port_dir,
  316. (u32 *)(RTL838X_SW_BASE + RTL838X_STORM_CTRL_PORT_MC(port)));
  317. debugfs_create_x32("storm_rate_bc", 0644, port_dir,
  318. (u32 *)(RTL838X_SW_BASE + RTL838X_STORM_CTRL_PORT_BC(port)));
  319. debugfs_create_x32("vlan_port_tag_sts_ctrl", 0644, port_dir,
  320. (u32 *)(RTL838X_SW_BASE + RTL838X_VLAN_PORT_TAG_STS_CTRL
  321. + (port << 2)));
  322. } else {
  323. debugfs_create_x32("storm_rate_uc", 0644, port_dir,
  324. (u32 *)(RTL838X_SW_BASE + RTL839X_STORM_CTRL_PORT_UC_0(port)));
  325. debugfs_create_x32("storm_rate_mc", 0644, port_dir,
  326. (u32 *)(RTL838X_SW_BASE + RTL839X_STORM_CTRL_PORT_MC_0(port)));
  327. debugfs_create_x32("storm_rate_bc", 0644, port_dir,
  328. (u32 *)(RTL838X_SW_BASE + RTL839X_STORM_CTRL_PORT_BC_0(port)));
  329. debugfs_create_x32("vlan_port_tag_sts_ctrl", 0644, port_dir,
  330. (u32 *)(RTL838X_SW_BASE + RTL839X_VLAN_PORT_TAG_STS_CTRL
  331. + (port << 2)));
  332. }
  333. debugfs_create_u32("id", 0444, port_dir, (u32 *)&priv->ports[port].dp->index);
  334. port_ctrl_regset = devm_kzalloc(priv->dev, sizeof(*port_ctrl_regset), GFP_KERNEL);
  335. if (!port_ctrl_regset)
  336. return -ENOMEM;
  337. port_ctrl_regset->regs = port_ctrl_regs;
  338. port_ctrl_regset->nregs = ARRAY_SIZE(port_ctrl_regs);
  339. port_ctrl_regset->base = (void *)(RTL838X_SW_BASE + (port << 2));
  340. debugfs_create_regset32("port_ctrl", 0400, port_dir, port_ctrl_regset);
  341. debugfs_create_file("stp_state", 0600, port_dir, &priv->ports[port], &stp_state_fops);
  342. debugfs_create_file("age_out", 0600, port_dir, &priv->ports[port], &age_out_fops);
  343. debugfs_create_file("port_egress_rate", 0600, port_dir, &priv->ports[port],
  344. &port_egress_fops);
  345. return 0;
  346. }
  347. static int rtl838x_dbgfs_leds(struct dentry *parent, struct rtl838x_switch_priv *priv)
  348. {
  349. struct dentry *led_dir;
  350. int p;
  351. char led_sw_p_ctrl_name[20];
  352. char port_led_name[20];
  353. led_dir = debugfs_create_dir("led", parent);
  354. if (priv->family_id == RTL8380_FAMILY_ID) {
  355. debugfs_create_x32("led_glb_ctrl", 0644, led_dir,
  356. (u32 *)(RTL838X_SW_BASE + RTL8380_LED_GLB_CTRL));
  357. debugfs_create_x32("led_mode_sel", 0644, led_dir,
  358. (u32 *)(RTL838X_SW_BASE + RTL8380_LED_MODE_SEL));
  359. debugfs_create_x32("led_mode_ctrl", 0644, led_dir,
  360. (u32 *)(RTL838X_SW_BASE + RTL8380_LED_MODE_CTRL));
  361. debugfs_create_x32("led_p_en_ctrl", 0644, led_dir,
  362. (u32 *)(RTL838X_SW_BASE + RTL8380_LED_P_EN_CTRL));
  363. debugfs_create_x32("led_sw_ctrl", 0644, led_dir,
  364. (u32 *)(RTL838X_SW_BASE + RTL8380_LED_SW_CTRL));
  365. debugfs_create_x32("led0_sw_p_en_ctrl", 0644, led_dir,
  366. (u32 *)(RTL838X_SW_BASE + RTL8380_LED0_SW_P_EN_CTRL));
  367. debugfs_create_x32("led1_sw_p_en_ctrl", 0644, led_dir,
  368. (u32 *)(RTL838X_SW_BASE + RTL8380_LED1_SW_P_EN_CTRL));
  369. debugfs_create_x32("led2_sw_p_en_ctrl", 0644, led_dir,
  370. (u32 *)(RTL838X_SW_BASE + RTL8380_LED2_SW_P_EN_CTRL));
  371. for (p = 0; p < 28; p++) {
  372. snprintf(led_sw_p_ctrl_name, sizeof(led_sw_p_ctrl_name),
  373. "led_sw_p_ctrl.%02d", p);
  374. debugfs_create_x32(led_sw_p_ctrl_name, 0644, led_dir,
  375. (u32 *)(RTL838X_SW_BASE + RTL8380_LED_SW_P_CTRL(p)));
  376. }
  377. } else if (priv->family_id == RTL8390_FAMILY_ID) {
  378. debugfs_create_x32("led_glb_ctrl", 0644, led_dir,
  379. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_GLB_CTRL));
  380. debugfs_create_x32("led_set_2_3", 0644, led_dir,
  381. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SET_2_3_CTRL));
  382. debugfs_create_x32("led_set_0_1", 0644, led_dir,
  383. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SET_0_1_CTRL));
  384. for (p = 0; p < 4; p++) {
  385. snprintf(port_led_name, sizeof(port_led_name), "led_copr_set_sel.%1d", p);
  386. debugfs_create_x32(port_led_name, 0644, led_dir,
  387. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COPR_SET_SEL_CTRL(p << 4)));
  388. snprintf(port_led_name, sizeof(port_led_name), "led_fib_set_sel.%1d", p);
  389. debugfs_create_x32(port_led_name, 0644, led_dir,
  390. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_FIB_SET_SEL_CTRL(p << 4)));
  391. }
  392. debugfs_create_x32("led_copr_pmask_ctrl_0", 0644, led_dir,
  393. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COPR_PMASK_CTRL(0)));
  394. debugfs_create_x32("led_copr_pmask_ctrl_1", 0644, led_dir,
  395. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COPR_PMASK_CTRL(32)));
  396. debugfs_create_x32("led_fib_pmask_ctrl_0", 0644, led_dir,
  397. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_FIB_PMASK_CTRL(0)));
  398. debugfs_create_x32("led_fib_pmask_ctrl_1", 0644, led_dir,
  399. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_FIB_PMASK_CTRL(32)));
  400. debugfs_create_x32("led_combo_ctrl_0", 0644, led_dir,
  401. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COMBO_CTRL(0)));
  402. debugfs_create_x32("led_combo_ctrl_1", 0644, led_dir,
  403. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_COMBO_CTRL(32)));
  404. debugfs_create_x32("led_sw_ctrl", 0644, led_dir,
  405. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SW_CTRL));
  406. for (p = 0; p < 5; p++) {
  407. snprintf(port_led_name, sizeof(port_led_name), "led_sw_p_en_ctrl.%1d", p);
  408. debugfs_create_x32(port_led_name, 0644, led_dir,
  409. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SW_P_EN_CTRL(p * 10)));
  410. }
  411. for (p = 0; p < 28; p++) {
  412. snprintf(port_led_name, sizeof(port_led_name), "led_sw_p_ctrl.%02d", p);
  413. debugfs_create_x32(port_led_name, 0644, led_dir,
  414. (u32 *)(RTL838X_SW_BASE + RTL8390_LED_SW_P_CTRL(p)));
  415. }
  416. }
  417. return 0;
  418. }
  419. void rtl838x_dbgfs_init(struct rtl838x_switch_priv *priv)
  420. {
  421. struct dentry *rtl838x_dir;
  422. struct dentry *port_dir;
  423. struct dentry *mirror_dir;
  424. struct debugfs_regset32 *port_ctrl_regset;
  425. int ret, i;
  426. char lag_name[10];
  427. char mirror_name[10];
  428. pr_info("%s called\n", __func__);
  429. rtl838x_dir = debugfs_lookup(RTL838X_DRIVER_NAME, NULL);
  430. if (!rtl838x_dir)
  431. rtl838x_dir = debugfs_create_dir(RTL838X_DRIVER_NAME, NULL);
  432. priv->dbgfs_dir = rtl838x_dir;
  433. debugfs_create_u32("soc", 0444, rtl838x_dir,
  434. (u32 *)(RTL838X_SW_BASE + RTL838X_MODEL_NAME_INFO));
  435. /* Create one directory per port */
  436. for (i = 0; i < priv->cpu_port; i++) {
  437. if (priv->ports[i].phy) {
  438. ret = rtl838x_dbgfs_port_init(rtl838x_dir, priv, i);
  439. if (ret)
  440. goto err;
  441. }
  442. }
  443. /* Create directory for CPU-port */
  444. port_dir = debugfs_create_dir("cpu_port", rtl838x_dir);
  445. port_ctrl_regset = devm_kzalloc(priv->dev, sizeof(*port_ctrl_regset), GFP_KERNEL);
  446. if (!port_ctrl_regset) {
  447. ret = -ENOMEM;
  448. goto err;
  449. }
  450. port_ctrl_regset->regs = port_ctrl_regs;
  451. port_ctrl_regset->nregs = ARRAY_SIZE(port_ctrl_regs);
  452. port_ctrl_regset->base = (void *)(RTL838X_SW_BASE + (priv->cpu_port << 2));
  453. debugfs_create_regset32("port_ctrl", 0400, port_dir, port_ctrl_regset);
  454. debugfs_create_u8("id", 0444, port_dir, &priv->cpu_port);
  455. /* Create entries for LAGs */
  456. for (i = 0; i < priv->n_lags; i++) {
  457. snprintf(lag_name, sizeof(lag_name), "lag.%02d", i);
  458. if (priv->family_id == RTL8380_FAMILY_ID)
  459. debugfs_create_x32(lag_name, 0644, rtl838x_dir,
  460. (u32 *)(RTL838X_SW_BASE + priv->r->trk_mbr_ctr(i)));
  461. else
  462. debugfs_create_x64(lag_name, 0644, rtl838x_dir,
  463. (u64 *)(RTL838X_SW_BASE + priv->r->trk_mbr_ctr(i)));
  464. }
  465. /* Create directories for mirror groups */
  466. for (i = 0; i < 4; i++) {
  467. snprintf(mirror_name, sizeof(mirror_name), "mirror.%1d", i);
  468. mirror_dir = debugfs_create_dir(mirror_name, rtl838x_dir);
  469. if (priv->family_id == RTL8380_FAMILY_ID) {
  470. debugfs_create_x32("ctrl", 0644, mirror_dir,
  471. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_CTRL + i * 4));
  472. debugfs_create_x32("ingress_pm", 0644, mirror_dir,
  473. (u32 *)(RTL838X_SW_BASE + priv->r->mir_spm + i * 4));
  474. debugfs_create_x32("egress_pm", 0644, mirror_dir,
  475. (u32 *)(RTL838X_SW_BASE + priv->r->mir_dpm + i * 4));
  476. debugfs_create_x32("qid", 0644, mirror_dir,
  477. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_QID_CTRL(i)));
  478. debugfs_create_x32("rspan_vlan", 0644, mirror_dir,
  479. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_VLAN_CTRL(i)));
  480. debugfs_create_x32("rspan_vlan_mac", 0644, mirror_dir,
  481. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_VLAN_CTRL_MAC(i)));
  482. debugfs_create_x32("rspan_tx", 0644, mirror_dir,
  483. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_TX_CTRL));
  484. debugfs_create_x32("rspan_tx_tag_rm", 0644, mirror_dir,
  485. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_TX_TAG_RM_CTRL));
  486. debugfs_create_x32("rspan_tx_tag_en", 0644, mirror_dir,
  487. (u32 *)(RTL838X_SW_BASE + RTL838X_MIR_RSPAN_TX_TAG_EN_CTRL));
  488. } else {
  489. debugfs_create_x32("ctrl", 0644, mirror_dir,
  490. (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_CTRL + i * 4));
  491. debugfs_create_x64("ingress_pm", 0644, mirror_dir,
  492. (u64 *)(RTL838X_SW_BASE + priv->r->mir_spm + i * 8));
  493. debugfs_create_x64("egress_pm", 0644, mirror_dir,
  494. (u64 *)(RTL838X_SW_BASE + priv->r->mir_dpm + i * 8));
  495. debugfs_create_x32("rspan_vlan", 0644, mirror_dir,
  496. (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_VLAN_CTRL(i)));
  497. debugfs_create_x32("rspan_tx", 0644, mirror_dir,
  498. (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_TX_CTRL));
  499. debugfs_create_x32("rspan_tx_tag_rm", 0644, mirror_dir,
  500. (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_TX_TAG_RM_CTRL));
  501. debugfs_create_x32("rspan_tx_tag_en", 0644, mirror_dir,
  502. (u32 *)(RTL838X_SW_BASE + RTL839X_MIR_RSPAN_TX_TAG_EN_CTRL));
  503. debugfs_create_x64("sample_rate", 0644, mirror_dir,
  504. (u64 *)(RTL838X_SW_BASE + RTL839X_MIR_SAMPLE_RATE_CTRL));
  505. }
  506. }
  507. if (priv->family_id == RTL8380_FAMILY_ID)
  508. debugfs_create_x32("bpdu_flood_mask", 0644, rtl838x_dir,
  509. (u32 *)(RTL838X_SW_BASE + priv->r->rma_bpdu_fld_pmask));
  510. else
  511. debugfs_create_x64("bpdu_flood_mask", 0644, rtl838x_dir,
  512. (u64 *)(RTL838X_SW_BASE + priv->r->rma_bpdu_fld_pmask));
  513. if (priv->family_id == RTL8380_FAMILY_ID)
  514. debugfs_create_x32("vlan_ctrl", 0644, rtl838x_dir,
  515. (u32 *)(RTL838X_SW_BASE + RTL838X_VLAN_CTRL));
  516. else
  517. debugfs_create_x32("vlan_ctrl", 0644, rtl838x_dir,
  518. (u32 *)(RTL838X_SW_BASE + RTL839X_VLAN_CTRL));
  519. ret = rtl838x_dbgfs_leds(rtl838x_dir, priv);
  520. if (ret)
  521. goto err;
  522. debugfs_create_file("drop_counters", 0400, rtl838x_dir, priv, &drop_counter_fops);
  523. return;
  524. err:
  525. rtl838x_dbgfs_cleanup(priv);
  526. }
  527. void rtl930x_dbgfs_init(struct rtl838x_switch_priv *priv)
  528. {
  529. struct dentry *dbg_dir;
  530. pr_info("%s called\n", __func__);
  531. dbg_dir = debugfs_lookup(RTL838X_DRIVER_NAME, NULL);
  532. if (!dbg_dir)
  533. dbg_dir = debugfs_create_dir(RTL838X_DRIVER_NAME, NULL);
  534. priv->dbgfs_dir = dbg_dir;
  535. debugfs_create_file("drop_counters", 0400, dbg_dir, priv, &drop_counter_fops);
  536. }