From: James Hilliard <james.hilliard1@gmail.com>
To: Russell King <linux@armlinux.org.uk>,
Andrew Lunn <andrew@lunn.ch>,
Heiner Kallweit <hkallweit1@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
Joakim Zhang <qiangqing.zhang@nxp.com>,
"Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>,
Maxime Chevallier <maxime.chevallier@bootlin.com>,
Andrew Lunn <andrew+netdev@lunn.ch>,
Maxime Coquelin <mcoquelin.stm32@gmail.com>,
Alexandre Torgue <alexandre.torgue@foss.st.com>,
Christian Marangi <ansuelsmth@gmail.com>,
Tiezhu Yang <yangtiezhu@loongson.cn>,
Huacai Chen <chenhuacai@kernel.org>,
Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Jesper Dangaard Brouer <hawk@kernel.org>,
John Fastabend <john.fastabend@gmail.com>,
Stanislav Fomichev <sdf@fomichev.me>,
Serge Semin <fancer.lancer@gmail.com>,
Suraj Jaiswal <quic_jsuraj@quicinc.com>,
Richard Cochran <richardcochran@gmail.com>,
Joao Pinto <Joao.Pinto@synopsys.com>,
Vladimir Oltean <vladimir.oltean@nxp.com>,
Ong Boon Leong <boon.leong.ong@intel.com>,
Voon Weifeng <weifeng.voon@intel.com>,
"Song, Yoong Siang" <yoong.siang.song@intel.com>
Cc: Richard Genoud <richard.genoud@bootlin.com>,
Alastair D'Silva <alastair@d-silva.org>,
Maxime Ripard <mripard@kernel.org>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-stm32@st-md-mailman.stormreply.com,
linux-arm-kernel@lists.infradead.org, bpf@vger.kernel.org,
ZhaoJinming <zhaojinming@uniontech.com>,
Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>,
Ding Hui <dinghui1111@163.com>,
James Hilliard <james.hilliard1@gmail.com>
Subject: [PATCH net v3 02/10] net: phylink: allow stopping a suspended instance
Date: Thu, 24 Sep 2026 11:44:32 -0600 [thread overview]
Message-ID: <20260924-submit-stmmac-reset-fixes-v1-v3-2-c031e3f3a282@gmail.com> (raw)
In-Reply-To: <20260924-submit-stmmac-reset-fixes-v1-v3-0-c031e3f3a282@gmail.com>
If a network driver's system resume fails before phylink_resume(), the
network device can remain administratively up with phylink suspended.
Closing the interface then needs to terminate that suspended instance.
Calling phylink_resume() merely to make phylink_stop() work is not a safe
substitute: resume reconfigures the MAC and restarts link resolution,
although the driver has not successfully restored the MAC.
This is a missing suspend-to-stop transition, independent of the reason
hardware restoration failed. No MAC recovery policy belongs in phylink;
the driver still decides whether to retry resume or wait for an ordinary
administrative down/up cycle.
Without MAC Wake-on-LAN, phylink_suspend() has already called
phylink_stop(). Do not repeat PHY, SFP and PCS shutdown. However,
phylink_prepare_resume() may have powered that stopped PHY back up to
provide the receive clock for MAC reset. Suspend it again if WoL permits,
without repeating phy_stop() on a PHY which is already halted.
With MAC Wake-on-LAN, suspend deliberately
defers mac_link_down() and sets PHYLINK_DISABLE_MAC_WOL. Finish that
deferred link-down, drain resolution work and clear the WoL disable bit
while retaining PHYLINK_DISABLE_STOPPED. Otherwise a subsequent start
cannot resolve the link.
Also undo PHY speed control performed by phylink_suspend(). As Andrew
Lunn pointed out, phylink_start() does not restore the advertised speeds
that phylink_resume() normally restores. Track suspend-owned speed control
and restore the saved advertisement from either resume or suspended stop,
including when PHY shutdown has already completed.
An explicit driver speed-down request, such as stmmac's close-time power
saving, must remain in effect until its matching speed-up. Restore any
suspend-owned reduction before applying that request, so it cannot save
the reduced advertisement over the original one. The following stop must
not undo the driver's new reduction.
Document that a suspended instance can be stopped directly. This neither
resumes the PHY nor reconfigures or brings up the MAC.
Fixes: f97493657c63 ("net: phylink: add suspend/resume support")
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/net/phy/phylink.c | 51 ++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 48 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 1bbcf46c8356..b7d30ca34031 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -78,6 +78,7 @@ struct phylink {
bool link_failed;
bool suspend_link_up;
+ bool suspend_speed_down;
bool force_major_config;
bool major_config_failed;
bool mac_supports_eee_ops;
@@ -2498,6 +2499,14 @@ void phylink_start(struct phylink *pl)
}
EXPORT_SYMBOL_GPL(phylink_start);
+static void phylink_restore_suspend_speed(struct phylink *pl)
+{
+ if (pl->suspend_speed_down) {
+ phylink_speed_up(pl);
+ pl->suspend_speed_down = false;
+ }
+}
+
/**
* phylink_stop() - stop a phylink instance
* @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -2509,11 +2518,30 @@ EXPORT_SYMBOL_GPL(phylink_start);
*
* This will synchronously bring down the link if the link is not already
* down (in other words, it will trigger a mac_link_down() method call.)
+ * A suspended instance may be stopped without first calling phylink_resume().
+ * In particular, closing a device after a failed resume must not restart the
+ * link or reconfigure the MAC just to finish shutting it down.
+ * Any PHY advertisement reduced by phylink_suspend() is restored as part
+ * of this transition.
+ * If phylink_prepare_resume() powered up an already stopped PHY, suspend
+ * it again when Wake-on-LAN permits.
*/
void phylink_stop(struct phylink *pl)
{
ASSERT_RTNL();
+ /* Also undo PHY speed control when terminating a suspended instance. */
+ phylink_restore_suspend_speed(pl);
+
+ if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
+ /* A failed MAC resume may have called phylink_prepare_resume()
+ * and powered the stopped PHY back up to supply its RX clock.
+ */
+ if (pl->phydev)
+ phy_suspend(pl->phydev);
+ return;
+ }
+
if (pl->sfp_bus)
sfp_upstream_stop(pl->sfp_bus);
if (pl->phydev)
@@ -2526,6 +2554,16 @@ void phylink_stop(struct phylink *pl)
phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
+ if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) {
+ /* Finish the link-down deferred by MAC WoL, without restarting. */
+ flush_work(&pl->resolve);
+ mutex_lock(&pl->state_mutex);
+ if (pl->suspend_link_up)
+ phylink_link_down(pl);
+ __clear_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state);
+ mutex_unlock(&pl->state_mutex);
+ }
+
pl->pcs_state = PCS_STATE_DOWN;
phylink_pcs_disable(pl->pcs);
@@ -2657,8 +2695,10 @@ void phylink_suspend(struct phylink *pl, bool mac_wol)
phylink_stop(pl);
}
- if (phylink_phy_pm_speed_ctrl(pl))
+ if (phylink_phy_pm_speed_ctrl(pl)) {
phylink_speed_down(pl, false);
+ pl->suspend_speed_down = true;
+ }
}
EXPORT_SYMBOL_GPL(phylink_suspend);
@@ -2698,8 +2738,7 @@ void phylink_resume(struct phylink *pl)
{
ASSERT_RTNL();
- if (phylink_phy_pm_speed_ctrl(pl))
- phylink_speed_up(pl);
+ phylink_restore_suspend_speed(pl);
if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) {
/* Wake-on-Lan enabled, MAC handling */
@@ -3616,6 +3655,12 @@ int phylink_speed_down(struct phylink *pl, bool sync)
ASSERT_RTNL();
+ /* An explicit request takes over from suspend-time speed control.
+ * Restore the original advertisement before saving it again, so a
+ * repeated speed-down cannot replace it with the reduced advertisement.
+ */
+ phylink_restore_suspend_speed(pl);
+
if (!pl->sfp_bus && pl->phydev)
ret = phy_speed_down(pl->phydev, sync);
--
2.53.0
next prev parent reply other threads:[~2026-09-24 17:44 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 17:44 [PATCH net v3 00/10] net: stmmac: preserve datapath state across MTU and resume failures James Hilliard
2026-09-24 17:44 ` [PATCH net v3 01/10] net: stmmac: unwind the WoL IRQ after a safety IRQ request failure James Hilliard
2026-09-24 17:44 ` James Hilliard [this message]
2026-09-24 17:44 ` [PATCH net v3 03/10] net: stmmac: keep datapath state coherent after reinitialization failure James Hilliard
2026-09-25 19:11 ` netdev-bot+sashiko
2026-09-24 17:44 ` [PATCH net v3 04/10] net: stmmac: leave the datapath running for normal-size MTU changes James Hilliard
2026-09-24 17:44 ` [PATCH net v3 05/10] net: stmmac: unwind partially allocated DMA configurations James Hilliard
2026-09-25 19:11 ` netdev-bot+sashiko
2026-09-24 17:44 ` [PATCH net v3 06/10] net: stmmac: keep DMA configurations at stable addresses James Hilliard
2026-09-25 19:12 ` netdev-bot+sashiko
2026-09-24 17:44 ` [PATCH net v3 07/10] net: stmmac: account for failed live XDP reopening James Hilliard
2026-09-25 19:12 ` netdev-bot+sashiko
2026-09-24 17:44 ` [PATCH net v3 08/10] net: stmmac: use the tracked datapath restart for XSK pool changes James Hilliard
2026-09-25 19:12 ` netdev-bot+sashiko
2026-09-24 17:44 ` [PATCH net v3 09/10] net: stmmac: retain PHY and PM ownership during ethtool reopening James Hilliard
2026-09-25 19:12 ` netdev-bot+sashiko
2026-09-24 17:44 ` [PATCH net v3 10/10] net: stmmac: retain DMA resources across MTU changes James Hilliard
2026-09-25 19:12 ` netdev-bot+sashiko
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=20260924-submit-stmmac-reset-fixes-v1-v3-2-c031e3f3a282@gmail.com \
--to=james.hilliard1@gmail.com \
--cc=Joao.Pinto@synopsys.com \
--cc=alastair@d-silva.org \
--cc=alexandre.torgue@foss.st.com \
--cc=andrew+netdev@lunn.ch \
--cc=andrew@lunn.ch \
--cc=ansuelsmth@gmail.com \
--cc=ast@kernel.org \
--cc=boon.leong.ong@intel.com \
--cc=bpf@vger.kernel.org \
--cc=chenhuacai@kernel.org \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=dinghui1111@163.com \
--cc=edumazet@google.com \
--cc=fancer.lancer@gmail.com \
--cc=hawk@kernel.org \
--cc=hkallweit1@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=kuba@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-stm32@st-md-mailman.stormreply.com \
--cc=linux@armlinux.org.uk \
--cc=lorenzo.bianconi@oss.qualcomm.com \
--cc=maxime.chevallier@bootlin.com \
--cc=mcoquelin.stm32@gmail.com \
--cc=mripard@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=qiangqing.zhang@nxp.com \
--cc=quic_jsuraj@quicinc.com \
--cc=richard.genoud@bootlin.com \
--cc=richardcochran@gmail.com \
--cc=rmk+kernel@armlinux.org.uk \
--cc=sdf@fomichev.me \
--cc=vladimir.oltean@nxp.com \
--cc=weifeng.voon@intel.com \
--cc=yangtiezhu@loongson.cn \
--cc=yoong.siang.song@intel.com \
--cc=zhaojinming@uniontech.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 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®