]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
net: bcmgenet: Correct overlaying of PHY and MAC Wake-on-LAN
authorFlorian Fainelli <florian.fainelli@broadcom.com>
Wed, 29 Jan 2025 23:13:42 +0000 (15:13 -0800)
committerJakub Kicinski <kuba@kernel.org>
Sun, 2 Feb 2025 00:53:33 +0000 (16:53 -0800)
Some Wake-on-LAN modes such as WAKE_FILTER may only be supported by the MAC,
while others might be only supported by the PHY. Make sure that the .get_wol()
returns the union of both rather than only that of the PHY if the PHY supports
Wake-on-LAN.

When disabling Wake-on-LAN, make sure that this is done at both the PHY
and MAC level, rather than doing an early return from the PHY driver.

Fixes: 7e400ff35cbe ("net: bcmgenet: Add support for PHY-based Wake-on-LAN")
Fixes: 9ee09edc05f2 ("net: bcmgenet: Properly overlay PHY and MAC Wake-on-LAN capabilities")
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20250129231342.35013-1-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c

index 0715ea5bf13ed9df75eeb4f50e99ada8cef631e9..3b082114f2e538a1a258e782e589dfc918ddacac 100644 (file)
@@ -41,9 +41,12 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
        struct bcmgenet_priv *priv = netdev_priv(dev);
        struct device *kdev = &priv->pdev->dev;
+       u32 phy_wolopts = 0;
 
-       if (dev->phydev)
+       if (dev->phydev) {
                phy_ethtool_get_wol(dev->phydev, wol);
+               phy_wolopts = wol->wolopts;
+       }
 
        /* MAC is not wake-up capable, return what the PHY does */
        if (!device_can_wakeup(kdev))
@@ -51,9 +54,14 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 
        /* Overlay MAC capabilities with that of the PHY queried before */
        wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
-       wol->wolopts = priv->wolopts;
-       memset(wol->sopass, 0, sizeof(wol->sopass));
+       wol->wolopts |= priv->wolopts;
 
+       /* Return the PHY configured magic password */
+       if (phy_wolopts & WAKE_MAGICSECURE)
+               return;
+
+       /* Otherwise the MAC one */
+       memset(wol->sopass, 0, sizeof(wol->sopass));
        if (wol->wolopts & WAKE_MAGICSECURE)
                memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass));
 }
@@ -70,7 +78,7 @@ int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        /* Try Wake-on-LAN from the PHY first */
        if (dev->phydev) {
                ret = phy_ethtool_set_wol(dev->phydev, wol);
-               if (ret != -EOPNOTSUPP)
+               if (ret != -EOPNOTSUPP && wol->wolopts)
                        return ret;
        }