67 lines
2.7 KiB
Diff
67 lines
2.7 KiB
Diff
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);
|