@@ -1643,6 +1643,84 @@ static const struct file_operations mv88e6xxx_regs_fops = {
1643
1643
.owner = THIS_MODULE ,
1644
1644
};
1645
1645
1646
+ static void mv88e6xxx_atu_show_header (struct seq_file * s )
1647
+ {
1648
+ seq_puts (s , "DB T/P Vec State Addr\n" );
1649
+ }
1650
+
1651
+ static void mv88e6xxx_atu_show_entry (struct seq_file * s , int dbnum ,
1652
+ unsigned char * addr , int data )
1653
+ {
1654
+ bool trunk = !!(data & GLOBAL_ATU_DATA_TRUNK );
1655
+ int portvec = ((data & GLOBAL_ATU_DATA_PORT_VECTOR_MASK ) >>
1656
+ GLOBAL_ATU_DATA_PORT_VECTOR_SHIFT );
1657
+ int state = data & GLOBAL_ATU_DATA_STATE_MASK ;
1658
+
1659
+ seq_printf (s , "%03x %5s %10pb %x %pM\n" ,
1660
+ dbnum , (trunk ? "Trunk" : "Port" ), & portvec , state , addr );
1661
+ }
1662
+
1663
+ static int mv88e6xxx_atu_show_db (struct seq_file * s , struct dsa_switch * ds ,
1664
+ int dbnum )
1665
+ {
1666
+ unsigned char bcast [] = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff };
1667
+ unsigned char addr [6 ];
1668
+ int ret , data , state ;
1669
+
1670
+ ret = __mv88e6xxx_write_addr (ds , bcast );
1671
+ if (ret < 0 )
1672
+ return ret ;
1673
+
1674
+ do {
1675
+ ret = _mv88e6xxx_atu_cmd (ds , dbnum , GLOBAL_ATU_OP_GET_NEXT_DB );
1676
+ if (ret < 0 )
1677
+ return ret ;
1678
+ data = _mv88e6xxx_reg_read (ds , REG_GLOBAL , GLOBAL_ATU_DATA );
1679
+ if (data < 0 )
1680
+ return data ;
1681
+
1682
+ state = data & GLOBAL_ATU_DATA_STATE_MASK ;
1683
+ if (state == GLOBAL_ATU_DATA_STATE_UNUSED )
1684
+ break ;
1685
+ ret = __mv88e6xxx_read_addr (ds , addr );
1686
+ if (ret < 0 )
1687
+ return ret ;
1688
+ mv88e6xxx_atu_show_entry (s , dbnum , addr , data );
1689
+ } while (state != GLOBAL_ATU_DATA_STATE_UNUSED );
1690
+
1691
+ return 0 ;
1692
+ }
1693
+
1694
+ static int mv88e6xxx_atu_show (struct seq_file * s , void * p )
1695
+ {
1696
+ struct dsa_switch * ds = s -> private ;
1697
+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1698
+ int dbnum ;
1699
+
1700
+ mv88e6xxx_atu_show_header (s );
1701
+
1702
+ for (dbnum = 0 ; dbnum < 255 ; dbnum ++ ) {
1703
+ mutex_lock (& ps -> smi_mutex );
1704
+ mv88e6xxx_atu_show_db (s , ds , dbnum );
1705
+ mutex_unlock (& ps -> smi_mutex );
1706
+ }
1707
+
1708
+ return 0 ;
1709
+ }
1710
+
1711
+ static int mv88e6xxx_atu_open (struct inode * inode , struct file * file )
1712
+ {
1713
+ return single_open (file , mv88e6xxx_atu_show , inode -> i_private );
1714
+ }
1715
+
1716
+ static const struct file_operations mv88e6xxx_atu_fops = {
1717
+ .open = mv88e6xxx_atu_open ,
1718
+ .read = seq_read ,
1719
+ .llseek = no_llseek ,
1720
+ .release = single_release ,
1721
+ .owner = THIS_MODULE ,
1722
+ };
1723
+
1646
1724
int mv88e6xxx_setup_common (struct dsa_switch * ds )
1647
1725
{
1648
1726
struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
@@ -1663,6 +1741,9 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds)
1663
1741
debugfs_create_file ("regs" , S_IRUGO , ps -> dbgfs , ds ,
1664
1742
& mv88e6xxx_regs_fops );
1665
1743
1744
+ debugfs_create_file ("atu" , S_IRUGO , ps -> dbgfs , ds ,
1745
+ & mv88e6xxx_atu_fops );
1746
+
1666
1747
return 0 ;
1667
1748
}
1668
1749
0 commit comments