From: Justin Chen <justin.chen@broadcom.com>
To: netdev@vger.kernel.org
Cc: bcm-kernel-feedback-list@broadcom.com, pabeni@redhat.com,
kuba@kernel.org, edumazet@google.com, davem@davemloft.net,
andrew+netdev@lunn.ch, florian.fainelli@broadcom.com,
Justin Chen <justin.chen@broadcom.com>
Subject: [PATCH net-next v3 2/2] net: bcmasp: Keep phy link during WoL sleep cycle
Date: Wed, 6 May 2026 14:31:14 -0700 [thread overview]
Message-ID: <20260506213114.2002886-3-justin.chen@broadcom.com> (raw)
In-Reply-To: <20260506213114.2002886-1-justin.chen@broadcom.com>
We currently more or less restart all the HW on resume. Since we also
stop the PHY, it takes a while for the PHY link to be re-negotiated on
resume. Instead of doing a full restart, we keep the HW state and the
PHY link, that way we can resume network traffic with a much smaller
delay.
Signed-off-by: Justin Chen <justin.chen@broadcom.com>
---
v3
- Reworked how we managed the phy state machine while suspended. We make sure
the state machine is not running to avoid races and restore the link
appropriately when the HW is reset.
v2
- In the resume case with a HW reset. We trigger a relink by setting the link
to PHY_UP instead of calling phy_restart_aneg().
.../net/ethernet/broadcom/asp2/bcmasp_intf.c | 62 ++++++++++++++-----
1 file changed, 48 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
index e2b51ec903af..ed0977832ce4 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -923,7 +923,7 @@ static void bcmasp_phy_hw_unprepare(struct bcmasp_intf *intf)
bcmasp_rgmii_mode_en_set(intf, false);
}
-static void bcmasp_netif_deinit(struct net_device *dev)
+static void bcmasp_netif_deinit(struct net_device *dev, bool stop_phy)
{
struct bcmasp_intf *intf = netdev_priv(dev);
u32 reg, timeout = 1000;
@@ -946,7 +946,8 @@ static void bcmasp_netif_deinit(struct net_device *dev)
umac_enable_set(intf, UMC_CMD_TX_EN, 0);
- phy_stop(dev->phydev);
+ if (stop_phy)
+ phy_stop(dev->phydev);
umac_enable_set(intf, UMC_CMD_RX_EN, 0);
@@ -974,7 +975,7 @@ static int bcmasp_stop(struct net_device *dev)
/* Stop tx from updating HW */
netif_tx_disable(dev);
- bcmasp_netif_deinit(dev);
+ bcmasp_netif_deinit(dev, true);
bcmasp_reclaim_free_buffers(intf);
@@ -1385,15 +1386,26 @@ int bcmasp_interface_suspend(struct bcmasp_intf *intf)
{
struct device *kdev = &intf->parent->pdev->dev;
struct net_device *dev = intf->ndev;
+ bool wake;
if (!netif_running(dev))
return 0;
netif_device_detach(dev);
- bcmasp_netif_deinit(dev);
+ wake = device_may_wakeup(kdev) && intf->wolopts;
- if (!intf->wolopts) {
+ bcmasp_netif_deinit(dev, !wake);
+
+ if (wake) {
+ /* Disable phy status updates while suspending */
+ mutex_lock(&dev->phydev->lock);
+ dev->phydev->state = PHY_READY;
+ mutex_unlock(&dev->phydev->lock);
+ cancel_delayed_work_sync(&dev->phydev->state_queue);
+
+ bcmasp_suspend_to_wol(intf);
+ } else {
bcmasp_phy_hw_unprepare(intf);
/* If Wake-on-LAN is disabled, we can safely
@@ -1402,9 +1414,6 @@ int bcmasp_interface_suspend(struct bcmasp_intf *intf)
bcmasp_core_clock_set_intf(intf, false);
}
- if (device_may_wakeup(kdev) && intf->wolopts)
- bcmasp_suspend_to_wol(intf);
-
clk_disable_unprepare(intf->parent->clk);
return 0;
@@ -1428,8 +1437,11 @@ static void bcmasp_resume_from_wol(struct bcmasp_intf *intf)
int bcmasp_interface_resume(struct bcmasp_intf *intf)
{
+ struct device *kdev = &intf->parent->pdev->dev;
struct net_device *dev = intf->ndev;
+ bool wake;
int ret;
+ u32 reg;
if (!netif_running(dev))
return 0;
@@ -1438,17 +1450,39 @@ int bcmasp_interface_resume(struct bcmasp_intf *intf)
if (ret)
return ret;
- bcmasp_core_clock_set_intf(intf, true);
+ wake = device_may_wakeup(kdev) && intf->wolopts;
- bcmasp_resume_from_wol(intf);
-
- bcmasp_phy_hw_prepare(intf);
+ bcmasp_core_clock_set_intf(intf, true);
- umac_reset_and_init(intf, dev->dev_addr);
+ /* The interface might be HW reset in some suspend modes, so we may
+ * need to restore the UNIMAC/PHY if that is the case.
+ */
+ reg = umac_rl(intf, UMC_CMD);
+ if (wake && (reg & UMC_CMD_RX_EN)) {
+ umac_enable_set(intf, UMC_CMD_TX_EN, 1);
+ bcmasp_resume_from_wol(intf);
+ } else {
+ bcmasp_phy_hw_prepare(intf);
+ umac_reset_and_init(intf, dev->dev_addr);
+ }
bcmasp_netif_init(dev);
- phy_start(dev->phydev);
+ if (wake) {
+ /* If HW was reset, reprogram the unimac/PHY before resuming
+ * link status tracking to avoid racing the state machine.
+ */
+ if (!(reg & UMC_CMD_RX_EN))
+ bcmasp_adj_link(dev);
+
+ /* Resume link status tracking */
+ mutex_lock(&dev->phydev->lock);
+ dev->phydev->state = dev->phydev->link ? PHY_RUNNING : PHY_NOLINK;
+ mutex_unlock(&dev->phydev->lock);
+ phy_trigger_machine(dev->phydev);
+ } else {
+ phy_start(dev->phydev);
+ }
netif_device_attach(dev);
--
2.34.1
next prev parent reply other threads:[~2026-05-06 21:31 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 21:31 [PATCH net-next v3 0/2] Keep PHY link during WoL sleep cycle Justin Chen
2026-05-06 21:31 ` [PATCH net-next v3 1/2] net: bcmasp: Divide init to allow partial bring up Justin Chen
2026-05-06 21:31 ` Justin Chen [this message]
2026-05-07 20:08 ` [PATCH net-next v3 2/2] net: bcmasp: Keep phy link during WoL sleep cycle Florian Fainelli
2026-05-08 23:50 ` [PATCH net-next v3 0/2] Keep PHY " patchwork-bot+netdevbpf
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=20260506213114.2002886-3-justin.chen@broadcom.com \
--to=justin.chen@broadcom.com \
--cc=andrew+netdev@lunn.ch \
--cc=bcm-kernel-feedback-list@broadcom.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=florian.fainelli@broadcom.com \
--cc=kuba@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox