mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net-next] net: phy: air_an8801: add WAKE_PHY Wake-on-LAN support
@ 2026-11-02 13:29 Tommy Shih
  2026-11-03 13:29 ` Andrew Lunn
  0 siblings, 1 reply; 4+ messages in thread
From: Tommy Shih @ 2026-11-02 13:29 UTC (permalink / raw)
  To: netdev
  Cc: Louis-Alexis Eyraud, AngeloGioacchino Del Regno, Daniel Golle,
	Lucien . Jheng, Andrew Lunn, David S. Miller, Eric Dumazet,
	Heiner Kallweit, Jakub Kicinski, Paolo Abeni, Russell King,
	linux-kernel

The AN8801R can wake up the system on a link change, but the driver
only supports WAKE_MAGIC and always masks the link change event on
suspend. Supporting WAKE_PHY allows the system to be woken up when
the cable is plugged in or unplugged.

Add WAKE_PHY support:
- Keep the link change interrupt enabled, and only disable it on
  suspend when the PHY is set to wake up by magic packet only.
- Report a wakeup event when a link change interrupt is seen with
  WAKE_PHY enabled.
- Enable device wakeup when either WAKE_MAGIC or WAKE_PHY is set.

Signed-off-by: Tommy Shih <tommy.shih92@gmail.com>
---

 drivers/net/phy/air_an8801.c | 38 +++++++++++++++++++++---------------
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/net/phy/air_an8801.c b/drivers/net/phy/air_an8801.c
index f97c78e43023..bf09c1fee398 100644
--- a/drivers/net/phy/air_an8801.c
+++ b/drivers/net/phy/air_an8801.c
@@ -560,7 +560,7 @@ static int an8801r_led_init(struct phy_device *phydev, u8 *led_cfg)
 	return ret;
 }
 
-static int an8801r_reset_wake(struct phy_device *phydev)
+static int an8801r_reset_wake(struct phy_device *phydev, bool suspend)
 {
 	struct an8801r_priv *priv = phydev->priv;
 	u32 reg_val = 0;
@@ -584,7 +584,10 @@ static int an8801r_reset_wake(struct phy_device *phydev)
 	if (priv->wake_magic_enabled)
 		reg_val |= AN8801_WOL_WAKE_MAGIC_EN;
 
-	if (priv->wake_lnkchg_enabled)
+	/* The link change event is needed for link state interrupts while
+	 * running, but must only wake the system up if WAKE_PHY is enabled.
+	 */
+	if (priv->wake_lnkchg_enabled || !suspend)
 		reg_val |= AN8801_WOL_WAKE_LNKCHG_EN;
 
 	ret = an8801_buckpbus_reg_write(phydev, AN8801_BPBUS_REG_WAKEUP_CTL1,
@@ -603,7 +606,7 @@ static int an8801r_ack_interrupt(struct phy_device *phydev)
 	int ret;
 
 	/* Reset wake status */
-	ret = an8801r_reset_wake(phydev);
+	ret = an8801r_reset_wake(phydev, phydev->suspended);
 	if (ret)
 		return ret;
 
@@ -651,6 +654,7 @@ static int an8801r_config_intr(struct phy_device *phydev)
 
 static irqreturn_t an8801r_handle_interrupt(struct phy_device *phydev)
 {
+	struct an8801r_priv *priv = phydev->priv;
 	u32 irq_status = 0;
 	bool irq_handled = false;
 	int ret;
@@ -670,6 +674,8 @@ static irqreturn_t an8801r_handle_interrupt(struct phy_device *phydev)
 	}
 
 	if (irq_status & AN8801_IRQ_WAKE_LNKCHG) {
+		if (priv->wake_lnkchg_enabled)
+			pm_wakeup_event(&phydev->mdio.dev, 0);
 		phy_trigger_machine(phydev);
 		irq_handled = true;
 	}
@@ -680,6 +686,7 @@ static irqreturn_t an8801r_handle_interrupt(struct phy_device *phydev)
 static void an8801r_get_wol(struct phy_device *phydev,
 			    struct ethtool_wolinfo *wol)
 {
+	struct an8801r_priv *priv = phydev->priv;
 	u32 reg_val;
 	int ret;
 
@@ -691,9 +698,12 @@ static void an8801r_get_wol(struct phy_device *phydev,
 		return;
 	}
 
-	wol->supported = WAKE_MAGIC;
+	wol->supported = WAKE_MAGIC | WAKE_PHY;
 	wol->wolopts = 0;
 
+	if (priv->wake_lnkchg_enabled)
+		wol->wolopts |= WAKE_PHY;
+
 	ret = an8801_buckpbus_reg_read(phydev, AN8801_BPBUS_REG_WAKEUP_CTL1,
 				       &reg_val);
 	if (ret)
@@ -717,7 +727,7 @@ static int an8801r_set_wol(struct phy_device *phydev,
 	if (!device_can_wakeup(&phydev->mdio.dev))
 		return -EOPNOTSUPP;
 
-	if (wol->wolopts & ~WAKE_MAGIC)
+	if (wol->wolopts & ~(WAKE_MAGIC | WAKE_PHY))
 		return -EINVAL;
 
 	if (wol->wolopts & WAKE_MAGIC) {
@@ -775,9 +785,11 @@ static int an8801r_set_wol(struct phy_device *phydev,
 	}
 
 	priv->wake_magic_enabled = !!(wol->wolopts & WAKE_MAGIC);
+	priv->wake_lnkchg_enabled = !!(wol->wolopts & WAKE_PHY);
 
 	return device_set_wakeup_enable(&phydev->mdio.dev,
-					priv->wake_magic_enabled);
+					priv->wake_magic_enabled ||
+					priv->wake_lnkchg_enabled);
 }
 
 static int an8801r_of_init_leds(struct phy_device *phydev, u8 *led_cfg)
@@ -1040,8 +1052,6 @@ static int an8801r_probe(struct phy_device *phydev)
 	if (!priv)
 		return -ENOMEM;
 
-	priv->wake_lnkchg_enabled = true;
-
 	phydev->priv = priv;
 
 	/* Mark this PHY as wakeup capable and register the interrupt as a
@@ -1063,12 +1073,11 @@ static int an8801r_suspend(struct phy_device *phydev)
 	int ret;
 
 	/* If the PHY may wake up by a Wake-on-LAN (WOL) event, disable the link
-	 * interrupt to only keep the WOL magic interrupt enabled
+	 * interrupt unless wake on link change (WAKE_PHY) is enabled
 	 */
 	if (device_may_wakeup(&phydev->mdio.dev)) {
-		priv->wake_lnkchg_enabled = false;
-
-		if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+		if (!priv->wake_lnkchg_enabled &&
+		    phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 			ret = an8801_buckpbus_reg_clear_bits(phydev,
 							     AN8801_BPBUS_REG_WAKE_IRQ_EN,
 							     AN8801_IRQ_WAKE_LNKCHG);
@@ -1077,7 +1086,7 @@ static int an8801r_suspend(struct phy_device *phydev)
 		}
 
 		/* Reset WOL status */
-		ret = an8801r_reset_wake(phydev);
+		ret = an8801r_reset_wake(phydev, true);
 		if (ret)
 			return ret;
 	}
@@ -1090,7 +1099,6 @@ static int an8801r_suspend(struct phy_device *phydev)
 
 static int an8801r_resume(struct phy_device *phydev)
 {
-	struct an8801r_priv *priv = phydev->priv;
 	int ret;
 
 	ret = genphy_resume(phydev);
@@ -1101,8 +1109,6 @@ static int an8801r_resume(struct phy_device *phydev)
 	 * state interrupts.
 	 */
 	if (device_may_wakeup(&phydev->mdio.dev)) {
-		priv->wake_lnkchg_enabled = true;
-
 		ret = an8801_buckpbus_reg_set_bits(phydev,
 						   AN8801_BPBUS_REG_WAKEUP_CTL1,
 						   AN8801_WOL_WAKE_LNKCHG_EN);
---
base-commit: 4dd16e31135ea8437a720222df34e8745f385d6d
branch: an8801-wake-phy

-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] net: phy: air_an8801: add WAKE_PHY Wake-on-LAN support
  2026-11-02 13:29 [PATCH net-next] net: phy: air_an8801: add WAKE_PHY Wake-on-LAN support Tommy Shih
@ 2026-11-03 13:29 ` Andrew Lunn
  2026-11-05 14:33   ` tommy shih
  0 siblings, 1 reply; 4+ messages in thread
From: Andrew Lunn @ 2026-11-03 13:29 UTC (permalink / raw)
  To: Tommy Shih
  Cc: netdev, Louis-Alexis Eyraud, AngeloGioacchino Del Regno,
	Daniel Golle, Lucien . Jheng, David S. Miller, Eric Dumazet,
	Heiner Kallweit, Jakub Kicinski, Paolo Abeni, Russell King,
	linux-kernel

On Mon, Nov 02, 2026 at 09:29:03PM +0800, Tommy Shih wrote:
> The AN8801R can wake up the system on a link change, but the driver
> only supports WAKE_MAGIC and always masks the link change event on
> suspend. Supporting WAKE_PHY allows the system to be woken up when
> the cable is plugged in or unplugged.
> 
> Add WAKE_PHY support:
> - Keep the link change interrupt enabled, and only disable it on
>   suspend when the PHY is set to wake up by magic packet only.
> - Report a wakeup event when a link change interrupt is seen with
>   WAKE_PHY enabled.
> - Enable device wakeup when either WAKE_MAGIC or WAKE_PHY is set.

This is an interesting definition of WAKE_PHY.

Are there any other drivers which use change in link to trigger a
wake?

How are you using it? Is your device plugged into a manages switch and
you are making the managed switch down/up the link?

Is the hardware capable of waking just on link up? Is there any point
waking up if the link goes down?

	Andrew

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] net: phy: air_an8801: add WAKE_PHY Wake-on-LAN support
  2026-11-03 13:29 ` Andrew Lunn
@ 2026-11-05 14:33   ` tommy shih
  2026-11-05 22:26     ` Andrew Lunn
  0 siblings, 1 reply; 4+ messages in thread
From: tommy shih @ 2026-11-05 14:33 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: netdev, Louis-Alexis Eyraud, AngeloGioacchino Del Regno,
	Daniel Golle, Lucien . Jheng, David S. Miller, Eric Dumazet,
	Heiner Kallweit, Jakub Kicinski, Paolo Abeni, Russell King,
	linux-kernel

On Tue, Nov 03, 2026 at 09:29:14PM +0800, Andrew Lunn wrote:
> This is an interesting definition of WAKE_PHY.
>
> Are there any other drivers which use change in link to trigger a
> wake?

Not really among the PHY drivers. mxl-gpy enables the link state
change interrupt (PHY_IMASK_LSTC) in set_wol() when WAKE_PHY is
requested, but it does not register the PHY as a wakeup source
itself.

> How are you using it? Is your device plugged into a manages switch and
> you are making the managed switch down/up the link?

I don't have a concrete use case for it. Waking on link change does
not seem to be a common way to wake a system over Ethernet; magic
packet is the usual method.

> Is the hardware capable of waking just on link up? Is there any point
> waking up if the link goes down?

No, the AN8801R only has a single link change wake event, which
triggers on both link up and link down, so it cannot be limited to
link up. I agree that waking up on link down is of little use.

Thanks,
Tommy

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next] net: phy: air_an8801: add WAKE_PHY Wake-on-LAN support
  2026-11-05 14:33   ` tommy shih
@ 2026-11-05 22:26     ` Andrew Lunn
  0 siblings, 0 replies; 4+ messages in thread
From: Andrew Lunn @ 2026-11-05 22:26 UTC (permalink / raw)
  To: tommy shih
  Cc: netdev, Louis-Alexis Eyraud, AngeloGioacchino Del Regno,
	Daniel Golle, Lucien . Jheng, David S. Miller, Eric Dumazet,
	Heiner Kallweit, Jakub Kicinski, Paolo Abeni, Russell King,
	linux-kernel

> I don't have a concrete use case for it. Waking on link change does
> not seem to be a common way to wake a system over Ethernet; magic
> packet is the usual method.

I'm tempted to reject this, because you don't seem to need it, and it
is not clear if it is even correct usage of the API.

   Andrew

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-11-05 22:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-02 13:29 [PATCH net-next] net: phy: air_an8801: add WAKE_PHY Wake-on-LAN support Tommy Shih
2026-11-03 13:29 ` Andrew Lunn
2026-11-05 14:33   ` tommy shih
2026-11-05 22:26     ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®