diff options
Diffstat (limited to 'target/linux/generic/backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch')
-rw-r--r-- | target/linux/generic/backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch b/target/linux/generic/backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch new file mode 100644 index 0000000000..596ecc8272 --- /dev/null +++ b/target/linux/generic/backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch @@ -0,0 +1,66 @@ +From 4c9633f75dc35abe1b9261e0415d77802f35741d Mon Sep 17 00:00:00 2001 +From: Russell King <rmk+kernel@armlinux.org.uk> +Date: Tue, 5 Nov 2019 11:58:00 +0000 +Subject: [PATCH 639/660] 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 <rmk+kernel@armlinux.org.uk> +--- + drivers/net/phy/phylink.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +--- a/drivers/net/phy/phylink.c ++++ b/drivers/net/phy/phylink.c +@@ -1210,7 +1210,13 @@ int phylink_ethtool_ksettings_set(struct + pl->link_config.duplex = our_kset.base.duplex; + pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE; + +- if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { ++ /* If we have a PHY, phylib will call our link state function if the ++ * mode has changed, which will trigger a resolve and update the MAC ++ * configuration. For a fixed link, this isn't able to change any ++ * parameters, which just leaves inband mode. ++ */ ++ if (pl->link_an_mode == MLO_AN_INBAND && ++ !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { + phylink_mac_config(pl, &pl->link_config); + phylink_mac_an_restart(pl); + } +@@ -1290,14 +1296,16 @@ int phylink_ethtool_set_pauseparam(struc + if (pause->tx_pause) + config->pause |= MLO_PAUSE_TX; + +- if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) { ++ /* If we have a PHY, phylib will call our link state function if the ++ * mode has changed, which will trigger a resolve and update the MAC ++ * configuration. ++ */ ++ if (pl->phydev) { ++ phy_set_asym_pause(pl->phydev, pause->rx_pause, ++ pause->tx_pause); ++ } else if (!test_bit(PHYLINK_DISABLE_STOPPED, ++ &pl->phylink_disable_state)) { + switch (pl->link_an_mode) { +- case MLO_AN_PHY: +- /* Silently mark the carrier down, and then trigger a resolve */ +- netif_carrier_off(pl->netdev); +- phylink_run_resolve(pl); +- break; +- + case MLO_AN_FIXED: + /* Should we allow fixed links to change against the config? */ + phylink_resolve_flow(pl, config); |