emac_drv.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * COPYRIGHT (C) 2018, Real-Thread Information Technology Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. * Change Logs:
  6. * Date Author Notes
  7. * 2015-07-15 Bernard The first version
  8. */
  9. #include <rtthread.h>
  10. #include <netif/ethernetif.h>
  11. #include <soc_memory_map.h>
  12. #include <stdint.h>
  13. #include <enet/enet.h>
  14. #include <lwipopts.h>
  15. #include "emac_drv.h"
  16. #define MAX_ADDR_LEN 6
  17. #define IMX_EMAC_DEVICE(eth) (struct emac_device*)(eth)
  18. struct emac_device
  19. {
  20. /* inherit from Ethernet device */
  21. struct eth_device parent;
  22. imx_enet_priv_t enet_priv;
  23. /* interface address info. */
  24. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* MAC address */
  25. };
  26. static struct emac_device _emac;
  27. #define ENET_PHY_ADDR 1
  28. extern int imx_enet_mii_type(imx_enet_priv_t * dev, enum imx_mii_type mii_type);
  29. extern void imx_enet_iomux(void);
  30. extern void imx_enet_phy_reset(void);
  31. static unsigned char s_pkt_send[2048];
  32. static unsigned char s_pkt_recv[2048];
  33. void init_enet(struct emac_device* emac)
  34. {
  35. // setup iomux for ENET
  36. imx_enet_iomux();
  37. imx_enet_phy_reset();
  38. // init enet0
  39. imx_enet_init(&emac->enet_priv, ENET_BASE_ADDR, ENET_PHY_ADDR);
  40. imx_enet_mii_type(&emac->enet_priv, RGMII);
  41. // init phy0.
  42. imx_enet_phy_init(&emac->enet_priv);
  43. // Check PHY link status.
  44. if (!(emac->enet_priv.status & ENET_STATUS_LINK_ON))
  45. {
  46. rt_kprintf("ENET link status check fail\n");
  47. }
  48. imx_enet_start(&emac->enet_priv, emac->dev_addr);
  49. }
  50. void imx_enet_isr(int vector, void *param)
  51. {
  52. unsigned int value = 0;
  53. imx_enet_priv_t * dev = &(_emac.enet_priv);
  54. volatile hw_enet_t *enet_reg = dev->enet_reg;
  55. value = enet_reg->EIR.U;
  56. enet_reg->EIR.U = value & (~ENET_EVENT_MII);
  57. if (value & ENET_EVENT_TX_ERR)
  58. {
  59. dev->tx_busy = 0;
  60. }
  61. else if (value & ENET_EVENT_TX)
  62. {
  63. dev->tx_busy = 0;
  64. }
  65. if (value & ENET_EVENT_RX)
  66. {
  67. eth_device_ready(&(_emac.parent));
  68. }
  69. if (value & ENET_EVENT_HBERR)
  70. {
  71. // printf("WARNGING[POLL]: Hearbeat error!\n");
  72. }
  73. if (value & ENET_EVENT_EBERR)
  74. {
  75. // printf("WARNING[POLL]: Ethernet Bus Error!\n");
  76. }
  77. }
  78. static rt_err_t imx_emac_init(rt_device_t dev)
  79. {
  80. struct emac_device *emac;
  81. emac = IMX_EMAC_DEVICE(dev);
  82. /* initialize enet */
  83. init_enet(emac);
  84. return RT_EOK;
  85. }
  86. static rt_err_t imx_emac_open(rt_device_t dev, rt_uint16_t oflag)
  87. {
  88. return RT_EOK;
  89. }
  90. static rt_err_t imx_emac_close(rt_device_t dev)
  91. {
  92. return RT_EOK;
  93. }
  94. static rt_size_t imx_emac_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  95. {
  96. rt_set_errno(-RT_ENOSYS);
  97. return 0;
  98. }
  99. static rt_size_t imx_emac_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  100. {
  101. rt_set_errno(-RT_ENOSYS);
  102. return 0;
  103. }
  104. static rt_err_t imx_emac_control(rt_device_t dev, int cmd, void *args)
  105. {
  106. struct emac_device *emac;
  107. emac = IMX_EMAC_DEVICE(dev);
  108. RT_ASSERT(emac != RT_NULL);
  109. switch(cmd)
  110. {
  111. case NIOCTL_GADDR:
  112. /* get MAC address */
  113. if(args) rt_memcpy(args, emac->dev_addr, 6);
  114. else return -RT_ERROR;
  115. break;
  116. default :
  117. break;
  118. }
  119. return RT_EOK;
  120. }
  121. /* Ethernet device interface */
  122. /* transmit packet. */
  123. rt_err_t imx_emac_tx(rt_device_t dev, struct pbuf* p)
  124. {
  125. rt_err_t result = RT_EOK;
  126. struct emac_device *emac;
  127. emac = IMX_EMAC_DEVICE(dev);
  128. RT_ASSERT(emac != RT_NULL);
  129. /* copy pbuf to a whole ETH frame */
  130. pbuf_copy_partial(p, s_pkt_send, p->tot_len, 0);
  131. /* send to the enet */
  132. imx_enet_send(&emac->enet_priv, s_pkt_send, p->tot_len, 1);
  133. return result;
  134. }
  135. /* reception packet. */
  136. struct pbuf *imx_emac_rx(rt_device_t dev)
  137. {
  138. int len;
  139. struct pbuf* p = RT_NULL;
  140. struct emac_device *emac;
  141. emac = IMX_EMAC_DEVICE(dev);
  142. RT_ASSERT(emac != RT_NULL);
  143. imx_enet_recv(&emac->enet_priv, s_pkt_recv, &len);
  144. if (len > 0)
  145. {
  146. /* We allocate a pbuf chain of pbufs from the pool. */
  147. p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  148. if (p != RT_NULL)
  149. {
  150. pbuf_take(p, s_pkt_recv, len);
  151. }
  152. }
  153. return p;
  154. }
  155. int imx_emac_hw_init(void)
  156. {
  157. /* test MAC address */
  158. _emac.dev_addr[0] = 0x00;
  159. _emac.dev_addr[1] = 0x11;
  160. _emac.dev_addr[2] = 0x22;
  161. _emac.dev_addr[3] = 0x33;
  162. _emac.dev_addr[4] = 0x44;
  163. _emac.dev_addr[5] = 0x55;
  164. _emac.parent.parent.init = imx_emac_init;
  165. _emac.parent.parent.open = imx_emac_open;
  166. _emac.parent.parent.close = imx_emac_close;
  167. _emac.parent.parent.read = imx_emac_read;
  168. _emac.parent.parent.write = imx_emac_write;
  169. _emac.parent.parent.control = imx_emac_control;
  170. _emac.parent.parent.user_data = RT_NULL;
  171. _emac.parent.eth_rx = imx_emac_rx;
  172. _emac.parent.eth_tx = imx_emac_tx;
  173. /* register ETH device */
  174. eth_device_init(&(_emac.parent), "e0");
  175. return 0;
  176. }
  177. INIT_DEVICE_EXPORT(imx_emac_hw_init);