[PATCH net 08/11] net: au1000: restore receive filtering after MAC initialization
From: Florian Fainelli
Date: Tue Oct 27 2026 - 18:33:16 EST
MAC initialization overwrites the receive mode, dropping promiscuous and
multicast settings after a watchdog reset without notifying the network
stack. Reapply the current netdev receive mode after initialization.
Protect the control register read-modify-write with the device lock so
it cannot overwrite a concurrent link adjustment or MAC stop.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Florian Fainelli <f.fainelli@xxxxxxxxx>
---
drivers/net/ethernet/amd/au1000_eth.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index f8976e324f0e..6b817d18329b 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -684,6 +684,8 @@ static const struct ethtool_ops au1000_ethtool_ops = {
.set_link_ksettings = phy_ethtool_set_link_ksettings,
};
+static void au1000_multicast_list(struct net_device *dev);
+
/*
* Initialize the interface.
*
@@ -742,6 +744,9 @@ static int au1000_init(struct net_device *dev)
wmb(); /* drain writebuffer */
spin_unlock_irqrestore(&aup->lock, flags);
+ netif_addr_lock_bh(dev);
+ au1000_multicast_list(dev);
+ netif_addr_unlock_bh(dev);
return 0;
}
@@ -1038,8 +1043,10 @@ static void au1000_multicast_list(struct net_device *dev)
{
struct au1000_private *aup = netdev_priv(dev);
u32 reg;
+ unsigned long flags;
netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags);
+ spin_lock_irqsave(&aup->lock, flags);
reg = readl(&aup->mac->control);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
reg |= MAC_PROMISCUOUS;
@@ -1062,6 +1069,7 @@ static void au1000_multicast_list(struct net_device *dev)
reg |= MAC_HASH_MODE;
}
writel(reg, &aup->mac->control);
+ spin_unlock_irqrestore(&aup->lock, flags);
}
static const struct net_device_ops au1000_netdev_ops = {
--
2.53.0