[net] net: ethernet: ave: Fix MAC to be in charge of PHY PM
Commit Message
The phylib callback is called after MAC driver's own resume callback is
called. For AVE driver, after resuming immediately, PHY state machine is
in PHY_NOLINK because there is a time lag from link-down to link-up due to
autoneg. The result is WARN_ON() dump in mdio_bus_phy_resume().
Since ave_resume() itself calls phy_resume(), AVE driver should manage
PHY PM. To indicate that MAC driver manages PHY PM, set
phydev->mac_managed_pm to true to avoid the unnecessary phylib call and
add missing phy_init_hw() to ave_resume().
Suggested-by: Heiner Kallweit <hkallweit1@gmail.com>
Fixes: fba863b81604 ("net: phy: make PHY PM ops a no-op if MAC driver manages PHY PM")
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
---
drivers/net/ethernet/socionext/sni_ave.c | 6 ++++++
1 file changed, 6 insertions(+)
Comments
Hello:
This patch was applied to netdev/net.git (master)
by Jakub Kicinski <kuba@kernel.org>:
On Mon, 24 Oct 2022 16:22:27 +0900 you wrote:
> The phylib callback is called after MAC driver's own resume callback is
> called. For AVE driver, after resuming immediately, PHY state machine is
> in PHY_NOLINK because there is a time lag from link-down to link-up due to
> autoneg. The result is WARN_ON() dump in mdio_bus_phy_resume().
>
> Since ave_resume() itself calls phy_resume(), AVE driver should manage
> PHY PM. To indicate that MAC driver manages PHY PM, set
> phydev->mac_managed_pm to true to avoid the unnecessary phylib call and
> add missing phy_init_hw() to ave_resume().
>
> [...]
Here is the summary with links:
- [net] net: ethernet: ave: Fix MAC to be in charge of PHY PM
https://git.kernel.org/netdev/net/c/e2badb4bd33a
You are awesome, thank you!
@@ -1229,6 +1229,8 @@ static int ave_init(struct net_device *ndev)
phy_support_asym_pause(phydev);
+ phydev->mac_managed_pm = true;
+
phy_attached_info(phydev);
return 0;
@@ -1756,6 +1758,10 @@ static int ave_resume(struct device *dev)
ave_global_reset(ndev);
+ ret = phy_init_hw(ndev->phydev);
+ if (ret)
+ return ret;
+
ave_ethtool_get_wol(ndev, &wol);
wol.wolopts = priv->wolopts;
__ave_ethtool_set_wol(ndev, &wol);