aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/pending-5.4/751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/pending-5.4/751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch')
-rw-r--r--target/linux/generic/pending-5.4/751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch58
1 files changed, 58 insertions, 0 deletions
diff --git a/target/linux/generic/pending-5.4/751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch b/target/linux/generic/pending-5.4/751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch
new file mode 100644
index 0000000000..1724d445b7
--- /dev/null
+++ b/target/linux/generic/pending-5.4/751-net-phylink-make-Broadcom-BCM84881-based-SFPs-work.patch
@@ -0,0 +1,58 @@
+From 3d8592a23dd67fb78ad85ddf711a059d3880fcb4 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Fri, 8 Nov 2019 17:19:16 +0000
+Subject: [PATCH 654/660] net: phylink: make Broadcom BCM84881 based SFPs work
+
+The Broadcom BCM84881 does not appear to send the SGMII control word
+when operating in SGMII mode, which causes network adapters to fail
+to link with the PHY, or decide to operate at fixed 1G speed, even if
+the PHY negotiated 100M.
+
+Work around this by detecting the Broadcom BCM84881 and switch to phy
+mode rather than inband mode.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+---
+ drivers/net/phy/phylink.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -1787,12 +1787,22 @@ static void phylink_sfp_link_up(void *up
+ phylink_run_resolve(pl);
+ }
+
++/* The Broadcom BCM84881 in the Methode DM7052 is unable to provide a SGMII
++ * or 802.3z control word, so inband will not work.
++ */
++static bool phylink_phy_no_inband(struct phy_device *phy)
++{
++ return phy->is_c45 &&
++ (phy->c45_ids.device_ids[1] & 0xfffffff0) == 0xae025150;
++}
++
+ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
+ {
+ struct phylink *pl = upstream;
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
+ phy_interface_t interface;
++ u8 mode;
+ int ret;
+
+ /*
+@@ -1807,8 +1817,13 @@ static int phylink_sfp_connect_phy(void
+ ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported);
+ ethtool_convert_legacy_u32_to_link_mode(advertising, phy->advertising);
+
++ if (phylink_phy_no_inband(phy))
++ mode = MLO_AN_PHY;
++ else
++ mode = MLO_AN_INBAND;
++
+ /* Do the initial configuration */
+- ret = phylink_sfp_config(pl, ML_AN_INBAND, supported, advertising);
++ ret = phylink_sfp_config(pl, mode, supported, advertising);
+ if (ret < 0)
+ return ret;
+