@@ -1458,14 +1458,82 @@ static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds,
14581458 return _mv88e6xxx_vtu_cmd (ds , GLOBAL_VTU_OP_STU_LOAD_PURGE );
14591459}
14601460
1461+ static int _mv88e6xxx_port_fid (struct dsa_switch * ds , int port , u16 * new ,
1462+ u16 * old )
1463+ {
1464+ u16 fid ;
1465+ int ret ;
1466+
1467+ /* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */
1468+ ret = _mv88e6xxx_reg_read (ds , REG_PORT (port ), PORT_BASE_VLAN );
1469+ if (ret < 0 )
1470+ return ret ;
1471+
1472+ fid = (ret & PORT_BASE_VLAN_FID_3_0_MASK ) >> 12 ;
1473+
1474+ if (new ) {
1475+ ret &= ~PORT_BASE_VLAN_FID_3_0_MASK ;
1476+ ret |= (* new << 12 ) & PORT_BASE_VLAN_FID_3_0_MASK ;
1477+
1478+ ret = _mv88e6xxx_reg_write (ds , REG_PORT (port ), PORT_BASE_VLAN ,
1479+ ret );
1480+ if (ret < 0 )
1481+ return ret ;
1482+ }
1483+
1484+ /* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */
1485+ ret = _mv88e6xxx_reg_read (ds , REG_PORT (port ), PORT_CONTROL_1 );
1486+ if (ret < 0 )
1487+ return ret ;
1488+
1489+ fid |= (ret & PORT_CONTROL_1_FID_11_4_MASK ) << 4 ;
1490+
1491+ if (new ) {
1492+ ret &= ~PORT_CONTROL_1_FID_11_4_MASK ;
1493+ ret |= (* new >> 4 ) & PORT_CONTROL_1_FID_11_4_MASK ;
1494+
1495+ ret = _mv88e6xxx_reg_write (ds , REG_PORT (port ), PORT_CONTROL_1 ,
1496+ ret );
1497+ if (ret < 0 )
1498+ return ret ;
1499+
1500+ netdev_dbg (ds -> ports [port ], "FID %d (was %d)\n" , * new , fid );
1501+ }
1502+
1503+ if (old )
1504+ * old = fid ;
1505+
1506+ return 0 ;
1507+ }
1508+
1509+ static int _mv88e6xxx_port_fid_get (struct dsa_switch * ds , int port , u16 * fid )
1510+ {
1511+ return _mv88e6xxx_port_fid (ds , port , NULL , fid );
1512+ }
1513+
1514+ static int _mv88e6xxx_port_fid_set (struct dsa_switch * ds , int port , u16 fid )
1515+ {
1516+ return _mv88e6xxx_port_fid (ds , port , & fid , NULL );
1517+ }
1518+
14611519static int _mv88e6xxx_fid_new (struct dsa_switch * ds , u16 * fid )
14621520{
1521+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
14631522 DECLARE_BITMAP (fid_bitmap , MV88E6XXX_N_FID );
14641523 struct mv88e6xxx_vtu_stu_entry vlan ;
1465- int err ;
1524+ int i , err ;
14661525
14671526 bitmap_zero (fid_bitmap , MV88E6XXX_N_FID );
14681527
1528+ /* Set every FID bit used by the (un)bridged ports */
1529+ for (i = 0 ; i < ps -> num_ports ; ++ i ) {
1530+ err = _mv88e6xxx_port_fid_get (ds , i , fid );
1531+ if (err )
1532+ return err ;
1533+
1534+ set_bit (* fid , fid_bitmap );
1535+ }
1536+
14691537 /* Set every FID bit used by the VLAN entries */
14701538 err = _mv88e6xxx_vtu_vid_write (ds , GLOBAL_VTU_VID_MASK );
14711539 if (err )
@@ -1824,7 +1892,11 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
18241892 struct mv88e6xxx_vtu_stu_entry vlan ;
18251893 int err ;
18261894
1827- err = _mv88e6xxx_vtu_get (ds , vid , & vlan , false);
1895+ /* Null VLAN ID corresponds to the port private database */
1896+ if (vid == 0 )
1897+ err = _mv88e6xxx_port_fid_get (ds , port , & vlan .fid );
1898+ else
1899+ err = _mv88e6xxx_vtu_get (ds , vid , & vlan , false);
18281900 if (err )
18291901 return err ;
18301902
@@ -1843,10 +1915,6 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
18431915 const struct switchdev_obj_port_fdb * fdb ,
18441916 struct switchdev_trans * trans )
18451917{
1846- /* We don't use per-port FDB */
1847- if (fdb -> vid == 0 )
1848- return - EOPNOTSUPP ;
1849-
18501918 /* We don't need any dynamic resource from the kernel (yet),
18511919 * so skip the prepare phase.
18521920 */
@@ -1982,10 +2050,20 @@ int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
19822050 struct mv88e6xxx_vtu_stu_entry vlan = {
19832051 .vid = GLOBAL_VTU_VID_MASK , /* all ones */
19842052 };
2053+ u16 fid ;
19852054 int err ;
19862055
19872056 mutex_lock (& ps -> smi_mutex );
19882057
2058+ /* Dump port's default Filtering Information Database (VLAN ID 0) */
2059+ err = _mv88e6xxx_port_fid_get (ds , port , & fid );
2060+ if (err )
2061+ goto unlock ;
2062+
2063+ err = _mv88e6xxx_port_fdb_dump_one (ds , fid , 0 , port , fdb , cb );
2064+ if (err )
2065+ goto unlock ;
2066+
19892067 /* Dump VLANs' Filtering Information Databases */
19902068 err = _mv88e6xxx_vtu_vid_write (ds , vlan .vid );
19912069 if (err )
@@ -2286,9 +2364,13 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
22862364 if (ret )
22872365 goto abort ;
22882366
2289- /* Port based VLAN map: do not give each port its own address
2367+ /* Port based VLAN map: give each port its own address
22902368 * database, and allow every port to egress frames on all other ports.
22912369 */
2370+ ret = _mv88e6xxx_port_fid_set (ds , port , port + 1 );
2371+ if (ret )
2372+ goto abort ;
2373+
22922374 reg = BIT (ps -> num_ports ) - 1 ; /* all ports */
22932375 reg &= ~BIT (port ); /* except itself */
22942376 ret = _mv88e6xxx_port_vlan_map_set (ds , port , reg );
0 commit comments