@@ -604,32 +604,66 @@ static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
604
604
return 0 ;
605
605
}
606
606
607
- static int icssg_prueth_hsr_add_mcast (struct net_device * ndev , const u8 * addr )
607
+ static void icssg_prueth_hsr_fdb_add_del (struct prueth_emac * emac ,
608
+ const u8 * addr , u8 vid , bool add )
608
609
{
609
- struct prueth_emac * emac = netdev_priv (ndev );
610
- struct prueth * prueth = emac -> prueth ;
611
-
612
- icssg_fdb_add_del (emac , addr , prueth -> default_vlan ,
610
+ icssg_fdb_add_del (emac , addr , vid ,
613
611
ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
614
612
ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
615
613
ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
616
- ICSSG_FDB_ENTRY_BLOCK , true);
614
+ ICSSG_FDB_ENTRY_BLOCK , add );
615
+
616
+ if (add )
617
+ icssg_vtbl_modify (emac , vid , BIT (emac -> port_id ),
618
+ BIT (emac -> port_id ), add );
619
+ }
620
+
621
+ static int icssg_prueth_hsr_add_mcast (struct net_device * ndev , const u8 * addr )
622
+ {
623
+ struct net_device * real_dev ;
624
+ struct prueth_emac * emac ;
625
+ u8 vlan_id , i ;
626
+
627
+ vlan_id = is_vlan_dev (ndev ) ? vlan_dev_vlan_id (ndev ) : PRUETH_DFLT_VLAN_HSR ;
628
+ real_dev = is_vlan_dev (ndev ) ? vlan_dev_real_dev (ndev ) : ndev ;
629
+
630
+ if (is_hsr_master (real_dev )) {
631
+ for (i = HSR_PT_SLAVE_A ; i < HSR_PT_INTERLINK ; i ++ ) {
632
+ emac = netdev_priv (hsr_get_port_ndev (real_dev , i ));
633
+ if (!emac )
634
+ return - EINVAL ;
635
+ icssg_prueth_hsr_fdb_add_del (emac , addr , vlan_id ,
636
+ true);
637
+ }
638
+ } else {
639
+ emac = netdev_priv (real_dev );
640
+ icssg_prueth_hsr_fdb_add_del (emac , addr , vlan_id , true);
641
+ }
617
642
618
- icssg_vtbl_modify (emac , emac -> port_vlan , BIT (emac -> port_id ),
619
- BIT (emac -> port_id ), true);
620
643
return 0 ;
621
644
}
622
645
623
646
static int icssg_prueth_hsr_del_mcast (struct net_device * ndev , const u8 * addr )
624
647
{
625
- struct prueth_emac * emac = netdev_priv (ndev );
626
- struct prueth * prueth = emac -> prueth ;
648
+ struct net_device * real_dev ;
649
+ struct prueth_emac * emac ;
650
+ u8 vlan_id , i ;
627
651
628
- icssg_fdb_add_del (emac , addr , prueth -> default_vlan ,
629
- ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
630
- ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
631
- ICSSG_FDB_ENTRY_P2_MEMBERSHIP |
632
- ICSSG_FDB_ENTRY_BLOCK , false);
652
+ vlan_id = is_vlan_dev (ndev ) ? vlan_dev_vlan_id (ndev ) : PRUETH_DFLT_VLAN_HSR ;
653
+ real_dev = is_vlan_dev (ndev ) ? vlan_dev_real_dev (ndev ) : ndev ;
654
+
655
+ if (is_hsr_master (real_dev )) {
656
+ for (i = HSR_PT_SLAVE_A ; i < HSR_PT_INTERLINK ; i ++ ) {
657
+ emac = netdev_priv (hsr_get_port_ndev (real_dev , i ));
658
+ if (!emac )
659
+ return - EINVAL ;
660
+ icssg_prueth_hsr_fdb_add_del (emac , addr , vlan_id ,
661
+ false);
662
+ }
663
+ } else {
664
+ emac = netdev_priv (real_dev );
665
+ icssg_prueth_hsr_fdb_add_del (emac , addr , vlan_id , false);
666
+ }
633
667
634
668
return 0 ;
635
669
}
@@ -647,8 +681,14 @@ static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
647
681
vdev -> addr_len );
648
682
netif_addr_unlock_bh (vdev );
649
683
650
- __hw_addr_sync_dev (& emac -> vlan_mcast_list [vid ], vdev ,
651
- icssg_prueth_add_mcast , icssg_prueth_del_mcast );
684
+ if (emac -> prueth -> is_hsr_offload_mode )
685
+ __hw_addr_sync_dev (& emac -> vlan_mcast_list [vid ], vdev ,
686
+ icssg_prueth_hsr_add_mcast ,
687
+ icssg_prueth_hsr_del_mcast );
688
+ else
689
+ __hw_addr_sync_dev (& emac -> vlan_mcast_list [vid ], vdev ,
690
+ icssg_prueth_add_mcast ,
691
+ icssg_prueth_del_mcast );
652
692
653
693
return 0 ;
654
694
}
@@ -893,6 +933,11 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
893
933
if (emac -> prueth -> is_hsr_offload_mode ) {
894
934
__dev_mc_sync (ndev , icssg_prueth_hsr_add_mcast ,
895
935
icssg_prueth_hsr_del_mcast );
936
+ if (rtnl_trylock ()) {
937
+ vlan_for_each (emac -> prueth -> hsr_dev ,
938
+ icssg_update_vlan_mcast , emac );
939
+ rtnl_unlock ();
940
+ }
896
941
} else {
897
942
__dev_mc_sync (ndev , icssg_prueth_add_mcast ,
898
943
icssg_prueth_del_mcast );
@@ -1290,7 +1335,7 @@ static int prueth_netdevice_port_link(struct net_device *ndev,
1290
1335
if (prueth -> br_members & BIT (PRUETH_PORT_MII0 ) &&
1291
1336
prueth -> br_members & BIT (PRUETH_PORT_MII1 )) {
1292
1337
prueth -> is_switch_mode = true;
1293
- prueth -> default_vlan = 1 ;
1338
+ prueth -> default_vlan = PRUETH_DFLT_VLAN_SW ;
1294
1339
emac -> port_vlan = prueth -> default_vlan ;
1295
1340
icssg_change_mode (prueth );
1296
1341
}
@@ -1348,7 +1393,7 @@ static int prueth_hsr_port_link(struct net_device *ndev)
1348
1393
NETIF_PRUETH_HSR_OFFLOAD_FEATURES ))
1349
1394
return - EOPNOTSUPP ;
1350
1395
prueth -> is_hsr_offload_mode = true;
1351
- prueth -> default_vlan = 1 ;
1396
+ prueth -> default_vlan = PRUETH_DFLT_VLAN_HSR ;
1352
1397
emac0 -> port_vlan = prueth -> default_vlan ;
1353
1398
emac1 -> port_vlan = prueth -> default_vlan ;
1354
1399
icssg_change_mode (prueth );
0 commit comments