Commit 1a1d5106 authored by Doug Berger's avatar Doug Berger Committed by David S. Miller

net: bcmgenet: move clk_wol management to bcmgenet_wol

The GENET_POWER_WOL_MAGIC power up and power down code configures
the device for WoL when suspending and disables the WoL logic when
resuming. It makes sense that this code should also manage the WoL
clocking.

This commit consolidates the logic and moves it earlier in the
resume sequence.

Since the clock is now only enabled if WoL is successfully entered
the wol_active flag is introduced to track that state to keep the
clock enables and disables balanced in case a suspend is aborted.
The MPD_EN hardware bit can't be used because it can be cleared
when the MAC is reset by a deep sleep.
Signed-off-by: default avatarDoug Berger <opendmb@gmail.com>
Acked-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6f768905
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* /*
* Broadcom GENET (Gigabit Ethernet) controller driver * Broadcom GENET (Gigabit Ethernet) controller driver
* *
* Copyright (c) 2014-2019 Broadcom * Copyright (c) 2014-2020 Broadcom
*/ */
#define pr_fmt(fmt) "bcmgenet: " fmt #define pr_fmt(fmt) "bcmgenet: " fmt
...@@ -3619,6 +3619,10 @@ static int bcmgenet_resume(struct device *d) ...@@ -3619,6 +3619,10 @@ static int bcmgenet_resume(struct device *d)
if (ret) if (ret)
return ret; return ret;
/* From WOL-enabled suspend, switch to regular clock */
if (device_may_wakeup(d) && priv->wolopts)
bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
/* If this is an internal GPHY, power it back on now, before UniMAC is /* If this is an internal GPHY, power it back on now, before UniMAC is
* brought out of reset as absolutely no UniMAC activity is allowed * brought out of reset as absolutely no UniMAC activity is allowed
*/ */
...@@ -3629,10 +3633,6 @@ static int bcmgenet_resume(struct device *d) ...@@ -3629,10 +3633,6 @@ static int bcmgenet_resume(struct device *d)
init_umac(priv); init_umac(priv);
/* From WOL-enabled suspend, switch to regular clock */
if (priv->wolopts)
clk_disable_unprepare(priv->clk_wol);
phy_init_hw(dev->phydev); phy_init_hw(dev->phydev);
/* Speed settings must be restored */ /* Speed settings must be restored */
...@@ -3650,9 +3650,6 @@ static int bcmgenet_resume(struct device *d) ...@@ -3650,9 +3650,6 @@ static int bcmgenet_resume(struct device *d)
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT); bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
} }
if (priv->wolopts)
bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
/* Disable RX/TX DMA and flush TX queues */ /* Disable RX/TX DMA and flush TX queues */
dma_ctrl = bcmgenet_dma_disable(priv); dma_ctrl = bcmgenet_dma_disable(priv);
...@@ -3702,12 +3699,10 @@ static int bcmgenet_suspend(struct device *d) ...@@ -3702,12 +3699,10 @@ static int bcmgenet_suspend(struct device *d)
phy_suspend(dev->phydev); phy_suspend(dev->phydev);
/* Prepare the device for Wake-on-LAN and switch to the slow clock */ /* Prepare the device for Wake-on-LAN and switch to the slow clock */
if (device_may_wakeup(d) && priv->wolopts) { if (device_may_wakeup(d) && priv->wolopts)
ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC); ret = bcmgenet_power_down(priv, GENET_POWER_WOL_MAGIC);
clk_prepare_enable(priv->clk_wol); else if (priv->internal_phy)
} else if (priv->internal_phy) {
ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE); ret = bcmgenet_power_down(priv, GENET_POWER_PASSIVE);
}
/* Turn off the clocks */ /* Turn off the clocks */
clk_disable_unprepare(priv->clk); clk_disable_unprepare(priv->clk);
......
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2014-2017 Broadcom * Copyright (c) 2014-2020 Broadcom
*/ */
#ifndef __BCMGENET_H__ #ifndef __BCMGENET_H__
...@@ -678,6 +678,7 @@ struct bcmgenet_priv { ...@@ -678,6 +678,7 @@ struct bcmgenet_priv {
struct clk *clk_wol; struct clk *clk_wol;
u32 wolopts; u32 wolopts;
u8 sopass[SOPASS_MAX]; u8 sopass[SOPASS_MAX];
bool wol_active;
struct bcmgenet_mib_counters mib; struct bcmgenet_mib_counters mib;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* /*
* Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
* *
* Copyright (c) 2014-2017 Broadcom * Copyright (c) 2014-2020 Broadcom
*/ */
#define pr_fmt(fmt) "bcmgenet_wol: " fmt #define pr_fmt(fmt) "bcmgenet_wol: " fmt
...@@ -155,6 +155,9 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, ...@@ -155,6 +155,9 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n", netif_dbg(priv, wol, dev, "MPD WOL-ready status set after %d msec\n",
retries); retries);
clk_prepare_enable(priv->clk_wol);
priv->wol_active = 1;
/* Enable CRC forward */ /* Enable CRC forward */
reg = bcmgenet_umac_readl(priv, UMAC_CMD); reg = bcmgenet_umac_readl(priv, UMAC_CMD);
priv->crc_fwd_en = 1; priv->crc_fwd_en = 1;
...@@ -183,9 +186,14 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, ...@@ -183,9 +186,14 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
return; return;
} }
if (!priv->wol_active)
return; /* failed to suspend so skip the rest */
priv->wol_active = 0;
clk_disable_unprepare(priv->clk_wol);
/* Disable Magic Packet Detection */
reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL); reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
if (!(reg & MPD_EN))
return; /* already powered up so skip the rest */
reg &= ~(MPD_EN | MPD_PW_EN); reg &= ~(MPD_EN | MPD_PW_EN);
bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL); bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment