phy.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  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. * 2020-09-27 wangqiang first version
  9. * 2024-10-08 zhujiale add phy v2.0
  10. */
  11. #include <stddef.h>
  12. #include <rthw.h>
  13. #include <rtdevice.h>
  14. #define DBG_TAG "rtdm.phy"
  15. #define DBG_LVL DBG_INFO
  16. #include <rtdbg.h>
  17. #ifdef RT_USING_PHY
  18. static rt_ssize_t phy_device_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t count)
  19. {
  20. struct rt_phy_device *phy = (struct rt_phy_device *)dev->user_data;
  21. struct rt_phy_msg *msg = (struct rt_phy_msg *)buffer;
  22. return phy->bus->ops->read(phy->bus, phy->addr, msg->reg, &(msg->value), 4);
  23. }
  24. static rt_ssize_t phy_device_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t count)
  25. {
  26. struct rt_phy_device *phy = (struct rt_phy_device *)dev->user_data;
  27. struct rt_phy_msg *msg = (struct rt_phy_msg *)buffer;
  28. return phy->bus->ops->write(phy->bus, phy->addr, msg->reg, &(msg->value), 4);
  29. }
  30. #ifdef RT_USING_DEVICE_OPS
  31. const static struct rt_device_ops phy_ops =
  32. {
  33. RT_NULL,
  34. RT_NULL,
  35. RT_NULL,
  36. phy_device_read,
  37. phy_device_write,
  38. RT_NULL,
  39. };
  40. #endif
  41. /*
  42. * phy device register
  43. */
  44. rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name)
  45. {
  46. rt_err_t ret;
  47. struct rt_device *device;
  48. device = &(phy->parent);
  49. device->type = RT_Device_Class_PHY;
  50. device->rx_indicate = RT_NULL;
  51. device->tx_complete = RT_NULL;
  52. #ifdef RT_USING_DEVICE_OPS
  53. device->ops = &phy_ops;
  54. #else
  55. device->init = NULL;
  56. device->open = NULL;
  57. device->close = NULL;
  58. device->read = phy_device_read;
  59. device->write = phy_device_write;
  60. device->control = NULL;
  61. #endif
  62. device->user_data = phy;
  63. /* register a character device */
  64. ret = rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
  65. return ret;
  66. }
  67. #endif
  68. #ifdef RT_USING_PHY_V2
  69. int rt_phy_set_supported(struct rt_phy_device *phydev, rt_uint32_t max_speed)
  70. {
  71. phydev->supported &= RT_PHY_DEFAULT_FEATURES;
  72. switch (max_speed)
  73. {
  74. default:
  75. return -ENOTSUP;
  76. case SPEED_1000:
  77. phydev->supported |= RT_PHY_1000BT_FEATURES;
  78. case SPEED_100:
  79. phydev->supported |= RT_PHY_100BT_FEATURES;
  80. case SPEED_10:
  81. phydev->supported |= RT_PHY_10BT_FEATURES;
  82. }
  83. return 0;
  84. }
  85. int rt_phy_read(struct rt_phy_device *phydev, int devad, int regnum)
  86. {
  87. struct mii_bus *bus = phydev->bus;
  88. if(phydev->is_c45)
  89. {
  90. if(bus->read_c45)
  91. return bus->read_c45(bus, phydev->addr, devad, regnum);
  92. }
  93. if( bus && bus->read )
  94. return bus->read(bus, phydev->addr, devad, regnum);
  95. LOG_D("no read function\n");
  96. return -1;
  97. }
  98. int rt_phy_write(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val)
  99. {
  100. struct mii_bus *bus = phydev->bus;
  101. if(phydev->is_c45)
  102. {
  103. if(bus->write_c45)
  104. return bus->write_c45(bus, phydev->addr, devad, regnum, val);
  105. }
  106. if( bus && bus->write )
  107. return bus->write(bus, phydev->addr, devad, regnum, val);
  108. LOG_D("no write function\n");
  109. return -1;
  110. }
  111. int rt_phy_startup(struct rt_phy_device *phydev)
  112. {
  113. if(!phydev->drv)
  114. {
  115. LOG_D("PHY device hace no driver\n");
  116. return -1;
  117. }
  118. if (phydev->drv->startup)
  119. return phydev->drv->startup(phydev);
  120. LOG_D("phy startup err\n");
  121. return -1;
  122. }
  123. int rt_phy_config(struct rt_phy_device *phydev)
  124. {
  125. if(!phydev->drv)
  126. {
  127. LOG_D("PHY device hace no driver\n");
  128. return -1;
  129. }
  130. if (phydev->drv->config)
  131. return phydev->drv->config(phydev);
  132. LOG_D("no config function\n");
  133. return -1;
  134. }
  135. int rt_phy_shutdown(struct rt_phy_device *phydev)
  136. {
  137. if(!phydev->drv)
  138. {
  139. LOG_D("PHY device hace no driver\n");
  140. return -1;
  141. }
  142. if (phydev->drv->shutdown)
  143. phydev->drv->shutdown(phydev);
  144. LOG_D("no shutdown function\n");
  145. return -1;
  146. }
  147. void rt_phy_mmd_start_indirect(struct rt_phy_device *phydev, int devad, int regnum)
  148. {
  149. /* Write the desired MMD Devad */
  150. rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_CTRL, devad);
  151. /* Write the desired MMD register address */
  152. rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_DATA, regnum);
  153. /* Select the Function : DATA with no post increment */
  154. rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_CTRL,
  155. (devad | RT_MII_MMD_CTRL_NOINCR));
  156. }
  157. int rt_phy_read_mmd(struct rt_phy_device *phydev, int devad, int regnum)
  158. {
  159. struct rt_phy_driver *drv = phydev->drv;
  160. if (regnum > (rt_uint16_t)~0 || devad > 32 || !drv)
  161. return -EINVAL;
  162. if (drv->read_mmd)
  163. return drv->read_mmd(phydev, devad, regnum);
  164. if ((drv->features & RT_PHY_10G_FEATURES) == RT_PHY_10G_FEATURES ||
  165. devad == RT_MDIO_DEVAD_NONE || !devad)
  166. return rt_phy_read(phydev, devad, regnum);
  167. rt_phy_mmd_start_indirect(phydev, devad, regnum);
  168. return rt_phy_read(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_DATA);
  169. }
  170. int rt_phy_write_mmd(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val)
  171. {
  172. struct rt_phy_driver *drv = phydev->drv;
  173. if (regnum > (rt_uint16_t)~0 || devad > 32 || !drv)
  174. return -EINVAL;
  175. if (drv->write_mmd)
  176. return drv->write_mmd(phydev, devad, regnum, val);
  177. if ((drv->features & RT_PHY_10G_FEATURES) == RT_PHY_10G_FEATURES ||
  178. devad == RT_MDIO_DEVAD_NONE || !devad)
  179. return rt_phy_write(phydev, devad, regnum, val);
  180. rt_phy_mmd_start_indirect(phydev, devad, regnum);
  181. return rt_phy_write(phydev, RT_MDIO_DEVAD_NONE, RT_MII_MMD_DATA, val);
  182. }
  183. int rt_phy_reset(struct rt_phy_device *phydev)
  184. {
  185. int reg;
  186. int timeout = 500;
  187. int devad = RT_MDIO_DEVAD_NONE;
  188. if (phydev->flags & RT_PHY_FLAG_BROKEN_RESET)
  189. return 0;
  190. if (rt_phy_write(phydev, devad, RT_MII_BMCR, RT_BMCR_RESET) < 0)
  191. {
  192. LOG_D("PHY reset failed\n");
  193. return -1;
  194. }
  195. reg = rt_phy_read(phydev, devad, RT_MII_BMCR);
  196. while ((reg & RT_BMCR_RESET) && timeout--)
  197. {
  198. reg = rt_phy_read(phydev, devad, RT_MII_BMCR);
  199. if (reg < 0)
  200. {
  201. LOG_D("PHY status read failed\n");
  202. return -1;
  203. }
  204. rt_thread_mdelay(1);
  205. }
  206. if (reg & RT_BMCR_RESET)
  207. {
  208. LOG_D("PHY reset timed out\n");
  209. return -1;
  210. }
  211. return 0;
  212. }
  213. static struct rt_bus rt_phy_bus;
  214. /**
  215. * @brief create a phy device
  216. *
  217. * Creates a new PHY device based on the given bus, address, PHY ID, and whether Clause 45 is supported.
  218. *
  219. * @param bus the pointer to the bus
  220. * @param addr PHY device address
  221. * @param phy_id PHY device id
  222. * @param is_c45 if suport Clause 45
  223. *
  224. * @return if create success return the phy device pointer,else return RT_NULL
  225. */
  226. struct rt_phy_device *rt_phy_device_create(struct mii_bus *bus, int addr,
  227. rt_uint32_t phy_id, rt_bool_t is_c45)
  228. {
  229. struct rt_phy_device *dev = rt_malloc(sizeof(struct rt_phy_device));
  230. if (!dev)
  231. {
  232. LOG_E("Failed to allocate PHY device for %s:%d\n",
  233. bus ? bus->name : "(null bus)", addr);
  234. return RT_NULL;
  235. }
  236. memset(dev, 0, sizeof(*dev));
  237. dev->duplex = -1;
  238. dev->link = 0;
  239. dev->interface = RT_PHY_INTERFACE_MODE_NA;
  240. #ifdef RT_USING_OFW
  241. dev->node = RT_NULL;
  242. #endif
  243. dev->autoneg = RT_TRUE;
  244. dev->addr = addr;
  245. dev->phy_id = phy_id;
  246. dev->is_c45 = is_c45;
  247. dev->bus = bus;
  248. if(rt_phy_device_register(dev))
  249. {
  250. LOG_D("register phy device filed")
  251. }
  252. if (addr >= 0 && addr < RT_PHY_MAX && phy_id != RT_PHY_FIXED_ID &&
  253. phy_id != RT_PHY_NCSI_ID)
  254. bus->phymap[addr] = dev;
  255. return dev;
  256. }
  257. /**
  258. * @brief get phy id
  259. *
  260. * get phy id by read the register 2 and 3 of PHY device,
  261. * Register of the MII management interface stipulates that
  262. * register 2 contains thehigh 16 bits of the PHY’s identifier
  263. * the register 3 contains the low 16 bits of the PHY’s identifier
  264. *
  265. * @param bus MII bus pointer
  266. * @param addr PHY device address
  267. * @param devad dev addr if be set to zero it means c22 mode,else it means c45 mode
  268. * @param phy_id the phy id which will be read
  269. *
  270. * @return if read success return 0,else return -RT_EIO
  271. */
  272. static int get_phy_id(struct mii_bus *bus, int addr, int devad, rt_uint32_t *phy_id)
  273. {
  274. int phy_reg;
  275. phy_reg = bus->read(bus, addr, devad, RT_MII_PHYSID1);
  276. if (phy_reg < 0)
  277. return -RT_EIO;
  278. *phy_id = (phy_reg & 0xffff) << 16;
  279. phy_reg = bus->read(bus, addr, devad, RT_MII_PHYSID2);
  280. if (phy_reg < 0)
  281. return -RT_EIO;
  282. *phy_id |= (phy_reg & 0xffff);
  283. return 0;
  284. }
  285. /**
  286. * @brief create phy device by mask
  287. *
  288. * @param bus MII bus pointer
  289. * @param phy_mask the mask which phy addr corresponding will be set 1
  290. * @param devad dev addr if be set to zero it means c22 mode,else it means c45 mode
  291. *
  292. * @return if create success return the phy device pointer,if create fail return NULL
  293. */
  294. static struct rt_phy_device *create_phy_by_mask(struct mii_bus *bus, unsigned int phy_mask,int devad)
  295. {
  296. rt_uint32_t id = 0xffffffff;
  297. rt_bool_t is_c45;
  298. while (phy_mask)
  299. {
  300. int addr = __rt_ffs(phy_mask) - 1;
  301. int r = get_phy_id(bus, addr, devad, &id);
  302. if (r == 0 && id == 0)
  303. {
  304. phy_mask &= ~(1 << addr);
  305. continue;
  306. }
  307. if (r == 0 && (id & 0x1fffffff) != 0x1fffffff)
  308. {
  309. is_c45 = (devad == RT_MDIO_DEVAD_NONE) ? RT_FALSE : RT_TRUE;
  310. return rt_phy_device_create(bus, addr, id, is_c45);
  311. }
  312. }
  313. return RT_NULL;
  314. }
  315. /**
  316. * @brief create phy device by mask
  317. *
  318. * it will create phy device by c22 mode or c45 mode
  319. *
  320. * @param bus mii bus pointer
  321. * @param phy_mask PHY mask it depend on the phy addr, the phy addr corresponding will be set 1
  322. *
  323. * @return if create success return the phy device pointer,if create fail return NULL
  324. */
  325. static struct rt_phy_device *rt_phydev_create_by_mask(struct mii_bus *bus, unsigned int phy_mask)
  326. {
  327. struct rt_phy_device *phy;
  328. /*
  329. *The bit of devad is dev addr which is the new features in c45
  330. *so if devad equal to zero it means it is c22 mode ,and if not
  331. *equal to zero it means it is c45 mode,which include PMD/PMA ,
  332. *WIS ,PCS,PHY XS,PHY XS ....
  333. */
  334. int devad[] = {
  335. /* Clause-22 */
  336. RT_MDIO_DEVAD_NONE,
  337. /* Clause-45 */
  338. RT_MDIO_MMD_PMAPMD,
  339. RT_MDIO_MMD_WIS,
  340. RT_MDIO_MMD_PCS,
  341. RT_MDIO_MMD_PHYXS,
  342. RT_MDIO_MMD_VEND1,
  343. };
  344. for (int i = 0; i < sizeof(devad)/sizeof(devad[0]); i++)
  345. {
  346. phy = create_phy_by_mask(bus, phy_mask, devad[i]);
  347. if(phy)
  348. return phy;
  349. }
  350. return RT_NULL;
  351. }
  352. struct rt_phy_device *rt_phy_find_by_mask(struct mii_bus *bus, unsigned int phy_mask)
  353. {
  354. struct rt_phy_device *phy;
  355. unsigned int mask = phy_mask;
  356. unsigned int addr;
  357. if (bus->reset)
  358. {
  359. bus->reset(bus);
  360. rt_thread_mdelay(15);
  361. }
  362. while (mask)
  363. {
  364. /*
  365. *Whichever bit of the mask is the 1,
  366. *which bit is the addr as the array subscript to search
  367. *such as mask = 1110 ,this loop will search for subscript
  368. *1,2,3,if the array subscript is not null then return it,
  369. *if the array subscript is null then continue to search
  370. */
  371. addr = __rt_ffs(mask) - 1;
  372. if (bus->phymap[addr])
  373. return bus->phymap[addr];
  374. mask &= ~(1U << addr);
  375. }
  376. /*ifcan't find phy device, create a new phy device*/
  377. phy = rt_phydev_create_by_mask(bus, phy_mask);
  378. return phy;
  379. }
  380. /**
  381. * @brief get phy device by given mii bus, node and address
  382. * @param bus MII bus pointer
  383. * @param np the dtb node of device which need to get phy device
  384. * @param addr address of phy device
  385. * @param interface interface of phy device
  386. *
  387. * @return phy device pointer or NULL if not found
  388. */
  389. struct rt_phy_device *rt_phy_get_device(struct mii_bus *bus,struct rt_ofw_node *np, int addr,rt_phy_interface interface)
  390. {
  391. struct rt_phy_device *phy = RT_NULL;
  392. unsigned int phy_mask = addr? 1 << addr:0xffffffff;
  393. #ifdef RT_USING_OFW
  394. if(np)
  395. phy = rt_ofw_create_phy(bus,np,addr);
  396. #endif
  397. if(!phy)
  398. phy = rt_phy_find_by_mask(bus,phy_mask);
  399. if(phy)
  400. {
  401. rt_phy_reset(phy);
  402. phy->interface = interface;
  403. return phy;
  404. }
  405. LOG_D("PHY device get failed");
  406. return RT_NULL;
  407. }
  408. static struct rt_phy_driver genphy = {
  409. .uid = 0xffffffff,
  410. .mask = 0xffffffff,
  411. .name = "Generic PHY",
  412. .features = RT_PHY_GBIT_FEATURES | RT_SUPPORTED_MII |
  413. RT_SUPPORTED_AUI | RT_SUPPORTED_FIBRE |
  414. RT_SUPPORTED_BNC,
  415. .config = rt_genphy_config,
  416. .startup = rt_genphy_startup,
  417. };
  418. RT_PHY_DRIVER_REGISTER(genphy);
  419. rt_err_t rt_phy_device_register(struct rt_phy_device *pdev)
  420. {
  421. rt_err_t err;
  422. RT_ASSERT(pdev != RT_NULL);
  423. err = rt_bus_add_device(&rt_phy_bus, &pdev->parent);
  424. if (err)
  425. {
  426. return err;
  427. }
  428. if(!pdev->drv)
  429. pdev->drv = &genphy;
  430. return RT_EOK;
  431. }
  432. rt_err_t rt_phy_driver_register(struct rt_phy_driver *pdrv)
  433. {
  434. RT_ASSERT(pdrv != RT_NULL);
  435. pdrv->parent.bus = &rt_phy_bus;
  436. #if RT_NAME_MAX > 0
  437. rt_strcpy(pdrv->parent.parent.name, pdrv->name);
  438. #else
  439. pdrv->parent.parent.name = pdrv->name;
  440. #endif
  441. return rt_driver_register(&pdrv->parent);
  442. }
  443. static rt_bool_t phy_match(rt_driver_t drv, rt_device_t dev)
  444. {
  445. struct rt_phy_device *pdev = rt_container_of(dev, struct rt_phy_device, parent);
  446. struct rt_phy_driver *pdrv = rt_container_of(drv, struct rt_phy_driver, parent);
  447. if ((pdrv->uid & pdrv->mask) == (pdev->phy_id & pdrv->mask))
  448. return RT_TRUE;
  449. return RT_FALSE;
  450. }
  451. static rt_err_t phy_probe(rt_device_t dev)
  452. {
  453. rt_err_t err = RT_EOK;
  454. struct rt_phy_driver *pdrv = rt_container_of(dev->drv, struct rt_phy_driver, parent);
  455. struct rt_phy_device *pdev = rt_container_of(dev, struct rt_phy_device, parent);
  456. pdev->drv = pdrv;
  457. pdev->advertising = pdev->drv->features;
  458. pdev->supported = pdev->drv->features;
  459. pdev->mmds = pdev->drv->mmds;
  460. if(pdrv->probe)
  461. err = pdrv->probe(pdev);
  462. return err;
  463. }
  464. static struct rt_bus rt_phy_bus =
  465. {
  466. .name = "phy",
  467. .match = phy_match,
  468. .probe = phy_probe,
  469. };
  470. static int rt_phy_bus_init(void)
  471. {
  472. rt_bus_register(&rt_phy_bus);
  473. return 0;
  474. }
  475. INIT_CORE_EXPORT(rt_phy_bus_init);
  476. #endif