ofw.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * Copyright (c) 2006-2024 RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-09-25 zhujiale the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <stdio.h>
  13. #define DBG_TAG "rtdm.phy"
  14. #define DBG_LVL DBG_INFO
  15. #include <rtdbg.h>
  16. #include "ofw.h"
  17. static const char* const rt_phy_modes[] =
  18. {
  19. [RT_PHY_INTERFACE_MODE_NA] = "",
  20. [RT_PHY_INTERFACE_MODE_INTERNAL] = "internal",
  21. [RT_PHY_INTERFACE_MODE_MII] = "mii",
  22. [RT_PHY_INTERFACE_MODE_GMII] = "gmii",
  23. [RT_PHY_INTERFACE_MODE_SGMII] = "sgmii",
  24. [RT_PHY_INTERFACE_MODE_TBI] = "tbi",
  25. [RT_PHY_INTERFACE_MODE_REVMII] = "rev-mii",
  26. [RT_PHY_INTERFACE_MODE_RMII] = "rmii",
  27. [RT_PHY_INTERFACE_MODE_REVRMII] = "rev-rmii",
  28. [RT_PHY_INTERFACE_MODE_RGMII] = "rgmii",
  29. [RT_PHY_INTERFACE_MODE_RGMII_ID] = "rgmii-id",
  30. [RT_PHY_INTERFACE_MODE_RGMII_RXID] = "rgmii-rxid",
  31. [RT_PHY_INTERFACE_MODE_RGMII_TXID] = "rgmii-txid",
  32. [RT_PHY_INTERFACE_MODE_RTBI] = "rtbi",
  33. [RT_PHY_INTERFACE_MODE_SMII] = "smii",
  34. [RT_PHY_INTERFACE_MODE_XGMII] = "xgmii",
  35. [RT_PHY_INTERFACE_MODE_XLGMII] = "xlgmii",
  36. [RT_PHY_INTERFACE_MODE_MOCA] = "moca",
  37. [RT_PHY_INTERFACE_MODE_PSGMII] = "psgmii",
  38. [RT_PHY_INTERFACE_MODE_QSGMII] = "qsgmii",
  39. [RT_PHY_INTERFACE_MODE_TRGMII] = "trgmii",
  40. [RT_PHY_INTERFACE_MODE_1000BASEX] = "1000base-x",
  41. [RT_PHY_INTERFACE_MODE_1000BASEKX] = "1000base-kx",
  42. [RT_PHY_INTERFACE_MODE_2500BASEX] = "2500base-x",
  43. [RT_PHY_INTERFACE_MODE_5GBASER] = "5gbase-r",
  44. [RT_PHY_INTERFACE_MODE_RXAUI] = "rxaui",
  45. [RT_PHY_INTERFACE_MODE_XAUI] = "xaui",
  46. [RT_PHY_INTERFACE_MODE_10GBASER] = "10gbase-r",
  47. [RT_PHY_INTERFACE_MODE_25GBASER] = "25gbase-r",
  48. [RT_PHY_INTERFACE_MODE_USXGMII] = "usxgmii",
  49. [RT_PHY_INTERFACE_MODE_10GKR] = "10gbase-kr",
  50. [RT_PHY_INTERFACE_MODE_100BASEX] = "100base-x",
  51. [RT_PHY_INTERFACE_MODE_QUSGMII] = "qusgmii",
  52. [RT_PHY_INTERFACE_MODE_MAX] = "",
  53. };
  54. static rt_err_t _get_interface_by_name(const char *name, rt_phy_interface *interface)
  55. {
  56. for (int i = 0; i < RT_PHY_INTERFACE_MODE_MAX; i++)
  57. {
  58. if (!strcmp(name, rt_phy_modes[i]))
  59. {
  60. *interface = i;
  61. return RT_EOK;
  62. }
  63. }
  64. return -RT_ERROR;
  65. }
  66. rt_err_t rt_ofw_get_interface(struct rt_ofw_node *np, rt_phy_interface *interface)
  67. {
  68. const char *phy_mode = RT_NULL;
  69. if (rt_ofw_prop_read_string(np, "phy-mode", &phy_mode))
  70. rt_ofw_prop_read_string(np, "phy-connection-type", &phy_mode);
  71. if (!phy_mode)
  72. return -RT_ERROR;
  73. return _get_interface_by_name(phy_mode, interface);
  74. }
  75. rt_err_t rt_ofw_get_mac_addr_by_name(struct rt_ofw_node *np, const char *name, rt_uint8_t *addr)
  76. {
  77. rt_ssize_t len;
  78. const void *p;
  79. p = rt_ofw_prop_read_raw(np, name, &len);
  80. if (p)
  81. {
  82. rt_memcpy(addr, p, len);
  83. return RT_EOK;
  84. }
  85. return -RT_ERROR;
  86. }
  87. rt_err_t rt_ofw_get_mac_addr(struct rt_ofw_node *np, rt_uint8_t *addr)
  88. {
  89. if (!rt_ofw_get_mac_addr_by_name(np, "mac-address", addr))
  90. return RT_EOK;
  91. if (!rt_ofw_get_mac_addr_by_name(np, "local-mac-address", addr))
  92. return RT_EOK;
  93. if (!rt_ofw_get_mac_addr_by_name(np, "address", addr))
  94. return RT_EOK;
  95. return -RT_ERROR;
  96. }
  97. rt_err_t rt_ofw_get_phyid(struct rt_ofw_node *np,rt_uint32_t *id)
  98. {
  99. const char *phy_id;
  100. unsigned int upper, lower;
  101. int ret;
  102. ret = rt_ofw_prop_read_string(np,"compatible",&phy_id);
  103. if (ret)
  104. return ret;
  105. ret = rt_sscanf(phy_id,"ethernet-phy-id%4x.%4x",&upper, &lower);
  106. if(ret != 2)
  107. return -RT_ERROR;
  108. *id = ((upper & 0xffff) << 16) | (lower & 0xffff);
  109. return RT_EOK;
  110. }
  111. struct rt_phy_device *rt_ofw_create_phy(struct mii_bus *bus,struct rt_ofw_node *np,int phyaddr)
  112. {
  113. struct rt_phy_device *dev = RT_NULL;
  114. struct rt_ofw_node *phy_node;
  115. int ret;
  116. rt_uint32_t id = 0xffff;
  117. phy_node = rt_ofw_parse_phandle(np, "phy-handle", 0);
  118. if (!phy_node)
  119. {
  120. LOG_D("Failed to find phy-handle");
  121. return RT_NULL;
  122. }
  123. ret = rt_ofw_get_phyid(np, &id);
  124. if (ret)
  125. {
  126. LOG_D("Failed to read eth PHY id, err: %d\n", ret);
  127. return RT_NULL;
  128. }
  129. LOG_D("Found a PHY id: 0x%x\n", id);
  130. dev = rt_phy_device_create(bus, phyaddr, id, RT_FALSE);
  131. if(dev)
  132. dev->node = phy_node;
  133. return dev;
  134. }