782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. From e19de30d20809af3221ef8a2648b8a8a52e02d90 Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <[email protected]>
  3. Date: Wed, 21 Sep 2022 01:23:14 +0100
  4. Subject: [PATCH 1/1] net: dsa: mt7530: add support for in-band link status
  5. Read link status from SGMII PCS for in-band managed 2500Base-X and
  6. 1000Base-X connection on a MAC port of the MT7531. This is needed to
  7. get the SFP cage working which is connected to SGMII interface of
  8. port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board.
  9. While at it also handle an_complete for both the autoneg and the
  10. non-autoneg codepath.
  11. Signed-off-by: Daniel Golle <[email protected]>
  12. Signed-off-by: David S. Miller <[email protected]>
  13. ---
  14. drivers/net/dsa/mt7530.c | 50 +++++++++++++++++++++++++++++-----------
  15. drivers/net/dsa/mt7530.h | 1 +
  16. 2 files changed, 38 insertions(+), 13 deletions(-)
  17. --- a/drivers/net/dsa/mt7530.c
  18. +++ b/drivers/net/dsa/mt7530.c
  19. @@ -2736,9 +2736,6 @@ mt7531_mac_config(struct dsa_switch *ds,
  20. case PHY_INTERFACE_MODE_NA:
  21. case PHY_INTERFACE_MODE_1000BASEX:
  22. case PHY_INTERFACE_MODE_2500BASEX:
  23. - if (phylink_autoneg_inband(mode))
  24. - return -EINVAL;
  25. -
  26. return mt7531_sgmii_setup_mode_force(priv, port, interface);
  27. default:
  28. return -EINVAL;
  29. @@ -2814,13 +2811,6 @@ unsupported:
  30. return;
  31. }
  32. - if (phylink_autoneg_inband(mode) &&
  33. - state->interface != PHY_INTERFACE_MODE_SGMII) {
  34. - dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
  35. - __func__);
  36. - return;
  37. - }
  38. -
  39. mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
  40. mcr_new = mcr_cur;
  41. mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
  42. @@ -2957,6 +2947,9 @@ static void mt753x_phylink_get_caps(stru
  43. config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
  44. MAC_10 | MAC_100 | MAC_1000FD;
  45. + if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
  46. + config->mac_capabilities |= MAC_2500FD;
  47. +
  48. /* This driver does not make use of the speed, duplex, pause or the
  49. * advertisement in its mac_config, so it is safe to mark this driver
  50. * as non-legacy.
  51. @@ -3022,6 +3015,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
  52. status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
  53. state->link = !!(status & MT7531_SGMII_LINK_STATUS);
  54. + state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
  55. if (state->interface == PHY_INTERFACE_MODE_SGMII &&
  56. (status & MT7531_SGMII_AN_ENABLE)) {
  57. val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
  58. @@ -3052,16 +3046,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
  59. return 0;
  60. }
  61. +static void
  62. +mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
  63. + struct phylink_link_state *state)
  64. +{
  65. + unsigned int val;
  66. +
  67. + val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
  68. + state->link = !!(val & MT7531_SGMII_LINK_STATUS);
  69. + if (!state->link)
  70. + return;
  71. +
  72. + state->an_complete = state->link;
  73. +
  74. + if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
  75. + state->speed = SPEED_2500;
  76. + else
  77. + state->speed = SPEED_1000;
  78. +
  79. + state->duplex = DUPLEX_FULL;
  80. + state->pause = MLO_PAUSE_NONE;
  81. +}
  82. +
  83. static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
  84. struct phylink_link_state *state)
  85. {
  86. struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
  87. int port = pcs_to_mt753x_pcs(pcs)->port;
  88. - if (state->interface == PHY_INTERFACE_MODE_SGMII)
  89. + if (state->interface == PHY_INTERFACE_MODE_SGMII) {
  90. mt7531_sgmii_pcs_get_state_an(priv, port, state);
  91. - else
  92. - state->link = false;
  93. + return;
  94. + } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
  95. + (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
  96. + mt7531_sgmii_pcs_get_state_inband(priv, port, state);
  97. + return;
  98. + }
  99. +
  100. + state->link = false;
  101. }
  102. static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
  103. @@ -3102,6 +3124,8 @@ mt753x_setup(struct dsa_switch *ds)
  104. priv->pcs[i].pcs.ops = priv->info->pcs_ops;
  105. priv->pcs[i].priv = priv;
  106. priv->pcs[i].port = i;
  107. + if (mt753x_is_mac_port(i))
  108. + priv->pcs[i].pcs.poll = 1;
  109. }
  110. ret = priv->info->sw_setup(ds);
  111. --- a/drivers/net/dsa/mt7530.h
  112. +++ b/drivers/net/dsa/mt7530.h
  113. @@ -373,6 +373,7 @@ enum mt7530_vlan_port_acc_frm {
  114. #define MT7531_SGMII_LINK_STATUS BIT(18)
  115. #define MT7531_SGMII_AN_ENABLE BIT(12)
  116. #define MT7531_SGMII_AN_RESTART BIT(9)
  117. +#define MT7531_SGMII_AN_COMPLETE BIT(21)
  118. /* Register for SGMII PCS_SPPED_ABILITY */
  119. #define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)