@@ -3278,13 +3280,11 @@ static void macb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct macb *bp = netdev_priv(netdev);
- if (bp->wol & MACB_WOL_HAS_MAGIC_PACKET) {
- phylink_ethtool_get_wol(bp->phylink, wol);
- wol->supported |= WAKE_MAGIC;
-
- if (bp->wol & MACB_WOL_ENABLED)
- wol->wolopts |= WAKE_MAGIC;
- }
+ phylink_ethtool_get_wol(bp->phylink, wol);
So you ask the PHY what it supports, and what it currently has
enabled.
+ wol->supported |= (bp->wol & MACB_WOL_HAS_MAGIC_PACKET) ? WAKE_MAGIC : 0;
+ wol->supported |= (bp->wol & MACB_WOL_HAS_ARP_PACKET) ? WAKE_ARP : 0;
You mask in what the MAC supports.
+ /* Pass wolopts to ethtool */
+ wol->wolopts = bp->wolopts;
And then you overwrite what the PHY is currently doing with
bp->wolopts.
Now, if we look at what macb_set_wol does:
@@ -3300,11 +3300,10 @@ static int macb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
if (!ret || ret != -EOPNOTSUPP)
return ret;
We are a little bit short of context here. This is checking the return
value of:
ret = phylink_ethtool_set_wol(bp->phylink, wol);
So if there is no error, or an error which is not EOPNOTSUPP, it
returns here. So if the PHY supports WAKE_MAGIC and/or WAKE_ARP, there
is nothing for the MAC to do. Importantly, the code below which sets
bp->wolopts is not reached.
So your get_wol looks wrong.
- if (!(bp->wol & MACB_WOL_HAS_MAGIC_PACKET) ||
- (wol->wolopts & ~WAKE_MAGIC))
- return -EOPNOTSUPP;
+ bp->wolopts = (wol->wolopts & WAKE_MAGIC) ? WAKE_MAGIC : 0;
+ bp->wolopts |= (wol->wolopts & WAKE_ARP) ? WAKE_ARP : 0;
- if (wol->wolopts & WAKE_MAGIC)
+ if (bp->wolopts)
bp->wol |= MACB_WOL_ENABLED;
else
bp->wol &= ~MACB_WOL_ENABLED;
@@ -5085,10 +5084,8 @@ static int macb_probe(struct platform_device *pdev)
else
bp->max_tx_length = GEM_MAX_TX_LEN;
@@ -5257,6 +5255,12 @@ static int __maybe_unused macb_suspend(struct device *dev)
return 0;
if (bp->wol & MACB_WOL_ENABLED) {
+ /* Check for IP address in WOL ARP mode */
+ ifa = rcu_dereference(__in_dev_get_rcu(bp->dev)->ifa_list);
+ if ((bp->wolopts & WAKE_ARP) && !ifa) {
+ netdev_err(netdev, "IP address not assigned\n");
+ return -EOPNOTSUPP;
+ }
I don't know suspend too well. Is returning an error enough abort the
suspend?
Andrew