Skip to content

Commit 4c8925c

Browse files
Russell King (Oracle)kuba-moo
authored andcommitted
net: phylink: fix suspend/resume with WoL enabled and link down
When WoL is enabled, we update the software state in phylink to indicate that the link is down, and disable the resolver from bringing the link back up. On resume, we attempt to bring the overall state into consistency by calling the .mac_link_down() method, but this is wrong if the link was already down, as phylink strictly orders the .mac_link_up() and .mac_link_down() methods - and this would break that ordering. Fixes: f974936 ("net: phylink: add suspend/resume support") Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Tested-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Link: https://patch.msgid.link/E1u55Qf-0016RN-PA@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent c03a49f commit 4c8925c

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

drivers/net/phy/phylink.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct phylink {
8181
unsigned int pcs_state;
8282

8383
bool link_failed;
84+
bool suspend_link_up;
8485
bool major_config_failed;
8586
bool mac_supports_eee_ops;
8687
bool mac_supports_eee;
@@ -2545,14 +2546,16 @@ void phylink_suspend(struct phylink *pl, bool mac_wol)
25452546
/* Stop the resolver bringing the link up */
25462547
__set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state);
25472548

2548-
/* Disable the carrier, to prevent transmit timeouts,
2549-
* but one would hope all packets have been sent. This
2550-
* also means phylink_resolve() will do nothing.
2551-
*/
2552-
if (pl->netdev)
2553-
netif_carrier_off(pl->netdev);
2554-
else
2549+
pl->suspend_link_up = phylink_link_is_up(pl);
2550+
if (pl->suspend_link_up) {
2551+
/* Disable the carrier, to prevent transmit timeouts,
2552+
* but one would hope all packets have been sent. This
2553+
* also means phylink_resolve() will do nothing.
2554+
*/
2555+
if (pl->netdev)
2556+
netif_carrier_off(pl->netdev);
25552557
pl->old_link_state = false;
2558+
}
25562559

25572560
/* We do not call mac_link_down() here as we want the
25582561
* link to remain up to receive the WoL packets.
@@ -2603,15 +2606,18 @@ void phylink_resume(struct phylink *pl)
26032606
if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) {
26042607
/* Wake-on-Lan enabled, MAC handling */
26052608

2606-
/* Call mac_link_down() so we keep the overall state balanced.
2607-
* Do this under the state_mutex lock for consistency. This
2608-
* will cause a "Link Down" message to be printed during
2609-
* resume, which is harmless - the true link state will be
2610-
* printed when we run a resolve.
2611-
*/
2612-
mutex_lock(&pl->state_mutex);
2613-
phylink_link_down(pl);
2614-
mutex_unlock(&pl->state_mutex);
2609+
if (pl->suspend_link_up) {
2610+
/* Call mac_link_down() so we keep the overall state
2611+
* balanced. Do this under the state_mutex lock for
2612+
* consistency. This will cause a "Link Down" message
2613+
* to be printed during resume, which is harmless -
2614+
* the true link state will be printed when we run a
2615+
* resolve.
2616+
*/
2617+
mutex_lock(&pl->state_mutex);
2618+
phylink_link_down(pl);
2619+
mutex_unlock(&pl->state_mutex);
2620+
}
26152621

26162622
/* Re-apply the link parameters so that all the settings get
26172623
* restored to the MAC.

0 commit comments

Comments
 (0)