emac_drv.c 4.7 KB

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