@@ -467,7 +467,7 @@ static int bcm_sf2_fast_age_op(struct bcm_sf2_priv *priv)
467
467
u32 reg ;
468
468
469
469
reg = core_readl (priv , CORE_FAST_AGE_CTRL );
470
- reg |= EN_AGE_PORT | EN_AGE_DYNAMIC | FAST_AGE_STR_DONE ;
470
+ reg |= EN_AGE_PORT | EN_AGE_VLAN | EN_AGE_DYNAMIC | FAST_AGE_STR_DONE ;
471
471
core_writel (priv , reg , CORE_FAST_AGE_CTRL );
472
472
473
473
do {
@@ -498,13 +498,86 @@ static int bcm_sf2_sw_fast_age_port(struct dsa_switch *ds, int port)
498
498
return bcm_sf2_fast_age_op (priv );
499
499
}
500
500
501
+ static int bcm_sf2_sw_fast_age_vlan (struct bcm_sf2_priv * priv , u16 vid )
502
+ {
503
+ core_writel (priv , vid , CORE_FAST_AGE_VID );
504
+
505
+ return bcm_sf2_fast_age_op (priv );
506
+ }
507
+
508
+ static int bcm_sf2_vlan_op_wait (struct bcm_sf2_priv * priv )
509
+ {
510
+ unsigned int timeout = 10 ;
511
+ u32 reg ;
512
+
513
+ do {
514
+ reg = core_readl (priv , CORE_ARLA_VTBL_RWCTRL );
515
+ if (!(reg & ARLA_VTBL_STDN ))
516
+ return 0 ;
517
+
518
+ usleep_range (1000 , 2000 );
519
+ } while (timeout -- );
520
+
521
+ return - ETIMEDOUT ;
522
+ }
523
+
524
+ static int bcm_sf2_vlan_op (struct bcm_sf2_priv * priv , u8 op )
525
+ {
526
+ core_writel (priv , ARLA_VTBL_STDN | op , CORE_ARLA_VTBL_RWCTRL );
527
+
528
+ return bcm_sf2_vlan_op_wait (priv );
529
+ }
530
+
531
+ static void bcm_sf2_set_vlan_entry (struct bcm_sf2_priv * priv , u16 vid ,
532
+ struct bcm_sf2_vlan * vlan )
533
+ {
534
+ int ret ;
535
+
536
+ core_writel (priv , vid & VTBL_ADDR_INDEX_MASK , CORE_ARLA_VTBL_ADDR );
537
+ core_writel (priv , vlan -> untag << UNTAG_MAP_SHIFT | vlan -> members ,
538
+ CORE_ARLA_VTBL_ENTRY );
539
+
540
+ ret = bcm_sf2_vlan_op (priv , ARLA_VTBL_CMD_WRITE );
541
+ if (ret )
542
+ pr_err ("failed to write VLAN entry\n" );
543
+ }
544
+
545
+ static int bcm_sf2_get_vlan_entry (struct bcm_sf2_priv * priv , u16 vid ,
546
+ struct bcm_sf2_vlan * vlan )
547
+ {
548
+ u32 entry ;
549
+ int ret ;
550
+
551
+ core_writel (priv , vid & VTBL_ADDR_INDEX_MASK , CORE_ARLA_VTBL_ADDR );
552
+
553
+ ret = bcm_sf2_vlan_op (priv , ARLA_VTBL_CMD_READ );
554
+ if (ret )
555
+ return ret ;
556
+
557
+ entry = core_readl (priv , CORE_ARLA_VTBL_ENTRY );
558
+ vlan -> members = entry & FWD_MAP_MASK ;
559
+ vlan -> untag = (entry >> UNTAG_MAP_SHIFT ) & UNTAG_MAP_MASK ;
560
+
561
+ return 0 ;
562
+ }
563
+
501
564
static int bcm_sf2_sw_br_join (struct dsa_switch * ds , int port ,
502
565
struct net_device * bridge )
503
566
{
504
567
struct bcm_sf2_priv * priv = ds_to_priv (ds );
568
+ s8 cpu_port = ds -> dst -> cpu_port ;
505
569
unsigned int i ;
506
570
u32 reg , p_ctl ;
507
571
572
+ /* Make this port leave the all VLANs join since we will have proper
573
+ * VLAN entries from now on
574
+ */
575
+ reg = core_readl (priv , CORE_JOIN_ALL_VLAN_EN );
576
+ reg &= ~BIT (port );
577
+ if ((reg & BIT (cpu_port )) == BIT (cpu_port ))
578
+ reg &= ~BIT (cpu_port );
579
+ core_writel (priv , reg , CORE_JOIN_ALL_VLAN_EN );
580
+
508
581
priv -> port_sts [port ].bridge_dev = bridge ;
509
582
p_ctl = core_readl (priv , CORE_PORT_VLAN_CTL_PORT (port ));
510
583
@@ -536,6 +609,7 @@ static void bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
536
609
{
537
610
struct bcm_sf2_priv * priv = ds_to_priv (ds );
538
611
struct net_device * bridge = priv -> port_sts [port ].bridge_dev ;
612
+ s8 cpu_port = ds -> dst -> cpu_port ;
539
613
unsigned int i ;
540
614
u32 reg , p_ctl ;
541
615
@@ -559,6 +633,13 @@ static void bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
559
633
core_writel (priv , p_ctl , CORE_PORT_VLAN_CTL_PORT (port ));
560
634
priv -> port_sts [port ].vlan_ctl_mask = p_ctl ;
561
635
priv -> port_sts [port ].bridge_dev = NULL ;
636
+
637
+ /* Make this port join all VLANs without VLAN entries */
638
+ reg = core_readl (priv , CORE_JOIN_ALL_VLAN_EN );
639
+ reg |= BIT (port );
640
+ if (!(reg & BIT (cpu_port )))
641
+ reg |= BIT (cpu_port );
642
+ core_writel (priv , reg , CORE_JOIN_ALL_VLAN_EN );
562
643
}
563
644
564
645
static void bcm_sf2_sw_br_set_stp_state (struct dsa_switch * ds , int port ,
@@ -1312,6 +1393,182 @@ static int bcm_sf2_sw_set_wol(struct dsa_switch *ds, int port,
1312
1393
return p -> ethtool_ops -> set_wol (p , wol );
1313
1394
}
1314
1395
1396
+ static void bcm_sf2_enable_vlan (struct bcm_sf2_priv * priv , bool enable )
1397
+ {
1398
+ u32 mgmt , vc0 , vc1 , vc4 , vc5 ;
1399
+
1400
+ mgmt = core_readl (priv , CORE_SWMODE );
1401
+ vc0 = core_readl (priv , CORE_VLAN_CTRL0 );
1402
+ vc1 = core_readl (priv , CORE_VLAN_CTRL1 );
1403
+ vc4 = core_readl (priv , CORE_VLAN_CTRL4 );
1404
+ vc5 = core_readl (priv , CORE_VLAN_CTRL5 );
1405
+
1406
+ mgmt &= ~SW_FWDG_MODE ;
1407
+
1408
+ if (enable ) {
1409
+ vc0 |= VLAN_EN | VLAN_LEARN_MODE_IVL ;
1410
+ vc1 |= EN_RSV_MCAST_UNTAG | EN_RSV_MCAST_FWDMAP ;
1411
+ vc4 &= ~(INGR_VID_CHK_MASK << INGR_VID_CHK_SHIFT );
1412
+ vc4 |= INGR_VID_CHK_DROP ;
1413
+ vc5 |= DROP_VTABLE_MISS | EN_VID_FFF_FWD ;
1414
+ } else {
1415
+ vc0 &= ~(VLAN_EN | VLAN_LEARN_MODE_IVL );
1416
+ vc1 &= ~(EN_RSV_MCAST_UNTAG | EN_RSV_MCAST_FWDMAP );
1417
+ vc4 &= ~(INGR_VID_CHK_MASK << INGR_VID_CHK_SHIFT );
1418
+ vc5 &= ~(DROP_VTABLE_MISS | EN_VID_FFF_FWD );
1419
+ vc4 |= INGR_VID_CHK_VID_VIOL_IMP ;
1420
+ }
1421
+
1422
+ core_writel (priv , vc0 , CORE_VLAN_CTRL0 );
1423
+ core_writel (priv , vc1 , CORE_VLAN_CTRL1 );
1424
+ core_writel (priv , 0 , CORE_VLAN_CTRL3 );
1425
+ core_writel (priv , vc4 , CORE_VLAN_CTRL4 );
1426
+ core_writel (priv , vc5 , CORE_VLAN_CTRL5 );
1427
+ core_writel (priv , mgmt , CORE_SWMODE );
1428
+ }
1429
+
1430
+ static void bcm_sf2_sw_configure_vlan (struct dsa_switch * ds )
1431
+ {
1432
+ struct bcm_sf2_priv * priv = ds_to_priv (ds );
1433
+ unsigned int port ;
1434
+
1435
+ /* Clear all VLANs */
1436
+ bcm_sf2_vlan_op (priv , ARLA_VTBL_CMD_CLEAR );
1437
+
1438
+ for (port = 0 ; port < priv -> hw_params .num_ports ; port ++ ) {
1439
+ if (!((1 << port ) & ds -> enabled_port_mask ))
1440
+ continue ;
1441
+
1442
+ core_writel (priv , 1 , CORE_DEFAULT_1Q_TAG_P (port ));
1443
+ }
1444
+ }
1445
+
1446
+ static int bcm_sf2_sw_vlan_filtering (struct dsa_switch * ds , int port ,
1447
+ bool vlan_filtering )
1448
+ {
1449
+ return 0 ;
1450
+ }
1451
+
1452
+ static int bcm_sf2_sw_vlan_prepare (struct dsa_switch * ds , int port ,
1453
+ const struct switchdev_obj_port_vlan * vlan ,
1454
+ struct switchdev_trans * trans )
1455
+ {
1456
+ struct bcm_sf2_priv * priv = ds_to_priv (ds );
1457
+
1458
+ bcm_sf2_enable_vlan (priv , true);
1459
+
1460
+ return 0 ;
1461
+ }
1462
+
1463
+ static void bcm_sf2_sw_vlan_add (struct dsa_switch * ds , int port ,
1464
+ const struct switchdev_obj_port_vlan * vlan ,
1465
+ struct switchdev_trans * trans )
1466
+ {
1467
+ struct bcm_sf2_priv * priv = ds_to_priv (ds );
1468
+ bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
1469
+ bool pvid = vlan -> flags & BRIDGE_VLAN_INFO_PVID ;
1470
+ s8 cpu_port = ds -> dst -> cpu_port ;
1471
+ struct bcm_sf2_vlan * vl ;
1472
+ u16 vid ;
1473
+
1474
+ for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; ++ vid ) {
1475
+ vl = & priv -> vlans [vid ];
1476
+
1477
+ bcm_sf2_get_vlan_entry (priv , vid , vl );
1478
+
1479
+ vl -> members |= BIT (port ) | BIT (cpu_port );
1480
+ if (untagged )
1481
+ vl -> untag |= BIT (port ) | BIT (cpu_port );
1482
+ else
1483
+ vl -> untag &= ~(BIT (port ) | BIT (cpu_port ));
1484
+
1485
+ bcm_sf2_set_vlan_entry (priv , vid , vl );
1486
+ bcm_sf2_sw_fast_age_vlan (priv , vid );
1487
+ }
1488
+
1489
+ if (pvid ) {
1490
+ core_writel (priv , vlan -> vid_end , CORE_DEFAULT_1Q_TAG_P (port ));
1491
+ core_writel (priv , vlan -> vid_end ,
1492
+ CORE_DEFAULT_1Q_TAG_P (cpu_port ));
1493
+ bcm_sf2_sw_fast_age_vlan (priv , vid );
1494
+ }
1495
+ }
1496
+
1497
+ static int bcm_sf2_sw_vlan_del (struct dsa_switch * ds , int port ,
1498
+ const struct switchdev_obj_port_vlan * vlan )
1499
+ {
1500
+ struct bcm_sf2_priv * priv = ds_to_priv (ds );
1501
+ bool untagged = vlan -> flags & BRIDGE_VLAN_INFO_UNTAGGED ;
1502
+ s8 cpu_port = ds -> dst -> cpu_port ;
1503
+ struct bcm_sf2_vlan * vl ;
1504
+ u16 vid , pvid ;
1505
+ int ret ;
1506
+
1507
+ pvid = core_readl (priv , CORE_DEFAULT_1Q_TAG_P (port ));
1508
+
1509
+ for (vid = vlan -> vid_begin ; vid <= vlan -> vid_end ; ++ vid ) {
1510
+ vl = & priv -> vlans [vid ];
1511
+
1512
+ ret = bcm_sf2_get_vlan_entry (priv , vid , vl );
1513
+ if (ret )
1514
+ return ret ;
1515
+
1516
+ vl -> members &= ~BIT (port );
1517
+ if ((vl -> members & BIT (cpu_port )) == BIT (cpu_port ))
1518
+ vl -> members = 0 ;
1519
+ if (pvid == vid )
1520
+ pvid = 0 ;
1521
+ if (untagged ) {
1522
+ vl -> untag &= ~BIT (port );
1523
+ if ((vl -> untag & BIT (port )) == BIT (cpu_port ))
1524
+ vl -> untag = 0 ;
1525
+ }
1526
+
1527
+ bcm_sf2_set_vlan_entry (priv , vid , vl );
1528
+ bcm_sf2_sw_fast_age_vlan (priv , vid );
1529
+ }
1530
+
1531
+ core_writel (priv , pvid , CORE_DEFAULT_1Q_TAG_P (port ));
1532
+ core_writel (priv , pvid , CORE_DEFAULT_1Q_TAG_P (cpu_port ));
1533
+ bcm_sf2_sw_fast_age_vlan (priv , vid );
1534
+
1535
+ return 0 ;
1536
+ }
1537
+
1538
+ static int bcm_sf2_sw_vlan_dump (struct dsa_switch * ds , int port ,
1539
+ struct switchdev_obj_port_vlan * vlan ,
1540
+ int (* cb )(struct switchdev_obj * obj ))
1541
+ {
1542
+ struct bcm_sf2_priv * priv = ds_to_priv (ds );
1543
+ struct bcm_sf2_port_status * p = & priv -> port_sts [port ];
1544
+ struct bcm_sf2_vlan * vl ;
1545
+ u16 vid , pvid ;
1546
+ int err = 0 ;
1547
+
1548
+ pvid = core_readl (priv , CORE_DEFAULT_1Q_TAG_P (port ));
1549
+
1550
+ for (vid = 0 ; vid < VLAN_N_VID ; vid ++ ) {
1551
+ vl = & priv -> vlans [vid ];
1552
+
1553
+ if (!(vl -> members & BIT (port )))
1554
+ continue ;
1555
+
1556
+ vlan -> vid_begin = vlan -> vid_end = vid ;
1557
+ vlan -> flags = 0 ;
1558
+
1559
+ if (vl -> untag & BIT (port ))
1560
+ vlan -> flags |= BRIDGE_VLAN_INFO_UNTAGGED ;
1561
+ if (p -> pvid == vid )
1562
+ vlan -> flags |= BRIDGE_VLAN_INFO_PVID ;
1563
+
1564
+ err = cb (& vlan -> obj );
1565
+ if (err )
1566
+ break ;
1567
+ }
1568
+
1569
+ return err ;
1570
+ }
1571
+
1315
1572
static int bcm_sf2_sw_setup (struct dsa_switch * ds )
1316
1573
{
1317
1574
const char * reg_names [BCM_SF2_REGS_NUM ] = BCM_SF2_REGS_NAME ;
@@ -1403,6 +1660,8 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
1403
1660
bcm_sf2_port_disable (ds , port , NULL );
1404
1661
}
1405
1662
1663
+ bcm_sf2_sw_configure_vlan (ds );
1664
+
1406
1665
rev = reg_readl (priv , REG_SWITCH_REVISION );
1407
1666
priv -> hw_params .top_rev = (rev >> SWITCH_TOP_REV_SHIFT ) &
1408
1667
SWITCH_TOP_REV_MASK ;
@@ -1457,6 +1716,11 @@ static struct dsa_switch_driver bcm_sf2_switch_driver = {
1457
1716
.port_fdb_add = bcm_sf2_sw_fdb_add ,
1458
1717
.port_fdb_del = bcm_sf2_sw_fdb_del ,
1459
1718
.port_fdb_dump = bcm_sf2_sw_fdb_dump ,
1719
+ .port_vlan_filtering = bcm_sf2_sw_vlan_filtering ,
1720
+ .port_vlan_prepare = bcm_sf2_sw_vlan_prepare ,
1721
+ .port_vlan_add = bcm_sf2_sw_vlan_add ,
1722
+ .port_vlan_del = bcm_sf2_sw_vlan_del ,
1723
+ .port_vlan_dump = bcm_sf2_sw_vlan_dump ,
1460
1724
};
1461
1725
1462
1726
static int __init bcm_sf2_init (void )
0 commit comments