Merge branch 'net-stmmac-eee-and-wol-cleanups'

Russell King says:

====================
net: stmmac: EEE and WoL cleanups

This series contains a series of cleanup patches for the EEE and WoL
code in stmmac, prompted by issues raised during the last three weeks.
====================

Link: https://patch.msgid.link/aJ8avIp8DBAckgMc@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-08-18 18:10:14 -07:00
commit 38e1467392
5 changed files with 25 additions and 43 deletions

View File

@ -602,7 +602,6 @@ struct mac_device_info {
unsigned int mcast_bits_log2;
unsigned int rx_csum;
unsigned int pcs;
unsigned int pmt;
unsigned int ps;
unsigned int xlgmac;
unsigned int num_vlan;

View File

@ -289,7 +289,6 @@ struct stmmac_priv {
u32 msg_enable;
int wolopts;
int wol_irq;
bool wol_irq_disabled;
int clk_csr;
struct timer_list eee_ctrl_timer;
int lpi_irq;
@ -376,6 +375,16 @@ enum stmmac_state {
extern const struct dev_pm_ops stmmac_simple_pm_ops;
static inline bool stmmac_wol_enabled_mac(struct stmmac_priv *priv)
{
return priv->plat->pmt && device_may_wakeup(priv->device);
}
static inline bool stmmac_wol_enabled_phy(struct stmmac_priv *priv)
{
return !priv->plat->pmt && device_may_wakeup(priv->device);
}
int stmmac_mdio_unregister(struct net_device *ndev);
int stmmac_mdio_register(struct net_device *ndev);
int stmmac_mdio_reset(struct mii_bus *mii);

View File

@ -803,7 +803,6 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct stmmac_priv *priv = netdev_priv(dev);
u32 support = WAKE_MAGIC | WAKE_UCAST;
if (!device_can_wakeup(priv->device))
return -EOPNOTSUPP;
@ -816,29 +815,7 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
return ret;
}
/* By default almost all GMAC devices support the WoL via
* magic frame but we can disable it if the HW capability
* register shows no support for pmt_magic_frame. */
if ((priv->hw_cap_support) && (!priv->dma_cap.pmt_magic_frame))
wol->wolopts &= ~WAKE_MAGIC;
if (wol->wolopts & ~support)
return -EINVAL;
if (wol->wolopts) {
pr_info("stmmac: wakeup enable\n");
device_set_wakeup_enable(priv->device, 1);
/* Avoid unbalanced enable_irq_wake calls */
if (priv->wol_irq_disabled)
enable_irq_wake(priv->wol_irq);
priv->wol_irq_disabled = false;
} else {
device_set_wakeup_enable(priv->device, 0);
/* Avoid unbalanced disable_irq_wake calls */
if (!priv->wol_irq_disabled)
disable_irq_wake(priv->wol_irq);
priv->wol_irq_disabled = true;
}
device_set_wakeup_enable(priv->device, !!wol->wolopts);
mutex_lock(&priv->lock);
priv->wolopts = wol->wolopts;
@ -852,9 +829,6 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
{
struct stmmac_priv *priv = netdev_priv(dev);
if (!priv->dma_cap.eee)
return -EOPNOTSUPP;
return phylink_ethtool_get_eee(priv->phylink, edata);
}
@ -863,9 +837,6 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
{
struct stmmac_priv *priv = netdev_priv(dev);
if (!priv->dma_cap.eee)
return -EOPNOTSUPP;
return phylink_ethtool_set_eee(priv->phylink, edata);
}

View File

@ -29,6 +29,7 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/pm_wakeirq.h>
#include <linux/prefetch.h>
#include <linux/pinctrl/consumer.h>
#ifdef CONFIG_DEBUG_FS
@ -3724,7 +3725,6 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
/* Request the Wake IRQ in case of another line
* is used for WoL
*/
priv->wol_irq_disabled = true;
if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) {
int_name = priv->int_name_wol;
sprintf(int_name, "%s:%s", dev->name, "wol");
@ -3885,7 +3885,6 @@ static int stmmac_request_irq_single(struct net_device *dev)
/* Request the Wake IRQ in case of another line
* is used for WoL
*/
priv->wol_irq_disabled = true;
if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) {
ret = request_irq(priv->wol_irq, stmmac_interrupt,
IRQF_SHARED, dev->name, dev);
@ -4139,8 +4138,13 @@ static int stmmac_release(struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
u32 chan;
/* If the PHY or MAC has WoL enabled, then the PHY will not be
* suspended when phylink_stop() is called below. Set the PHY
* to its slowest speed to save power.
*/
if (device_may_wakeup(priv->device))
phylink_speed_down(priv->phylink, false);
/* Stop and disconnect the PHY */
phylink_stop(priv->phylink);
phylink_disconnect_phy(priv->phylink);
@ -7240,7 +7244,6 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
priv->plat->enh_desc = priv->dma_cap.enh_desc;
priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up &&
!(priv->plat->flags & STMMAC_FLAG_USE_PHY_WOL);
priv->hw->pmt = priv->plat->pmt;
if (priv->dma_cap.hash_tb_sz) {
priv->hw->multicast_filter_bins =
(BIT(priv->dma_cap.hash_tb_sz) << 5);
@ -7278,6 +7281,7 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
if (priv->plat->pmt) {
dev_info(priv->device, "Wake-Up On Lan supported\n");
device_set_wakeup_capable(priv->device, 1);
devm_pm_set_wake_irq(priv->device, priv->wol_irq);
}
if (priv->dma_cap.tsoen)
@ -7858,7 +7862,7 @@ int stmmac_suspend(struct device *dev)
priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
/* Enable Power down mode by programming the PMT regs */
if (device_may_wakeup(priv->device) && priv->plat->pmt) {
if (stmmac_wol_enabled_mac(priv)) {
stmmac_pmt(priv, priv->hw, priv->wolopts);
priv->irq_wake = 1;
} else {
@ -7869,11 +7873,10 @@ int stmmac_suspend(struct device *dev)
mutex_unlock(&priv->lock);
rtnl_lock();
if (device_may_wakeup(priv->device) && !priv->plat->pmt)
if (stmmac_wol_enabled_phy(priv))
phylink_speed_down(priv->phylink, false);
phylink_suspend(priv->phylink,
device_may_wakeup(priv->device) && priv->plat->pmt);
phylink_suspend(priv->phylink, stmmac_wol_enabled_mac(priv));
rtnl_unlock();
if (stmmac_fpe_supported(priv))
@ -7949,7 +7952,7 @@ int stmmac_resume(struct device *dev)
* this bit because it can generate problems while resuming
* from another devices (e.g. serial console).
*/
if (device_may_wakeup(priv->device) && priv->plat->pmt) {
if (stmmac_wol_enabled_mac(priv)) {
mutex_lock(&priv->lock);
stmmac_pmt(priv, priv->hw, 0);
mutex_unlock(&priv->lock);
@ -8009,7 +8012,7 @@ int stmmac_resume(struct device *dev)
* workqueue thread, which will race with initialisation.
*/
phylink_resume(priv->phylink);
if (device_may_wakeup(priv->device) && !priv->plat->pmt)
if (stmmac_wol_enabled_phy(priv))
phylink_speed_up(priv->phylink);
rtnl_unlock();

View File

@ -934,7 +934,7 @@ static int __maybe_unused stmmac_pltfr_noirq_suspend(struct device *dev)
if (!netif_running(ndev))
return 0;
if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
if (!stmmac_wol_enabled_mac(priv)) {
/* Disable clock in case of PWM is off */
clk_disable_unprepare(priv->plat->clk_ptp_ref);
@ -955,7 +955,7 @@ static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
if (!netif_running(ndev))
return 0;
if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
if (!stmmac_wol_enabled_mac(priv)) {
/* enable the clk previously disabled */
ret = pm_runtime_force_resume(dev);
if (ret)