@@ -1259,7 +1259,13 @@ static int _mv88e6xxx_vtu_stu_data_write(struct dsa_switch *ds,
12591259 return 0 ;
12601260}
12611261
1262- static int _mv88e6xxx_vtu_getnext (struct dsa_switch * ds , u16 vid ,
1262+ static int _mv88e6xxx_vtu_vid_write (struct dsa_switch * ds , u16 vid )
1263+ {
1264+ return _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_VTU_VID ,
1265+ vid & GLOBAL_VTU_VID_MASK );
1266+ }
1267+
1268+ static int _mv88e6xxx_vtu_getnext (struct dsa_switch * ds ,
12631269 struct mv88e6xxx_vtu_stu_entry * entry )
12641270{
12651271 struct mv88e6xxx_vtu_stu_entry next = { 0 };
@@ -1269,11 +1275,6 @@ static int _mv88e6xxx_vtu_getnext(struct dsa_switch *ds, u16 vid,
12691275 if (ret < 0 )
12701276 return ret ;
12711277
1272- ret = _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_VTU_VID ,
1273- vid & GLOBAL_VTU_VID_MASK );
1274- if (ret < 0 )
1275- return ret ;
1276-
12771278 ret = _mv88e6xxx_vtu_cmd (ds , GLOBAL_VTU_OP_VTU_GET_NEXT );
12781279 if (ret < 0 )
12791280 return ret ;
@@ -1485,7 +1486,12 @@ int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
14851486 int err ;
14861487
14871488 mutex_lock (& ps -> smi_mutex );
1488- err = _mv88e6xxx_vtu_getnext (ds , vid - 1 , & vlan );
1489+
1490+ err = _mv88e6xxx_vtu_vid_write (ds , vid - 1 );
1491+ if (err )
1492+ goto unlock ;
1493+
1494+ err = _mv88e6xxx_vtu_getnext (ds , & vlan );
14891495 if (err )
14901496 goto unlock ;
14911497
@@ -1514,7 +1520,11 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
15141520
15151521 mutex_lock (& ps -> smi_mutex );
15161522
1517- err = _mv88e6xxx_vtu_getnext (ds , vid - 1 , & vlan );
1523+ err = _mv88e6xxx_vtu_vid_write (ds , vid - 1 );
1524+ if (err )
1525+ goto unlock ;
1526+
1527+ err = _mv88e6xxx_vtu_getnext (ds , & vlan );
15181528 if (err )
15191529 goto unlock ;
15201530
@@ -1549,29 +1559,6 @@ int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
15491559 return err ;
15501560}
15511561
1552- static int _mv88e6xxx_port_vtu_getnext (struct dsa_switch * ds , int port , u16 vid ,
1553- struct mv88e6xxx_vtu_stu_entry * entry )
1554- {
1555- int err ;
1556-
1557- do {
1558- if (vid == 4095 )
1559- return - ENOENT ;
1560-
1561- err = _mv88e6xxx_vtu_getnext (ds , vid , entry );
1562- if (err )
1563- return err ;
1564-
1565- if (!entry -> valid )
1566- return - ENOENT ;
1567-
1568- vid = entry -> vid ;
1569- } while (entry -> data [port ] != GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED &&
1570- entry -> data [port ] != GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED );
1571-
1572- return 0 ;
1573- }
1574-
15751562int mv88e6xxx_vlan_getnext (struct dsa_switch * ds , u16 * vid ,
15761563 unsigned long * ports , unsigned long * untagged )
15771564{
@@ -1584,7 +1571,12 @@ int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
15841571 return - ENOENT ;
15851572
15861573 mutex_lock (& ps -> smi_mutex );
1587- err = _mv88e6xxx_vtu_getnext (ds , * vid , & next );
1574+ err = _mv88e6xxx_vtu_vid_write (ds , * vid );
1575+ if (err )
1576+ goto unlock ;
1577+
1578+ err = _mv88e6xxx_vtu_getnext (ds , & next );
1579+ unlock :
15881580 mutex_unlock (& ps -> smi_mutex );
15891581
15901582 if (err )
@@ -1732,7 +1724,6 @@ int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
17321724}
17331725
17341726static int _mv88e6xxx_atu_getnext (struct dsa_switch * ds , u16 fid ,
1735- const unsigned char * addr ,
17361727 struct mv88e6xxx_atu_entry * entry )
17371728{
17381729 struct mv88e6xxx_atu_entry next = { 0 };
@@ -1744,10 +1735,6 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
17441735 if (ret < 0 )
17451736 return ret ;
17461737
1747- ret = _mv88e6xxx_atu_mac_write (ds , addr );
1748- if (ret < 0 )
1749- return ret ;
1750-
17511738 ret = _mv88e6xxx_reg_write (ds , REG_GLOBAL , GLOBAL_ATU_FID , fid );
17521739 if (ret < 0 )
17531740 return ret ;
@@ -1785,46 +1772,69 @@ static int _mv88e6xxx_atu_getnext(struct dsa_switch *ds, u16 fid,
17851772 return 0 ;
17861773}
17871774
1788- /* get next entry for port */
1789- int mv88e6xxx_port_fdb_getnext ( struct dsa_switch * ds , int port ,
1790- unsigned char * addr , u16 * vid , bool * is_static )
1775+ int mv88e6xxx_port_fdb_dump ( struct dsa_switch * ds , int port ,
1776+ struct switchdev_obj_port_fdb * fdb ,
1777+ int ( * cb )( struct switchdev_obj * obj ) )
17911778{
17921779 struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1793- struct mv88e6xxx_atu_entry next ;
1794- u16 fid = * vid ; /* We use one FID per VLAN */
1795- int ret ;
1780+ struct mv88e6xxx_vtu_stu_entry vlan = {
1781+ .vid = GLOBAL_VTU_VID_MASK , /* all ones */
1782+ };
1783+ int err ;
17961784
17971785 mutex_lock (& ps -> smi_mutex );
17981786
1787+ err = _mv88e6xxx_vtu_vid_write (ds , vlan .vid );
1788+ if (err )
1789+ goto unlock ;
1790+
17991791 do {
1800- if (is_broadcast_ether_addr (addr )) {
1801- struct mv88e6xxx_vtu_stu_entry vtu ;
1792+ struct mv88e6xxx_atu_entry addr = {
1793+ .mac = { 0xff , 0xff , 0xff , 0xff , 0xff , 0xff },
1794+ };
18021795
1803- ret = _mv88e6xxx_port_vtu_getnext (ds , port , * vid , & vtu );
1804- if (ret < 0 )
1805- goto unlock ;
1796+ err = _mv88e6xxx_vtu_getnext (ds , & vlan );
1797+ if (err )
1798+ goto unlock ;
18061799
1807- * vid = vtu .vid ;
1808- fid = vtu .fid ;
1809- }
1800+ if (!vlan .valid )
1801+ break ;
18101802
1811- ret = _mv88e6xxx_atu_getnext (ds , fid , addr , & next );
1812- if (ret < 0 )
1803+ err = _mv88e6xxx_atu_mac_write (ds , addr . mac );
1804+ if (err )
18131805 goto unlock ;
18141806
1815- ether_addr_copy (addr , next .mac );
1807+ do {
1808+ err = _mv88e6xxx_atu_getnext (ds , vlan .fid , & addr );
1809+ if (err )
1810+ goto unlock ;
18161811
1817- if (next .state == GLOBAL_ATU_DATA_STATE_UNUSED )
1818- continue ;
1819- } while (next .trunk || (next .portv_trunkid & BIT (port )) == 0 );
1812+ if (addr .state == GLOBAL_ATU_DATA_STATE_UNUSED )
1813+ break ;
1814+
1815+ if (!addr .trunk && addr .portv_trunkid & BIT (port )) {
1816+ bool is_static = addr .state ==
1817+ (is_multicast_ether_addr (addr .mac ) ?
1818+ GLOBAL_ATU_DATA_STATE_MC_STATIC :
1819+ GLOBAL_ATU_DATA_STATE_UC_STATIC );
1820+
1821+ fdb -> vid = vlan .vid ;
1822+ ether_addr_copy (fdb -> addr , addr .mac );
1823+ fdb -> ndm_state = is_static ? NUD_NOARP :
1824+ NUD_REACHABLE ;
1825+
1826+ err = cb (& fdb -> obj );
1827+ if (err )
1828+ goto unlock ;
1829+ }
1830+ } while (!is_broadcast_ether_addr (addr .mac ));
1831+
1832+ } while (vlan .vid < GLOBAL_VTU_VID_MASK );
18201833
1821- * is_static = next .state == (is_multicast_ether_addr (addr ) ?
1822- GLOBAL_ATU_DATA_STATE_MC_STATIC :
1823- GLOBAL_ATU_DATA_STATE_UC_STATIC );
18241834unlock :
18251835 mutex_unlock (& ps -> smi_mutex );
18261836
1827- return ret ;
1837+ return err ;
18281838}
18291839
18301840static void mv88e6xxx_bridge_work (struct work_struct * work )
0 commit comments