703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. From e2e7f6e29c99a1c6afc0e0aa4b9ea80302d28720 Mon Sep 17 00:00:00 2001
  2. From: Daniel Golle <[email protected]>
  3. Date: Tue, 4 Jan 2022 12:07:46 +0000
  4. Subject: [PATCH 3/3] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
  5. access
  6. Implement read and write access to IEEE 802.3 Clause 45 Ethernet
  7. phy registers while making use of new mdiobus_c45_regad and
  8. mdiobus_c45_devad helpers.
  9. Tested on the Ubiquiti UniFi 6 LR access point featuring
  10. MediaTek MT7622BV WiSoC with Aquantia AQR112C.
  11. Signed-off-by: Daniel Golle <[email protected]>
  12. Signed-off-by: David S. Miller <[email protected]>
  13. ---
  14. drivers/net/ethernet/mediatek/mtk_eth_soc.c | 70 +++++++++++++++++----
  15. drivers/net/ethernet/mediatek/mtk_eth_soc.h | 3 +
  16. 2 files changed, 60 insertions(+), 13 deletions(-)
  17. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  18. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
  19. @@ -196,13 +196,35 @@ static int _mtk_mdio_write(struct mtk_et
  20. if (ret < 0)
  21. return ret;
  22. - mtk_w32(eth, PHY_IAC_ACCESS |
  23. - PHY_IAC_START_C22 |
  24. - PHY_IAC_CMD_WRITE |
  25. - PHY_IAC_REG(phy_reg) |
  26. - PHY_IAC_ADDR(phy_addr) |
  27. - PHY_IAC_DATA(write_data),
  28. - MTK_PHY_IAC);
  29. + if (phy_reg & MII_ADDR_C45) {
  30. + mtk_w32(eth, PHY_IAC_ACCESS |
  31. + PHY_IAC_START_C45 |
  32. + PHY_IAC_CMD_C45_ADDR |
  33. + PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
  34. + PHY_IAC_ADDR(phy_addr) |
  35. + PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
  36. + MTK_PHY_IAC);
  37. +
  38. + ret = mtk_mdio_busy_wait(eth);
  39. + if (ret < 0)
  40. + return ret;
  41. +
  42. + mtk_w32(eth, PHY_IAC_ACCESS |
  43. + PHY_IAC_START_C45 |
  44. + PHY_IAC_CMD_WRITE |
  45. + PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
  46. + PHY_IAC_ADDR(phy_addr) |
  47. + PHY_IAC_DATA(write_data),
  48. + MTK_PHY_IAC);
  49. + } else {
  50. + mtk_w32(eth, PHY_IAC_ACCESS |
  51. + PHY_IAC_START_C22 |
  52. + PHY_IAC_CMD_WRITE |
  53. + PHY_IAC_REG(phy_reg) |
  54. + PHY_IAC_ADDR(phy_addr) |
  55. + PHY_IAC_DATA(write_data),
  56. + MTK_PHY_IAC);
  57. + }
  58. ret = mtk_mdio_busy_wait(eth);
  59. if (ret < 0)
  60. @@ -219,12 +241,33 @@ static int _mtk_mdio_read(struct mtk_eth
  61. if (ret < 0)
  62. return ret;
  63. - mtk_w32(eth, PHY_IAC_ACCESS |
  64. - PHY_IAC_START_C22 |
  65. - PHY_IAC_CMD_C22_READ |
  66. - PHY_IAC_REG(phy_reg) |
  67. - PHY_IAC_ADDR(phy_addr),
  68. - MTK_PHY_IAC);
  69. + if (phy_reg & MII_ADDR_C45) {
  70. + mtk_w32(eth, PHY_IAC_ACCESS |
  71. + PHY_IAC_START_C45 |
  72. + PHY_IAC_CMD_C45_ADDR |
  73. + PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
  74. + PHY_IAC_ADDR(phy_addr) |
  75. + PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
  76. + MTK_PHY_IAC);
  77. +
  78. + ret = mtk_mdio_busy_wait(eth);
  79. + if (ret < 0)
  80. + return ret;
  81. +
  82. + mtk_w32(eth, PHY_IAC_ACCESS |
  83. + PHY_IAC_START_C45 |
  84. + PHY_IAC_CMD_C45_READ |
  85. + PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
  86. + PHY_IAC_ADDR(phy_addr),
  87. + MTK_PHY_IAC);
  88. + } else {
  89. + mtk_w32(eth, PHY_IAC_ACCESS |
  90. + PHY_IAC_START_C22 |
  91. + PHY_IAC_CMD_C22_READ |
  92. + PHY_IAC_REG(phy_reg) |
  93. + PHY_IAC_ADDR(phy_addr),
  94. + MTK_PHY_IAC);
  95. + }
  96. ret = mtk_mdio_busy_wait(eth);
  97. if (ret < 0)
  98. @@ -683,6 +726,7 @@ static int mtk_mdio_init(struct mtk_eth
  99. eth->mii_bus->name = "mdio";
  100. eth->mii_bus->read = mtk_mdio_read;
  101. eth->mii_bus->write = mtk_mdio_write;
  102. + eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
  103. eth->mii_bus->priv = eth;
  104. eth->mii_bus->parent = eth->dev;
  105. --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
  106. +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
  107. @@ -322,9 +322,12 @@
  108. #define PHY_IAC_ADDR_MASK GENMASK(24, 20)
  109. #define PHY_IAC_ADDR(x) FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
  110. #define PHY_IAC_CMD_MASK GENMASK(19, 18)
  111. +#define PHY_IAC_CMD_C45_ADDR FIELD_PREP(PHY_IAC_CMD_MASK, 0)
  112. #define PHY_IAC_CMD_WRITE FIELD_PREP(PHY_IAC_CMD_MASK, 1)
  113. #define PHY_IAC_CMD_C22_READ FIELD_PREP(PHY_IAC_CMD_MASK, 2)
  114. +#define PHY_IAC_CMD_C45_READ FIELD_PREP(PHY_IAC_CMD_MASK, 3)
  115. #define PHY_IAC_START_MASK GENMASK(17, 16)
  116. +#define PHY_IAC_START_C45 FIELD_PREP(PHY_IAC_START_MASK, 0)
  117. #define PHY_IAC_START_C22 FIELD_PREP(PHY_IAC_START_MASK, 1)
  118. #define PHY_IAC_DATA_MASK GENMASK(15, 0)
  119. #define PHY_IAC_DATA(x) FIELD_PREP(PHY_IAC_DATA_MASK, (x))