@@ -1458,14 +1458,82 @@ static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds,
1458
1458
return _mv88e6xxx_vtu_cmd (ds , GLOBAL_VTU_OP_STU_LOAD_PURGE );
1459
1459
}
1460
1460
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
+
1461
1519
static int _mv88e6xxx_fid_new (struct dsa_switch * ds , u16 * fid )
1462
1520
{
1521
+ struct mv88e6xxx_priv_state * ps = ds_to_priv (ds );
1463
1522
DECLARE_BITMAP (fid_bitmap , MV88E6XXX_N_FID );
1464
1523
struct mv88e6xxx_vtu_stu_entry vlan ;
1465
- int err ;
1524
+ int i , err ;
1466
1525
1467
1526
bitmap_zero (fid_bitmap , MV88E6XXX_N_FID );
1468
1527
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
+
1469
1537
/* Set every FID bit used by the VLAN entries */
1470
1538
err = _mv88e6xxx_vtu_vid_write (ds , GLOBAL_VTU_VID_MASK );
1471
1539
if (err )
@@ -1824,7 +1892,11 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
1824
1892
struct mv88e6xxx_vtu_stu_entry vlan ;
1825
1893
int err ;
1826
1894
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);
1828
1900
if (err )
1829
1901
return err ;
1830
1902
@@ -1843,10 +1915,6 @@ int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
1843
1915
const struct switchdev_obj_port_fdb * fdb ,
1844
1916
struct switchdev_trans * trans )
1845
1917
{
1846
- /* We don't use per-port FDB */
1847
- if (fdb -> vid == 0 )
1848
- return - EOPNOTSUPP ;
1849
-
1850
1918
/* We don't need any dynamic resource from the kernel (yet),
1851
1919
* so skip the prepare phase.
1852
1920
*/
@@ -1982,10 +2050,20 @@ int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,
1982
2050
struct mv88e6xxx_vtu_stu_entry vlan = {
1983
2051
.vid = GLOBAL_VTU_VID_MASK , /* all ones */
1984
2052
};
2053
+ u16 fid ;
1985
2054
int err ;
1986
2055
1987
2056
mutex_lock (& ps -> smi_mutex );
1988
2057
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
+
1989
2067
/* Dump VLANs' Filtering Information Databases */
1990
2068
err = _mv88e6xxx_vtu_vid_write (ds , vlan .vid );
1991
2069
if (err )
@@ -2286,9 +2364,13 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
2286
2364
if (ret )
2287
2365
goto abort ;
2288
2366
2289
- /* Port based VLAN map: do not give each port its own address
2367
+ /* Port based VLAN map: give each port its own address
2290
2368
* database, and allow every port to egress frames on all other ports.
2291
2369
*/
2370
+ ret = _mv88e6xxx_port_fid_set (ds , port , port + 1 );
2371
+ if (ret )
2372
+ goto abort ;
2373
+
2292
2374
reg = BIT (ps -> num_ports ) - 1 ; /* all ports */
2293
2375
reg &= ~BIT (port ); /* except itself */
2294
2376
ret = _mv88e6xxx_port_vlan_map_set (ds , port , reg );
0 commit comments