795-backport-phylink_pcs-helpers.patch 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. From 027586ae8ecacff49757ed854c020f35d24a599c Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <daniel@makrotopia.org>
  3. Date: Sat, 11 Mar 2023 03:44:41 +0000
  4. Subject: [PATCH] generic: backport some phylink helper functions
  5. It isn't feasible to literally backport all upstream phylink_pcs changes
  6. down to Linux 5.15: It's just too many patches, and many downstream
  7. drivers and hacks are likely to break. We are too close to branching off
  8. to risk this, and it's also just too much work.
  9. Instead just add helper functions used by modern PCS drivers while keeping
  10. the original functions instact as well. While this may add a kilobyte or
  11. two of extra kernel size, it has the advantage that we get the best of both
  12. worlds: None of the existing codepaths are touched, but yet we have the
  13. option to backport singular improvements to Ethernet drivers where needed.
  14. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  15. --- a/include/linux/phylink.h
  16. +++ b/include/linux/phylink.h
  17. @@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl)
  18. #define phylink_test(bm, mode) __phylink_do_bit(test_bit, bm, mode)
  19. void phylink_set_port_modes(unsigned long *bits);
  20. +
  21. +/**
  22. + * phylink_get_link_timer_ns - return the PCS link timer value
  23. + * @interface: link &typedef phy_interface_t mode
  24. + *
  25. + * Return the PCS link timer setting in nanoseconds for the PHY @interface
  26. + * mode, or -EINVAL if not appropriate.
  27. + */
  28. +static inline int phylink_get_link_timer_ns(phy_interface_t interface)
  29. +{
  30. + switch (interface) {
  31. + case PHY_INTERFACE_MODE_SGMII:
  32. + return 1600000;
  33. +
  34. + case PHY_INTERFACE_MODE_1000BASEX:
  35. + case PHY_INTERFACE_MODE_2500BASEX:
  36. + return 10000000;
  37. +
  38. + default:
  39. + return -EINVAL;
  40. + }
  41. +}
  42. +
  43. void phylink_helper_basex_speed(struct phylink_link_state *state);
  44. +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
  45. + u16 bmsr, u16 lpa);
  46. void phylink_mii_c22_pcs_get_state(struct mdio_device *pcs,
  47. struct phylink_link_state *state);
  48. +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
  49. + const unsigned long *advertising);
  50. int phylink_mii_c22_pcs_set_advertisement(struct mdio_device *pcs,
  51. phy_interface_t interface,
  52. const unsigned long *advertising);
  53. --- a/drivers/net/phy/phylink.c
  54. +++ b/drivers/net/phy/phylink.c
  55. @@ -931,7 +931,6 @@ static int phylink_change_inband_advert(
  56. return 0;
  57. }
  58. -
  59. static void phylink_mac_pcs_get_state(struct phylink *pl,
  60. struct phylink_link_state *state)
  61. {
  62. @@ -3015,6 +3014,52 @@ void phylink_mii_c22_pcs_get_state(struc
  63. EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
  64. /**
  65. + * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
  66. + * @state: a pointer to a &struct phylink_link_state.
  67. + * @bmsr: The value of the %MII_BMSR register
  68. + * @lpa: The value of the %MII_LPA register
  69. + *
  70. + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
  71. + * clause 37 negotiation and/or SGMII control.
  72. + *
  73. + * Parse the Clause 37 or Cisco SGMII link partner negotiation word into
  74. + * the phylink @state structure. This is suitable to be used for implementing
  75. + * the mac_pcs_get_state() member of the struct phylink_mac_ops structure if
  76. + * accessing @bmsr and @lpa cannot be done with MDIO directly.
  77. + */
  78. +void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
  79. + u16 bmsr, u16 lpa)
  80. +{
  81. + state->link = !!(bmsr & BMSR_LSTATUS);
  82. + state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
  83. + /* If there is no link or autonegotiation is disabled, the LP advertisement
  84. + * data is not meaningful, so don't go any further.
  85. + */
  86. + if (!state->link || !state->an_enabled)
  87. + return;
  88. +
  89. + switch (state->interface) {
  90. + case PHY_INTERFACE_MODE_1000BASEX:
  91. + phylink_decode_c37_word(state, lpa, SPEED_1000);
  92. + break;
  93. +
  94. + case PHY_INTERFACE_MODE_2500BASEX:
  95. + phylink_decode_c37_word(state, lpa, SPEED_2500);
  96. + break;
  97. +
  98. + case PHY_INTERFACE_MODE_SGMII:
  99. + case PHY_INTERFACE_MODE_QSGMII:
  100. + phylink_decode_sgmii_word(state, lpa);
  101. + break;
  102. +
  103. + default:
  104. + state->link = false;
  105. + break;
  106. + }
  107. +}
  108. +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_decode_state);
  109. +
  110. +/**
  111. * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
  112. * advertisement
  113. * @pcs: a pointer to a &struct mdio_device.
  114. @@ -3086,6 +3131,46 @@ int phylink_mii_c22_pcs_set_advertisemen
  115. EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
  116. /**
  117. + * phylink_mii_c22_pcs_encode_advertisement() - configure the clause 37 PCS
  118. + * advertisement
  119. + * @interface: the PHY interface mode being configured
  120. + * @advertising: the ethtool advertisement mask
  121. + *
  122. + * Helper for MAC PCS supporting the 802.3 clause 22 register set for
  123. + * clause 37 negotiation and/or SGMII control.
  124. + *
  125. + * Encode the clause 37 PCS advertisement as specified by @interface and
  126. + * @advertising.
  127. + *
  128. + * Return: The new value for @adv, or ``-EINVAL`` if it should not be changed.
  129. + */
  130. +int phylink_mii_c22_pcs_encode_advertisement(phy_interface_t interface,
  131. + const unsigned long *advertising)
  132. +{
  133. + u16 adv;
  134. +
  135. + switch (interface) {
  136. + case PHY_INTERFACE_MODE_1000BASEX:
  137. + case PHY_INTERFACE_MODE_2500BASEX:
  138. + adv = ADVERTISE_1000XFULL;
  139. + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
  140. + advertising))
  141. + adv |= ADVERTISE_1000XPAUSE;
  142. + if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
  143. + advertising))
  144. + adv |= ADVERTISE_1000XPSE_ASYM;
  145. + return adv;
  146. + case PHY_INTERFACE_MODE_SGMII:
  147. + case PHY_INTERFACE_MODE_QSGMII:
  148. + return 0x0001;
  149. + default:
  150. + /* Nothing to do for other modes */
  151. + return -EINVAL;
  152. + }
  153. +}
  154. +EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_encode_advertisement);
  155. +
  156. +/**
  157. * phylink_mii_c22_pcs_config() - configure clause 22 PCS
  158. * @pcs: a pointer to a &struct mdio_device.
  159. * @mode: link autonegotiation mode