750-net-pcs-mtk-lynxi-workaround-2500BaseX-no-an.patch 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. From 880d1311335120f64447ca9d11933872d734e19a Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <[email protected]>
  3. Date: Mon, 27 Mar 2023 18:41:54 +0100
  4. Subject: [PATCH] generic: pcs-mtk-lynxi: add hack to use 2500Base-X without AN
  5. Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
  6. disabling auto-negotiation, e.g. using ethtool. While a proper fix
  7. using SFP quirks is being discussed upstream, bring a work-around to
  8. restore user experience to what it was before the switch to the
  9. dedicated SGMII PCS driver.
  10. Signed-off-by: Daniel Golle <[email protected]>
  11. --- a/drivers/net/pcs/pcs-mtk-lynxi.c
  12. +++ b/drivers/net/pcs/pcs-mtk-lynxi.c
  13. @@ -114,14 +114,23 @@ static void mtk_pcs_lynxi_get_state(stru
  14. struct phylink_link_state *state)
  15. {
  16. struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
  17. - unsigned int bm, adv;
  18. + unsigned int bm, bmsr, adv;
  19. /* Read the BMSR and LPA */
  20. regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
  21. - regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
  22. + bmsr = FIELD_GET(SGMII_BMSR, bm);
  23. +
  24. + if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
  25. + state->link = !!(bmsr & BMSR_LSTATUS);
  26. + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
  27. + state->speed = SPEED_2500;
  28. + state->duplex = DUPLEX_FULL;
  29. - phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
  30. - FIELD_GET(SGMII_LPA, adv));
  31. + return;
  32. + }
  33. +
  34. + regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
  35. + phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
  36. }
  37. static void mtk_sgmii_reset(struct mtk_pcs_lynxi *mpcs)
  38. @@ -163,7 +172,8 @@ static int mtk_pcs_lynxi_config(struct p
  39. if (neg_mode & PHYLINK_PCS_NEG_INBAND)
  40. sgm_mode |= SGMII_REMOTE_FAULT_DIS;
  41. - if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
  42. + if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
  43. + interface != PHY_INTERFACE_MODE_2500BASEX) {
  44. if (interface == PHY_INTERFACE_MODE_SGMII)
  45. sgm_mode |= SGMII_SPEED_DUPLEX_AN;
  46. bmcr = BMCR_ANENABLE;