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