fsl_enet.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-06-16 songchao support emac driver
  9. */
  10. #include <rtthread.h>
  11. #include "fsl_enet.h"
  12. #include "fsl_iomuxc.h"
  13. #include "ioremap.h"
  14. #define DBG_TAG "drv.enet"
  15. #define DBG_LVL DBG_LOG
  16. #include <rtdbg.h>
  17. #include "drv_eth.h"
  18. #define ETH_ENABLE (1U)
  19. /*******************************************************************************
  20. * Definitions
  21. ******************************************************************************/
  22. /*! @brief IPv4 PTP message IP version offset. */
  23. #define ENET_PTP1588_IPVERSION_OFFSET 0x0EU
  24. /*! @brief IPv4 PTP message UDP protocol offset. */
  25. #define ENET_PTP1588_IPV4_UDP_PROTOCOL_OFFSET 0x17U
  26. /*! @brief IPv4 PTP message UDP port offset. */
  27. #define ENET_PTP1588_IPV4_UDP_PORT_OFFSET 0x24U
  28. /*! @brief IPv4 PTP message UDP message type offset. */
  29. #define ENET_PTP1588_IPV4_UDP_MSGTYPE_OFFSET 0x2AU
  30. /*! @brief IPv4 PTP message UDP version offset. */
  31. #define ENET_PTP1588_IPV4_UDP_VERSION_OFFSET 0x2BU
  32. /*! @brief IPv4 PTP message UDP clock id offset. */
  33. #define ENET_PTP1588_IPV4_UDP_CLKID_OFFSET 0x3EU
  34. /*! @brief IPv4 PTP message UDP sequence id offset. */
  35. #define ENET_PTP1588_IPV4_UDP_SEQUENCEID_OFFSET 0x48U
  36. /*! @brief IPv4 PTP message UDP control offset. */
  37. #define ENET_PTP1588_IPV4_UDP_CTL_OFFSET 0x4AU
  38. /*! @brief IPv6 PTP message UDP protocol offset. */
  39. #define ENET_PTP1588_IPV6_UDP_PROTOCOL_OFFSET 0x14U
  40. /*! @brief IPv6 PTP message UDP port offset. */
  41. #define ENET_PTP1588_IPV6_UDP_PORT_OFFSET 0x38U
  42. /*! @brief IPv6 PTP message UDP message type offset. */
  43. #define ENET_PTP1588_IPV6_UDP_MSGTYPE_OFFSET 0x3EU
  44. /*! @brief IPv6 PTP message UDP version offset. */
  45. #define ENET_PTP1588_IPV6_UDP_VERSION_OFFSET 0x3FU
  46. /*! @brief IPv6 PTP message UDP clock id offset. */
  47. #define ENET_PTP1588_IPV6_UDP_CLKID_OFFSET 0x52U
  48. /*! @brief IPv6 PTP message UDP sequence id offset. */
  49. #define ENET_PTP1588_IPV6_UDP_SEQUENCEID_OFFSET 0x5CU
  50. /*! @brief IPv6 PTP message UDP control offset. */
  51. #define ENET_PTP1588_IPV6_UDP_CTL_OFFSET 0x5EU
  52. /*! @brief PTPv2 message Ethernet packet type offset. */
  53. #define ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET 0x0CU
  54. /*! @brief PTPv2 message Ethernet message type offset. */
  55. #define ENET_PTP1588_ETHL2_MSGTYPE_OFFSET 0x0EU
  56. /*! @brief PTPv2 message Ethernet version type offset. */
  57. #define ENET_PTP1588_ETHL2_VERSION_OFFSET 0X0FU
  58. /*! @brief PTPv2 message Ethernet clock id offset. */
  59. #define ENET_PTP1588_ETHL2_CLOCKID_OFFSET 0x22
  60. /*! @brief PTPv2 message Ethernet sequence id offset. */
  61. #define ENET_PTP1588_ETHL2_SEQUENCEID_OFFSET 0x2c
  62. /*! @brief Packet type Ethernet IEEE802.3 for PTPv2. */
  63. #define ENET_ETHERNETL2 0x88F7U
  64. /*! @brief Packet type IPv4. */
  65. #define ENET_IPV4 0x0800U
  66. /*! @brief Packet type IPv6. */
  67. #define ENET_IPV6 0x86ddU
  68. /*! @brief Packet type VLAN. */
  69. #define ENET_8021QVLAN 0x8100U
  70. /*! @brief UDP protocol type. */
  71. #define ENET_UDPVERSION 0x0011U
  72. /*! @brief Packet IP version IPv4. */
  73. #define ENET_IPV4VERSION 0x0004U
  74. /*! @brief Packet IP version IPv6. */
  75. #define ENET_IPV6VERSION 0x0006U
  76. /*! @brief Ethernet mac address length. */
  77. #define ENET_FRAME_MACLEN 6U
  78. /*! @brief Ethernet VLAN header length. */
  79. #define ENET_FRAME_VLAN_TAGLEN 4U
  80. /*! @brief MDC frequency. */
  81. #define ENET_MDC_FREQUENCY 2500000U
  82. /*! @brief NanoSecond in one second. */
  83. #define ENET_NANOSECOND_ONE_SECOND 1000000000U
  84. /*! @brief Define a common clock cycle delays used for time stamp capture. */
  85. #define ENET_1588TIME_DELAY_COUNT 10U
  86. /*! @brief Defines the macro for converting constants from host byte order to network byte order. */
  87. #define ENET_HTONS(n) __REV16(n)
  88. #define ENET_HTONL(n) __REV(n)
  89. #define ENET_NTOHS(n) __REV16(n)
  90. #define ENET_NTOHL(n) __REV(n)
  91. /* Typedef for interrupt handler. */
  92. typedef void (*enet_isr_t)(ENET_Type *base, enet_handle_t *handle);
  93. /*******************************************************************************
  94. * Prototypes
  95. ******************************************************************************/
  96. /*!
  97. * @brief Get the ENET instance from peripheral base address.
  98. *
  99. * @param base ENET peripheral base address.
  100. * @return ENET instance.
  101. */
  102. uint32_t ENET_GetInstance(ENET_Type *base);
  103. /*!
  104. * @brief Set ENET MAC controller with the configuration.
  105. *
  106. * @param base ENET peripheral base address.
  107. * @param config ENET Mac configuration.
  108. * @param bufferConfig ENET buffer configuration.
  109. * @param macAddr ENET six-byte mac address.
  110. * @param srcClock_Hz ENET module clock source, normally it's system clock.
  111. */
  112. static void ENET_SetMacController(ENET_Type *base,
  113. const enet_config_t *config,
  114. const enet_buffer_config_t *bufferConfig,
  115. uint8_t *macAddr,
  116. uint32_t srcClock_Hz);
  117. /*!
  118. * @brief Set ENET handler.
  119. *
  120. * @param base ENET peripheral base address.
  121. * @param handle The ENET handle pointer.
  122. * @param config ENET configuration stucture pointer.
  123. * @param bufferConfig ENET buffer configuration.
  124. */
  125. static void ENET_SetHandler(ENET_Type *base,
  126. enet_handle_t *handle,
  127. const enet_config_t *config,
  128. const enet_buffer_config_t *bufferConfig);
  129. /*!
  130. * @brief Set ENET MAC transmit buffer descriptors.
  131. *
  132. * @param txBdStartAlign The aligned start address of ENET transmit buffer descriptors.
  133. * is recommended to evenly divisible by 16.
  134. * @param txBuffStartAlign The aligned start address of ENET transmit buffers, must be evenly divisible by 16.
  135. * @param txBuffSizeAlign The aligned ENET transmit buffer size, must be evenly divisible by 16.
  136. * @param txBdNumber The number of ENET transmit buffers.
  137. */
  138. static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartAlign,
  139. uint8_t *txBuffStartAlign,
  140. uint32_t txBuffSizeAlign,
  141. uint32_t txBdNumber);
  142. /*!
  143. * @brief Set ENET MAC receive buffer descriptors.
  144. *
  145. * @param rxBdStartAlign The aligned start address of ENET receive buffer descriptors.
  146. * is recommended to evenly divisible by 16.
  147. * @param rxBuffStartAlign The aligned start address of ENET receive buffers, must be evenly divisible by 16.
  148. * @param rxBuffSizeAlign The aligned ENET receive buffer size, must be evenly divisible by 16.
  149. * @param rxBdNumber The number of ENET receive buffers.
  150. * @param enableInterrupt Enable/disables to generate the receive byte and frame interrupt.
  151. * It's used for ENET_ENHANCEDBUFFERDESCRIPTOR_MODE enabled case.
  152. */
  153. static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartAlign,
  154. uint8_t *rxBuffStartAlign,
  155. uint32_t rxBuffSizeAlign,
  156. uint32_t rxBdNumber,
  157. bool enableInterrupt);
  158. /*!
  159. * @brief Updates the ENET read buffer descriptors.
  160. *
  161. * @param base ENET peripheral base address.
  162. * @param handle The ENET handle pointer.
  163. */
  164. static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle);
  165. void rt_hw_cpu_dcache_clean(void *addr, int size);
  166. void rt_hw_cpu_dcache_invalidate(void *addr, int size);
  167. /*******************************************************************************
  168. * Variables
  169. ******************************************************************************/
  170. /*! @brief Pointers to enet handles for each instance. */
  171. static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL,NULL};
  172. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  173. /*! @brief Pointers to enet clocks for each instance. */
  174. const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;
  175. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  176. /*! @brief Pointers to enet bases for each instance. */
  177. static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
  178. /* ENET ISR for transactional APIs. */
  179. static enet_isr_t s_enetTxIsr = NULL;
  180. static enet_isr_t s_enetRxIsr = NULL;
  181. static enet_isr_t s_enetErrIsr = NULL;
  182. static enet_isr_t s_enetTsIsr = NULL;
  183. /*******************************************************************************
  184. * Code
  185. ******************************************************************************/
  186. uint32_t ENET_GetInstance(ENET_Type *base)
  187. {
  188. uint32_t instance;
  189. /* Find the instance index from base address mappings. */
  190. for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++)
  191. {
  192. if (s_enetBases[instance] == base)
  193. {
  194. break;
  195. }
  196. }
  197. RT_ASSERT(instance < ARRAY_SIZE(s_enetBases));
  198. return instance;
  199. }
  200. void ENET_GetDefaultConfig(enet_config_t *config)
  201. {
  202. /* Checks input parameter. */
  203. RT_ASSERT(config);
  204. /* Initializes the MAC configure structure to zero. */
  205. memset(config, 0, sizeof(enet_config_t));
  206. /* Sets MII mode, full duplex, 100Mbps for MAC and PHY data interface. */
  207. config->miiMode = kENET_RmiiMode;
  208. config->miiSpeed = kENET_MiiSpeed100M;
  209. config->miiDuplex = kENET_MiiFullDuplex;
  210. /* Sets the maximum receive frame length. */
  211. config->rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN;
  212. }
  213. void ENET_Init(ENET_Type *base,
  214. enet_handle_t *handle,
  215. const enet_config_t *config,
  216. const enet_buffer_config_t *bufferConfig,
  217. uint8_t *macAddr,
  218. uint32_t srcClock_Hz)
  219. {
  220. /* Checks input parameters. */
  221. RT_ASSERT(handle);
  222. RT_ASSERT(config);
  223. RT_ASSERT(bufferConfig);
  224. RT_ASSERT(bufferConfig->rxBdStartAddrAlign);
  225. RT_ASSERT(bufferConfig->txBdStartAddrAlign);
  226. RT_ASSERT(bufferConfig->rxBufferAlign);
  227. RT_ASSERT(bufferConfig->txBufferAlign);
  228. RT_ASSERT(macAddr);
  229. RT_ASSERT(bufferConfig->rxBuffSizeAlign >= ENET_RX_MIN_BUFFERSIZE);
  230. /* Make sure the buffers should be have the capability of process at least one maximum frame. */
  231. if (config->macSpecialConfig & kENET_ControlVLANTagEnable)
  232. {
  233. RT_ASSERT(bufferConfig->txBuffSizeAlign * bufferConfig->txBdNumber > (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN));
  234. }
  235. else
  236. {
  237. RT_ASSERT(bufferConfig->txBuffSizeAlign * bufferConfig->txBdNumber > ENET_FRAME_MAX_FRAMELEN);
  238. RT_ASSERT(bufferConfig->rxBuffSizeAlign * bufferConfig->rxBdNumber > config->rxMaxFrameLen);
  239. }
  240. /* Reset ENET module. */
  241. ENET_Reset(base);
  242. /* Initializes the ENET transmit buffer descriptors. */
  243. ENET_SetTxBufferDescriptors(bufferConfig->txBdStartAddrAlign, bufferConfig->txPhyBufferAlign,
  244. bufferConfig->txBuffSizeAlign, bufferConfig->txBdNumber);
  245. /* Initializes the ENET receive buffer descriptors. */
  246. ENET_SetRxBufferDescriptors(bufferConfig->rxBdStartAddrAlign, bufferConfig->rxPhyBufferAlign,
  247. bufferConfig->rxBuffSizeAlign, bufferConfig->rxBdNumber,
  248. !!(config->interrupt & (kENET_RxFrameInterrupt | kENET_RxBufferInterrupt)));
  249. /* Initializes the ENET MAC controller. */
  250. ENET_SetMacController(base, config, bufferConfig, macAddr, srcClock_Hz);
  251. /* Set all buffers or data in handler for data transmit/receive process. */
  252. ENET_SetHandler(base, handle, config, bufferConfig);
  253. }
  254. void ENET_Deinit(ENET_Type *base)
  255. {
  256. /* Disable interrupt. */
  257. base->EIMR = 0;
  258. /* Disable ENET. */
  259. base->ECR &= ~ENET_ECR_ETHEREN_MASK;
  260. }
  261. void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData)
  262. {
  263. RT_ASSERT(handle);
  264. /* Set callback and userData. */
  265. handle->callback = callback;
  266. handle->userData = userData;
  267. }
  268. static void ENET_SetHandler(ENET_Type *base,
  269. enet_handle_t *handle,
  270. const enet_config_t *config,
  271. const enet_buffer_config_t *bufferConfig)
  272. {
  273. struct rt_imx6ul_ethps *imx6ul_device = rt_container_of(config,struct rt_imx6ul_ethps,config);
  274. uint32_t instance = get_instance_by_base(base);
  275. memset(handle, 0, sizeof(enet_handle_t));
  276. handle->rxBdBase = bufferConfig->rxBdStartAddrAlign;
  277. handle->rxBdCurrent = bufferConfig->rxBdStartAddrAlign;
  278. handle->txBdBase = bufferConfig->txBdStartAddrAlign;
  279. handle->txBdCurrent = bufferConfig->txBdStartAddrAlign;
  280. handle->rxBuffSizeAlign = bufferConfig->rxBuffSizeAlign;
  281. handle->txBuffSizeAlign = bufferConfig->txBuffSizeAlign;
  282. /* Save the handle pointer in the global variables. */
  283. s_ENETHandle[instance] = handle;
  284. /* Set the IRQ handler when the interrupt is enabled. */
  285. if (config->interrupt & ENET_TX_INTERRUPT)
  286. {
  287. s_enetTxIsr = ENET_TransmitIRQHandler;
  288. EnableIRQ(imx6ul_device->irq_num);
  289. }
  290. if (config->interrupt & ENET_RX_INTERRUPT)
  291. {
  292. s_enetRxIsr = ENET_ReceiveIRQHandler;
  293. EnableIRQ(imx6ul_device->irq_num);
  294. }
  295. if (config->interrupt & ENET_ERR_INTERRUPT)
  296. {
  297. s_enetErrIsr = ENET_ErrorIRQHandler;
  298. EnableIRQ(imx6ul_device->irq_num);
  299. }
  300. }
  301. static void ENET_SetMacController(ENET_Type *base,
  302. const enet_config_t *config,
  303. const enet_buffer_config_t *bufferConfig,
  304. uint8_t *macAddr,
  305. uint32_t srcClock_Hz)
  306. {
  307. uint32_t rcr = 0;
  308. uint32_t tcr = 0;
  309. uint32_t ecr = 0;
  310. uint32_t macSpecialConfig = config->macSpecialConfig;
  311. uint32_t maxFrameLen = config->rxMaxFrameLen;
  312. /* Maximum frame length check. */
  313. if ((macSpecialConfig & kENET_ControlVLANTagEnable) && (maxFrameLen <= ENET_FRAME_MAX_FRAMELEN))
  314. {
  315. maxFrameLen = (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN);
  316. }
  317. /* Configures MAC receive controller with user configure structure. */
  318. rcr = ENET_RCR_NLC(!!(macSpecialConfig & kENET_ControlRxPayloadCheckEnable)) |
  319. ENET_RCR_CFEN(!!(macSpecialConfig & kENET_ControlFlowControlEnable)) |
  320. ENET_RCR_FCE(!!(macSpecialConfig & kENET_ControlFlowControlEnable)) |
  321. ENET_RCR_PADEN(!!(macSpecialConfig & kENET_ControlRxPadRemoveEnable)) |
  322. ENET_RCR_BC_REJ(!!(macSpecialConfig & kENET_ControlRxBroadCastRejectEnable)) |
  323. ENET_RCR_PROM(!!(macSpecialConfig & kENET_ControlPromiscuousEnable)) | ENET_RCR_MII_MODE(1) |
  324. ENET_RCR_RMII_MODE(config->miiMode) | ENET_RCR_RMII_10T(!config->miiSpeed) |
  325. ENET_RCR_MAX_FL(maxFrameLen) | ENET_RCR_CRCFWD(1);
  326. /* Receive setting for half duplex. */
  327. if (config->miiDuplex == kENET_MiiHalfDuplex)
  328. {
  329. rcr |= ENET_RCR_DRT_MASK;
  330. }
  331. /* Sets internal loop only for MII mode. */
  332. if ((config->macSpecialConfig & kENET_ControlMIILoopEnable) && (config->miiMode == kENET_MiiMode))
  333. {
  334. rcr |= ENET_RCR_LOOP_MASK;
  335. rcr &= ~ENET_RCR_DRT_MASK;
  336. }
  337. base->RCR = rcr;
  338. /* Configures MAC transmit controller: duplex mode, mac address insertion. */
  339. tcr = base->TCR & ~(ENET_TCR_FDEN_MASK | ENET_TCR_ADDINS_MASK);
  340. tcr |= ENET_TCR_FDEN(config->miiDuplex) | ENET_TCR_ADDINS(!!(macSpecialConfig & kENET_ControlMacAddrInsert));
  341. base->TCR = tcr;
  342. /* Configures receive and transmit accelerator. */
  343. base->TACC = config->txAccelerConfig;
  344. base->RACC = config->rxAccelerConfig;
  345. /* Sets the pause duration and FIFO threshold for the flow control enabled case. */
  346. if (macSpecialConfig & kENET_ControlFlowControlEnable)
  347. {
  348. uint32_t reemReg;
  349. base->OPD = config->pauseDuration;
  350. reemReg = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold);
  351. #if defined (FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD
  352. reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold);
  353. #endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */
  354. base->RSEM = reemReg;
  355. }
  356. /* FIFO threshold setting for store and forward enable/disable case. */
  357. if (macSpecialConfig & kENET_ControlStoreAndFwdDisable)
  358. {
  359. /* Transmit fifo watermark settings. */
  360. base->TFWR = config->txFifoWatermark & ENET_TFWR_TFWR_MASK;
  361. /* Receive fifo full threshold settings. */
  362. base->RSFL = config->rxFifoFullThreshold & ENET_RSFL_RX_SECTION_FULL_MASK;
  363. }
  364. else
  365. {
  366. /* Transmit fifo watermark settings. */
  367. base->TFWR = ENET_TFWR_STRFWD_MASK;
  368. base->RSFL = 0;
  369. }
  370. /* Enable store and forward when accelerator is enabled */
  371. if (config->txAccelerConfig & (kENET_TxAccelIpCheckEnabled | kENET_TxAccelProtoCheckEnabled))
  372. {
  373. base->TFWR = ENET_TFWR_STRFWD_MASK;
  374. }
  375. if (config->rxAccelerConfig & (kENET_RxAccelIpCheckEnabled | kENET_RxAccelProtoCheckEnabled))
  376. {
  377. base->RSFL = 0;
  378. }
  379. /* Initializes transmit buffer descriptor rings start address, two start address should be aligned. */
  380. base->TDSR = (uint32_t)bufferConfig->txPhyBdStartAddrAlign;
  381. base->RDSR = (uint32_t)bufferConfig->rxPhyBdStartAddrAlign;
  382. /* Initializes the maximum buffer size, the buffer size should be aligned. */
  383. base->MRBR = ENET_MRBR_R_BUF_SIZE(bufferConfig->rxBuffSizeAlign);
  384. /* Configures the Mac address. */
  385. ENET_SetMacAddr(base, macAddr);
  386. /* Initialize the SMI if uninitialized. */
  387. if (!ENET_GetSMI(base))
  388. {
  389. ENET_SetSMI(base, srcClock_Hz, !!(config->macSpecialConfig & kENET_ControlSMIPreambleDisable));
  390. }
  391. /* Enables Ethernet interrupt and NVIC. */
  392. #if defined(FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE
  393. if (config->intCoalesceCfg)
  394. {
  395. uint32_t intMask = (ENET_EIMR_TXB_MASK | ENET_EIMR_RXB_MASK);
  396. /* Clear all buffer interrupts. */
  397. base->EIMR &= ~intMask;
  398. /* Set the interrupt coalescence. */
  399. base->TXIC = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[0]) |
  400. config->intCoalesceCfg->txCoalesceTimeCount[0] | ENET_TXIC_ICCS_MASK | ENET_TXIC_ICEN_MASK;
  401. base->RXIC = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[0]) |
  402. config->intCoalesceCfg->rxCoalesceTimeCount[0] | ENET_RXIC_ICCS_MASK | ENET_RXIC_ICEN_MASK;
  403. }
  404. #endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */
  405. ENET_EnableInterrupts(base, config->interrupt);
  406. /* ENET control register setting. */
  407. ecr = base->ECR;
  408. /* Enables Ethernet module after all configuration except the buffer descriptor active. */
  409. ecr |= ENET_ECR_ETHEREN_MASK | ENET_ECR_DBSWP_MASK;
  410. base->ECR = ecr;
  411. }
  412. static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartAlign,
  413. uint8_t *txBuffStartAlign,
  414. uint32_t txBuffSizeAlign,
  415. uint32_t txBdNumber)
  416. {
  417. RT_ASSERT(txBdStartAlign);
  418. RT_ASSERT(txBuffStartAlign);
  419. uint32_t count;
  420. volatile enet_tx_bd_struct_t *curBuffDescrip = txBdStartAlign;
  421. for (count = 0; count < txBdNumber; count++)
  422. {
  423. /* Set data buffer address. */
  424. curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffStartAlign[count * txBuffSizeAlign]);
  425. /* Initializes data length. */
  426. curBuffDescrip->length = 0;
  427. /* Sets the crc. */
  428. curBuffDescrip->control = (ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK);
  429. /* Sets the last buffer descriptor with the wrap flag. */
  430. if (count == txBdNumber - 1)
  431. {
  432. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK;
  433. }
  434. /* Add cache clean operation. */
  435. rt_hw_cpu_dcache_clean((void *)curBuffDescrip, sizeof(enet_tx_bd_struct_t));
  436. /* Increase the index. */
  437. curBuffDescrip++;
  438. }
  439. }
  440. static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartAlign,
  441. uint8_t *rxBuffStartAlign,
  442. uint32_t rxBuffSizeAlign,
  443. uint32_t rxBdNumber,
  444. bool enableInterrupt)
  445. {
  446. RT_ASSERT(rxBdStartAlign);
  447. RT_ASSERT(rxBuffStartAlign);
  448. volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdStartAlign;
  449. uint32_t count = 0;
  450. /* Initializes receive buffer descriptors. */
  451. for (count = 0; count < rxBdNumber; count++)
  452. {
  453. /* Set data buffer and the length. */
  454. curBuffDescrip->buffer = (uint8_t *)((void *)&rxBuffStartAlign[count * rxBuffSizeAlign]);
  455. curBuffDescrip->length = 0;
  456. /* Initializes the buffer descriptors with empty bit. */
  457. curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  458. /* Sets the last buffer descriptor with the wrap flag. */
  459. if (count == rxBdNumber - 1)
  460. {
  461. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
  462. }
  463. /* Add cache clean operation. */
  464. rt_hw_cpu_dcache_clean((void *)curBuffDescrip, sizeof(enet_rx_bd_struct_t));
  465. /* Increase the index. */
  466. curBuffDescrip++;
  467. }
  468. }
  469. void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
  470. {
  471. uint32_t rcr = base->RCR;
  472. uint32_t tcr = base->TCR;
  473. /* Sets speed mode. */
  474. if (kENET_MiiSpeed10M == speed)
  475. {
  476. rcr |= ENET_RCR_RMII_10T_MASK;
  477. }
  478. else
  479. {
  480. rcr &= ~ENET_RCR_RMII_10T_MASK;
  481. }
  482. /* Set duplex mode. */
  483. if (duplex == kENET_MiiHalfDuplex)
  484. {
  485. rcr |= ENET_RCR_DRT_MASK;
  486. tcr &= ~ENET_TCR_FDEN_MASK;
  487. }
  488. else
  489. {
  490. rcr &= ~ENET_RCR_DRT_MASK;
  491. tcr |= ENET_TCR_FDEN_MASK;
  492. }
  493. base->RCR = rcr;
  494. base->TCR = tcr;
  495. }
  496. void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr)
  497. {
  498. uint32_t address;
  499. /* Set physical address lower register. */
  500. address = (uint32_t)(((uint32_t)macAddr[0] << 24U) | ((uint32_t)macAddr[1] << 16U) | ((uint32_t)macAddr[2] << 8U) |
  501. (uint32_t)macAddr[3]);
  502. base->PALR = address;
  503. /* Set physical address high register. */
  504. address = (uint32_t)(((uint32_t)macAddr[4] << 8U) | ((uint32_t)macAddr[5]));
  505. base->PAUR = address << ENET_PAUR_PADDR2_SHIFT;
  506. }
  507. void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr)
  508. {
  509. RT_ASSERT(macAddr);
  510. uint32_t address;
  511. /* Get from physical address lower register. */
  512. address = base->PALR;
  513. macAddr[0] = 0xFFU & (address >> 24U);
  514. macAddr[1] = 0xFFU & (address >> 16U);
  515. macAddr[2] = 0xFFU & (address >> 8U);
  516. macAddr[3] = 0xFFU & address;
  517. /* Get from physical address high register. */
  518. address = (base->PAUR & ENET_PAUR_PADDR2_MASK) >> ENET_PAUR_PADDR2_SHIFT;
  519. macAddr[4] = 0xFFU & (address >> 8U);
  520. macAddr[5] = 0xFFU & address;
  521. }
  522. void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled)
  523. {
  524. RT_ASSERT(srcClock_Hz);
  525. uint32_t clkCycle = 0;
  526. uint32_t speed = 0;
  527. uint32_t mscr = 0;
  528. /* Calculate the MII speed which controls the frequency of the MDC. */
  529. speed = srcClock_Hz / (2 * ENET_MDC_FREQUENCY);
  530. /* Calculate the hold time on the MDIO output. */
  531. clkCycle = (10 + ENET_NANOSECOND_ONE_SECOND / srcClock_Hz - 1) / (ENET_NANOSECOND_ONE_SECOND / srcClock_Hz) - 1;
  532. /* Build the configuration for MDC/MDIO control. */
  533. mscr = ENET_MSCR_MII_SPEED(speed) | ENET_MSCR_DIS_PRE(isPreambleDisabled) | ENET_MSCR_HOLDTIME(clkCycle);
  534. base->MSCR = mscr;
  535. }
  536. void ENET_StartSMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_write_t operation, uint32_t data)
  537. {
  538. uint32_t mmfr = 0;
  539. /* Build MII write command. */
  540. mmfr = ENET_MMFR_ST(1) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2) |
  541. (data & 0xFFFF);
  542. base->MMFR = mmfr;
  543. }
  544. void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation)
  545. {
  546. uint32_t mmfr = 0;
  547. /* Build MII read command. */
  548. mmfr = ENET_MMFR_ST(1) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2);
  549. base->MMFR = mmfr;
  550. }
  551. #if defined(FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO
  552. void ENET_StartExtC45SMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
  553. {
  554. uint32_t mmfr = 0;
  555. /* Parse the address from the input register. */
  556. uint16_t devAddr = (phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU;
  557. uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
  558. /* Address write firstly. */
  559. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  560. ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
  561. base->MMFR = mmfr;
  562. /* Build MII write command. */
  563. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  564. ENET_MMFR_TA(2) | ENET_MMFR_DATA(data);
  565. base->MMFR = mmfr;
  566. }
  567. void ENET_StartExtC45SMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg)
  568. {
  569. uint32_t mmfr = 0;
  570. /* Parse the address from the input register. */
  571. uint16_t devAddr = (phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU;
  572. uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
  573. /* Address write firstly. */
  574. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  575. ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
  576. base->MMFR = mmfr;
  577. /* Build MII read command. */
  578. mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
  579. ENET_MMFR_TA(2);
  580. base->MMFR = mmfr;
  581. }
  582. #endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */
  583. void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic)
  584. {
  585. RT_ASSERT(handle);
  586. RT_ASSERT(handle->rxBdCurrent);
  587. RT_ASSERT(eErrorStatic);
  588. uint16_t control = 0;
  589. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent;
  590. do
  591. {
  592. /* Add the cache invalidate maintain. */
  593. rt_hw_cpu_dcache_invalidate((void *)curBuffDescrip, sizeof(enet_rx_bd_struct_t));
  594. /* The last buffer descriptor of a frame. */
  595. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  596. {
  597. control = curBuffDescrip->control;
  598. if (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK)
  599. {
  600. /* The receive truncate error. */
  601. eErrorStatic->statsRxTruncateErr++;
  602. }
  603. if (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK)
  604. {
  605. /* The receive over run error. */
  606. eErrorStatic->statsRxOverRunErr++;
  607. }
  608. if (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK)
  609. {
  610. /* The receive length violation error. */
  611. eErrorStatic->statsRxLenGreaterErr++;
  612. }
  613. if (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK)
  614. {
  615. /* The receive alignment error. */
  616. eErrorStatic->statsRxAlignErr++;
  617. }
  618. if (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK)
  619. {
  620. /* The receive CRC error. */
  621. eErrorStatic->statsRxFcsErr++;
  622. }
  623. break;
  624. }
  625. /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
  626. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  627. {
  628. curBuffDescrip = handle->rxBdBase;
  629. }
  630. else
  631. {
  632. curBuffDescrip++;
  633. }
  634. } while (curBuffDescrip != handle->rxBdCurrent);
  635. }
  636. status_t ENET_ReadFrame(ENET_Type *base,enet_handle_t *handle,const enet_config_t *config,uint8_t *data,uint16_t *length)
  637. {
  638. RT_ASSERT(handle);
  639. RT_ASSERT(handle->rxBdCurrent);
  640. RT_ASSERT(length);
  641. /* Reset the length to zero. */
  642. *length = 0;
  643. uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  644. volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent;
  645. rt_hw_cpu_dcache_invalidate((void *)physical_to_virtual(curBuffDescrip->buffer), handle->rxBuffSizeAlign);
  646. /* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */
  647. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK)
  648. {
  649. return kStatus_ENET_RxFrameEmpty;
  650. }
  651. else
  652. {
  653. if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
  654. {
  655. if(curBuffDescrip->length <= config->rxMaxFrameLen)
  656. {
  657. *length = curBuffDescrip->length;
  658. rt_memcpy(data, physical_to_virtual(curBuffDescrip->buffer),curBuffDescrip->length);
  659. /* Updates the receive buffer descriptors. */
  660. ENET_UpdateReadBuffers(base, handle);
  661. return kStatus_Success;
  662. }
  663. else
  664. {
  665. LOG_E("frame error0 curBuffDescrip->control 0x%04x length %d\n",curBuffDescrip->control,curBuffDescrip->length);
  666. *length = curBuffDescrip->length;
  667. /* Updates the receive buffer descriptors. */
  668. ENET_UpdateReadBuffers(base, handle);
  669. return kStatus_ENET_RxFrameError;
  670. }
  671. }
  672. else
  673. {
  674. LOG_E("frame error1 curBuffDescrip->control 0x%04x length %d\n",curBuffDescrip->control,curBuffDescrip->length);
  675. *length = curBuffDescrip->length;
  676. ENET_UpdateReadBuffers(base, handle);
  677. return kStatus_ENET_RxFrameError;
  678. }
  679. }
  680. /* The frame is on processing - set to empty status to make application to receive it next time. */
  681. return kStatus_ENET_RxFrameEmpty;
  682. }
  683. static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle)
  684. {
  685. RT_ASSERT(handle);
  686. /* Clears status. */
  687. handle->rxBdCurrent->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
  688. /* Sets the receive buffer descriptor with the empty flag. */
  689. handle->rxBdCurrent->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
  690. /* Increase current buffer descriptor to the next one. */
  691. if (handle->rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
  692. {
  693. handle->rxBdCurrent = handle->rxBdBase;
  694. }
  695. else
  696. {
  697. handle->rxBdCurrent++;
  698. }
  699. /* Actives the receive buffer descriptor. */
  700. base->RDAR = ENET_RDAR_RDAR_MASK;
  701. }
  702. status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, const uint8_t *data, uint16_t length,uint32_t last_flag)
  703. {
  704. RT_ASSERT(handle);
  705. RT_ASSERT(handle->txBdCurrent);
  706. RT_ASSERT(data);
  707. RT_ASSERT(length <= ENET_FRAME_MAX_FRAMELEN);
  708. volatile enet_tx_bd_struct_t *curBuffDescrip = handle->txBdCurrent;
  709. /* Check if the transmit buffer is ready. */
  710. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)
  711. {
  712. return kStatus_ENET_TxFrameBusy;
  713. }
  714. /* One transmit buffer is enough for one frame. */
  715. if (handle->txBuffSizeAlign >= length)
  716. {
  717. /* Copy data to the buffer for uDMA transfer. */
  718. rt_memcpy(physical_to_virtual(curBuffDescrip->buffer), data, length);
  719. /* Set data length. */
  720. curBuffDescrip->length = length;
  721. if(last_flag)
  722. {
  723. curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
  724. }
  725. else
  726. {
  727. curBuffDescrip->control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
  728. curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
  729. }
  730. rt_hw_cpu_dcache_clean((void *)physical_to_virtual(curBuffDescrip->buffer),length);
  731. /* Active the transmit buffer descriptor. */
  732. base->TDAR = ENET_TDAR_TDAR_MASK;
  733. /* Increase the buffer descriptor address. */
  734. while((base->TDAR != 0))
  735. {
  736. }
  737. if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)
  738. {
  739. handle->txBdCurrent = handle->txBdBase;
  740. }
  741. else
  742. {
  743. handle->txBdCurrent++;
  744. }
  745. return kStatus_Success;
  746. }
  747. else
  748. {
  749. return kStatus_ENET_RxFrameError;
  750. }
  751. }
  752. void ENET_AddMulticastGroup(ENET_Type *base, uint8_t *address)
  753. {
  754. RT_ASSERT(address);
  755. uint32_t crc = 0xFFFFFFFFU;
  756. uint32_t count1 = 0;
  757. uint32_t count2 = 0;
  758. /* Calculates the CRC-32 polynomial on the multicast group address. */
  759. for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
  760. {
  761. uint8_t c = address[count1];
  762. for (count2 = 0; count2 < 0x08U; count2++)
  763. {
  764. if ((c ^ crc) & 1U)
  765. {
  766. crc >>= 1U;
  767. c >>= 1U;
  768. crc ^= 0xEDB88320U;
  769. }
  770. else
  771. {
  772. crc >>= 1U;
  773. c >>= 1U;
  774. }
  775. }
  776. }
  777. /* Enable a multicast group address. */
  778. if (!((crc >> 0x1FU) & 1U))
  779. {
  780. base->GALR |= 1U << ((crc >> 0x1AU) & 0x1FU);
  781. }
  782. else
  783. {
  784. base->GAUR |= 1U << ((crc >> 0x1AU) & 0x1FU);
  785. }
  786. }
  787. void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address)
  788. {
  789. RT_ASSERT(address);
  790. uint32_t crc = 0xFFFFFFFFU;
  791. uint32_t count1 = 0;
  792. uint32_t count2 = 0;
  793. /* Calculates the CRC-32 polynomial on the multicast group address. */
  794. for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
  795. {
  796. uint8_t c = address[count1];
  797. for (count2 = 0; count2 < 0x08U; count2++)
  798. {
  799. if ((c ^ crc) & 1U)
  800. {
  801. crc >>= 1U;
  802. c >>= 1U;
  803. crc ^= 0xEDB88320U;
  804. }
  805. else
  806. {
  807. crc >>= 1U;
  808. c >>= 1U;
  809. }
  810. }
  811. }
  812. /* Set the hash table. */
  813. if (!((crc >> 0x1FU) & 1U))
  814. {
  815. base->GALR &= ~(1U << ((crc >> 0x1AU) & 0x1FU));
  816. }
  817. else
  818. {
  819. base->GAUR &= ~(1U << ((crc >> 0x1AU) & 0x1FU));
  820. }
  821. }
  822. void tx_enet_callback(void *base);
  823. void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
  824. {
  825. RT_ASSERT(handle);
  826. /* Check if the transmit interrupt happen. */
  827. if((kENET_TxBufferInterrupt | kENET_TxFrameInterrupt) & base->EIR)
  828. {
  829. /* Clear the transmit interrupt event. */
  830. base->EIR = kENET_TxFrameInterrupt | kENET_TxBufferInterrupt;
  831. }
  832. tx_enet_callback((void *)base);
  833. }
  834. void rx_enet_callback(void *base);
  835. void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
  836. {
  837. RT_ASSERT(handle);
  838. /* Check if the receive interrupt happen. */
  839. if((kENET_RxBufferInterrupt | kENET_RxFrameInterrupt) & base->EIR)
  840. {
  841. /* Clear the transmit interrupt event. */
  842. base->EIR = kENET_RxFrameInterrupt | kENET_RxBufferInterrupt;
  843. rx_enet_callback((void *)base);
  844. }
  845. }
  846. void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
  847. {
  848. RT_ASSERT(handle);
  849. uint32_t errMask = kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_PayloadRxInterrupt |
  850. kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt;
  851. /* Check if the error interrupt happen. */
  852. if (kENET_WakeupInterrupt & base->EIR)
  853. {
  854. /* Clear the wakeup interrupt. */
  855. base->EIR = kENET_WakeupInterrupt;
  856. /* wake up and enter the normal mode. */
  857. ENET_EnableSleepMode(base, false);
  858. /* Callback function. */
  859. if (handle->callback)
  860. {
  861. handle->callback(base, handle, kENET_WakeUpEvent, handle->userData);
  862. }
  863. }
  864. else
  865. {
  866. /* Clear the error interrupt event status. */
  867. errMask &= base->EIR;
  868. base->EIR = errMask;
  869. /* Callback function. */
  870. if (handle->callback)
  871. {
  872. handle->callback(base, handle, kENET_ErrEvent, handle->userData);
  873. }
  874. }
  875. }
  876. void ENET_CommonFrame0IRQHandler(ENET_Type *base)
  877. {
  878. uint32_t event = base->EIR;
  879. uint32_t instance = get_instance_by_base(base);
  880. if(base->EIMR & ENET_TX_INTERRUPT)
  881. {
  882. if (event & ENET_TX_INTERRUPT)
  883. {
  884. if(s_enetTxIsr)
  885. {
  886. s_enetTxIsr(base, s_ENETHandle[instance]);
  887. }
  888. }
  889. }
  890. if (base->EIMR & ENET_RX_INTERRUPT)
  891. {
  892. if (event & ENET_RX_INTERRUPT)
  893. {
  894. if(s_enetRxIsr)
  895. {
  896. s_enetRxIsr(base, s_ENETHandle[instance]);
  897. }
  898. }
  899. }
  900. if(base->EIMR & ENET_TS_INTERRUPT)
  901. {
  902. if (event & ENET_TS_INTERRUPT)
  903. {
  904. if(s_enetTsIsr)
  905. {
  906. s_enetTsIsr(base, s_ENETHandle[instance]);
  907. }
  908. }
  909. }
  910. if(base->EIMR & ENET_ERR_INTERRUPT)
  911. {
  912. if (event & ENET_ERR_INTERRUPT)
  913. {
  914. if(s_enetErrIsr)
  915. {
  916. s_enetErrIsr(base, s_ENETHandle[instance]);
  917. }
  918. }
  919. }
  920. }
  921. void ENET_DriverIRQHandler(int irq, void *base)
  922. {
  923. ENET_CommonFrame0IRQHandler((ENET_Type *)base);
  924. }