1 #include <linux/uaccess.h>
2 #include <linux/trace_seq.h>
3 #include <linux/seq_file.h>
4 #include <linux/proc_fs.h>
5 #include <linux/u64_stats_sync.h>
7 #include "./rtl8367c/include/rtk_switch.h"
8 #include "./rtl8367c/include/port.h"
9 #include "./rtl8367c/include/vlan.h"
10 #include "./rtl8367c/include/rtl8367c_asicdrv_port.h"
11 #include "./rtl8367c/include/stat.h"
12 #include "./rtl8367c/include/l2.h"
13 #include "./rtl8367c/include/smi.h"
14 #include "./rtl8367c/include/mirror.h"
15 #include "./rtl8367c/include/igmp.h"
16 #include "./rtl8367c/include/leaky.h"
18 static struct proc_dir_entry
*proc_reg_dir
;
19 static struct proc_dir_entry
*proc_esw_cnt
;
20 static struct proc_dir_entry
*proc_vlan_cnt
;
21 static struct proc_dir_entry
*proc_mac_tbl
;
22 static struct proc_dir_entry
*proc_reg
;
23 static struct proc_dir_entry
*proc_phyreg
;
24 static struct proc_dir_entry
*proc_mirror
;
25 static struct proc_dir_entry
*proc_igmp
;
27 #define PROCREG_ESW_CNT "esw_cnt"
28 #define PROCREG_VLAN "vlan"
29 #define PROCREG_MAC_TBL "mac_tbl"
30 #define PROCREG_REG "reg"
31 #define PROCREG_PHYREG "phyreg"
32 #define PROCREG_MIRROR "mirror"
33 #define PROCREG_IGMP "igmp"
34 #define PROCREG_DIR "rtk_gsw"
36 #define RTK_SW_VID_RANGE 16
38 static void rtk_dump_mib_type(rtk_stat_port_type_t cntr_idx
)
41 rtk_stat_counter_t Cntr
;
43 for (port
= UTP_PORT0
; port
< (UTP_PORT0
+ 5); port
++) {
44 rtk_stat_port_get(port
, cntr_idx
, &Cntr
);
45 printk("%8llu", Cntr
);
48 for (port
= EXT_PORT0
; port
< (EXT_PORT0
+ 2); port
++) {
49 rtk_stat_port_get(port
, cntr_idx
, &Cntr
);
50 printk("%8llu", Cntr
);
55 static void rtk_hal_dump_mib(void)
58 printk("==================%8s%8s%8s%8s%8s%8s%8s\n", "Port0", "Port1",
59 "Port2", "Port3", "Port4", "Port16", "Port17");
60 /* Get TX Unicast Pkts */
61 printk("TX Unicast Pkts :");
62 rtk_dump_mib_type(STAT_IfOutUcastPkts
);
63 /* Get TX Multicast Pkts */
64 printk("TX Multicast Pkts:");
65 rtk_dump_mib_type(STAT_IfOutMulticastPkts
);
66 /* Get TX BroadCast Pkts */
67 printk("TX BroadCast Pkts:");
68 rtk_dump_mib_type(STAT_IfOutBroadcastPkts
);
69 /* Get TX Collisions */
70 /* Get TX Puase Frames */
71 printk("TX Pause Frames :");
72 rtk_dump_mib_type(STAT_Dot3OutPauseFrames
);
73 /* Get TX Drop Events */
74 /* Get RX Unicast Pkts */
75 printk("RX Unicast Pkts :");
76 rtk_dump_mib_type(STAT_IfInUcastPkts
);
77 /* Get RX Multicast Pkts */
78 printk("RX Multicast Pkts:");
79 rtk_dump_mib_type(STAT_IfInMulticastPkts
);
80 /* Get RX Broadcast Pkts */
81 printk("RX Broadcast Pkts:");
82 rtk_dump_mib_type(STAT_IfInBroadcastPkts
);
83 /* Get RX FCS Erros */
84 printk("RX FCS Errors :");
85 rtk_dump_mib_type(STAT_Dot3StatsFCSErrors
);
86 /* Get RX Undersize Pkts */
87 printk("RX Undersize Pkts:");
88 rtk_dump_mib_type(STAT_EtherStatsUnderSizePkts
);
89 /* Get RX Discard Pkts */
90 printk("RX Discard Pkts :");
91 rtk_dump_mib_type(STAT_Dot1dTpPortInDiscards
);
92 /* Get RX Fragments */
93 printk("RX Fragments :");
94 rtk_dump_mib_type(STAT_EtherStatsFragments
);
95 /* Get RX Oversize Pkts */
96 printk("RX Oversize Pkts :");
97 rtk_dump_mib_type(STAT_EtherOversizeStats
);
99 printk("RX Jabbers :");
100 rtk_dump_mib_type(STAT_EtherStatsJabbers
);
101 /* Get RX Pause Frames */
102 printk("RX Pause Frames :");
103 rtk_dump_mib_type(STAT_Dot3InPauseFrames
);
105 rtk_stat_global_reset();
109 static int rtk_hal_dump_vlan(void)
114 printk("vid portmap\n");
115 for (i
= 0; i
< RTK_SW_VID_RANGE
; i
++) {
116 rtk_vlan_get(i
, &vlan
);
119 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
120 UTP_PORT0
) ? '1' : '-');
122 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
123 UTP_PORT1
) ? '1' : '-');
125 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
126 UTP_PORT2
) ? '1' : '-');
128 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
129 UTP_PORT3
) ? '1' : '-');
131 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
132 UTP_PORT4
) ? '1' : '-');
134 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
135 EXT_PORT0
) ? '1' : '-');
137 RTK_PORTMASK_IS_PORT_SET(vlan
.mbr
,
138 EXT_PORT1
) ? '1' : '-');
145 static void rtk_hal_dump_table(void)
148 rtk_uint32 address
= 0;
149 rtk_l2_ucastAddr_t l2_data
;
150 rtk_l2_ipMcastAddr_t ipMcastAddr
;
151 rtk_l2_age_time_t age_timout
;
153 rtk_l2_aging_get(&age_timout
);
154 printk("Mac table age timeout =%d\n",(unsigned int)age_timout
);
156 printk("hash port(0:17) fid vid mac-address\n");
158 if (rtk_l2_addr_next_get(READMETHOD_NEXT_L2UC
, UTP_PORT0
, &address
, &l2_data
) != RT_ERR_OK
) {
161 printk("%03x ", l2_data
.address
);
162 for (i
= 0; i
< 5; i
++)
163 if ( l2_data
.port
== i
)
167 for (i
= 16; i
< 18; i
++)
168 if ( l2_data
.port
== i
)
173 printk(" %2d", l2_data
.fid
);
174 printk(" %4d", l2_data
.cvid
);
175 printk(" %02x%02x%02x%02x%02x%02x\n", l2_data
.mac
.octet
[0],
176 l2_data
.mac
.octet
[1], l2_data
.mac
.octet
[2], l2_data
.mac
.octet
[3],
177 l2_data
.mac
.octet
[4], l2_data
.mac
.octet
[5]);
184 if (rtk_l2_ipMcastAddr_next_get(&address
, &ipMcastAddr
) != RT_ERR_OK
) {
187 printk("%03x ", ipMcastAddr
.address
);
188 for (i
= 0; i
< 5; i
++)
189 printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr
.portmask
, i
) ? '1' : '-');
190 for (i
= 16; i
< 18; i
++)
191 printk("%c", RTK_PORTMASK_IS_PORT_SET(ipMcastAddr
.portmask
, i
) ? '1' : '-');
193 printk("01005E%06x\n", (ipMcastAddr
.dip
& 0xefffff));
199 static void rtk_hal_clear_table(void)
203 ret
= rtk_l2_table_clear();
204 if (ret
!= RT_ERR_OK
)
205 printk("rtk_l2_table_clear failed\n");
208 static void rtk_hal_read_reg(unsigned int reg_addr
)
211 unsigned int reg_val
;
213 retVal
= smi_read(reg_addr
, ®_val
);
215 if(retVal
!= RT_ERR_OK
)
216 printk("switch reg read failed\n");
218 printk("reg0x%x = 0x%x\n", reg_addr
, reg_val
);
221 static void rtk_hal_write_reg(unsigned int reg_addr
, unsigned int reg_val
)
225 retVal
= smi_write(reg_addr
, reg_val
);
227 if(retVal
!= RT_ERR_OK
)
228 printk("switch reg write failed\n");
230 printk("write switch reg0x%x 0x%x success\n", reg_addr
, reg_val
);
233 static void rtk_hal_get_phy_reg(unsigned int port
,unsigned int reg_addr
)
236 rtk_port_phy_data_t Data
;
238 retVal
= rtk_port_phyReg_get(port
, reg_addr
, &Data
);
239 if (retVal
== RT_ERR_OK
)
240 printk("Get: phy[%d].reg[%d] = 0x%04x\n", port
, reg_addr
, Data
);
242 printk("read phy reg failed\n");
245 static void rtk_hal_set_phy_reg(unsigned int port
,unsigned int reg_addr
,unsigned int reg_val
)
249 retVal
= rtk_port_phyReg_set(port
, reg_addr
, reg_val
);
250 if (retVal
== RT_ERR_OK
)
251 printk("Set: phy[%d].reg[%d] = 0x%04x\n", port
, reg_addr
, reg_val
);
253 printk("write phy reg failed\n");
256 static void rtk_hal_set_port_mirror(unsigned int port
,unsigned int rx_port_map
,unsigned int tx_port_map
)
258 rtk_portmask_t rx_portmask
;
259 rtk_portmask_t tx_portmask
;
263 rtk_mirror_portIso_set(ENABLED
);
264 RTK_PORTMASK_CLEAR(rx_portmask
);
265 RTK_PORTMASK_CLEAR(tx_portmask
);
267 for (i
= 0; i
< 5; i
++)
268 if (rx_port_map
& (1 << i
))
269 RTK_PORTMASK_PORT_SET(rx_portmask
, i
);
271 for (i
= 0; i
< 2; i
++)
272 if (rx_port_map
& (1 << (i
+ 5)))
273 RTK_PORTMASK_PORT_SET(rx_portmask
, (i
+ EXT_PORT0
));
275 RTK_PORTMASK_CLEAR(tx_portmask
);
277 for (i
= 0; i
< 5; i
++)
278 if (tx_port_map
& (1 << i
))
279 RTK_PORTMASK_PORT_SET(tx_portmask
, i
);
281 for (i
= 0; i
< 2; i
++)
282 if (tx_port_map
& (1 << (i
+ 5)))
283 RTK_PORTMASK_PORT_SET(tx_portmask
, (i
+ EXT_PORT0
));
285 ret
= rtk_mirror_portBased_set(port
, &rx_portmask
, &tx_portmask
);
288 printk("rtk_mirror_portBased_set success\n");
292 static void rtk_hal_enable_igmpsnoop(int hw_on
)
295 rtk_portmask_t pmask
;
297 ret
= rtk_igmp_init();
299 RTK_PORTMASK_CLEAR(pmask
);
300 RTK_PORTMASK_PORT_SET(pmask
, EXT_PORT0
);
301 ret
|= rtk_igmp_static_router_port_set(&pmask
);
302 ret
|= rtk_igmp_protocol_set(UTP_PORT4
, PROTOCOL_IGMPv1
, IGMP_ACTION_FORWARD
);
303 ret
|= rtk_igmp_protocol_set(UTP_PORT4
, PROTOCOL_IGMPv2
, IGMP_ACTION_FORWARD
);
304 ret
|= rtk_igmp_protocol_set(UTP_PORT4
, PROTOCOL_MLDv1
, IGMP_ACTION_FORWARD
);
305 ret
|= rtk_igmp_protocol_set(EXT_PORT1
, PROTOCOL_IGMPv1
, IGMP_ACTION_FORWARD
);
306 ret
|= rtk_igmp_protocol_set(EXT_PORT1
, PROTOCOL_IGMPv2
, IGMP_ACTION_FORWARD
);
307 ret
|= rtk_igmp_protocol_set(EXT_PORT1
, PROTOCOL_MLDv1
, IGMP_ACTION_FORWARD
);
308 ret
|= rtk_igmp_protocol_set(UTP_PORT0
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
309 ret
|= rtk_igmp_protocol_set(UTP_PORT1
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
310 ret
|= rtk_igmp_protocol_set(UTP_PORT2
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
311 ret
|= rtk_igmp_protocol_set(UTP_PORT3
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
312 ret
|= rtk_igmp_protocol_set(EXT_PORT0
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
314 ret
|= rtk_leaky_vlan_set(LEAKY_IPMULTICAST
, ENABLED
);
315 ret
|= rtk_l2_ipMcastForwardRouterPort_set(DISABLED
);
316 /* drop unknown multicast packets*/
317 /* ret |= rtk_trap_unknownMcastPktAction_set(UTP_PORT4, MCAST_IPV4, MCAST_ACTION_DROP);*/
319 RTK_PORTMASK_CLEAR(pmask
);
320 RTK_PORTMASK_PORT_SET(pmask
, EXT_PORT0
);
321 RTK_PORTMASK_PORT_SET(pmask
, EXT_PORT1
);
322 ret
|= rtk_igmp_protocol_set(UTP_PORT0
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
323 ret
|= rtk_igmp_protocol_set(UTP_PORT1
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
324 ret
|= rtk_igmp_protocol_set(UTP_PORT2
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
325 ret
|= rtk_igmp_protocol_set(UTP_PORT3
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
326 ret
|= rtk_igmp_protocol_set(EXT_PORT0
, PROTOCOL_IGMPv3
, IGMP_ACTION_ASIC
);
328 ret
|= rtk_igmp_static_router_port_set(&pmask
);
332 printk("enable switch igmpsnoop failed\n");
336 static void rtk_hal_disable_igmpsnoop(void)
338 if (rtk_igmp_state_set(DISABLED
) != RT_ERR_OK
)
339 printk("Disable IGMP SNOOPING failed\n");
342 static ssize_t
mac_tbl_write(struct file
*file
,
343 const char __user
*buffer
, size_t count
,
346 rtk_hal_clear_table();
352 static ssize_t
phyreg_ops(struct file
*file
,
353 const char __user
*buffer
, size_t count
,
363 if (copy_from_user(buf
, buffer
, count
))
369 if(sscanf(buf
, "w %d %x %x", &port
,&offset
,&val
) == -1)
372 rtk_hal_set_phy_reg(port
,offset
,val
);
376 if(sscanf(buf
, "r %d %x",&port
, &offset
) == -1)
379 rtk_hal_get_phy_reg(port
,offset
);
385 static ssize_t
reg_ops(struct file
*file
,
386 const char __user
*buffer
, size_t count
,
395 if (copy_from_user(buf
, buffer
, count
))
401 if(sscanf(buf
, "w %x %x", &offset
,&val
) == -1)
404 rtk_hal_write_reg(offset
,val
);
408 if(sscanf(buf
, "r %x", &offset
) == -1)
411 rtk_hal_read_reg(offset
);
417 static ssize_t
mirror_ops(struct file
*file
,
418 const char __user
*buffer
, size_t count
,
423 unsigned int tx_map
,rx_map
;
427 if (copy_from_user(buf
, buffer
, count
))
430 if(sscanf(buf
, "%d %x %x", &port
,&rx_map
,&tx_map
) == -1)
433 rtk_hal_set_port_mirror(port
,rx_map
,tx_map
);
439 static ssize_t
igmp_ops(struct file
*file
,
440 const char __user
*buffer
, size_t count
,
446 if (copy_from_user(buf
, buffer
, count
))
449 if(sscanf(buf
, "%d", &ops
) == -1)
453 rtk_hal_disable_igmpsnoop();
455 rtk_hal_enable_igmpsnoop(0);
457 rtk_hal_enable_igmpsnoop(1);
463 static int esw_cnt_read(struct seq_file
*seq
, void *v
)
469 static int vlan_read(struct seq_file
*seq
, void *v
)
475 static int mac_tbl_read(struct seq_file
*seq
, void *v
)
477 rtk_hal_dump_table();
481 static int reg_show(struct seq_file
*seq
, void *v
)
486 static int phyreg_show(struct seq_file
*seq
, void *v
)
491 static int mirror_show(struct seq_file
*seq
, void *v
)
496 static int igmp_show(struct seq_file
*seq
, void *v
)
501 static int switch_count_open(struct inode
*inode
, struct file
*file
)
503 return single_open(file
, esw_cnt_read
, 0);
506 static int switch_vlan_open(struct inode
*inode
, struct file
*file
)
508 return single_open(file
, vlan_read
, 0);
511 static int mac_tbl_open(struct inode
*inode
, struct file
*file
)
513 return single_open(file
, mac_tbl_read
, 0);
516 static int reg_open(struct inode
*inode
, struct file
*file
)
518 return single_open(file
, reg_show
, 0);
521 static int phyreg_open(struct inode
*inode
, struct file
*file
)
523 return single_open(file
, phyreg_show
, 0);
526 static int mirror_open(struct inode
*inode
, struct file
*file
)
528 return single_open(file
, mirror_show
, 0);
531 static int igmp_open(struct inode
*inode
, struct file
*file
)
533 return single_open(file
, igmp_show
, 0);
537 static const struct proc_ops switch_count_fops
= {
538 .proc_open
= switch_count_open
,
539 .proc_read
= seq_read
,
540 .proc_lseek
= seq_lseek
,
541 .proc_release
= single_release
544 static const struct proc_ops switch_vlan_fops
= {
545 .proc_open
= switch_vlan_open
,
546 .proc_read
= seq_read
,
547 .proc_lseek
= seq_lseek
,
548 .proc_release
= single_release
551 static const struct proc_ops mac_tbl_fops
= {
552 .proc_open
= mac_tbl_open
,
553 .proc_read
= seq_read
,
554 .proc_lseek
= seq_lseek
,
555 .proc_write
= mac_tbl_write
,
556 .proc_release
= single_release
559 static const struct proc_ops reg_fops
= {
560 .proc_open
= reg_open
,
561 .proc_read
= seq_read
,
562 .proc_lseek
= seq_lseek
,
563 .proc_write
= reg_ops
,
564 .proc_release
= single_release
567 static const struct proc_ops phyreg_fops
= {
568 .proc_open
= phyreg_open
,
569 .proc_read
= seq_read
,
570 .proc_lseek
= seq_lseek
,
571 .proc_write
= phyreg_ops
,
572 .proc_release
= single_release
575 static const struct proc_ops mirror_fops
= {
576 .proc_open
= mirror_open
,
577 .proc_read
= seq_read
,
578 .proc_lseek
= seq_lseek
,
579 .proc_write
= mirror_ops
,
580 .proc_release
= single_release
583 static const struct proc_ops igmp_fops
= {
584 .proc_open
= igmp_open
,
585 .proc_read
= seq_read
,
586 .proc_lseek
= seq_lseek
,
587 .proc_write
= igmp_ops
,
588 .proc_release
= single_release
591 int gsw_debug_proc_init(void)
595 proc_reg_dir
= proc_mkdir(PROCREG_DIR
, NULL
);
598 proc_create(PROCREG_ESW_CNT
, 0, proc_reg_dir
, &switch_count_fops
);
601 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT
);
604 proc_create(PROCREG_VLAN
, 0, proc_reg_dir
, &switch_vlan_fops
);
607 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_VLAN
);
610 proc_create(PROCREG_MAC_TBL
, 0, proc_reg_dir
, &mac_tbl_fops
);
613 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MAC_TBL
);
616 proc_create(PROCREG_REG
, 0, proc_reg_dir
, ®_fops
);
619 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_REG
);
622 proc_create(PROCREG_PHYREG
, 0, proc_reg_dir
, &phyreg_fops
);
625 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_PHYREG
);
628 proc_create(PROCREG_MIRROR
, 0, proc_reg_dir
, &mirror_fops
);
631 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_MIRROR
);
634 proc_create(PROCREG_IGMP
, 0, proc_reg_dir
, &igmp_fops
);
637 pr_err("!! FAIL to create %s PROC !!\n", PROCREG_IGMP
);
642 void gsw_debug_proc_exit(void)
645 remove_proc_entry(PROCREG_ESW_CNT
, proc_reg_dir
);