Skip to content

Commit 161087d

Browse files
danish-tiPaolo Abeni
authored andcommitted
net: ti: icssg-prueth: Add Support for Multicast filtering with VLAN in HSR mode
Add multicast filtering support for VLAN interfaces in HSR offload mode for ICSSG driver. The driver calls vlan_for_each() API on the hsr device's ndev to get the list of available vlans for the hsr device. The driver then sync mc addr of vlan interface with a locally mainatined list emac->vlan_mcast_list[vid] using __hw_addr_sync_multiple() API. The driver then calls the sync / unsync callbacks. In the sync / unsync call back, driver checks if the vdev's real dev is hsr device or not. If the real dev is hsr device, driver gets the per port device using hsr_get_port_ndev() and then driver passes appropriate vid to FDB helper functions. Signed-off-by: MD Danish Anwar <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 9c10dd8 commit 161087d

File tree

2 files changed

+66
-19
lines changed

2 files changed

+66
-19
lines changed

drivers/net/ethernet/ti/icssg/icssg_prueth.c

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -604,32 +604,66 @@ static int icssg_prueth_del_mcast(struct net_device *ndev, const u8 *addr)
604604
return 0;
605605
}
606606

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)
608609
{
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,
613611
ICSSG_FDB_ENTRY_P0_MEMBERSHIP |
614612
ICSSG_FDB_ENTRY_P1_MEMBERSHIP |
615613
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+
}
617642

618-
icssg_vtbl_modify(emac, emac->port_vlan, BIT(emac->port_id),
619-
BIT(emac->port_id), true);
620643
return 0;
621644
}
622645

623646
static int icssg_prueth_hsr_del_mcast(struct net_device *ndev, const u8 *addr)
624647
{
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;
627651

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+
}
633667

634668
return 0;
635669
}
@@ -647,8 +681,14 @@ static int icssg_update_vlan_mcast(struct net_device *vdev, int vid,
647681
vdev->addr_len);
648682
netif_addr_unlock_bh(vdev);
649683

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);
652692

653693
return 0;
654694
}
@@ -893,6 +933,11 @@ static void emac_ndo_set_rx_mode_work(struct work_struct *work)
893933
if (emac->prueth->is_hsr_offload_mode) {
894934
__dev_mc_sync(ndev, icssg_prueth_hsr_add_mcast,
895935
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+
}
896941
} else {
897942
__dev_mc_sync(ndev, icssg_prueth_add_mcast,
898943
icssg_prueth_del_mcast);
@@ -1290,7 +1335,7 @@ static int prueth_netdevice_port_link(struct net_device *ndev,
12901335
if (prueth->br_members & BIT(PRUETH_PORT_MII0) &&
12911336
prueth->br_members & BIT(PRUETH_PORT_MII1)) {
12921337
prueth->is_switch_mode = true;
1293-
prueth->default_vlan = 1;
1338+
prueth->default_vlan = PRUETH_DFLT_VLAN_SW;
12941339
emac->port_vlan = prueth->default_vlan;
12951340
icssg_change_mode(prueth);
12961341
}
@@ -1348,7 +1393,7 @@ static int prueth_hsr_port_link(struct net_device *ndev)
13481393
NETIF_PRUETH_HSR_OFFLOAD_FEATURES))
13491394
return -EOPNOTSUPP;
13501395
prueth->is_hsr_offload_mode = true;
1351-
prueth->default_vlan = 1;
1396+
prueth->default_vlan = PRUETH_DFLT_VLAN_HSR;
13521397
emac0->port_vlan = prueth->default_vlan;
13531398
emac1->port_vlan = prueth->default_vlan;
13541399
icssg_change_mode(prueth);

drivers/net/ethernet/ti/icssg/icssg_prueth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@
8484
#define ICSS_CMD_ADD_MAC 0x8
8585

8686
/* VLAN Filtering Related MACROs */
87+
#define PRUETH_DFLT_VLAN_HSR 1
88+
#define PRUETH_DFLT_VLAN_SW 1
8789
#define PRUETH_DFLT_VLAN_MAC 0
8890
#define MAX_VLAN_ID 256
8991

0 commit comments

Comments
 (0)