@@ -467,7 +467,7 @@ static int bcm_sf2_fast_age_op(struct bcm_sf2_priv *priv)
467467 u32 reg ;
468468
469469 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 ;
471471 core_writel (priv , reg , CORE_FAST_AGE_CTRL );
472472
473473 do {
@@ -498,13 +498,86 @@ static int bcm_sf2_sw_fast_age_port(struct dsa_switch *ds, int port)
498498 return bcm_sf2_fast_age_op (priv );
499499}
500500
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+
501564static int bcm_sf2_sw_br_join (struct dsa_switch * ds , int port ,
502565 struct net_device * bridge )
503566{
504567 struct bcm_sf2_priv * priv = ds_to_priv (ds );
568+ s8 cpu_port = ds -> dst -> cpu_port ;
505569 unsigned int i ;
506570 u32 reg , p_ctl ;
507571
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+
508581 priv -> port_sts [port ].bridge_dev = bridge ;
509582 p_ctl = core_readl (priv , CORE_PORT_VLAN_CTL_PORT (port ));
510583
@@ -536,6 +609,7 @@ static void bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
536609{
537610 struct bcm_sf2_priv * priv = ds_to_priv (ds );
538611 struct net_device * bridge = priv -> port_sts [port ].bridge_dev ;
612+ s8 cpu_port = ds -> dst -> cpu_port ;
539613 unsigned int i ;
540614 u32 reg , p_ctl ;
541615
@@ -559,6 +633,13 @@ static void bcm_sf2_sw_br_leave(struct dsa_switch *ds, int port)
559633 core_writel (priv , p_ctl , CORE_PORT_VLAN_CTL_PORT (port ));
560634 priv -> port_sts [port ].vlan_ctl_mask = p_ctl ;
561635 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 );
562643}
563644
564645static 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,
13121393 return p -> ethtool_ops -> set_wol (p , wol );
13131394}
13141395
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+
13151572static int bcm_sf2_sw_setup (struct dsa_switch * ds )
13161573{
13171574 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)
14031660 bcm_sf2_port_disable (ds , port , NULL );
14041661 }
14051662
1663+ bcm_sf2_sw_configure_vlan (ds );
1664+
14061665 rev = reg_readl (priv , REG_SWITCH_REVISION );
14071666 priv -> hw_params .top_rev = (rev >> SWITCH_TOP_REV_SHIFT ) &
14081667 SWITCH_TOP_REV_MASK ;
@@ -1457,6 +1716,11 @@ static struct dsa_switch_driver bcm_sf2_switch_driver = {
14571716 .port_fdb_add = bcm_sf2_sw_fdb_add ,
14581717 .port_fdb_del = bcm_sf2_sw_fdb_del ,
14591718 .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 ,
14601724};
14611725
14621726static int __init bcm_sf2_init (void )
0 commit comments