1724d445b7087191fce2e359d024800c7ab46953
[oweals/openwrt.git] / target / linux / generic / pending-5.4 / 751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch
1 From 3d8592a23dd67fb78ad85ddf711a059d3880fcb4 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@armlinux.org.uk>
3 Date: Fri, 8 Nov 2019 17:19:16 +0000
4 Subject: [PATCH 654/660] net: phylink: make Broadcom BCM84881 based SFPs work
5
6 The Broadcom BCM84881 does not appear to send the SGMII control word
7 when operating in SGMII mode, which causes network adapters to fail
8 to link with the PHY, or decide to operate at fixed 1G speed, even if
9 the PHY negotiated 100M.
10
11 Work around this by detecting the Broadcom BCM84881 and switch to phy
12 mode rather than inband mode.
13
14 Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
15 ---
16  drivers/net/phy/phylink.c | 17 ++++++++++++++++-
17  1 file changed, 16 insertions(+), 1 deletion(-)
18
19 --- a/drivers/net/phy/phylink.c
20 +++ b/drivers/net/phy/phylink.c
21 @@ -1787,12 +1787,22 @@ static void phylink_sfp_link_up(void *up
22         phylink_run_resolve(pl);
23  }
24  
25 +/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII
26 + * or 802.3z control word, so inband will not work.
27 + */
28 +static bool phylink_phy_no_inband(struct phy_device *phy)
29 +{
30 +       return phy->is_c45 &&
31 +               (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150;
32 +}
33 +
34  static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
35  {
36         struct phylink *pl = upstream;
37         __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
38         __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
39         phy_interface_t interface;
40 +       u8 mode;
41         int ret;
42  
43         /*
44 @@ -1807,8 +1817,13 @@ static int phylink_sfp_connect_phy(void
45         ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
46         ethtool_convert_legacy_u32_to_link_mode(advertising, phy->advertising);
47  
48 +       if (phylink_phy_no_inband(phy))
49 +               mode = MLO_AN_PHY;
50 +       else
51 +               mode = MLO_AN_INBAND;
52 +
53         /* Do the initial configuration */
54 -       ret = phylink_sfp_config(pl, ML_AN_INBAND, supported, advertising);
55 +       ret = phylink_sfp_config(pl, mode, supported, advertising);
56         if (ret < 0)
57                 return ret;
58