From: Rosen Penev <rosenp@gmail.com>
To: netdev@vger.kernel.org
Cc: Andrew Lunn <andrew@lunn.ch>,
Heiner Kallweit <hkallweit1@gmail.com>,
Russell King <linux@armlinux.org.uk>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Michael Stapelberg <michael@stapelberg.de>,
linux-kernel@vger.kernel.org (open list)
Subject: [PATCHv2 net] net: phy: marvell: undo WoL setup when Wake-on-LAN is disabled
Date: Mon, 14 Sep 2026 14:24:09 -0700 [thread overview]
Message-ID: <20260914212409.74539-1-rosenp@gmail.com> (raw)
Fully disabling Wake-on-LAN on the 88E1318S/88E1510 used to leave
the WoL interrupt enable bit (CSIER.WOL_EIE) set and LED[2]
configured as the INTn pin. A magic packet arriving after "wol d"
would still assert INTn, and a later "wol g" re-enabled WoL from a
dirty register state.
Fully disabling WoL clears CSIER.WOL_EIE on the copper page. The
LED[2]/INTn pin mux is disposed of only when this driver forced it to
the INTn function: the INTn enable and polarity bits read at arming
time are saved, and restored once all WoL options are cleared, so PHYs
serving the MAC interrupt, strap configs, or marvell,reg-init values
are never touched. The FORCE_INT bit is not set while disposing of the
pin: it holds the interrupt line asserted and turns the shared PHY
interrupt into a "nobody cared" IRQ storm when the PHY interrupt is in
use.
Fixes: 3871c3876f80 ("mv643xx_eth with 88E1318S: support Wake on LAN")
Assisted-by: LLM
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
v2: move to net with Fixes. Address phy_interrupt_is_valid issue.
drivers/net/phy/marvell.c | 54 +++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f71cffa88406..64862f12eb42 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -354,6 +354,8 @@ struct marvell_priv {
u32 step;
s8 pair;
u8 vct_phase;
+ u16 wol_led_tcr;
+ bool wol_led_armed;
};
static int marvell_read_page(struct phy_device *phydev)
@@ -1969,6 +1971,7 @@ static void m88e1318_get_wol(struct phy_device *phydev,
static int m88e1318_set_wol(struct phy_device *phydev,
struct ethtool_wolinfo *wol)
{
+ struct marvell_priv *priv = phydev->priv;
int err = 0, oldpage;
oldpage = phy_save_page(phydev);
@@ -2000,6 +2003,22 @@ static int m88e1318_set_wol(struct phy_device *phydev,
if (err < 0)
goto error;
+ /* Remember the LED[2]/INTn mux before forcing the pin to
+ * INTn, so it can be restored when WoL is disabled again.
+ * Only save it once, or a re-enable would overwrite the
+ * value read before WoL was first armed.
+ */
+ if (!priv->wol_led_armed) {
+ err = __phy_read(phydev, MII_88E1318S_PHY_LED_TCR);
+ if (err < 0)
+ goto error;
+
+ priv->wol_led_tcr = err &
+ (MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
+ MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW);
+ priv->wol_led_armed = true;
+ }
+
/* Setup LED[2] as interrupt pin (active low) */
err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,
MII_88E1318S_PHY_LED_TCR_FORCE_INT,
@@ -2074,6 +2093,41 @@ static int m88e1318_set_wol(struct phy_device *phydev,
goto error;
}
+ if (!(wol->wolopts & (WAKE_MAGIC | WAKE_PHY))) {
+ /* Fully disabled: undo the WoL interrupt setup done above,
+ * so a later re-enable starts from a clean state. The
+ * LED[2]/INTn pin mux is only touched when it was forced
+ * to INTn here, and is restored to the value read at
+ * arming time; PHYs serving the MAC interrupt, straps, or
+ * marvell,reg-init values are left alone.
+ */
+ err = marvell_write_page(phydev, MII_MARVELL_COPPER_PAGE);
+ if (err < 0)
+ goto error;
+
+ err = __phy_clear_bits(phydev, MII_88E1318S_PHY_CSIER,
+ MII_88E1318S_PHY_CSIER_WOL_EIE);
+ if (err < 0)
+ goto error;
+
+ if (!priv->wol_led_armed)
+ goto error;
+
+ err = marvell_write_page(phydev, MII_MARVELL_LED_PAGE);
+ if (err < 0)
+ goto error;
+
+ err = __phy_modify(phydev, MII_88E1318S_PHY_LED_TCR,
+ MII_88E1318S_PHY_LED_TCR_FORCE_INT |
+ MII_88E1318S_PHY_LED_TCR_INTn_ENABLE |
+ MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW,
+ priv->wol_led_tcr);
+ if (err < 0)
+ goto error;
+
+ priv->wol_led_armed = false;
+ }
+
error:
return phy_restore_page(phydev, oldpage, err);
}
--
2.55.0
next reply other threads:[~2026-09-14 21:24 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-14 21:24 Rosen Penev [this message]
2026-09-17 21:24 ` [PATCHv2 net] net: phy: marvell: undo WoL setup when Wake-on-LAN is disabled netdev-bot+sashiko
2026-09-19 22:41 ` Jakub Kicinski
2026-09-20 1:05 ` Rosen Penev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260914212409.74539-1-rosenp@gmail.com \
--to=rosenp@gmail.com \
--cc=andrew@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=michael@stapelberg.de \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.