100-malibu-phy-drop-usage-of-first_phy_addr.patch 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. From 46ed8163ac0d9a11a629f1c446e8c5e711cf35d6 Mon Sep 17 00:00:00 2001
  2. From: Christian Marangi <[email protected]>
  3. Date: Sat, 11 Nov 2023 18:13:02 +0100
  4. Subject: [PATCH] malibu-phy: drop usage of first_phy_addr
  5. I'm very confused by this and to me it's not clear the real usage of
  6. this logic.
  7. From what I can see the usage of this is EXTREMELY FRAGILE and results
  8. in dangerous results if the OEM (or anyone that by chance try to
  9. implement things in a logical manner) deviates from the default values
  10. from the "magical template".
  11. To be in more details. With QSDK 12.4, some tweaks were done to improve
  12. autoneg and now on every call of port status, the phydev is tried to
  13. add. This resulted in the call and log spam of an error with ports that
  14. are actually not present on the system with qsdk reporting phydev is
  15. NULL. This itself is not an error and printing the error is correct.
  16. What is actually an error from ages is setting generic bitmap reporting
  17. presence of port that are actually not present. This is very common on
  18. OEM where the switch_lan_bmp is always a variant of 0x1e (that on bitmap
  19. results in PORT1 PORT2 PORT3 PORT4 present) or 0x3e (PORT1 PORT2 PORT3
  20. PORT4 PORT5). Reality is that many device are used as AP with one LAN
  21. port or one WAN port. (or even exotic configuration with PORT1 not
  22. present and PORT2 PORT3 PORT4 present (Xiaomi 3600)
  23. With this finding one can say... ok nice, then lets update the DT and
  24. set the correct bitmap...
  25. Again world is a bad place and reality is that this cause wonderful
  26. regression in some case of by extreme luck the first ever connected
  27. port working and the rest of the switch dead.
  28. The problem has been bisected to all the device that doesn't have the
  29. PORT1 declared in any of the bitmap.
  30. With this perfection in mind, on to the REAL problem.
  31. malibu_phy_hw_init FOR SOME REASON, set a global variable first_phy_addr
  32. to the first detected PHY addr that coincidentally is always PORT1.
  33. PORT1 addr is 0x0. The entire code in malibu_phy use this variable to
  34. derive the phy addrs in some function.
  35. Declaring a bitmap where the PORT1 is missing (or worse PORT4 the only
  36. one connected) result in first_phy_addr set to 1 or whatever phy addr is
  37. detected first setting wrong value all over the init stage.
  38. To fix this, just drop this variable and hardcode everything to assume
  39. the first phy adrr is ALWAYS 0 and remove calculation and use define for
  40. special case.
  41. With the following change normal switch traffic is restored and ports
  42. function is recovered.
  43. Signed-off-by: Christian Marangi <[email protected]>
  44. ---
  45. src/hsl/phy/malibu_phy.c | 63 +++++++++++++++++-----------------------
  46. 1 file changed, 26 insertions(+), 37 deletions(-)
  47. --- a/src/hsl/phy/malibu_phy.c
  48. +++ b/src/hsl/phy/malibu_phy.c
  49. @@ -26,8 +26,9 @@
  50. #include "qcaphy_common.h"
  51. #include "ssdk_plat.h"
  52. -static a_uint32_t first_phy_addr = MAX_PHY_ADDR;
  53. static a_uint32_t combo_phy_addr = MAX_PHY_ADDR;
  54. +#define PORT4_PHY_ID 0x4
  55. +#define PORT5_PHY_ID 0x5
  56. #define COMBO_PHY_ID combo_phy_addr
  57. /******************************************************************************
  58. @@ -1250,10 +1251,10 @@ sw_error_t
  59. malibu_phy_serdes_reset(a_uint32_t dev_id)
  60. {
  61. - hsl_phy_mii_reg_write(dev_id, first_phy_addr + MALIBU_PHY_PSGMII_ADDR_INC,
  62. + hsl_phy_mii_reg_write(dev_id, MALIBU_PHY_PSGMII_ADDR_INC,
  63. MALIBU_MODE_RESET_REG, MALIBU_MODE_CHANAGE_RESET);
  64. mdelay(100);
  65. - hsl_phy_mii_reg_write(dev_id, first_phy_addr + MALIBU_PHY_PSGMII_ADDR_INC,
  66. + hsl_phy_mii_reg_write(dev_id, MALIBU_PHY_PSGMII_ADDR_INC,
  67. MALIBU_MODE_RESET_REG, MALIBU_MODE_RESET_DEFAULT_VALUE);
  68. return SW_OK;
  69. @@ -1271,8 +1272,7 @@ malibu_phy_interface_set_mode(a_uint32_t
  70. a_uint16_t phy_data = 0;
  71. static fal_port_interface_mode_t phy_mode = PORT_INTERFACE_MODE_MAX;
  72. - if ((phy_addr < first_phy_addr) ||
  73. - (phy_addr > (first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)))
  74. + if (phy_addr > MALIBU_PHY_MAX_ADDR_INC)
  75. return SW_NOT_SUPPORTED;
  76. /*if interface_mode have been configured, then no need to configure again*/
  77. if(phy_mode == interface_mode)
  78. @@ -1295,20 +1295,19 @@ malibu_phy_interface_set_mode(a_uint32_t
  79. return SW_BAD_PARAM;
  80. }
  81. - hsl_phy_modify_mii(dev_id,
  82. - first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG,
  83. + hsl_phy_modify_mii(dev_id, MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG,
  84. BITS(0, 4), phy_data);
  85. /* reset operation */
  86. malibu_phy_serdes_reset(dev_id);
  87. if (interface_mode == PHY_PSGMII_FIBER) {
  88. - hsl_phy_mii_reg_write(dev_id, first_phy_addr + MALIBU_PHY_MAX_ADDR_INC,
  89. + hsl_phy_mii_reg_write(dev_id, MALIBU_PHY_MAX_ADDR_INC,
  90. MALIBU_PHY_CHIP_CONFIG, MALIBU_MODECTRL_DFLT);
  91. - hsl_phy_mii_reg_write(dev_id, first_phy_addr + MALIBU_PHY_MAX_ADDR_INC,
  92. + hsl_phy_mii_reg_write(dev_id, MALIBU_PHY_MAX_ADDR_INC,
  93. MALIBU_PHY_CONTROL, MALIBU_MIICTRL_DFLT);
  94. hsl_phy_phydev_autoneg_update(dev_id,
  95. - first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, A_FALSE, 0);
  96. + MALIBU_PHY_MAX_ADDR_INC, A_FALSE, 0);
  97. }
  98. phy_mode = interface_mode;
  99. SSDK_DEBUG("malibu phy is configured as phy_mode:0x%x\n", phy_mode);
  100. @@ -1329,13 +1328,12 @@ malibu_phy_interface_get_mode(a_uint32_t
  101. a_uint16_t phy_data;
  102. a_uint16_t copper_mode;
  103. - if ((phy_addr < first_phy_addr) ||
  104. - (phy_addr > (first_phy_addr + MALIBU_PHY_MAX_ADDR_INC))) {
  105. + if (phy_addr > MALIBU_PHY_MAX_ADDR_INC) {
  106. return SW_NOT_SUPPORTED;
  107. }
  108. phy_data = hsl_phy_mii_reg_read(dev_id,
  109. - first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG);
  110. + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG);
  111. copper_mode = ((phy_data & MALIBU_PHY_COPPER_MODE) >> 0xf);
  112. phy_data &= 0x000f;
  113. @@ -1344,13 +1342,13 @@ malibu_phy_interface_get_mode(a_uint32_t
  114. *interface_mode = PHY_PSGMII_BASET;
  115. break;
  116. case MALIBU_PHY_PSGMII_BX1000:
  117. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  118. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  119. *interface_mode = PHY_PSGMII_BX1000;
  120. else
  121. *interface_mode = PHY_PSGMII_BASET;
  122. break;
  123. case MALIBU_PHY_PSGMII_FX100:
  124. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  125. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  126. *interface_mode = PHY_PSGMII_FX100;
  127. else
  128. *interface_mode = PHY_PSGMII_BASET;
  129. @@ -1359,14 +1357,14 @@ malibu_phy_interface_get_mode(a_uint32_t
  130. if (copper_mode) {
  131. *interface_mode = PHY_PSGMII_BASET;
  132. } else {
  133. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  134. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  135. *interface_mode = PHY_PSGMII_FIBER;
  136. else
  137. *interface_mode = PHY_PSGMII_BASET;
  138. }
  139. break;
  140. case MALIBU_PHY_SGMII_BASET:
  141. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  142. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  143. *interface_mode = PHY_SGMII_BASET;
  144. else
  145. *interface_mode = PORT_QSGMII;
  146. @@ -1392,13 +1390,12 @@ malibu_phy_interface_get_mode_status(a_u
  147. a_uint16_t phy_data, phy_mode, phy_mode_status;
  148. a_uint16_t copper_mode;
  149. - if ((phy_addr < first_phy_addr) ||
  150. - (phy_addr > (first_phy_addr + MALIBU_PHY_MAX_ADDR_INC))) {
  151. + if (phy_addr > MALIBU_PHY_MAX_ADDR_INC) {
  152. return SW_NOT_SUPPORTED;
  153. }
  154. phy_data = hsl_phy_mii_reg_read(dev_id,
  155. - first_phy_addr + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG);
  156. + MALIBU_PHY_MAX_ADDR_INC, MALIBU_PHY_CHIP_CONFIG);
  157. copper_mode = ((phy_data & MALIBU_PHY_COPPER_MODE) >> 0xf);
  158. phy_mode = phy_data & 0x000f;
  159. phy_mode_status = (phy_data & 0x00f0) >> 0x4;
  160. @@ -1407,7 +1404,7 @@ malibu_phy_interface_get_mode_status(a_u
  161. if (copper_mode) {
  162. *interface_mode_status = PHY_PSGMII_BASET;
  163. } else {
  164. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  165. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  166. *interface_mode_status = PHY_PSGMII_FIBER;
  167. else
  168. *interface_mode_status = PHY_PSGMII_BASET;
  169. @@ -1418,19 +1415,19 @@ malibu_phy_interface_get_mode_status(a_u
  170. *interface_mode_status = PHY_PSGMII_BASET;
  171. break;
  172. case MALIBU_PHY_PSGMII_BX1000:
  173. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  174. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  175. *interface_mode_status = PHY_PSGMII_BX1000;
  176. else
  177. *interface_mode_status = PHY_PSGMII_BASET;
  178. break;
  179. case MALIBU_PHY_PSGMII_FX100:
  180. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  181. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  182. *interface_mode_status = PHY_PSGMII_FX100;
  183. else
  184. *interface_mode_status = PHY_PSGMII_BASET;
  185. break;
  186. case MALIBU_PHY_SGMII_BASET:
  187. - if (phy_addr == first_phy_addr + MALIBU_PHY_MAX_ADDR_INC)
  188. + if (phy_addr == MALIBU_PHY_MAX_ADDR_INC)
  189. *interface_mode_status = PHY_SGMII_BASET;
  190. else
  191. *interface_mode_status = PORT_QSGMII;
  192. @@ -1795,10 +1792,6 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_
  193. {
  194. phy_cnt ++;
  195. phy_addr = qca_ssdk_port_to_phy_addr(dev_id, port_id);
  196. - if (phy_addr < first_phy_addr)
  197. - {
  198. - first_phy_addr = phy_addr;
  199. - }
  200. /*enable phy power saving function by default */
  201. malibu_phy_set_8023az(dev_id, phy_addr, A_TRUE);
  202. malibu_phy_set_powersave(dev_id, phy_addr, A_TRUE);
  203. @@ -1824,29 +1817,25 @@ malibu_phy_hw_init(a_uint32_t dev_id, a_
  204. MALIBU_EXTENDED_NEXT_PAGE_EN, 0);
  205. }
  206. }
  207. - /* qca 8072 two ports phy chip's firstly address to init phy chip */
  208. - if ((phy_cnt == QCA8072_PHY_NUM) && (first_phy_addr >= 0x3)) {
  209. - first_phy_addr = first_phy_addr - 0x3;
  210. - }
  211. /*workaround to enable AZ transmitting ability*/
  212. - hsl_phy_mmd_reg_write(dev_id, first_phy_addr + 5, A_FALSE, MALIBU_PHY_MMD1_NUM,
  213. + hsl_phy_mmd_reg_write(dev_id, PORT5_PHY_ID, A_FALSE, MALIBU_PHY_MMD1_NUM,
  214. MALIBU_PSGMII_MODE_CTRL, MALIBU_PHY_PSGMII_MODE_CTRL_ADJUST_VALUE);
  215. /* adjust psgmii serdes tx amp */
  216. - hsl_phy_mii_reg_write(dev_id, first_phy_addr + 5,
  217. + hsl_phy_mii_reg_write(dev_id, PORT5_PHY_ID,
  218. MALIBU_PSGMII_TX_DRIVER_1_CTRL, MALIBU_PHY_PSGMII_REDUCE_SERDES_TX_AMP);
  219. /* to avoid psgmii module goes into hibernation, work with psgmii self test*/
  220. - hsl_phy_modify_mmd(dev_id, first_phy_addr + 4, A_FALSE, MALIBU_PHY_MMD3_NUM,
  221. + hsl_phy_modify_mmd(dev_id, PORT4_PHY_ID, A_FALSE, MALIBU_PHY_MMD3_NUM,
  222. MALIBU_PHY_MMD3_ADDR_REMOTE_LOOPBACK_CTRL, BIT(1), 0);
  223. mode = ssdk_dt_global_get_mac_mode(dev_id, 0);
  224. if (mode == PORT_WRAPPER_PSGMII_FIBER)
  225. - malibu_phy_interface_set_mode(dev_id, first_phy_addr, PHY_PSGMII_FIBER);
  226. + malibu_phy_interface_set_mode(dev_id, 0x0, PHY_PSGMII_FIBER);
  227. /*init combo phy address*/
  228. - combo_phy_addr = first_phy_addr+4;
  229. + combo_phy_addr = PORT4_PHY_ID;
  230. return SW_OK;
  231. }