Skip to content

Commit

Permalink
net: phylink: add a function to resume phy alone to fix resume issue …
Browse files Browse the repository at this point in the history
…with WoL enabled

Issue we met:
On some platforms, mac cannot work after resumed from the suspend with WoL
enabled.

The cause of the issue:
1. phylink_resolve() is in a workqueue which will not be executed immediately.
   This is the call sequence:
       phylink_resolve()->phylink_link_up()->pl->mac_ops->mac_link_up()
   For stmmac driver, mac_link_up() will set the correct speed/duplex...
   values which are from link_state.
2. In stmmac_resume(), it will call stmmac_hw_setup() after called the
   phylink_resume(), because mac need phy rx_clk to do the reset.
   stmmac_core_init() is called in function stmmac_hw_setup(), which will
   reset the mac and set the speed/duplex... to default value.
Conclusion: Because phylink_resolve() cannot determine when it is called, it
            cannot be guaranteed to be called after stmmac_core_init().
	    Once stmmac_core_init() is called after phylink_resolve(),
	    the mac will be misconfigured and cannot be used.

In order to avoid this problem, add a function called phylink_phy_resume()
to resume phy separately. This eliminates the need to call phylink_resume()
before stmmac_hw_setup().

Add another judgement before called phy_start() in phylink_start(). This way
phy_start() will not be called multiple times when resumes. At the same time,
it may not affect other drivers that do not use phylink_phy_resume().

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
  • Loading branch information
wangxiaoningnxp authored and intel-lab-lkp committed Feb 1, 2023
1 parent dd25cfa commit 6df0562
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
29 changes: 28 additions & 1 deletion drivers/net/phy/phylink.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ struct phylink {
DECLARE_PHY_INTERFACE_MASK(sfp_interfaces);
__ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support);
u8 sfp_port;

bool mac_resume_phy_separately;
};

#define phylink_printk(level, pl, fmt, ...) \
Expand Down Expand Up @@ -1509,6 +1511,7 @@ struct phylink *phylink_create(struct phylink_config *config,
return ERR_PTR(-EINVAL);
}

pl->mac_resume_phy_separately = false;
pl->using_mac_select_pcs = using_mac_select_pcs;
pl->phy_state.interface = iface;
pl->link_interface = iface;
Expand Down Expand Up @@ -1944,7 +1947,10 @@ void phylink_start(struct phylink *pl)
if (poll)
mod_timer(&pl->link_poll, jiffies + HZ);
if (pl->phydev)
phy_start(pl->phydev);
if (!pl->mac_resume_phy_separately)
phy_start(pl->phydev);
else
pl->mac_resume_phy_separately = false;
if (pl->sfp_bus)
sfp_upstream_start(pl->sfp_bus);
}
Expand Down Expand Up @@ -2024,6 +2030,27 @@ void phylink_suspend(struct phylink *pl, bool mac_wol)
}
EXPORT_SYMBOL_GPL(phylink_suspend);

/**
* phylink_phy_resume() - resume phy alone
* @pl: a pointer to a &struct phylink returned from phylink_create()
*
* In the MAC driver using phylink, if the MAC needs the clock of the phy
* when it resumes, can call this function to resume the phy separately.
* Then proceed to MAC resume operations.
*/
void phylink_phy_resume(struct phylink *pl)
{
ASSERT_RTNL();

if (!test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)
&& pl->phydev) {
phy_start(pl->phydev);
pl->mac_resume_phy_separately = true;
}

}
EXPORT_SYMBOL_GPL(phylink_phy_resume);

/**
* phylink_resume() - handle a network device resume event
* @pl: a pointer to a &struct phylink returned from phylink_create()
Expand Down
1 change: 1 addition & 0 deletions include/linux/phylink.h
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ void phylink_stop(struct phylink *);

void phylink_suspend(struct phylink *pl, bool mac_wol);
void phylink_resume(struct phylink *pl);
void phylink_phy_resume(struct phylink *pl);

void phylink_ethtool_get_wol(struct phylink *, struct ethtool_wolinfo *);
int phylink_ethtool_set_wol(struct phylink *, struct ethtool_wolinfo *);
Expand Down

0 comments on commit 6df0562

Please sign in to comment.