drv_enet.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. /*
  2. * Copyright (c) 2021 - 2022 hpmicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-01-11 hpmicro First version
  9. * 2022-07-10 hpmicro Driver optimization for multiple instances
  10. */
  11. #include <rtdevice.h>
  12. #ifdef BSP_USING_ETH
  13. #include <rtdbg.h>
  14. #include <netif/ethernetif.h>
  15. #include "board.h"
  16. #include "drv_enet.h"
  17. #include "hpm_soc_feature.h"
  18. #include "hpm_enet_soc_drv.h"
  19. #include "hpm_enet_drv.h"
  20. #define ETH_DEBUG
  21. #ifdef BSP_USING_ETH0
  22. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
  23. __RW enet_rx_desc_t enet0_dma_rx_desc_tab[ENET0_RX_BUFF_COUNT] ; /* Ethernet0 Rx DMA Descriptor */
  24. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
  25. __RW enet_tx_desc_t enet0_dma_tx_desc_tab[ENET0_TX_BUFF_COUNT] ; /* Ethernet0 Tx DMA Descriptor */
  26. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
  27. __RW uint8_t enet0_rx_buff[ENET0_RX_BUFF_COUNT][ENET0_RX_BUFF_SIZE]; /* Ethernet0 Receive Buffer */
  28. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
  29. __RW uint8_t enet0_tx_buff[ENET0_TX_BUFF_COUNT][ENET0_TX_BUFF_SIZE]; /* Ethernet0 Transmit Buffer */
  30. struct eth_device eth0_dev;
  31. static enet_device enet0_dev;
  32. static enet_buff_config_t enet0_rx_buff_cfg = {.buffer = (uint32_t)enet0_rx_buff,
  33. .count = ENET0_RX_BUFF_COUNT,
  34. .size = ENET0_RX_BUFF_SIZE
  35. };
  36. static enet_buff_config_t enet0_tx_buff_cfg = {.buffer = (uint32_t)enet0_tx_buff,
  37. .count = ENET0_TX_BUFF_COUNT,
  38. .size = ENET0_TX_BUFF_SIZE
  39. };
  40. static enet_ptp_time_t ptp_timestamp0 = {0, 0};
  41. static enet_ptp_config_t ptp_config0 = {.sub_sec_count_res = enet_ptp_count_res_low,
  42. .update_method = enet_ptp_time_fine_update,
  43. .addend = 0xffffffff,
  44. };
  45. static hpm_enet_t enet0 = {.name = "ETH0",
  46. .base = HPM_ENET0,
  47. .irq_num = IRQn_ENET0,
  48. .inf = BOARD_ENET0_INF,
  49. .eth_dev = &eth0_dev,
  50. .enet_dev = &enet0_dev,
  51. .rx_buff_cfg = &enet0_rx_buff_cfg,
  52. .tx_buff_cfg = &enet0_tx_buff_cfg,
  53. .dma_rx_desc_tab = enet0_dma_rx_desc_tab,
  54. .dma_tx_desc_tab = enet0_dma_tx_desc_tab,
  55. .tx_delay = BOARD_ENET0_TX_DLY,
  56. .rx_delay = BOARD_ENET0_RX_DLY,
  57. .ptp_enable = true,
  58. .ptp_clk_src = BOARD_ENET0_PTP_CLOCK,
  59. .ptp_config = &ptp_config0,
  60. .ptp_timestamp = &ptp_timestamp0
  61. };
  62. #endif
  63. #ifdef BSP_USING_ETH1
  64. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
  65. __RW enet_rx_desc_t enet1_dma_rx_desc_tab[ENET1_RX_BUFF_COUNT]; /* Ethernet1 Rx DMA Descriptor */
  66. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_DESC_ADDR_ALIGNMENT)
  67. __RW enet_tx_desc_t enet1_dma_tx_desc_tab[ENET1_TX_BUFF_COUNT]; /* Ethernet1 Tx DMA Descriptor */
  68. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
  69. __RW uint8_t enet1_rx_buff[ENET1_RX_BUFF_COUNT][ENET1_RX_BUFF_SIZE]; /* Ethernet1 Receive Buffer */
  70. ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(ENET_SOC_BUFF_ADDR_ALIGNMENT)
  71. __RW uint8_t enet1_tx_buff[ENET1_TX_BUFF_COUNT][ENET1_TX_BUFF_SIZE]; /* Ethernet1 Transmit Buffer */
  72. struct eth_device eth1_dev;
  73. static enet_device enet1_dev;
  74. static enet_buff_config_t enet1_rx_buff_cfg = {.buffer = (uint32_t)enet1_rx_buff,
  75. .count = ENET1_RX_BUFF_COUNT,
  76. .size = ENET1_RX_BUFF_SIZE
  77. };
  78. static enet_buff_config_t enet1_tx_buff_cfg = {.buffer = (uint32_t)enet1_tx_buff,
  79. .count = ENET1_TX_BUFF_COUNT,
  80. .size = ENET1_TX_BUFF_SIZE
  81. };
  82. static enet_ptp_time_t ptp_timestamp1 = {0, 0};
  83. static enet_ptp_config_t ptp_config1 = {.sub_sec_count_res = enet_ptp_count_res_low,
  84. .update_method = enet_ptp_time_fine_update,
  85. .addend = 0xffffffff,
  86. };
  87. static hpm_enet_t enet1 = {.name = "ETH1",
  88. .base = HPM_ENET1,
  89. .irq_num = IRQn_ENET1,
  90. .inf = BOARD_ENET1_INF,
  91. .eth_dev = &eth1_dev,
  92. .enet_dev = &enet1_dev,
  93. .rx_buff_cfg = &enet1_rx_buff_cfg,
  94. .tx_buff_cfg = &enet1_tx_buff_cfg,
  95. .dma_rx_desc_tab = enet1_dma_rx_desc_tab,
  96. .dma_tx_desc_tab = enet1_dma_tx_desc_tab,
  97. .int_refclk = BOARD_ENET1_INT_REF_CLK,
  98. .ptp_enable = true,
  99. .ptp_clk_src = BOARD_ENET1_PTP_CLOCK,
  100. .ptp_config = &ptp_config1,
  101. .ptp_timestamp = &ptp_timestamp1
  102. };
  103. #endif
  104. static hpm_enet_t *s_geths[] = {
  105. #ifdef BSP_USING_ETH0
  106. &enet0,
  107. #endif
  108. #ifdef BSP_USING_ETH1
  109. &enet1
  110. #endif
  111. };
  112. static hpm_stat_t hpm_enet_init(enet_device *init)
  113. {
  114. /* Initialize eth controller */
  115. enet_controller_init(init->instance, init->media_interface, &init->desc, &init->mac_config, init->mask, init->dis_mask);
  116. if (init->media_interface == enet_inf_rmii)
  117. {
  118. /* Initialize reference clock */
  119. board_init_enet_rmii_reference_clock(init->instance, init->int_refclk);
  120. enet_rmii_enable_clock(init->instance, init->int_refclk);
  121. }
  122. /* Set RGMII clock delay */
  123. if (init->media_interface == enet_inf_rgmii)
  124. {
  125. enet_rgmii_enable_clock(init->instance);
  126. enet_rgmii_set_clock_delay(init->instance, init->tx_delay, init->rx_delay);
  127. }
  128. if (init->ptp_enable)
  129. {
  130. /* initialize Ethernet PTP Module */
  131. init->ptp_config.ssinc = ENET_ONE_SEC_IN_NANOSEC / clock_get_frequency(init->ptp_clk_src);
  132. enet_init_ptp(init->instance, &init->ptp_config);
  133. /* set the initial timestamp */
  134. enet_set_ptp_timestamp(init->instance, &init->ptp_timestamp);
  135. }
  136. /* enable irq */
  137. intc_m_enable_irq(init->irq_number);
  138. }
  139. static rt_err_t rt_hpm_eth_init(rt_device_t dev)
  140. {
  141. enet_device *enet_dev = (enet_device *)dev->user_data;
  142. /* Initialize GPIOs */
  143. board_init_enet_pins(enet_dev->instance);
  144. /* Reset an enet PHY */
  145. board_reset_enet_phy(enet_dev->instance);
  146. /* Initialize MAC and DMA */
  147. if (hpm_enet_init(enet_dev) == 0) {
  148. LOG_D("Ethernet control initialize successfully\n");
  149. }
  150. return RT_EOK;
  151. }
  152. static rt_err_t rt_hpm_eth_open(rt_device_t dev, rt_uint16_t oflag)
  153. {
  154. return RT_EOK;
  155. }
  156. static rt_err_t rt_hpm_eth_close(rt_device_t dev)
  157. {
  158. return RT_EOK;
  159. }
  160. static rt_ssize_t rt_hpm_eth_read(rt_device_t dev, rt_off_t pos, void * buffer, rt_size_t size)
  161. {
  162. return 0;
  163. }
  164. static rt_ssize_t rt_hpm_eth_write(rt_device_t dev, rt_off_t pos, const void * buffer, rt_size_t size)
  165. {
  166. return 0;
  167. }
  168. static rt_err_t rt_hpm_eth_control(rt_device_t dev, int cmd, void * args)
  169. {
  170. uint8_t *mac;
  171. switch (cmd)
  172. {
  173. case NIOCTL_GADDR:
  174. /* read MAC address */
  175. if (args != NULL)
  176. {
  177. mac = (uint8_t *)args;
  178. mac[0] = MAC_ADDR0;
  179. mac[1] = MAC_ADDR1;
  180. mac[2] = MAC_ADDR2;
  181. mac[3] = MAC_ADDR3;
  182. mac[4] = MAC_ADDR4;
  183. mac[5] = MAC_ADDR5;
  184. SMEMCPY(args, mac, 6);
  185. }
  186. else
  187. {
  188. return -RT_ERROR;
  189. }
  190. break;
  191. default:
  192. break;
  193. }
  194. return RT_EOK;
  195. }
  196. static rt_err_t rt_hpm_eth_tx(rt_device_t dev, struct pbuf * p)
  197. {
  198. rt_err_t ret = -RT_ERROR;
  199. uint32_t status;
  200. enet_device *enet_dev = (enet_device *)dev->user_data;
  201. uint32_t tx_buff_size = enet_dev->desc.tx_buff_cfg.size;
  202. struct pbuf *q;
  203. uint8_t *buffer;
  204. __IO enet_tx_desc_t *dma_tx_desc;
  205. uint32_t frame_length = 0;
  206. uint32_t buffer_offset = 0;
  207. uint32_t bytes_left_to_copy = 0;
  208. uint32_t payload_offset = 0;
  209. enet_tx_desc_t *tx_desc_list_cur = enet_dev->desc.tx_desc_list_cur;
  210. dma_tx_desc = tx_desc_list_cur;
  211. buffer = (uint8_t *)(dma_tx_desc->tdes2_bm.buffer1);
  212. buffer_offset = 0;
  213. /* copy frame from pbufs to driver buffers */
  214. for (q = p; q != NULL; q = q->next)
  215. {
  216. /* Get bytes in current lwIP buffer */
  217. bytes_left_to_copy = q->len;
  218. payload_offset = 0;
  219. /* Check if the length of data to copy is bigger than Tx buffer size*/
  220. while ((bytes_left_to_copy + buffer_offset) > tx_buff_size)
  221. {
  222. /* Copy data to Tx buffer*/
  223. SMEMCPY((uint8_t *)((uint8_t *)buffer + buffer_offset),
  224. (uint8_t *)((uint8_t *)q->payload + payload_offset),
  225. tx_buff_size - buffer_offset);
  226. /* Point to next descriptor */
  227. dma_tx_desc = (enet_tx_desc_t *)(dma_tx_desc->tdes3_bm.next_desc);
  228. /* Check if the buffer is available */
  229. if (dma_tx_desc->tdes0_bm.own != 0)
  230. {
  231. LOG_E("DMA tx desc buffer is not valid\n");
  232. return ERR_USE;
  233. }
  234. buffer = (uint8_t *)(dma_tx_desc->tdes2_bm.buffer1);
  235. bytes_left_to_copy = bytes_left_to_copy - (tx_buff_size - buffer_offset);
  236. payload_offset = payload_offset + (tx_buff_size - buffer_offset);
  237. frame_length = frame_length + (tx_buff_size - buffer_offset);
  238. buffer_offset = 0;
  239. }
  240. /* Copy the remaining bytes */
  241. SMEMCPY((uint8_t *)((uint8_t *)buffer + buffer_offset),
  242. (uint8_t *)((uint8_t *)q->payload + payload_offset),
  243. bytes_left_to_copy);
  244. buffer_offset = buffer_offset + bytes_left_to_copy;
  245. frame_length = frame_length + bytes_left_to_copy;
  246. }
  247. /* Prepare transmit descriptors to give to DMA */
  248. LOG_D("The length of the transmitted frame: %d\n", frame_length);
  249. frame_length += 4;
  250. status = enet_prepare_transmission_descriptors(enet_dev->instance, &enet_dev->desc.tx_desc_list_cur, frame_length, enet_dev->desc.tx_buff_cfg.size);
  251. if (status != ENET_SUCCESS)
  252. {
  253. LOG_E("Ethernet controller transmit unsuccessfully: %d\n", status);
  254. }
  255. return ERR_OK;
  256. }
  257. static struct pbuf *rt_hpm_eth_rx(rt_device_t dev)
  258. {
  259. struct pbuf *p = NULL, *q = NULL;
  260. enet_device *enet_dev = (enet_device *)dev->user_data;
  261. uint32_t rx_buff_size = enet_dev->desc.rx_buff_cfg.size;
  262. uint16_t len = 0;
  263. uint8_t *buffer;
  264. enet_frame_t frame = {0, 0, 0};
  265. enet_rx_desc_t *dma_rx_desc;
  266. uint32_t buffer_offset = 0;
  267. uint32_t payload_offset = 0;
  268. uint32_t bytes_left_to_copy = 0;
  269. uint32_t i = 0;
  270. /* Get a received frame */
  271. frame = enet_get_received_frame_interrupt(&enet_dev->desc.rx_desc_list_cur,
  272. &enet_dev->desc.rx_frame_info,
  273. enet_dev->desc.rx_buff_cfg.count);
  274. /* Obtain the size of the packet and put it into the "len" variable. */
  275. len = frame.length;
  276. buffer = (uint8_t *)frame.buffer;
  277. LOG_D("The current received frame length : %d\n", len);
  278. if (len > 0)
  279. {
  280. /* allocate a pbuf chain of pbufs from the Lwip buffer pool */
  281. p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
  282. }
  283. if (p != NULL)
  284. {
  285. dma_rx_desc = frame.rx_desc;
  286. buffer_offset = 0;
  287. for (q = p; q != NULL; q = q->next)
  288. {
  289. bytes_left_to_copy = q->len;
  290. payload_offset = 0;
  291. /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
  292. while ((bytes_left_to_copy + buffer_offset) > rx_buff_size)
  293. {
  294. /* Copy data to pbuf */
  295. SMEMCPY((uint8_t *)((uint8_t *)q->payload + payload_offset), (uint8_t *)((uint8_t *)buffer + buffer_offset), (rx_buff_size - buffer_offset));
  296. /* Point to next descriptor */
  297. dma_rx_desc = (enet_rx_desc_t *)(dma_rx_desc->rdes3_bm.next_desc);
  298. buffer = (uint8_t *)(dma_rx_desc->rdes2_bm.buffer1);
  299. bytes_left_to_copy = bytes_left_to_copy - (rx_buff_size - buffer_offset);
  300. payload_offset = payload_offset + (rx_buff_size - buffer_offset);
  301. buffer_offset = 0;
  302. }
  303. /* Copy remaining data in pbuf */
  304. SMEMCPY((uint8_t *)((uint8_t *)q->payload + payload_offset), (uint8_t *)((uint8_t *)buffer + buffer_offset), bytes_left_to_copy);
  305. buffer_offset = buffer_offset + bytes_left_to_copy;
  306. }
  307. }
  308. else
  309. {
  310. return NULL;
  311. }
  312. /* Release descriptors to DMA */
  313. /* Point to first descriptor */
  314. dma_rx_desc = frame.rx_desc;
  315. /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
  316. for (i = 0; i < enet_dev->desc.rx_frame_info.seg_count; i++)
  317. {
  318. dma_rx_desc->rdes0_bm.own = 1;
  319. dma_rx_desc = (enet_rx_desc_t*)(dma_rx_desc->rdes3_bm.next_desc);
  320. }
  321. /* Clear Segment_Count */
  322. enet_dev->desc.rx_frame_info.seg_count = 0;
  323. return p;
  324. }
  325. static void eth_rx_callback(struct eth_device* dev)
  326. {
  327. rt_err_t result;
  328. result = eth_device_ready(dev);
  329. if (result != RT_EOK)
  330. {
  331. LOG_I("Receive callback error = %d\n", result);
  332. }
  333. }
  334. void isr_enet(hpm_enet_t *obj)
  335. {
  336. uint32_t status;
  337. status = obj->base->DMA_STATUS;
  338. if (ENET_DMA_STATUS_GLPII_GET(status)) {
  339. obj->base->DMA_STATUS |= ENET_DMA_STATUS_GLPII_SET(ENET_DMA_STATUS_GLPII_GET(status));
  340. }
  341. if (ENET_DMA_STATUS_RI_GET(status)) {
  342. obj->base->DMA_STATUS |= ENET_DMA_STATUS_RI_SET(ENET_DMA_STATUS_RI_GET(status));
  343. eth_rx_callback(obj->eth_dev);
  344. }
  345. }
  346. #ifdef BSP_USING_ETH0
  347. void isr_enet0(void)
  348. {
  349. isr_enet(&enet0);
  350. }
  351. SDK_DECLARE_EXT_ISR_M(IRQn_ENET0, isr_enet0)
  352. #endif
  353. #ifdef BSP_USING_ETH1
  354. void isr_enet1(void)
  355. {
  356. isr_enet(&enet1);
  357. }
  358. SDK_DECLARE_EXT_ISR_M(IRQn_ENET1, isr_enet1)
  359. #endif
  360. int rt_hw_eth_init(void)
  361. {
  362. rt_err_t err = -RT_ERROR;
  363. for (uint32_t i = 0; i < ARRAY_SIZE(s_geths); i++)
  364. {
  365. /* Clear memory */
  366. memset((uint8_t *)s_geths[i]->dma_rx_desc_tab, 0x00, sizeof(enet_rx_desc_t) * s_geths[i]->rx_buff_cfg->count);
  367. memset((uint8_t *)s_geths[i]->dma_tx_desc_tab, 0x00, sizeof(enet_tx_desc_t) * s_geths[i]->tx_buff_cfg->count);
  368. memset((uint8_t *)s_geths[i]->rx_buff_cfg->buffer, 0x00, sizeof(s_geths[i]->rx_buff_cfg->size));
  369. memset((uint8_t *)s_geths[i]->tx_buff_cfg->buffer, 0x00, sizeof(s_geths[i]->tx_buff_cfg->size));
  370. /* Set list heads */
  371. s_geths[i]->enet_dev->desc.tx_desc_list_head = (enet_tx_desc_t *)core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)s_geths[i]->dma_tx_desc_tab);
  372. s_geths[i]->enet_dev->desc.rx_desc_list_head = (enet_rx_desc_t *)core_local_mem_to_sys_address(BOARD_RUNNING_CORE, (uint32_t)s_geths[i]->dma_rx_desc_tab);
  373. s_geths[i]->enet_dev->desc.tx_buff_cfg.buffer = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, s_geths[i]->tx_buff_cfg->buffer);
  374. s_geths[i]->enet_dev->desc.tx_buff_cfg.count = s_geths[i]->tx_buff_cfg->count;
  375. s_geths[i]->enet_dev->desc.tx_buff_cfg.size = s_geths[i]->tx_buff_cfg->size;
  376. s_geths[i]->enet_dev->desc.rx_buff_cfg.buffer = core_local_mem_to_sys_address(BOARD_RUNNING_CORE, s_geths[i]->rx_buff_cfg->buffer);
  377. s_geths[i]->enet_dev->desc.rx_buff_cfg.count = s_geths[i]->rx_buff_cfg->count;
  378. s_geths[i]->enet_dev->desc.rx_buff_cfg.size = s_geths[i]->rx_buff_cfg->size;
  379. /* Set mac0 address */
  380. s_geths[i]->enet_dev->mac_config.mac_addr_high[0] = MAC_ADDR5 << 8 | MAC_ADDR4;
  381. s_geths[i]->enet_dev->mac_config.mac_addr_low[0] = MAC_ADDR3 << 24 | MAC_ADDR2 << 16 | MAC_ADDR1 << 8 | MAC_ADDR0;
  382. s_geths[i]->enet_dev->mac_config.valid_max_count = 1;
  383. /* Set instance */
  384. s_geths[i]->enet_dev->instance = s_geths[i]->base;
  385. /* Set media interface */
  386. s_geths[i]->enet_dev->media_interface = s_geths[i]->inf;
  387. /* Set refclk */
  388. s_geths[i]->enet_dev->int_refclk = s_geths[i]->int_refclk;
  389. /* Set TX delay */
  390. s_geths[i]->enet_dev->tx_delay = s_geths[i]->tx_delay;
  391. /* Set RX delay */
  392. s_geths[i]->enet_dev->rx_delay = s_geths[i]->rx_delay;
  393. /* Set PTP function */
  394. s_geths[i]->enet_dev->ptp_enable = s_geths[i]->ptp_enable;
  395. s_geths[i]->enet_dev->ptp_clk_src = s_geths[i]->ptp_clk_src;
  396. s_geths[i]->enet_dev->ptp_config = *s_geths[i]->ptp_config;
  397. s_geths[i]->enet_dev->ptp_timestamp = *s_geths[i]->ptp_timestamp;
  398. /* Set the interrupt enable mask */
  399. s_geths[i]->enet_dev->mask = ENET_DMA_INTR_EN_NIE_SET(1) /* Enable normal interrupt summary */
  400. | ENET_DMA_INTR_EN_RIE_SET(1); /* Enable receive interrupt */
  401. /* Set the interrupt disable mask */
  402. s_geths[i]->enet_dev->dis_mask = ENET_INTR_MASK_RGSMIIIM_SET(1);
  403. /* Set the irq number */
  404. s_geths[i]->enet_dev->irq_number = s_geths[i]->irq_num;
  405. /* Set the parent parameters */
  406. s_geths[i]->eth_dev->parent.init = rt_hpm_eth_init;
  407. s_geths[i]->eth_dev->parent.open = rt_hpm_eth_open;
  408. s_geths[i]->eth_dev->parent.close = rt_hpm_eth_close;
  409. s_geths[i]->eth_dev->parent.read = rt_hpm_eth_read;
  410. s_geths[i]->eth_dev->parent.write = rt_hpm_eth_write;
  411. s_geths[i]->eth_dev->parent.control = rt_hpm_eth_control;
  412. s_geths[i]->eth_dev->parent.user_data = s_geths[i]->enet_dev;
  413. s_geths[i]->eth_dev->eth_rx = rt_hpm_eth_rx;
  414. s_geths[i]->eth_dev->eth_tx = rt_hpm_eth_tx;
  415. err = eth_device_init(s_geths[i]->eth_dev, s_geths[i]->name);
  416. if (RT_EOK == err)
  417. {
  418. LOG_D("Ethernet device initialize successfully!\n");
  419. }
  420. else
  421. {
  422. LOG_D("Ethernet device initialize unsuccessfully!\n");
  423. return err;
  424. }
  425. }
  426. return err;
  427. }
  428. INIT_DEVICE_EXPORT(rt_hw_eth_init);
  429. #endif /* BSP_USING_ETH */