aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-5.4/741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch
diff options
context:
space:
mode:
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.patch66
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);