generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN
authorDaniel Golle <daniel@makrotopia.org>
Mon, 27 Mar 2023 17:41:54 +0000 (18:41 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Mon, 27 Mar 2023 18:07:54 +0000 (19:07 +0100)
Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
disabling auto-negotiation, e.g. using ethtool. While a proper fix
using SFP quirks is being discussed upstream, bring a work-around to
restore user experience to what it was before the switch to the
dedicated SGMII PCS driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch [new file with mode: 0644]

diff --git a/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch b/target/linux/generic/hack-5.15/750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch
new file mode 100644 (file)
index 0000000..b03f0fe
--- /dev/null
@@ -0,0 +1,40 @@
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(stru
+                                   struct phylink_link_state *state)
+ {
+       struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
+-      unsigned int bm, adv;
++      unsigned int bm, bmsr, adv;
+       /* Read the BMSR and LPA */
+       regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
+-      regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
++      bmsr = FIELD_GET(SGMII_BMSR, bm);
++
++      if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
++              state->link = !!(bmsr & BMSR_LSTATUS);
++              state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
++              state->speed = SPEED_2500;
++              state->duplex = DUPLEX_FULL;
+-      phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
+-                                       FIELD_GET(SGMII_LPA, adv));
++              return;
++      }
++
++      regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
++      phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
+ }
+ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int mode,
+@@ -134,7 +143,8 @@ static int mtk_pcs_lynxi_config(struct p
+               /* 1000base-X or 2500base-X autoneg */
+               sgm_mode = SGMII_REMOTE_FAULT_DIS;
+               use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+-                                         advertising);
++                                         advertising) &&
++                       !(interface == PHY_INTERFACE_MODE_2500BASEX);
+       } else {
+               /* 1000base-X or 2500base-X without autoneg */
+               sgm_mode = 0;