596ecc8272bcdd0d727781c40ce6f38a443f02d8
[openwrt/staging/rmilecki.git] / target / linux / generic / backport-5.4 / 741-v5.5-net-phylink-fix-link-mode-modification-in-PHY-mode.patch
1 From 4c9633f75dc35abe1b9261e0415d77802f35741d Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@armlinux.org.uk>
3 Date: Tue, 5 Nov 2019 11:58:00 +0000
4 Subject: [PATCH 639/660] net: phylink: fix link mode modification in PHY mode
5
6 Modifying the link settings via phylink_ethtool_ksettings_set() and
7 phylink_ethtool_set_pauseparam() didn't always work as intended for
8 PHY based setups, as calling phylink_mac_config() would result in the
9 unresolved configuration being committed to the MAC, rather than the
10 configuration with the speed and duplex setting.
11
12 This would work fine if the update caused the link to renegotiate,
13 but if no settings have changed, phylib won't trigger a renegotiation
14 cycle, and the MAC will be left incorrectly configured.
15
16 Avoid calling phylink_mac_config() unless we are using an inband mode
17 in phylink_ethtool_ksettings_set(), and use phy_set_asym_pause() as
18 introduced in 4.20 to set the PHY settings in
19 phylink_ethtool_set_pauseparam().
20
21 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
22 ---
23 drivers/net/phy/phylink.c | 24 ++++++++++++++++--------
24 1 file changed, 16 insertions(+), 8 deletions(-)
25
26 --- a/drivers/net/phy/phylink.c
27 +++ b/drivers/net/phy/phylink.c
28 @@ -1210,7 +1210,13 @@ int phylink_ethtool_ksettings_set(struct
29 pl->link_config.duplex = our_kset.base.duplex;
30 pl->link_config.an_enabled = our_kset.base.autoneg != AUTONEG_DISABLE;
31
32 - if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
33 + /* If we have a PHY, phylib will call our link state function if the
34 + * mode has changed, which will trigger a resolve and update the MAC
35 + * configuration. For a fixed link, this isn't able to change any
36 + * parameters, which just leaves inband mode.
37 + */
38 + if (pl->link_an_mode == MLO_AN_INBAND &&
39 + !test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
40 phylink_mac_config(pl, &pl->link_config);
41 phylink_mac_an_restart(pl);
42 }
43 @@ -1290,14 +1296,16 @@ int phylink_ethtool_set_pauseparam(struc
44 if (pause->tx_pause)
45 config->pause |= MLO_PAUSE_TX;
46
47 - if (!test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state)) {
48 + /* If we have a PHY, phylib will call our link state function if the
49 + * mode has changed, which will trigger a resolve and update the MAC
50 + * configuration.
51 + */
52 + if (pl->phydev) {
53 + phy_set_asym_pause(pl->phydev, pause->rx_pause,
54 + pause->tx_pause);
55 + } else if (!test_bit(PHYLINK_DISABLE_STOPPED,
56 + &pl->phylink_disable_state)) {
57 switch (pl->link_an_mode) {
58 - case MLO_AN_PHY:
59 - /* Silently mark the carrier down, and then trigger a resolve */
60 - netif_carrier_off(pl->netdev);
61 - phylink_run_resolve(pl);
62 - break;
63 -
64 case MLO_AN_FIXED:
65 /* Should we allow fixed links to change against the config? */
66 phylink_resolve_flow(pl, config);