Skip to content

Commit d9922c0

Browse files
Russell Kingdavem330
authored andcommitted
net: phylink: fix link mode modification in PHY mode
Modifying the link settings via phylink_ethtool_ksettings_set() and phylink_ethtool_set_pauseparam() didn't always work as intended for PHY based setups, as calling phylink_mac_config() would result in the unresolved configuration being committed to the MAC, rather than the configuration with the speed and duplex setting. This would work fine if the update caused the link to renegotiate, but if no settings have changed, phylib won't trigger a renegotiation cycle, and the MAC will be left incorrectly configured. Avoid calling phylink_mac_config() unless we are using an inband mode in phylink_ethtool_ksettings_set(), and use phy_set_asym_pause() as introduced in 4.20 to set the PHY settings in phylink_ethtool_set_pauseparam(). Signed-off-by: Russell King <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 269a6b5 commit d9922c0

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

drivers/net/phy/phylink.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,7 +1258,13 @@ int phylink_ethtool_ksettings_set(struct phylink *pl,
12581258
pl->link_config.duplex = our_kset.base.duplex;
12591259
pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE;
12601260

1261-
if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
1261+
/* If we have a PHY, phylib will call our link state function if the
1262+
* mode has changed, which will trigger a resolve and update the MAC
1263+
* configuration. For a fixed link, this isn't able to change any
1264+
* parameters, which just leaves inband mode.
1265+
*/
1266+
if (pl->link_an_mode == MLO_AN_INBAND &&
1267+
!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
12621268
phylink_mac_config(pl, &pl->link_config);
12631269
phylink_mac_an_restart(pl);
12641270
}
@@ -1338,15 +1344,16 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl,
13381344
if (pause->tx_pause)
13391345
config->pause |= MLO_PAUSE_TX;
13401346

1341-
if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
1347+
/* If we have a PHY, phylib will call our link state function if the
1348+
* mode has changed, which will trigger a resolve and update the MAC
1349+
* configuration.
1350+
*/
1351+
if (pl->phydev) {
1352+
phy_set_asym_pause(pl->phydev, pause->rx_pause,
1353+
pause->tx_pause);
1354+
} else if (!test_bit(PHYLINK_DISABLE_STOPPED,
1355+
&pl->phylink_disable_state)) {
13421356
switch (pl->link_an_mode) {
1343-
case MLO_AN_PHY:
1344-
/* Silently mark the carrier down, and then trigger a resolve */
1345-
if (pl->netdev)
1346-
netif_carrier_off(pl->netdev);
1347-
phylink_run_resolve(pl);
1348-
break;
1349-
13501357
case MLO_AN_FIXED:
13511358
/* Should we allow fixed links to change against the config? */
13521359
phylink_resolve_flow(pl, config);

0 commit comments

Comments
 (0)