1 /*
2  * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2024 NXP
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_enet.h"
9 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
10 #include "fsl_cache.h"
11 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
12 
13 /*******************************************************************************
14  * Definitions
15  ******************************************************************************/
16 
17 /* Component ID definition, used by tools. */
18 #ifndef FSL_COMPONENT_ID
19 #define FSL_COMPONENT_ID "platform.drivers.enet"
20 #endif
21 
22 /*! @brief Ethernet mac address length. */
23 #define ENET_FRAME_MACLEN 6U
24 /*! @brief MDC frequency. */
25 #define ENET_MDC_FREQUENCY 2500000U
26 /*! @brief NanoSecond in one second. */
27 #define ENET_NANOSECOND_ONE_SECOND 1000000000U
28 
29 /*! @brief Define the ENET ring/class bumber . */
30 enum
31 {
32     kENET_Ring0 = 0U, /*!< ENET ring/class 0. */
33 #if FSL_FEATURE_ENET_QUEUE > 1
34     kENET_Ring1 = 1U, /*!< ENET ring/class 1. */
35     kENET_Ring2 = 2U  /*!< ENET ring/class 2. */
36 #endif                /* FSL_FEATURE_ENET_QUEUE > 1 */
37 };
38 
39 /*******************************************************************************
40  * Variables
41  ******************************************************************************/
42 
43 /*! @brief Pointers to enet clocks for each instance. */
44 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
45 const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;
46 #if defined(FSL_FEATURE_ENET_HAS_EXTRA_CLOCK_GATE) && FSL_FEATURE_ENET_HAS_EXTRA_CLOCK_GATE
47 const clock_ip_name_t s_enetExtraClock[] = ENET_EXTRA_CLOCKS;
48 #endif
49 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
50 
51 /*! @brief Pointers to enet transmit IRQ number for each instance. */
52 static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
53 /*! @brief Pointers to enet receive IRQ number for each instance. */
54 static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
55 #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
56 /*! @brief Pointers to enet timestamp IRQ number for each instance. */
57 static const IRQn_Type s_enetTsIrqId[] = ENET_Ts_IRQS;
58 /*! @brief Pointers to enet 1588 timestamp IRQ number for each instance. */
59 static const IRQn_Type s_enet1588TimerIrqId[] = ENET_1588_Timer_IRQS;
60 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
61 /*! @brief Pointers to enet error IRQ number for each instance. */
62 static const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;
63 
64 /*! @brief Pointers to enet bases for each instance. */
65 static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
66 
67 /*! @brief Pointers to enet handles for each instance. */
68 static enet_handle_t *s_ENETHandle[ARRAY_SIZE(s_enetBases)];
69 
70 /* ENET ISR for transactional APIs. */
71 #if FSL_FEATURE_ENET_QUEUE > 1
72 static enet_isr_ring_t s_enetTxIsr[ARRAY_SIZE(s_enetBases)];
73 static enet_isr_ring_t s_enetRxIsr[ARRAY_SIZE(s_enetBases)];
74 #else
75 static enet_isr_t s_enetTxIsr[ARRAY_SIZE(s_enetBases)];
76 static enet_isr_t s_enetRxIsr[ARRAY_SIZE(s_enetBases)];
77 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
78 static enet_isr_t s_enetErrIsr[ARRAY_SIZE(s_enetBases)];
79 static enet_isr_t s_enetTsIsr[ARRAY_SIZE(s_enetBases)];
80 static enet_isr_t s_enet1588TimerIsr[ARRAY_SIZE(s_enetBases)];
81 
82 /*******************************************************************************
83  * Prototypes
84  ******************************************************************************/
85 
86 /*!
87  * @brief Set ENET MAC controller with the configuration.
88  *
89  * @param base ENET peripheral base address.
90  * @param config ENET Mac configuration.
91  * @param bufferConfig ENET buffer configuration.
92  * @param macAddr ENET six-byte mac address.
93  * @param srcClock_Hz ENET module clock source, normally it's system clock.
94  */
95 static void ENET_SetMacController(ENET_Type *base,
96                                   const enet_config_t *config,
97                                   const enet_buffer_config_t *bufferConfig,
98                                   uint8_t *macAddr,
99                                   uint32_t srcClock_Hz);
100 
101 /*!
102  * @brief Set ENET handler.
103  *
104  * @param base ENET peripheral base address.
105  * @param handle The ENET handle pointer.
106  * @param config ENET configuration stucture pointer.
107  * @param bufferConfig ENET buffer configuration.
108  */
109 static void ENET_SetHandler(ENET_Type *base,
110                             enet_handle_t *handle,
111                             const enet_config_t *config,
112                             const enet_buffer_config_t *bufferConfig,
113                             uint32_t srcClock_Hz);
114 
115 /*!
116  * @brief Set ENET MAC transmit buffer descriptors.
117  *
118  * @param config The ENET configuration structure.
119  * @param bufferConfig The ENET buffer configuration.
120  */
121 static void ENET_SetTxBufferDescriptors(const enet_config_t *config, const enet_buffer_config_t *bufferConfig);
122 
123 /*!
124  * @brief Set ENET MAC receive buffer descriptors.
125  *
126  * @param base ENET peripheral base address.
127  * @param config The ENET configuration structure.
128  * @param bufferConfig The ENET buffer configuration.
129  */
130 static status_t ENET_SetRxBufferDescriptors(ENET_Type *base,
131                                             const enet_config_t *config,
132                                             const enet_buffer_config_t *bufferConfig);
133 
134 /*!
135  * @brief Updates the ENET read buffer descriptors.
136  *
137  * @param base ENET peripheral base address.
138  * @param handle The ENET handle pointer.
139  * @param ringId The descriptor ring index, range from 0 ~ (FSL_FEATURE_ENET_INSTANCE_QUEUEn(x) - 1).
140  */
141 static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint8_t ringId);
142 
143 /*!
144  * @brief Updates index.
145  */
146 static uint16_t ENET_IncreaseIndex(uint16_t index, uint16_t max);
147 
148 /*!
149  * @brief Frees all Rx buffers in BDs.
150  */
151 static void ENET_RxBufferFreeAll(ENET_Type *base, enet_handle_t *handle);
152 
153 /*******************************************************************************
154  * Code
155  ******************************************************************************/
156 
157 /*!
158  * @brief Get the ENET instance from peripheral base address.
159  *
160  * @param base ENET peripheral base address.
161  * @return ENET instance.
162  */
ENET_GetInstance(ENET_Type * base)163 uint32_t ENET_GetInstance(ENET_Type *base)
164 {
165     uint32_t instance;
166 
167     /* Find the instance index from base address mappings. */
168     for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++)
169     {
170         if (s_enetBases[instance] == base)
171         {
172             break;
173         }
174     }
175 
176     assert(instance < ARRAY_SIZE(s_enetBases));
177 
178     return instance;
179 }
180 
181 /*!
182  * brief Gets the ENET default configuration structure.
183  *
184  * The purpose of this API is to get the default ENET MAC controller
185  * configure structure for ENET_Init(). User may use the initialized
186  * structure unchanged in ENET_Init(), or modify some fields of the
187  * structure before calling ENET_Init().
188  * Example:
189    code
190    enet_config_t config;
191    ENET_GetDefaultConfig(&config);
192    endcode
193  * param config The ENET mac controller configuration structure pointer.
194  */
ENET_GetDefaultConfig(enet_config_t * config)195 void ENET_GetDefaultConfig(enet_config_t *config)
196 {
197     /* Checks input parameter. */
198     assert(config != NULL);
199 
200     /* Initializes the MAC configure structure to zero. */
201     (void)memset(config, 0, sizeof(enet_config_t));
202 
203     /* Sets MII mode, full duplex, 100Mbps for MAC and PHY data interface. */
204 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
205     config->miiMode = kENET_RgmiiMode;
206 #else
207     config->miiMode = kENET_RmiiMode;
208 #endif
209     config->miiSpeed  = kENET_MiiSpeed100M;
210     config->miiDuplex = kENET_MiiFullDuplex;
211 
212     config->ringNum = 1;
213 
214     /* Sets the maximum receive frame length. */
215     config->rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN;
216 }
217 
218 /*!
219  * brief Initializes the ENET module.
220  *
221  * This function initializes the module with the ENET configuration.
222  * note ENET has two buffer descriptors legacy buffer descriptors and
223  * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To
224  * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor
225  * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure()
226  * to configure the 1588 feature and related buffers after calling ENET_Up().
227  *
228  * param base    ENET peripheral base address.
229  * param handle  ENET handler pointer.
230  * param config  ENET mac configuration structure pointer.
231  *        The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
232  *        can be used directly. It is also possible to verify the Mac configuration using other methods.
233  * param bufferConfig  ENET buffer configuration structure pointer.
234  *        The buffer configuration should be prepared for ENET Initialization.
235  *        It is the start address of "ringNum" enet_buffer_config structures.
236  *        To support added multi-ring features in some soc and compatible with the previous
237  *        enet driver version. For single ring supported, this bufferConfig is a buffer
238  *        configure structure pointer, for multi-ring supported and used case, this bufferConfig
239  *        pointer should be a buffer configure structure array pointer.
240  * param macAddr  ENET mac address of Ethernet device. This MAC address should be
241  *        provided.
242  * param srcClock_Hz The internal module clock source for MII clock.
243  * retval kStatus_Success  Succeed to initialize the ethernet driver.
244  * retval kStatus_ENET_InitMemoryFail  Init fails since buffer memory is not enough.
245  */
ENET_Up(ENET_Type * base,enet_handle_t * handle,const enet_config_t * config,const enet_buffer_config_t * bufferConfig,uint8_t * macAddr,uint32_t srcClock_Hz)246 status_t ENET_Up(ENET_Type *base,
247                  enet_handle_t *handle,
248                  const enet_config_t *config,
249                  const enet_buffer_config_t *bufferConfig,
250                  uint8_t *macAddr,
251                  uint32_t srcClock_Hz)
252 {
253     /* Checks input parameters. */
254     assert(handle != NULL);
255     assert(config != NULL);
256     assert(bufferConfig != NULL);
257     assert(macAddr != NULL);
258     assert(FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) != -1);
259     assert(config->ringNum <= (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
260 
261     status_t result = kStatus_Success;
262 
263     /* Set all buffers or data in handler for data transmit/receive process. */
264     ENET_SetHandler(base, handle, config, bufferConfig, srcClock_Hz);
265 
266     /* Initializes the ENET transmit buffer descriptors. */
267     ENET_SetTxBufferDescriptors(config, bufferConfig);
268 
269     /* Initializes the ENET receive buffer descriptors. */
270     result = ENET_SetRxBufferDescriptors(base, config, bufferConfig);
271     if (result == kStatus_ENET_InitMemoryFail)
272     {
273         ENET_RxBufferFreeAll(base, handle);
274         return result;
275     }
276 
277     /* Initializes the ENET MAC controller with basic function. */
278     ENET_SetMacController(base, config, bufferConfig, macAddr, srcClock_Hz);
279 
280     return result;
281 }
282 
283 /*!
284  * brief Initializes the ENET module.
285  *
286  * This function ungates the module clock and initializes it with the ENET configuration.
287  * note ENET has two buffer descriptors legacy buffer descriptors and
288  * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To
289  * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor
290  * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure()
291  * to configure the 1588 feature and related buffers after calling ENET_Init().
292  *
293  * param base    ENET peripheral base address.
294  * param handle  ENET handler pointer.
295  * param config  ENET mac configuration structure pointer.
296  *        The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
297  *        can be used directly. It is also possible to verify the Mac configuration using other methods.
298  * param bufferConfig  ENET buffer configuration structure pointer.
299  *        The buffer configuration should be prepared for ENET Initialization.
300  *        It is the start address of "ringNum" enet_buffer_config structures.
301  *        To support added multi-ring features in some soc and compatible with the previous
302  *        enet driver version. For single ring supported, this bufferConfig is a buffer
303  *        configure structure pointer, for multi-ring supported and used case, this bufferConfig
304  *        pointer should be a buffer configure structure array pointer.
305  * param macAddr  ENET mac address of Ethernet device. This MAC address should be
306  *        provided.
307  * param srcClock_Hz The internal module clock source for MII clock.
308  * retval kStatus_Success  Succeed to initialize the ethernet driver.
309  * retval kStatus_ENET_InitMemoryFail  Init fails since buffer memory is not enough.
310  */
ENET_Init(ENET_Type * base,enet_handle_t * handle,const enet_config_t * config,const enet_buffer_config_t * bufferConfig,uint8_t * macAddr,uint32_t srcClock_Hz)311 status_t ENET_Init(ENET_Type *base,
312                    enet_handle_t *handle,
313                    const enet_config_t *config,
314                    const enet_buffer_config_t *bufferConfig,
315                    uint8_t *macAddr,
316                    uint32_t srcClock_Hz)
317 {
318 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
319     uint32_t instance = ENET_GetInstance(base);
320 
321     /* Ungate ENET clock. */
322     (void)CLOCK_EnableClock(s_enetClock[instance]);
323 
324 #if defined(FSL_FEATURE_ENET_HAS_EXTRA_CLOCK_GATE) && FSL_FEATURE_ENET_HAS_EXTRA_CLOCK_GATE
325     /* Ungate ENET extra clock. */
326     (void)CLOCK_EnableClock(s_enetExtraClock[instance]);
327 #endif
328 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
329     /* Reset ENET module. */
330     ENET_Reset(base);
331 
332     return ENET_Up(base, handle, config, bufferConfig, macAddr, srcClock_Hz);
333 }
334 
335 /*!
336  * brief Stops the ENET module.
337 
338  * This function disables the ENET module.
339  *
340  * param base  ENET peripheral base address.
341  */
ENET_Down(ENET_Type * base)342 void ENET_Down(ENET_Type *base)
343 {
344     uint32_t instance     = ENET_GetInstance(base);
345     enet_handle_t *handle = s_ENETHandle[instance];
346 
347     /* Disable interrupt. */
348     base->EIMR = 0;
349 
350     /* Disable ENET. */
351     base->ECR &= ~ENET_ECR_ETHEREN_MASK;
352 
353     if (handle->rxBuffFree != NULL)
354     {
355         ENET_RxBufferFreeAll(base, handle);
356     }
357 }
358 
359 /*!
360  * brief Deinitializes the ENET module.
361 
362  * This function gates the module clock, clears ENET interrupts, and disables the ENET module.
363  *
364  * param base  ENET peripheral base address.
365  */
ENET_Deinit(ENET_Type * base)366 void ENET_Deinit(ENET_Type *base)
367 {
368     ENET_Down(base);
369 
370 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
371     /* Disables the clock source. */
372     (void)CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]);
373 
374 #if defined(FSL_FEATURE_ENET_HAS_EXTRA_CLOCK_GATE) && FSL_FEATURE_ENET_HAS_EXTRA_CLOCK_GATE
375     /* Disables ENET extra clock. */
376     (void)CLOCK_DisableClock(s_enetExtraClock[ENET_GetInstance(base)]);
377 #endif
378 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
379 }
380 
381 #if defined(ENET_RSTS)
ENET_ResetHareware(void)382 void ENET_ResetHareware(void)
383 {
384     RESET_PeripheralReset(kENET_IPG_RST_SHIFT_RSTn);
385     RESET_PeripheralReset(kENET_IPG_S_RST_SHIFT_RSTn);
386 }
387 #endif /* ENET_RSTS */
388 
389 #if FSL_FEATURE_ENET_QUEUE > 1
ENET_SetRxISRHandler(ENET_Type * base,enet_isr_ring_t ISRHandler)390 void ENET_SetRxISRHandler(ENET_Type *base, enet_isr_ring_t ISRHandler)
391 {
392     uint32_t instance = ENET_GetInstance(base);
393 
394     s_enetRxIsr[instance] = ISRHandler;
395     (void)EnableIRQ(s_enetRxIrqId[instance]);
396 }
397 
ENET_SetTxISRHandler(ENET_Type * base,enet_isr_ring_t ISRHandler)398 void ENET_SetTxISRHandler(ENET_Type *base, enet_isr_ring_t ISRHandler)
399 {
400     uint32_t instance = ENET_GetInstance(base);
401 
402     s_enetTxIsr[instance] = ISRHandler;
403     (void)EnableIRQ(s_enetTxIrqId[instance]);
404 }
405 #else
ENET_SetRxISRHandler(ENET_Type * base,enet_isr_t ISRHandler)406 void ENET_SetRxISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
407 {
408     uint32_t instance = ENET_GetInstance(base);
409 
410     s_enetRxIsr[instance] = ISRHandler;
411     (void)EnableIRQ(s_enetRxIrqId[instance]);
412 }
413 
ENET_SetTxISRHandler(ENET_Type * base,enet_isr_t ISRHandler)414 void ENET_SetTxISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
415 {
416     uint32_t instance = ENET_GetInstance(base);
417 
418     s_enetTxIsr[instance] = ISRHandler;
419     (void)EnableIRQ(s_enetTxIrqId[instance]);
420 }
421 #endif
422 
ENET_SetErrISRHandler(ENET_Type * base,enet_isr_t ISRHandler)423 void ENET_SetErrISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
424 {
425     uint32_t instance = ENET_GetInstance(base);
426 
427     s_enetErrIsr[instance] = ISRHandler;
428     (void)EnableIRQ(s_enetErrIrqId[instance]);
429 }
430 
431 #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
ENET_SetTsISRHandler(ENET_Type * base,enet_isr_t ISRHandler)432 void ENET_SetTsISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
433 {
434     uint32_t instance = ENET_GetInstance(base);
435 
436     s_enetTsIsr[instance] = ISRHandler;
437     (void)EnableIRQ(s_enetTsIrqId[instance]);
438 }
439 
ENET_Set1588TimerISRHandler(ENET_Type * base,enet_isr_t ISRHandler)440 void ENET_Set1588TimerISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
441 {
442     uint32_t instance = ENET_GetInstance(base);
443 
444     s_enet1588TimerIsr[instance] = ISRHandler;
445     (void)EnableIRQ(s_enet1588TimerIrqId[instance]);
446 }
447 #endif
448 
ENET_SetHandler(ENET_Type * base,enet_handle_t * handle,const enet_config_t * config,const enet_buffer_config_t * bufferConfig,uint32_t srcClock_Hz)449 static void ENET_SetHandler(ENET_Type *base,
450                             enet_handle_t *handle,
451                             const enet_config_t *config,
452                             const enet_buffer_config_t *bufferConfig,
453                             uint32_t srcClock_Hz)
454 {
455     uint8_t count;
456     uint32_t instance                   = ENET_GetInstance(base);
457     const enet_buffer_config_t *buffCfg = bufferConfig;
458 
459     /* Store transfer parameters in handle pointer. */
460     (void)memset(handle, 0, sizeof(enet_handle_t));
461 
462     for (count = 0; count < config->ringNum; count++)
463     {
464         assert(buffCfg->rxBuffSizeAlign * buffCfg->rxBdNumber > config->rxMaxFrameLen);
465 
466         handle->rxBdRing[count].rxBdBase       = buffCfg->rxBdStartAddrAlign;
467         handle->rxBuffSizeAlign[count]         = buffCfg->rxBuffSizeAlign;
468         handle->rxBdRing[count].rxRingLen      = buffCfg->rxBdNumber;
469         handle->rxMaintainEnable[count]        = buffCfg->rxMaintainEnable;
470         handle->txBdRing[count].txBdBase       = buffCfg->txBdStartAddrAlign;
471         handle->txBuffSizeAlign[count]         = buffCfg->txBuffSizeAlign;
472         handle->txBdRing[count].txRingLen      = buffCfg->txBdNumber;
473         handle->txMaintainEnable[count]        = buffCfg->txMaintainEnable;
474         handle->txDirtyRing[count].txDirtyBase = buffCfg->txFrameInfo;
475         handle->txDirtyRing[count].txRingLen   = buffCfg->txBdNumber;
476         buffCfg++;
477     }
478 
479     handle->ringNum     = config->ringNum;
480     handle->rxBuffAlloc = config->rxBuffAlloc;
481     handle->rxBuffFree  = config->rxBuffFree;
482     handle->callback    = config->callback;
483     handle->userData    = config->userData;
484 #if defined(FSL_FEATURE_ENET_TIMESTAMP_CAPTURE_BIT_INVALID) && FSL_FEATURE_ENET_TIMESTAMP_CAPTURE_BIT_INVALID
485     handle->enetClock = srcClock_Hz;
486 #endif
487 
488     /* Save the handle pointer in the global variables. */
489     s_ENETHandle[instance] = handle;
490 
491     /* Set the IRQ handler when the interrupt is enabled. */
492     if (0U != (config->interrupt & (uint32_t)ENET_TX_INTERRUPT))
493     {
494         ENET_SetTxISRHandler(base, ENET_TransmitIRQHandler);
495     }
496     if (0U != (config->interrupt & (uint32_t)ENET_RX_INTERRUPT))
497     {
498         ENET_SetRxISRHandler(base, ENET_ReceiveIRQHandler);
499     }
500     if (0U != (config->interrupt & (uint32_t)ENET_ERR_INTERRUPT))
501     {
502         ENET_SetErrISRHandler(base, ENET_ErrorIRQHandler);
503     }
504 }
505 
ENET_SetMacController(ENET_Type * base,const enet_config_t * config,const enet_buffer_config_t * bufferConfig,uint8_t * macAddr,uint32_t srcClock_Hz)506 static void ENET_SetMacController(ENET_Type *base,
507                                   const enet_config_t *config,
508                                   const enet_buffer_config_t *bufferConfig,
509                                   uint8_t *macAddr,
510                                   uint32_t srcClock_Hz)
511 {
512 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
513     if (FSL_FEATURE_ENET_INSTANCE_HAS_AVBn(base) == 1)
514     {
515         /* Check the MII mode/speed/duplex setting. */
516         if (config->miiSpeed == kENET_MiiSpeed1000M)
517         {
518             /* Only RGMII mode has the 1000M bit/s. The 1000M only support full duplex. */
519             assert(config->miiMode == kENET_RgmiiMode);
520             assert(config->miiDuplex == kENET_MiiFullDuplex);
521         }
522     }
523 #endif /* FSL_FEATURE_ENET_HAS_AVB */
524 
525     uint32_t rcr              = 0;
526     uint32_t tcr              = 0;
527     uint32_t ecr              = base->ECR;
528     uint32_t macSpecialConfig = config->macSpecialConfig;
529     uint32_t maxFrameLen      = config->rxMaxFrameLen;
530     uint32_t configVal        = 0;
531 
532     /* Maximum frame length check. */
533     if (0U != (macSpecialConfig & (uint32_t)kENET_ControlVLANTagEnable))
534     {
535         maxFrameLen = (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN);
536 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
537         if (FSL_FEATURE_ENET_INSTANCE_HAS_AVBn(base) == 1)
538         {
539             if (0U != (macSpecialConfig & (uint32_t)kENET_ControlSVLANEnable))
540             {
541                 /* Double vlan tag (SVLAN) supported. */
542                 maxFrameLen += ENET_FRAME_VLAN_TAGLEN;
543             }
544             ecr |= (uint32_t)(((macSpecialConfig & (uint32_t)kENET_ControlSVLANEnable) != 0U) ?
545                                   (ENET_ECR_SVLANEN_MASK | ENET_ECR_SVLANDBL_MASK) :
546                                   0U) |
547                    (uint32_t)(((macSpecialConfig & (uint32_t)kENET_ControlVLANUseSecondTag) != 0U) ?
548                                   ENET_ECR_VLANUSE2ND_MASK :
549                                   0U);
550         }
551 #endif /* FSL_FEATURE_ENET_HAS_AVB */
552     }
553 
554     /* Configures MAC receive controller with user configure structure. */
555     rcr = ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxPayloadCheckEnable)) ? ENET_RCR_NLC_MASK : 0U) |
556           ((0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) ? ENET_RCR_CFEN_MASK : 0U) |
557           ((0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) ? ENET_RCR_FCE_MASK : 0U) |
558           ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxPadRemoveEnable)) ? ENET_RCR_PADEN_MASK : 0U) |
559           ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxBroadCastRejectEnable)) ? ENET_RCR_BC_REJ_MASK : 0U) |
560           ((0U != (macSpecialConfig & (uint32_t)kENET_ControlPromiscuousEnable)) ? ENET_RCR_PROM_MASK : 0U) |
561           ENET_RCR_MAX_FL(maxFrameLen) | ENET_RCR_CRCFWD_MASK;
562 
563 /* Set the RGMII or RMII, MII mode and control register. */
564 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
565     if (FSL_FEATURE_ENET_INSTANCE_HAS_AVBn(base) == 1)
566     {
567         if (config->miiMode == kENET_RgmiiMode)
568         {
569             rcr |= ENET_RCR_RGMII_EN_MASK;
570         }
571         else
572         {
573             rcr &= ~ENET_RCR_RGMII_EN_MASK;
574         }
575 
576         if (config->miiSpeed == kENET_MiiSpeed1000M)
577         {
578             ecr |= ENET_ECR_SPEED_MASK;
579         }
580         else
581         {
582             ecr &= ~ENET_ECR_SPEED_MASK;
583         }
584     }
585 #endif /* FSL_FEATURE_ENET_HAS_AVB */
586     rcr |= ENET_RCR_MII_MODE_MASK;
587     if (config->miiMode == kENET_RmiiMode)
588     {
589         rcr |= ENET_RCR_RMII_MODE_MASK;
590     }
591 
592     /* Speed. */
593     if (config->miiSpeed == kENET_MiiSpeed10M)
594     {
595         rcr |= ENET_RCR_RMII_10T_MASK;
596     }
597 
598     /* Receive setting for half duplex. */
599     if (config->miiDuplex == kENET_MiiHalfDuplex)
600     {
601         rcr |= ENET_RCR_DRT_MASK;
602     }
603     /* Sets internal loop only for MII mode. */
604     if ((0U != (config->macSpecialConfig & (uint32_t)kENET_ControlMIILoopEnable)) &&
605         (config->miiMode != kENET_RmiiMode))
606     {
607         rcr |= ENET_RCR_LOOP_MASK;
608         rcr &= ~ENET_RCR_DRT_MASK;
609     }
610     base->RCR = rcr;
611 
612     /* Configures MAC transmit controller: duplex mode, mac address insertion. */
613     tcr = base->TCR & ~(ENET_TCR_FDEN_MASK | ENET_TCR_ADDINS_MASK);
614     tcr |= ((kENET_MiiHalfDuplex != config->miiDuplex) ? (uint32_t)ENET_TCR_FDEN_MASK : 0U) |
615            ((0U != (macSpecialConfig & (uint32_t)kENET_ControlMacAddrInsert)) ? (uint32_t)ENET_TCR_ADDINS_MASK : 0U);
616     base->TCR = tcr;
617 
618     /* Configures receive and transmit accelerator. */
619     base->TACC = config->txAccelerConfig;
620     base->RACC = config->rxAccelerConfig;
621 
622     /* Sets the pause duration and FIFO threshold for the flow control enabled case. */
623     if (0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable))
624     {
625         uint32_t reemReg;
626         base->OPD = config->pauseDuration;
627         reemReg   = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold);
628 #if defined(FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD
629         reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold);
630 #endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */
631         base->RSEM = reemReg;
632     }
633 
634     /* FIFO threshold setting for store and forward enable/disable case. */
635     if (0U != (macSpecialConfig & (uint32_t)kENET_ControlStoreAndFwdDisable))
636     {
637         /* Transmit fifo watermark settings. */
638         configVal  = ((uint32_t)config->txFifoWatermark) & ENET_TFWR_TFWR_MASK;
639         base->TFWR = configVal;
640         /* Receive fifo full threshold settings. */
641         configVal  = ((uint32_t)config->rxFifoFullThreshold) & ENET_RSFL_RX_SECTION_FULL_MASK;
642         base->RSFL = configVal;
643     }
644     else
645     {
646         /* Transmit fifo watermark settings. */
647         base->TFWR = ENET_TFWR_STRFWD_MASK;
648         base->RSFL = 0;
649     }
650 
651     /* Enable store and forward when accelerator is enabled */
652     if (0U !=
653         (config->txAccelerConfig & ((uint32_t)kENET_TxAccelIpCheckEnabled | (uint32_t)kENET_TxAccelProtoCheckEnabled)))
654     {
655         base->TFWR = ENET_TFWR_STRFWD_MASK;
656     }
657     if (0U != ((config->rxAccelerConfig &
658                 ((uint32_t)kENET_RxAccelIpCheckEnabled | (uint32_t)kENET_RxAccelProtoCheckEnabled))))
659     {
660         base->RSFL = 0;
661     }
662 
663 /* Initializes the ring 0. */
664 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
665     base->TDSR = MEMORY_ConvertMemoryMapAddress((uintptr_t)bufferConfig->txBdStartAddrAlign, kMEMORY_Local2DMA);
666     base->RDSR = MEMORY_ConvertMemoryMapAddress((uintptr_t)bufferConfig->rxBdStartAddrAlign, kMEMORY_Local2DMA);
667 #else
668     base->TDSR = (uint32_t)(uintptr_t)bufferConfig->txBdStartAddrAlign;
669     base->RDSR = (uint32_t)(uintptr_t)bufferConfig->rxBdStartAddrAlign;
670 #endif
671     base->MRBR = (uint32_t)bufferConfig->rxBuffSizeAlign;
672 
673 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
674     if (FSL_FEATURE_ENET_INSTANCE_HAS_AVBn(base) == 1)
675     {
676         const enet_buffer_config_t *buffCfg = bufferConfig;
677 
678         if (config->ringNum > 1U)
679         {
680             /* Initializes the ring 1. */
681             buffCfg++;
682 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
683             base->TDSR1 = MEMORY_ConvertMemoryMapAddress((uintptr_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA);
684             base->RDSR1 = MEMORY_ConvertMemoryMapAddress((uintptr_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA);
685 #else
686             base->TDSR1 = (uint32_t)(uintptr_t)buffCfg->txBdStartAddrAlign;
687             base->RDSR1 = (uint32_t)(uintptr_t)buffCfg->rxBdStartAddrAlign;
688 #endif
689             base->MRBR1 = (uint32_t)buffCfg->rxBuffSizeAlign;
690             /* Enable the DMAC for ring 1 and with no rx classification set. */
691             base->DMACFG[0] = ENET_DMACFG_DMA_CLASS_EN_MASK;
692         }
693         if (config->ringNum > 2U)
694         {
695             /* Initializes the ring 2. */
696             buffCfg++;
697 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
698             base->TDSR2 = MEMORY_ConvertMemoryMapAddress((uintptr_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA);
699             base->RDSR2 = MEMORY_ConvertMemoryMapAddress((uintptr_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA);
700 #else
701             base->TDSR2 = (uint32_t)(uintptr_t)buffCfg->txBdStartAddrAlign;
702             base->RDSR2 = (uint32_t)(uintptr_t)buffCfg->rxBdStartAddrAlign;
703 #endif
704             base->MRBR2 = (uint32_t)buffCfg->rxBuffSizeAlign;
705             /* Enable the DMAC for ring 2 and with no rx classification set. */
706             base->DMACFG[1] = ENET_DMACFG_DMA_CLASS_EN_MASK;
707         }
708 
709         /* Defaulting the class/ring 1 and 2 are not enabled and the receive classification is disabled
710          * so we set the default transmit scheme with the round-robin mode. Beacuse the legacy bd mode
711          * only supports the round-robin mode. If the avb feature is required, just call the setup avb
712          * feature API. */
713         base->QOS |= ENET_QOS_TX_SCHEME(1);
714     }
715 #endif /*  FSL_FEATURE_ENET_HAS_AVB */
716 
717     /* Configures the Mac address. */
718     ENET_SetMacAddr(base, macAddr);
719 
720     /* Initialize the SMI if uninitialized. */
721     if (!ENET_GetSMI(base))
722     {
723         ENET_SetSMI(base, srcClock_Hz,
724                     ((0U != (config->macSpecialConfig & (uint32_t)kENET_ControlSMIPreambleDisable)) ? true : false));
725     }
726 
727 /* Enables Ethernet interrupt, enables the interrupt coalsecing if it is required. */
728 #if defined(FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE
729     uint8_t queue = 0;
730 
731     if (NULL != config->intCoalesceCfg)
732     {
733         uint32_t intMask = (ENET_EIMR_TXB_MASK | ENET_EIMR_RXB_MASK);
734 
735 #if FSL_FEATURE_ENET_QUEUE > 1
736         if (FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) > 1)
737         {
738             intMask |= ENET_EIMR_TXB2_MASK | ENET_EIMR_RXB2_MASK | ENET_EIMR_TXB1_MASK | ENET_EIMR_RXB1_MASK;
739         }
740 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
741 
742         /* Clear all buffer interrupts. */
743         base->EIMR &= ~intMask;
744 
745         /* Set the interrupt coalescence. */
746         for (queue = 0; queue < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base); queue++)
747         {
748             base->TXIC[queue] = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[queue]) |
749                                 config->intCoalesceCfg->txCoalesceTimeCount[queue] | ENET_TXIC_ICCS_MASK |
750                                 ENET_TXIC_ICEN_MASK;
751             base->RXIC[queue] = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[queue]) |
752                                 config->intCoalesceCfg->rxCoalesceTimeCount[queue] | ENET_RXIC_ICCS_MASK |
753                                 ENET_RXIC_ICEN_MASK;
754         }
755     }
756 #endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */
757     ENET_EnableInterrupts(base, config->interrupt);
758 
759 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
760     /* Sets the 1588 enhanced feature. */
761     ecr |= ENET_ECR_EN1588_MASK;
762 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
763     /* Enables Ethernet module after all configuration except the buffer descriptor active. */
764     ecr |= ENET_ECR_ETHEREN_MASK | ENET_ECR_DBSWP_MASK;
765     base->ECR = ecr;
766 }
767 
ENET_SetTxBufferDescriptors(const enet_config_t * config,const enet_buffer_config_t * bufferConfig)768 static void ENET_SetTxBufferDescriptors(const enet_config_t *config, const enet_buffer_config_t *bufferConfig)
769 {
770     const enet_buffer_config_t *buffCfg = bufferConfig;
771     uintptr_t txBuffer                  = 0;
772     uint32_t txBuffSizeAlign;
773     uint16_t txBdNumber;
774     uint8_t ringNum;
775     uint16_t count;
776 
777     /* Check the input parameters. */
778     for (ringNum = 0; ringNum < config->ringNum; ringNum++)
779     {
780         if (buffCfg->txBdStartAddrAlign != NULL)
781         {
782             volatile enet_tx_bd_struct_t *curBuffDescrip = buffCfg->txBdStartAddrAlign;
783             txBuffSizeAlign                              = buffCfg->txBuffSizeAlign;
784             txBdNumber                                   = buffCfg->txBdNumber;
785 
786             if (buffCfg->txBufferAlign != NULL)
787             {
788 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
789                 txBuffer = MEMORY_ConvertMemoryMapAddress((uintptr_t)buffCfg->txBufferAlign, kMEMORY_Local2DMA);
790 #else
791                 txBuffer = (uintptr_t)buffCfg->txBufferAlign;
792 #endif
793                 assert((uint64_t)txBuffer + (uint64_t)txBdNumber * txBuffSizeAlign - 1U <= UINT32_MAX);
794             }
795 
796             for (count = 0; count < txBdNumber; count++)
797             {
798                 if (buffCfg->txBufferAlign != NULL)
799                 {
800                     /* Set data buffer address. */
801                     curBuffDescrip->buffer = (uint32_t)(txBuffer + count * txBuffSizeAlign);
802                 }
803                 /* Initializes data length. */
804                 curBuffDescrip->length = 0;
805                 /* Sets the crc. */
806                 curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK;
807                 /* Sets the last buffer descriptor with the wrap flag. */
808                 if (count == (txBdNumber - 1U))
809                 {
810                     curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK;
811                 }
812 
813 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
814                 /* Enable transmit interrupt for store the transmit timestamp. */
815                 curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK;
816 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
817                 /* Set the type of the frame when the credit-based scheme is used. */
818                 curBuffDescrip->controlExtend1 |= (uint16_t)(ENET_BD_FTYPE(ringNum));
819 #endif /* FSL_FEATURE_ENET_HAS_AVB */
820 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
821                 /* Increase the index. */
822                 curBuffDescrip++;
823             }
824         }
825         buffCfg++;
826     }
827 }
828 
ENET_SetRxBufferDescriptors(ENET_Type * base,const enet_config_t * config,const enet_buffer_config_t * bufferConfig)829 static status_t ENET_SetRxBufferDescriptors(ENET_Type *base,
830                                             const enet_config_t *config,
831                                             const enet_buffer_config_t *bufferConfig)
832 {
833     const enet_buffer_config_t *buffCfg = bufferConfig;
834     uintptr_t rxBuffer                  = 0;
835     uint8_t ringNum;
836     uint16_t count;
837 
838 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
839     uint32_t mask = ((uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt);
840 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
841 
842     /* Check the input parameters. */
843     for (ringNum = 0; ringNum < config->ringNum; ringNum++)
844     {
845         assert(buffCfg->rxBuffSizeAlign >= ENET_RX_MIN_BUFFERSIZE);
846 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
847 #if FSL_FEATURE_ENET_QUEUE > 1
848         if (ringNum == 1U)
849         {
850             mask = ((uint32_t)kENET_RxFrame1Interrupt | (uint32_t)kENET_RxBuffer1Interrupt);
851         }
852         else if (ringNum == 2U)
853         {
854             mask = ((uint32_t)kENET_RxFrame2Interrupt | (uint32_t)kENET_RxBuffer2Interrupt);
855         }
856         else
857         {
858             /* Intentional empty */
859         }
860 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
861 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
862 
863         /* Initialize the Rx buffer descriptor. */
864         if ((buffCfg->rxBdStartAddrAlign != NULL) && ((buffCfg->rxBufferAlign != NULL) || config->rxBuffAlloc != NULL))
865         {
866             volatile enet_rx_bd_struct_t *curBuffDescrip = buffCfg->rxBdStartAddrAlign;
867 
868             for (count = 0; count < buffCfg->rxBdNumber; count++)
869             {
870                 /* If zero copy is enabled, used buffer from allocation. */
871                 if (config->rxBuffAlloc == NULL)
872                 {
873                     rxBuffer = (uintptr_t)buffCfg->rxBufferAlign + (uintptr_t)count * buffCfg->rxBuffSizeAlign;
874                 }
875                 else
876                 {
877                     rxBuffer = (uintptr_t)(uint8_t *)config->rxBuffAlloc(base, config->userData, ringNum);
878                     if (rxBuffer == 0U)
879                     {
880                         return kStatus_ENET_InitMemoryFail;
881                     }
882                 }
883                 assert((uint64_t)rxBuffer + buffCfg->rxBuffSizeAlign - 1U <= UINT32_MAX);
884 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
885                 if (buffCfg->rxMaintainEnable)
886                 {
887                     /* Invalidate rx buffers before DMA transfer data into them. */
888                     DCACHE_InvalidateByRange(rxBuffer, (uint32_t)buffCfg->rxBuffSizeAlign);
889                 }
890 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
891 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
892                 rxBuffer = MEMORY_ConvertMemoryMapAddress(rxBuffer, kMEMORY_Local2DMA);
893 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
894 
895                 /* Set data buffer and the length. */
896                 curBuffDescrip->buffer = (uint32_t)rxBuffer;
897                 curBuffDescrip->length = 0;
898 
899                 /* Initializes the buffer descriptors with empty bit. */
900                 curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
901 
902                 /* Sets the last buffer descriptor with the wrap flag. */
903                 if (count == (buffCfg->rxBdNumber - 1U))
904                 {
905                     curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
906                 }
907 
908 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
909                 if (0U != (config->interrupt & mask))
910                 {
911                     /* Enable receive interrupt. */
912                     curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK;
913                 }
914                 else
915                 {
916                     curBuffDescrip->controlExtend1 = 0;
917                 }
918 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
919                 /* Increase the index. */
920                 curBuffDescrip++;
921             }
922         }
923         buffCfg++;
924     }
925 
926     return kStatus_Success;
927 }
928 
929 /*!
930  * brief Frees all Rx buffers in BDs.
931  */
ENET_RxBufferFreeAll(ENET_Type * base,enet_handle_t * handle)932 static void ENET_RxBufferFreeAll(ENET_Type *base, enet_handle_t *handle)
933 {
934     assert(handle->rxBuffFree != NULL);
935 
936     uint16_t index;
937     enet_rx_bd_ring_t *rxBdRing;
938     volatile enet_rx_bd_struct_t *curBuffDescrip;
939     uintptr_t buffer;
940     uint16_t ringId;
941 
942     for (ringId = 0; ringId < handle->ringNum; ringId++)
943     {
944         assert(handle->rxBdRing[ringId].rxBdBase != NULL);
945 
946         rxBdRing       = &handle->rxBdRing[ringId];
947         curBuffDescrip = rxBdRing->rxBdBase;
948         index          = 0;
949 
950         /* Free memory for all buffers in buffer descriptor */
951         do
952         {
953             if (curBuffDescrip->buffer != 0U)
954             {
955 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
956                 buffer = MEMORY_ConvertMemoryMapAddress(curBuffDescrip->buffer, kMEMORY_DMA2Local);
957 #else
958                 buffer = curBuffDescrip->buffer;
959 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
960                 handle->rxBuffFree(base, (void *)(uint8_t *)buffer, handle->userData, ringId);
961                 curBuffDescrip->buffer = 0;
962                 /* Clears status. */
963                 curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
964             }
965 
966             /* Increase the buffer descriptor, if it's the last one, increase to first one of the ring. */
967             index          = ENET_IncreaseIndex(index, rxBdRing->rxRingLen);
968             curBuffDescrip = rxBdRing->rxBdBase + index;
969         } while (index != 0U);
970     }
971 }
972 
973 /*!
974  * brief Activates frame reception for specified ring.
975  *
976  * This function is to active the enet read process for specified ring.
977  * note This must be called after the MAC configuration and
978  * state are ready. It must be called after the ENET_Init() and
979  * ENET_Ptp1588Configure(). This should be called when the ENET receive required.
980  *
981  * param base  ENET peripheral base address.
982  * param ringId The ring index, range from 0 ~ (FSL_FEATURE_ENET_INSTANCE_QUEUEn(x) - 1).
983  */
ENET_ActiveReadRing(ENET_Type * base,uint8_t ringId)984 static inline void ENET_ActiveReadRing(ENET_Type *base, uint8_t ringId)
985 {
986     assert(ringId < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
987 
988     /* Ensure previous data update is completed with Data Synchronization Barrier before activing Rx BD. */
989     __DSB();
990 
991     /* Actives the receive buffer descriptor. */
992     switch (ringId)
993     {
994         case kENET_Ring0:
995             base->RDAR = ENET_RDAR_RDAR_MASK;
996             break;
997 #if FSL_FEATURE_ENET_QUEUE > 1
998         case kENET_Ring1:
999             base->RDAR1 = ENET_RDAR1_RDAR_MASK;
1000             break;
1001         case kENET_Ring2:
1002             base->RDAR2 = ENET_RDAR2_RDAR_MASK;
1003             break;
1004 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
1005         default:
1006             assert(false);
1007             break;
1008     }
1009 }
1010 
1011 /*!
1012  * brief Activates frame sending for specified ring.
1013  * note This must be called after the MAC configuration and
1014  * state are ready. It must be called after the ENET_Init() and
1015  * this should be called when the ENET receive required.
1016  *
1017  * param base  ENET peripheral base address.
1018  * param ringId The descriptor ring index, range from 0 ~ (FSL_FEATURE_ENET_INSTANCE_QUEUEn(x) - 1).
1019  *
1020  */
ENET_ActiveSendRing(ENET_Type * base,uint8_t ringId)1021 static void ENET_ActiveSendRing(ENET_Type *base, uint8_t ringId)
1022 {
1023     assert(ringId < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
1024 
1025     volatile uint32_t *txDesActive = NULL;
1026 
1027     /* Ensure previous data update is completed with Data Synchronization Barrier before activing Tx BD. */
1028     __DSB();
1029 
1030     switch (ringId)
1031     {
1032         case kENET_Ring0:
1033             txDesActive = &(base->TDAR);
1034             break;
1035 #if FSL_FEATURE_ENET_QUEUE > 1
1036         case kENET_Ring1:
1037             txDesActive = &(base->TDAR1);
1038             break;
1039         case kENET_Ring2:
1040             txDesActive = &(base->TDAR2);
1041             break;
1042 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
1043         default:
1044             txDesActive = &(base->TDAR);
1045             break;
1046     }
1047 
1048 #if defined(FSL_FEATURE_ENET_HAS_ERRATA_007885) && FSL_FEATURE_ENET_HAS_ERRATA_007885
1049     /* There is a TDAR race condition for mutliQ when the software sets TDAR
1050      * and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
1051      * This will cause the udma_tx and udma_tx_arbiter state machines to hang.
1052      * Software workaround: introduces a delay by reading the relevant ENET_TDARn_TDAR 4 times
1053      */
1054     for (uint8_t i = 0; i < 4U; i++)
1055     {
1056         if (*txDesActive == 0U)
1057         {
1058             break;
1059         }
1060     }
1061 #endif
1062 
1063     /* Write to active tx descriptor */
1064     *txDesActive = 0;
1065 }
1066 
1067 /*!
1068  * brief Sets the ENET MII speed and duplex.
1069  *
1070  * This API is provided to dynamically change the speed and dulpex for MAC.
1071  *
1072  * param base  ENET peripheral base address.
1073  * param speed The speed of the RMII mode.
1074  * param duplex The duplex of the RMII mode.
1075  */
ENET_SetMII(ENET_Type * base,enet_mii_speed_t speed,enet_mii_duplex_t duplex)1076 void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
1077 {
1078     uint32_t rcr = base->RCR;
1079     uint32_t tcr = base->TCR;
1080 
1081 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
1082     if (FSL_FEATURE_ENET_INSTANCE_HAS_AVBn(base) == 1)
1083     {
1084         uint32_t ecr = base->ECR;
1085 
1086         if (kENET_MiiSpeed1000M == speed)
1087         {
1088             assert(duplex == kENET_MiiFullDuplex);
1089             ecr |= ENET_ECR_SPEED_MASK;
1090         }
1091         else
1092         {
1093             ecr &= ~ENET_ECR_SPEED_MASK;
1094         }
1095 
1096         base->ECR = ecr;
1097     }
1098 #endif /* FSL_FEATURE_ENET_HAS_AVB */
1099 
1100     /* Sets speed mode. */
1101     if (kENET_MiiSpeed10M == speed)
1102     {
1103         rcr |= ENET_RCR_RMII_10T_MASK;
1104     }
1105     else
1106     {
1107         rcr &= ~ENET_RCR_RMII_10T_MASK;
1108     }
1109     /* Set duplex mode. */
1110     if (duplex == kENET_MiiHalfDuplex)
1111     {
1112         rcr |= ENET_RCR_DRT_MASK;
1113         tcr &= ~ENET_TCR_FDEN_MASK;
1114     }
1115     else
1116     {
1117         rcr &= ~ENET_RCR_DRT_MASK;
1118         tcr |= ENET_TCR_FDEN_MASK;
1119     }
1120 
1121     base->RCR = rcr;
1122     base->TCR = tcr;
1123 }
1124 
1125 /*!
1126  * brief Sets the ENET module Mac address.
1127  *
1128  * param base  ENET peripheral base address.
1129  * param macAddr The six-byte Mac address pointer.
1130  *        The pointer is allocated by application and input into the API.
1131  */
ENET_SetMacAddr(ENET_Type * base,uint8_t * macAddr)1132 void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr)
1133 {
1134     uint32_t address;
1135 
1136     /* Set physical address lower register. */
1137     address = (uint32_t)(((uint32_t)macAddr[0] << 24U) | ((uint32_t)macAddr[1] << 16U) | ((uint32_t)macAddr[2] << 8U) |
1138                          (uint32_t)macAddr[3]);
1139     base->PALR = address;
1140     /* Set physical address high register. */
1141     address    = (uint32_t)(((uint32_t)macAddr[4] << 8U) | ((uint32_t)macAddr[5]));
1142     base->PAUR = address << ENET_PAUR_PADDR2_SHIFT;
1143 }
1144 
1145 /*!
1146  * brief Gets the ENET module Mac address.
1147  *
1148  * param base  ENET peripheral base address.
1149  * param macAddr The six-byte Mac address pointer.
1150  *        The pointer is allocated by application and input into the API.
1151  */
ENET_GetMacAddr(ENET_Type * base,uint8_t * macAddr)1152 void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr)
1153 {
1154     assert(macAddr != NULL);
1155 
1156     uint32_t address;
1157 
1158     /* Get from physical address lower register. */
1159     address    = base->PALR;
1160     macAddr[0] = 0xFFU & (uint8_t)(address >> 24U);
1161     macAddr[1] = 0xFFU & (uint8_t)(address >> 16U);
1162     macAddr[2] = 0xFFU & (uint8_t)(address >> 8U);
1163     macAddr[3] = 0xFFU & (uint8_t)address;
1164 
1165     /* Get from physical address high register. */
1166     address    = (base->PAUR & ENET_PAUR_PADDR2_MASK) >> ENET_PAUR_PADDR2_SHIFT;
1167     macAddr[4] = 0xFFU & (uint8_t)(address >> 8U);
1168     macAddr[5] = 0xFFU & (uint8_t)address;
1169 }
1170 
1171 /*!
1172  * brief Sets the ENET SMI(serial management interface)- MII management interface.
1173  *
1174  * param base  ENET peripheral base address.
1175  * param srcClock_Hz This is the ENET module clock frequency. See clock distribution.
1176  * param isPreambleDisabled The preamble disable flag.
1177  *        - true   Enables the preamble.
1178  *        - false  Disables the preamble.
1179  */
ENET_SetSMI(ENET_Type * base,uint32_t srcClock_Hz,bool isPreambleDisabled)1180 void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled)
1181 {
1182     /* Due to bits limitation of SPEED and HOLDTIME, srcClock_Hz must ensure MDC <= 2.5M and holdtime >= 10ns. */
1183     assert((srcClock_Hz != 0U) && (srcClock_Hz <= 320000000U));
1184 
1185     uint32_t clkCycle = 0;
1186     uint32_t speed    = 0;
1187     uint32_t mscr     = 0;
1188 
1189     /* Use (param + N - 1) / N to increase accuracy with rounding. */
1190     /* Calculate the MII speed which controls the frequency of the MDC. */
1191     speed = (srcClock_Hz + 2U * ENET_MDC_FREQUENCY - 1U) / (2U * ENET_MDC_FREQUENCY) - 1U;
1192     /* Calculate the hold time on the MDIO output. */
1193     clkCycle = (10U + ENET_NANOSECOND_ONE_SECOND / srcClock_Hz - 1U) / (ENET_NANOSECOND_ONE_SECOND / srcClock_Hz) - 1U;
1194     /* Build the configuration for MDC/MDIO control. */
1195     mscr =
1196         ENET_MSCR_MII_SPEED(speed) | ENET_MSCR_HOLDTIME(clkCycle) | (isPreambleDisabled ? ENET_MSCR_DIS_PRE_MASK : 0U);
1197     base->MSCR = mscr;
1198 }
1199 
ENET_MDIOWaitTransferOver(ENET_Type * base)1200 static status_t ENET_MDIOWaitTransferOver(ENET_Type *base)
1201 {
1202     status_t result = kStatus_Success;
1203 #ifdef ENET_MDIO_TIMEOUT_COUNT
1204     uint32_t counter;
1205 #endif
1206 
1207     /* Wait for MDIO access to complete. */
1208 #ifdef ENET_MDIO_TIMEOUT_COUNT
1209     for (counter = ENET_MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
1210     {
1211         if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
1212         {
1213             break;
1214         }
1215     }
1216     /* Check for timeout. */
1217     if (0U == counter)
1218     {
1219         result = kStatus_Timeout;
1220     }
1221 #else
1222     while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
1223     {
1224     }
1225 #endif
1226     return result;
1227 }
1228 
1229 /*!
1230  * @brief MDIO write with IEEE802.3 Clause 22 format.
1231  *
1232  * @param base  ENET peripheral base address.
1233  * @param phyAddr  The PHY address.
1234  * @param regAddr  The PHY register. Range from 0 ~ 31.
1235  * @param data  The data written to PHY.
1236  * @return kStatus_Success  MDIO access succeeds.
1237  * @return kStatus_Timeout  MDIO access timeout.
1238  */
ENET_MDIOWrite(ENET_Type * base,uint8_t phyAddr,uint8_t regAddr,uint16_t data)1239 status_t ENET_MDIOWrite(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
1240 {
1241     status_t result = kStatus_Success;
1242 
1243     /* Clear the MDIO access complete event. */
1244     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1245 
1246     /* Starts MDIO write command. */
1247     ENET_StartSMIWrite(base, phyAddr, regAddr, kENET_MiiWriteValidFrame, data);
1248 
1249     result = ENET_MDIOWaitTransferOver(base);
1250     if (result != kStatus_Success)
1251     {
1252         return result;
1253     }
1254 
1255     /* Clear the MDIO access complete event. */
1256     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1257 
1258     return result;
1259 }
1260 
1261 /*!
1262  * @brief MDIO read with IEEE802.3 Clause 22 format.
1263  *
1264  * @param base  ENET peripheral base address.
1265  * @param phyAddr  The PHY address.
1266  * @param regAddr  The PHY register. Range from 0 ~ 31.
1267  * @param pData  The data read from PHY.
1268  * @return kStatus_Success  MDIO access succeeds.
1269  * @return kStatus_Timeout  MDIO access timeout.
1270  */
ENET_MDIORead(ENET_Type * base,uint8_t phyAddr,uint8_t regAddr,uint16_t * pData)1271 status_t ENET_MDIORead(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
1272 {
1273     assert(pData != NULL);
1274 
1275     status_t result = kStatus_Success;
1276 
1277     /* Clear the MDIO access complete event. */
1278     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1279 
1280     /* Starts a MDIO read command operation. */
1281     ENET_StartSMIRead(base, phyAddr, regAddr, kENET_MiiReadValidFrame);
1282 
1283     result = ENET_MDIOWaitTransferOver(base);
1284     if (result != kStatus_Success)
1285     {
1286         return result;
1287     }
1288 
1289     /* Get received data. */
1290     *pData = (uint16_t)ENET_ReadSMIData(base);
1291 
1292     /* Clear the MDIO access complete event. */
1293     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1294 
1295     return result;
1296 }
1297 
1298 #if defined(FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO
1299 /*!
1300  * @brief MDIO write with IEEE802.3 Clause 45 format.
1301  *
1302  * @param base  ENET peripheral base address.
1303  * @param portAddr  The MDIO port address(PHY address).
1304  * @param devAddr  The device address.
1305  * @param regAddr  The PHY register address.
1306  * @param data  The data written to PHY.
1307  * @return kStatus_Success  MDIO access succeeds.
1308  * @return kStatus_Timeout  MDIO access timeout.
1309  */
ENET_MDIOC45Write(ENET_Type * base,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t data)1310 status_t ENET_MDIOC45Write(ENET_Type *base, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t data)
1311 {
1312     status_t result = kStatus_Success;
1313 
1314     /* Write the register address */
1315     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1316     ENET_StartExtC45SMIWriteReg(base, portAddr, devAddr, regAddr);
1317     result = ENET_MDIOWaitTransferOver(base);
1318     if (result != kStatus_Success)
1319     {
1320         return result;
1321     }
1322     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1323 
1324     /* Write data to the specified register address */
1325     ENET_StartExtC45SMIWriteData(base, portAddr, devAddr, data);
1326     result = ENET_MDIOWaitTransferOver(base);
1327     if (result != kStatus_Success)
1328     {
1329         return result;
1330     }
1331     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1332 
1333     return result;
1334 }
1335 /*!
1336  * @brief MDIO read with IEEE802.3 Clause 45 format.
1337  *
1338  * @param base  ENET peripheral base address.
1339  * @param portAddr  The MDIO port address(PHY address).
1340  * @param devAddr  The device address.
1341  * @param regAddr  The PHY register address.
1342  * @param pData  The data read from PHY.
1343  * @return kStatus_Success  MDIO access succeeds.
1344  * @return kStatus_Timeout  MDIO access timeout.
1345  */
ENET_MDIOC45Read(ENET_Type * base,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t * pData)1346 status_t ENET_MDIOC45Read(ENET_Type *base, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t *pData)
1347 {
1348     assert(pData != NULL);
1349 
1350     status_t result = kStatus_Success;
1351 
1352     /* Write the register address */
1353     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1354     ENET_StartExtC45SMIWriteReg(base, portAddr, devAddr, regAddr);
1355     result = ENET_MDIOWaitTransferOver(base);
1356     if (result != kStatus_Success)
1357     {
1358         return result;
1359     }
1360 
1361     /* Read data from the specified register address */
1362     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1363     ENET_StartExtC45SMIReadData(base, portAddr, devAddr);
1364     result = ENET_MDIOWaitTransferOver(base);
1365     if (result != kStatus_Success)
1366     {
1367         return result;
1368     }
1369     ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
1370     *pData = (uint16_t)ENET_ReadSMIData(base);
1371     return result;
1372 }
1373 #endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */
1374 
ENET_IncreaseIndex(uint16_t index,uint16_t max)1375 static uint16_t ENET_IncreaseIndex(uint16_t index, uint16_t max)
1376 {
1377     assert(index < max);
1378 
1379     /* Increase the index. */
1380     index++;
1381     if (index >= max)
1382     {
1383         index = 0;
1384     }
1385     return index;
1386 }
1387 
ENET_TxDirtyRingAvailable(enet_tx_dirty_ring_t * txDirtyRing)1388 static inline bool ENET_TxDirtyRingAvailable(enet_tx_dirty_ring_t *txDirtyRing)
1389 {
1390     return !txDirtyRing->isFull;
1391 }
1392 
1393 /*!
1394  * brief Gets the error statistics of a received frame for ENET specified ring.
1395  *
1396  * This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame().
1397  * If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError,
1398  * the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics.
1399  * This is an example.
1400  * code
1401  *       status = ENET_GetRxFrameSize(&g_handle, &length, 0);
1402  *       if (status == kStatus_ENET_RxFrameError)
1403  *       {
1404  *           ENET_GetRxErrBeforeReadFrame(&g_handle, &eErrStatic, 0);
1405  *           ENET_ReadFrame(EXAMPLE_ENET, &g_handle, NULL, 0);
1406  *       }
1407  * endcode
1408  * param handle The ENET handler structure pointer. This is the same handler pointer used in the ENET_Init.
1409  * param eErrorStatic The error statistics structure pointer.
1410  * param ringId The ring index, range from 0 ~ (FSL_FEATURE_ENET_INSTANCE_QUEUEn(x) - 1).
1411  */
ENET_GetRxErrBeforeReadFrame(enet_handle_t * handle,enet_data_error_stats_t * eErrorStatic,uint8_t ringId)1412 void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic, uint8_t ringId)
1413 {
1414     assert(handle != NULL);
1415     assert(eErrorStatic != NULL);
1416     assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
1417 
1418     uint16_t control                             = 0;
1419     enet_rx_bd_ring_t *rxBdRing                  = &handle->rxBdRing[ringId];
1420     volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
1421     volatile enet_rx_bd_struct_t *cmpBuffDescrip = curBuffDescrip;
1422 
1423     do
1424     {
1425         /* The last buffer descriptor of a frame. */
1426         if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
1427         {
1428             control = curBuffDescrip->control;
1429             if (0U != (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK))
1430             {
1431                 /* The receive truncate error. */
1432                 eErrorStatic->statsRxTruncateErr++;
1433             }
1434             if (0U != (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK))
1435             {
1436                 /* The receive over run error. */
1437                 eErrorStatic->statsRxOverRunErr++;
1438             }
1439             if (0U != (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK))
1440             {
1441                 /* The receive length violation error. */
1442                 eErrorStatic->statsRxLenGreaterErr++;
1443             }
1444             if (0U != (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK))
1445             {
1446                 /* The receive alignment error. */
1447                 eErrorStatic->statsRxAlignErr++;
1448             }
1449             if (0U != (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK))
1450             {
1451                 /* The receive CRC error. */
1452                 eErrorStatic->statsRxFcsErr++;
1453             }
1454 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
1455             uint16_t controlExt = curBuffDescrip->controlExtend1;
1456             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_MACERR_MASK))
1457             {
1458                 /* The MAC error. */
1459                 eErrorStatic->statsRxMacErr++;
1460             }
1461             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK))
1462             {
1463                 /* The PHY error. */
1464                 eErrorStatic->statsRxPhyErr++;
1465             }
1466             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK))
1467             {
1468                 /* The receive collision error. */
1469                 eErrorStatic->statsRxCollisionErr++;
1470             }
1471 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
1472 
1473             break;
1474         }
1475 
1476         /* Increase the buffer descriptor, if it's the last one, increase to first one of the ring buffer. */
1477         if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK))
1478         {
1479             curBuffDescrip = rxBdRing->rxBdBase;
1480         }
1481         else
1482         {
1483             curBuffDescrip++;
1484         }
1485 
1486     } while (curBuffDescrip != cmpBuffDescrip);
1487 }
1488 
1489 /*!
1490  * brief Gets statistical data in transfer.
1491  *
1492  * param base  ENET peripheral base address.
1493  * param statistics The statistics structure pointer.
1494  */
ENET_GetStatistics(ENET_Type * base,enet_transfer_stats_t * statistics)1495 void ENET_GetStatistics(ENET_Type *base, enet_transfer_stats_t *statistics)
1496 {
1497     /* Rx statistics */
1498     statistics->statsRxFrameCount      = base->RMON_R_PACKETS;
1499     statistics->statsRxFrameOk         = base->IEEE_R_FRAME_OK;
1500     statistics->statsRxCrcErr          = base->IEEE_R_CRC;
1501     statistics->statsRxAlignErr        = base->IEEE_R_ALIGN;
1502     statistics->statsRxDropInvalidSFD  = base->IEEE_R_DROP;
1503     statistics->statsRxFifoOverflowErr = base->IEEE_R_MACERR;
1504 
1505     /* Tx statistics */
1506     statistics->statsTxFrameCount      = base->RMON_T_PACKETS;
1507     statistics->statsTxFrameOk         = base->IEEE_T_FRAME_OK;
1508     statistics->statsTxCrcAlignErr     = base->RMON_T_CRC_ALIGN;
1509     statistics->statsTxFifoUnderRunErr = base->IEEE_T_MACERR;
1510 }
1511 
1512 /*!
1513  * brief Gets the size of the read frame for specified ring.
1514  *
1515  * This function gets a received frame size from the ENET buffer descriptors.
1516  * note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS.
1517  * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to receive frame and update the BD
1518  * if the result is not "kStatus_ENET_RxFrameEmpty".
1519  *
1520  * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
1521  * param length The length of the valid frame received.
1522  * param ringId The ring index or ring number.
1523  * retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame.
1524  * retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data
1525  *         and NULL length to update the receive buffers.
1526  * retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame
1527  *         should be called with the right data buffer and the captured data length input.
1528  */
ENET_GetRxFrameSize(enet_handle_t * handle,uint32_t * length,uint8_t ringId)1529 status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length, uint8_t ringId)
1530 {
1531     assert(handle != NULL);
1532     assert(length != NULL);
1533     assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
1534 
1535     /* Reset the length to zero. */
1536     *length = 0;
1537 
1538     uint16_t validLastMask                       = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
1539     enet_rx_bd_ring_t *rxBdRing                  = &handle->rxBdRing[ringId];
1540     volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
1541     uint16_t index                               = rxBdRing->rxGenIdx;
1542     bool isReturn                                = false;
1543     status_t result                              = kStatus_Success;
1544 
1545     /* Check the current buffer descriptor's empty flag. If empty means there is no frame received. */
1546     if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK))
1547     {
1548         isReturn = true;
1549         result   = kStatus_ENET_RxFrameEmpty;
1550     }
1551     else
1552     {
1553         do
1554         {
1555             /* Add check for abnormal case. */
1556             if (curBuffDescrip->length == 0U)
1557             {
1558                 isReturn = true;
1559                 result   = kStatus_ENET_RxFrameError;
1560                 break;
1561             }
1562 
1563             /* Find the last buffer descriptor. */
1564             if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
1565             {
1566                 isReturn = true;
1567                 /* The last buffer descriptor in the frame check the status of the received frame. */
1568                 if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK))
1569                 {
1570                     result = kStatus_ENET_RxFrameError;
1571                     break;
1572                 }
1573 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
1574                 if (0U != (curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK))
1575                 {
1576                     result = kStatus_ENET_RxFrameError;
1577                     break;
1578                 }
1579 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
1580 
1581                 /* FCS is removed by MAC. */
1582                 *length = curBuffDescrip->length;
1583                 break;
1584             }
1585             /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
1586             index          = ENET_IncreaseIndex(index, rxBdRing->rxRingLen);
1587             curBuffDescrip = rxBdRing->rxBdBase + index;
1588         } while (index != rxBdRing->rxGenIdx);
1589     }
1590 
1591     if (isReturn == false)
1592     {
1593         /* The frame is on processing - set to empty status to make application to receive it next time. */
1594         result = kStatus_ENET_RxFrameEmpty;
1595     }
1596 
1597     return result;
1598 }
1599 
1600 /*!
1601  * brief Reads a frame from the ENET device.
1602  * This function reads a frame (both the data and the length) from the ENET buffer descriptors.
1603  * User can get timestamp through ts pointer if the ts is not NULL.
1604  * note It doesn't store the timestamp in the receive timestamp queue.
1605  * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer.
1606  * This API uses memcpy to copy data from DMA buffer to application buffer, 4 bytes aligned data buffer
1607  * in 32 bits platforms provided by user may let compiler use optimization instruction to reduce time
1608  * consumption.
1609  * This is an example:
1610  * code
1611  *       uint32_t length;
1612  *       enet_handle_t g_handle;
1613  *       Comments: Get the received frame size firstly.
1614  *       status = ENET_GetRxFrameSize(&g_handle, &length, 0);
1615  *       if (length != 0)
1616  *       {
1617  *           Comments: Allocate memory here with the size of "length"
1618  *           uint8_t *data = memory allocate interface;
1619  *           if (!data)
1620  *           {
1621  *               ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0, NULL);
1622  *               Comments: Add the console warning log.
1623  *           }
1624  *           else
1625  *           {
1626  *               status = ENET_ReadFrame(ENET, &g_handle, data, length, 0, NULL);
1627  *               Comments: Call stack input API to deliver the data to stack
1628  *           }
1629  *       }
1630  *       else if (status == kStatus_ENET_RxFrameError)
1631  *       {
1632  *           Comments: Update the received buffer when a error frame is received.
1633  *           ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0, NULL);
1634  *       }
1635  * endcode
1636  * param base  ENET peripheral base address.
1637  * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
1638  * param data The data buffer provided by user to store the frame which memory size should be at least "length".
1639  * param length The size of the data buffer which is still the length of the received frame.
1640  * param ringId The ring index or ring number.
1641  * param ts The timestamp address to store received timestamp.
1642  * return The execute status, successful or failure.
1643  */
ENET_ReadFrame(ENET_Type * base,enet_handle_t * handle,uint8_t * data,uint32_t length,uint8_t ringId,uint32_t * ts)1644 status_t ENET_ReadFrame(
1645     ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length, uint8_t ringId, uint32_t *ts)
1646 {
1647     assert(handle != NULL);
1648     assert(FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) != -1);
1649     assert(ringId < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
1650 
1651     uint32_t len    = 0;
1652     uint32_t offset = 0;
1653     uint16_t control;
1654     bool isLastBuff                              = false;
1655     enet_rx_bd_ring_t *rxBdRing                  = &handle->rxBdRing[ringId];
1656     volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
1657     uint16_t index                               = rxBdRing->rxGenIdx;
1658     status_t result                              = kStatus_Success;
1659     uintptr_t address;
1660     uintptr_t dest;
1661 
1662     /* For data-NULL input, only update the buffer descriptor. */
1663     if (data == NULL)
1664     {
1665         do
1666         {
1667             /* Update the control flag. */
1668             control = curBuffDescrip->control;
1669 
1670             /* Updates the receive buffer descriptors. */
1671             ENET_UpdateReadBuffers(base, handle, ringId);
1672 
1673             /* Find the last buffer descriptor for the frame. */
1674             if (0U != (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
1675             {
1676                 break;
1677             }
1678             curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
1679         } while (index != rxBdRing->rxGenIdx);
1680     }
1681     else
1682     {
1683         while (!isLastBuff)
1684         {
1685 /* A frame on one buffer or several receive buffers are both considered. */
1686 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1687             address = MEMORY_ConvertMemoryMapAddress(curBuffDescrip->buffer, kMEMORY_DMA2Local);
1688 #else
1689             address = curBuffDescrip->buffer;
1690 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
1691 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
1692             if (handle->rxMaintainEnable[ringId])
1693             {
1694                 /* Add the cache invalidate maintain. */
1695                 DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]);
1696             }
1697 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
1698 
1699             dest = (uintptr_t)data + offset;
1700             /* The last buffer descriptor of a frame. */
1701             if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
1702             {
1703                 /* This is a valid frame. */
1704                 isLastBuff = true;
1705                 if (length == curBuffDescrip->length)
1706                 {
1707                     /* Copy the frame to user's buffer without FCS. */
1708                     len = curBuffDescrip->length - offset;
1709                     (void)memcpy((void *)(uint8_t *)dest, (void *)(uint8_t *)address, len);
1710 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
1711                     /* Get the timestamp if the ts isn't NULL. */
1712                     if (ts != NULL)
1713                     {
1714                         *ts = curBuffDescrip->timestamp;
1715                     }
1716 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
1717 
1718                     /* Updates the receive buffer descriptors. */
1719                     ENET_UpdateReadBuffers(base, handle, ringId);
1720                     break;
1721                 }
1722                 else
1723                 {
1724                     /* Updates the receive buffer descriptors. */
1725                     ENET_UpdateReadBuffers(base, handle, ringId);
1726                 }
1727             }
1728             else
1729             {
1730                 /* Store a frame on several buffer descriptors. */
1731                 isLastBuff = false;
1732                 /* Length check. */
1733                 if (offset >= length)
1734                 {
1735                     result = kStatus_ENET_RxFrameFail;
1736                     break;
1737                 }
1738                 (void)memcpy((void *)(uint8_t *)dest, (void *)(uint8_t *)address, handle->rxBuffSizeAlign[ringId]);
1739                 offset += handle->rxBuffSizeAlign[ringId];
1740 
1741                 /* Updates the receive buffer descriptors. */
1742                 ENET_UpdateReadBuffers(base, handle, ringId);
1743             }
1744 
1745             /* Get the current buffer descriptor. */
1746             curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
1747         }
1748     }
1749 
1750     return result;
1751 }
1752 
ENET_UpdateReadBuffers(ENET_Type * base,enet_handle_t * handle,uint8_t ringId)1753 static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint8_t ringId)
1754 {
1755     assert(handle != NULL);
1756     assert(FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) != -1);
1757     assert(ringId < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
1758 
1759     enet_rx_bd_ring_t *rxBdRing                  = &handle->rxBdRing[ringId];
1760     volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
1761 
1762     /* Clears status. */
1763     curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
1764     /* Sets the receive buffer descriptor with the empty flag. */
1765     curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
1766 
1767     /* Increase current buffer descriptor to the next one. */
1768     rxBdRing->rxGenIdx = ENET_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
1769 
1770     ENET_ActiveReadRing(base, ringId);
1771 }
1772 
1773 /*!
1774  * brief Transmits an ENET frame for specified ring.
1775  * note The CRC is automatically appended to the data. Input the data to send without the CRC.
1776  * This API uses memcpy to copy data from DMA buffer to application buffer, 4 bytes aligned data buffer
1777  * in 32 bits platforms provided by user may let compiler use optimization instruction to reduce time
1778  * consumption.
1779  *
1780  *
1781  * param base  ENET peripheral base address.
1782  * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
1783  * param data The data buffer provided by user to send.
1784  * param length The length of the data to send.
1785  * param ringId The ring index or ring number.
1786  * param tsFlag Timestamp enable flag.
1787  * param context Used by user to handle some events after transmit over.
1788  * retval kStatus_Success  Send frame succeed.
1789  * retval kStatus_ENET_TxFrameBusy  Transmit buffer descriptor is busy under transmission.
1790  *        The transmit busy happens when the data send rate is over the MAC capacity.
1791  *        The waiting mechanism is recommended to be added after each call return with
1792  *        kStatus_ENET_TxFrameBusy.
1793  */
ENET_SendFrame(ENET_Type * base,enet_handle_t * handle,const uint8_t * data,uint32_t length,uint8_t ringId,bool tsFlag,void * context)1794 status_t ENET_SendFrame(ENET_Type *base,
1795                         enet_handle_t *handle,
1796                         const uint8_t *data,
1797                         uint32_t length,
1798                         uint8_t ringId,
1799                         bool tsFlag,
1800                         void *context)
1801 {
1802     assert(handle != NULL);
1803     assert(data != NULL);
1804     assert(FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) != -1);
1805     assert(ringId < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
1806 
1807     volatile enet_tx_bd_struct_t *curBuffDescrip;
1808     enet_tx_bd_ring_t *txBdRing       = &handle->txBdRing[ringId];
1809     enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
1810     enet_frame_info_t *txDirty        = NULL;
1811     uint32_t len                      = 0;
1812     uint32_t sizeleft                 = 0;
1813     uintptr_t address;
1814     status_t result = kStatus_Success;
1815     uintptr_t src;
1816     uint32_t configVal;
1817     bool isReturn = false;
1818     uint32_t primask;
1819 
1820     /* Check the frame length. */
1821     if (length > ENET_FRAME_TX_LEN_LIMITATION(base))
1822     {
1823         result = kStatus_ENET_TxFrameOverLen;
1824     }
1825     else
1826     {
1827         /* Check if the transmit buffer is ready. */
1828         curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
1829         if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
1830         {
1831             result = kStatus_ENET_TxFrameBusy;
1832         }
1833         /* Check txDirtyRing if need frameinfo in tx interrupt callback. */
1834         else if ((handle->txReclaimEnable[ringId]) && !ENET_TxDirtyRingAvailable(txDirtyRing))
1835         {
1836             result = kStatus_ENET_TxFrameBusy;
1837         }
1838         else
1839         {
1840             /* One transmit buffer is enough for one frame. */
1841             if (handle->txBuffSizeAlign[ringId] >= length)
1842             {
1843                 /* Copy data to the buffer for uDMA transfer. */
1844 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1845                 address = MEMORY_ConvertMemoryMapAddress(curBuffDescrip->buffer, kMEMORY_DMA2Local);
1846 #else
1847                 address = curBuffDescrip->buffer;
1848 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
1849                 (void)memcpy((void *)(uint8_t *)address, (const void *)data, length);
1850 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
1851                 if (handle->txMaintainEnable[ringId])
1852                 {
1853                     DCACHE_CleanByRange(address, length);
1854                 }
1855 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
1856                 /* Set data length. */
1857                 curBuffDescrip->length = (uint16_t)length;
1858 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
1859                 /* For enable the timestamp. */
1860                 if (tsFlag)
1861                 {
1862                     curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
1863                 }
1864                 else
1865                 {
1866                     curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
1867                 }
1868 
1869 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
1870                 curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
1871 
1872                 /* Increase the buffer descriptor address. */
1873                 txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
1874 
1875                 /* Add context to frame info ring */
1876                 if (handle->txReclaimEnable[ringId])
1877                 {
1878                     txDirty               = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
1879                     txDirty->context      = context;
1880                     txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
1881                     if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
1882                     {
1883                         txDirtyRing->isFull = true;
1884                     }
1885                     primask = DisableGlobalIRQ();
1886                     txBdRing->txDescUsed++;
1887                     EnableGlobalIRQ(primask);
1888                 }
1889 
1890                 /* Active the transmit buffer descriptor. */
1891                 ENET_ActiveSendRing(base, ringId);
1892             }
1893             else
1894             {
1895                 /* One frame requires more than one transmit buffers. */
1896                 do
1897                 {
1898 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
1899                     /* For enable the timestamp. */
1900                     if (tsFlag)
1901                     {
1902                         curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
1903                     }
1904                     else
1905                     {
1906                         curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
1907                     }
1908 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
1909 
1910                     /* Update the size left to be transmit. */
1911                     sizeleft = length - len;
1912 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
1913                     address = MEMORY_ConvertMemoryMapAddress(curBuffDescrip->buffer, kMEMORY_DMA2Local);
1914 #else
1915                     address = curBuffDescrip->buffer;
1916 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
1917                     src = (uintptr_t)data + len;
1918 
1919                     /* Increase the current software index of BD */
1920                     txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
1921 
1922                     if (sizeleft > handle->txBuffSizeAlign[ringId])
1923                     {
1924                         /* Data copy. */
1925                         (void)memcpy((void *)(uint8_t *)address, (void *)(uint8_t *)src,
1926                                      handle->txBuffSizeAlign[ringId]);
1927 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
1928                         if (handle->txMaintainEnable[ringId])
1929                         {
1930                             /* Add the cache clean maintain. */
1931                             DCACHE_CleanByRange(address, handle->txBuffSizeAlign[ringId]);
1932                         }
1933 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
1934                         /* Data length update. */
1935                         curBuffDescrip->length = handle->txBuffSizeAlign[ringId];
1936                         len += handle->txBuffSizeAlign[ringId];
1937                         /* Sets the control flag. */
1938                         configVal = (uint32_t)curBuffDescrip->control;
1939                         configVal &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
1940                         configVal |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
1941                         curBuffDescrip->control = (uint16_t)configVal;
1942 
1943                         if (handle->txReclaimEnable[ringId])
1944                         {
1945                             primask = DisableGlobalIRQ();
1946                             txBdRing->txDescUsed++;
1947                             EnableGlobalIRQ(primask);
1948                         }
1949 
1950                         /* Active the transmit buffer descriptor*/
1951                         ENET_ActiveSendRing(base, ringId);
1952                     }
1953                     else
1954                     {
1955                         (void)memcpy((void *)(uint8_t *)address, (void *)(uint8_t *)src, sizeleft);
1956 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
1957                         if (handle->txMaintainEnable[ringId])
1958                         {
1959                             /* Add the cache clean maintain. */
1960                             DCACHE_CleanByRange(address, sizeleft);
1961                         }
1962 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
1963                         curBuffDescrip->length = (uint16_t)sizeleft;
1964                         /* Set Last buffer wrap flag. */
1965                         curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
1966 
1967                         if (handle->txReclaimEnable[ringId])
1968                         {
1969                             /* Add context to frame info ring */
1970                             txDirty               = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
1971                             txDirty->context      = context;
1972                             txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
1973                             if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
1974                             {
1975                                 txDirtyRing->isFull = true;
1976                             }
1977                             primask = DisableGlobalIRQ();
1978                             txBdRing->txDescUsed++;
1979                             EnableGlobalIRQ(primask);
1980                         }
1981 
1982                         /* Active the transmit buffer descriptor. */
1983                         ENET_ActiveSendRing(base, ringId);
1984                         isReturn = true;
1985                         break;
1986                     }
1987                     /* Update the buffer descriptor address. */
1988                     curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
1989                 } while (0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
1990 
1991                 if (isReturn == false)
1992                 {
1993                     result = kStatus_ENET_TxFrameBusy;
1994                 }
1995             }
1996         }
1997     }
1998     return result;
1999 }
2000 
2001 /*!
2002  * brief Enable or disable tx descriptors reclaim mechanism.
2003  * note This function must be called when no pending send frame action.
2004  * Set enable if you want to reclaim context or timestamp in interrupt.
2005  *
2006  * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
2007  * param isEnable Enable or disable flag.
2008  * param ringId The ring index or ring number.
2009  * retval kStatus_Success  Succeed to enable/disable Tx reclaim.
2010  * retval kStatus_Fail  Fail to enable/disable Tx reclaim.
2011  */
ENET_SetTxReclaim(enet_handle_t * handle,bool isEnable,uint8_t ringId)2012 status_t ENET_SetTxReclaim(enet_handle_t *handle, bool isEnable, uint8_t ringId)
2013 {
2014     assert(handle != NULL);
2015     assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
2016 
2017     enet_tx_bd_ring_t *txBdRing       = &handle->txBdRing[ringId];
2018     enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
2019 
2020     status_t result = kStatus_Success;
2021 
2022     /* If tx dirty ring is empty, can set this flag and reset txConsumIdx */
2023     if ((txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) && ENET_TxDirtyRingAvailable(txDirtyRing))
2024     {
2025         if (isEnable)
2026         {
2027             handle->txReclaimEnable[ringId] = true;
2028             txBdRing->txConsumIdx           = txBdRing->txGenIdx;
2029         }
2030         else
2031         {
2032             handle->txReclaimEnable[ringId] = false;
2033         }
2034     }
2035     else
2036     {
2037         result = kStatus_Fail;
2038     }
2039     return result;
2040 }
2041 
2042 /*!
2043  * brief Reclaim tx descriptors.
2044  * This function is used to update the tx descriptor status and
2045  * store the tx timestamp when the 1588 feature is enabled.
2046  * This is called by the transmit interupt IRQ handler after the
2047  * complete of a frame transmission.
2048  *
2049  * param base   ENET peripheral base address.
2050  * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
2051  * param ringId The ring index or ring number.
2052  */
ENET_ReclaimTxDescriptor(ENET_Type * base,enet_handle_t * handle,uint8_t ringId)2053 void ENET_ReclaimTxDescriptor(ENET_Type *base, enet_handle_t *handle, uint8_t ringId)
2054 {
2055     assert(FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) != -1);
2056     assert(ringId < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base));
2057 
2058     enet_tx_bd_ring_t *txBdRing                  = &handle->txBdRing[ringId];
2059     volatile enet_tx_bd_struct_t *curBuffDescrip = txBdRing->txBdBase + txBdRing->txConsumIdx;
2060     enet_tx_dirty_ring_t *txDirtyRing            = &handle->txDirtyRing[ringId];
2061     enet_frame_info_t *txDirty                   = NULL;
2062     uint32_t primask;
2063 
2064     /* Need to update the first index for transmit buffer free. */
2065     while ((0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) && (txBdRing->txDescUsed > 0U))
2066     {
2067         if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK) != 0U)
2068         {
2069             txDirty                  = txDirtyRing->txDirtyBase + txDirtyRing->txConsumIdx;
2070             txDirtyRing->txConsumIdx = ENET_IncreaseIndex(txDirtyRing->txConsumIdx, txDirtyRing->txRingLen);
2071             txDirtyRing->isFull      = false;
2072 
2073 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2074             txDirty->isTsAvail = false;
2075             if ((curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK) != 0U)
2076             {
2077                 enet_ptp_time_t *ts = &txDirty->timeStamp;
2078                 /* Get transmit time stamp second. */
2079                 txDirty->isTsAvail = true;
2080                 ts->second         = handle->msTimerSecond;
2081                 ts->nanosecond     = curBuffDescrip->timestamp;
2082             }
2083 #endif
2084             /* For tx buffer free or requeue for last descriptor.
2085              * The tx interrupt callback should free/requeue the tx buffer. */
2086             if (handle->callback != NULL)
2087             {
2088 #if FSL_FEATURE_ENET_QUEUE > 1
2089                 handle->callback(base, handle, ringId, kENET_TxEvent, txDirty, handle->userData);
2090 #else
2091                 handle->callback(base, handle, kENET_TxEvent, txDirty, handle->userData);
2092 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
2093             }
2094         }
2095 
2096         primask = DisableGlobalIRQ();
2097         txBdRing->txDescUsed--;
2098         EnableGlobalIRQ(primask);
2099 
2100         /* Update the index. */
2101         txBdRing->txConsumIdx = ENET_IncreaseIndex(txBdRing->txConsumIdx, txBdRing->txRingLen);
2102         curBuffDescrip        = txBdRing->txBdBase + txBdRing->txConsumIdx;
2103     }
2104 }
2105 
ENET_GetRxFrameErr(enet_rx_bd_struct_t * rxDesc,enet_rx_frame_error_t * rxFrameError)2106 static inline status_t ENET_GetRxFrameErr(enet_rx_bd_struct_t *rxDesc, enet_rx_frame_error_t *rxFrameError)
2107 {
2108     assert(rxDesc != NULL);
2109     assert(rxFrameError != NULL);
2110 
2111     status_t result  = kStatus_Success;
2112     uint16_t control = rxDesc->control;
2113 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2114     uint16_t controlExtend1 = rxDesc->controlExtend1;
2115 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
2116 
2117     union _frame_error
2118     {
2119         uint32_t data;
2120         enet_rx_frame_error_t frameError;
2121     };
2122     union _frame_error error;
2123 
2124     /* The last buffer descriptor in the frame check the status of the received frame. */
2125     if (0U != (control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK))
2126     {
2127         result = kStatus_ENET_RxFrameError;
2128     }
2129 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2130     else if (0U != (controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK))
2131     {
2132         result = kStatus_ENET_RxFrameError;
2133     }
2134     else
2135     {
2136         /* Intentional empty */
2137     }
2138 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
2139 
2140     if (result != kStatus_Success)
2141     {
2142         error.data = control;
2143 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2144         error.data |= ((uint32_t)controlExtend1 << 16U);
2145 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
2146         *rxFrameError = error.frameError;
2147     }
2148     else
2149     {
2150         (void)memset((void *)rxFrameError, 0, sizeof(enet_rx_frame_error_t));
2151     }
2152 
2153     return result;
2154 }
2155 
2156 /*!
2157  * brief Receives one frame in specified BD ring with zero copy.
2158  *
2159  * This function uses the user-defined allocation and free callbacks. Every time application gets one frame through
2160  * this function, driver stores the buffer address(es) in enet_buffer_struct_t and allocate new buffer(s) for the BD(s).
2161  * If there's no memory buffer in the pool, this function drops current one frame to keep the Rx frame in BD ring is as
2162  * fresh as possible.
2163  * note Application must provide a memory pool including at least BD number + n buffers in order for this function to work
2164  * properly, because each BD must always take one buffer while driver is running, then other extra n buffer(s) can be taken
2165  * by application. Here n is the ceil(max_frame_length(set by RCR) / bd_rx_size(set by MRBR)). Application must also provide
2166  * an array structure in rxFrame->rxBuffArray with n index to receive one complete frame in any case.
2167  *
2168  * param base   ENET peripheral base address.
2169  * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
2170  * param rxFrame The received frame information structure provided by user.
2171  * param ringId The ring index or ring number.
2172  * retval kStatus_Success  Succeed to get one frame and allocate new memory for Rx buffer.
2173  * retval kStatus_ENET_RxFrameEmpty  There's no Rx frame in the BD.
2174  * retval kStatus_ENET_RxFrameError  There's issue in this receiving.
2175  * retval kStatus_ENET_RxFrameDrop  There's no new buffer memory for BD, drop this frame.
2176  */
ENET_GetRxFrame(ENET_Type * base,enet_handle_t * handle,enet_rx_frame_struct_t * rxFrame,uint8_t ringId)2177 status_t ENET_GetRxFrame(ENET_Type *base, enet_handle_t *handle, enet_rx_frame_struct_t *rxFrame, uint8_t ringId)
2178 {
2179     assert(handle != NULL);
2180     assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
2181     assert(handle->rxBdRing[ringId].rxBdBase != NULL);
2182     assert(rxFrame != NULL);
2183     assert(rxFrame->rxBuffArray != NULL);
2184 
2185     status_t result                              = kStatus_ENET_RxFrameEmpty;
2186     enet_rx_bd_ring_t *rxBdRing                  = &handle->rxBdRing[ringId];
2187     volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
2188     bool isLastBuff                              = false;
2189     uintptr_t newBuff                            = 0;
2190     uint16_t buffLen                             = 0;
2191     enet_buffer_struct_t *rxBuffer;
2192     uintptr_t address;
2193     uintptr_t buffer;
2194     uint16_t index;
2195 
2196     /* Check the current buffer descriptor's empty flag. If empty means there is no frame received. */
2197     index = rxBdRing->rxGenIdx;
2198     while (0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK))
2199     {
2200         /* Find the last buffer descriptor. */
2201         if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
2202         {
2203             /* The last buffer descriptor stores the error status of this received frame. */
2204             result = ENET_GetRxFrameErr((enet_rx_bd_struct_t *)(uintptr_t)curBuffDescrip, &rxFrame->rxFrameError);
2205             break;
2206         }
2207 
2208         /* Get feedback that no-empty BD takes frame length of 0. Probably an IP issue and drop this BD. */
2209         if (curBuffDescrip->length == 0U)
2210         {
2211             /* Set LAST bit manually to let following drop error frame operation drop this abnormal BD. */
2212             curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_LAST_MASK;
2213             result = kStatus_ENET_RxFrameError;
2214             break;
2215         }
2216 
2217         /* Can't find the last BD flag, no valid frame. */
2218         index          = ENET_IncreaseIndex(index, rxBdRing->rxRingLen);
2219         curBuffDescrip = rxBdRing->rxBdBase + index;
2220         if (index == rxBdRing->rxGenIdx)
2221         {
2222             /* kStatus_ENET_RxFrameEmpty. */
2223             break;
2224         }
2225     }
2226 
2227     /* Drop the error frame. */
2228     if (result == kStatus_ENET_RxFrameError)
2229     {
2230         curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
2231         do
2232         {
2233             /* The last buffer descriptor of a frame. */
2234             if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
2235             {
2236                 isLastBuff = true;
2237             }
2238 
2239             /* Clears status including the owner flag. */
2240             curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
2241             /* Sets the receive buffer descriptor with the empty flag. */
2242             curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
2243 
2244             /* Increase current buffer descriptor to the next one. */
2245             rxBdRing->rxGenIdx = ENET_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
2246             curBuffDescrip     = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
2247         } while (!isLastBuff);
2248 
2249         ENET_ActiveReadRing(base, ringId);
2250 
2251         return result;
2252     }
2253     else if (result != kStatus_Success)
2254     {
2255         return result;
2256     }
2257     else
2258     {
2259         /* Intentional empty */
2260     }
2261 
2262     /* Get the valid frame */
2263     curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
2264     index          = 0;
2265     do
2266     {
2267         newBuff = (uintptr_t)(uint8_t *)handle->rxBuffAlloc(base, handle->userData, ringId);
2268         if (newBuff != 0U)
2269         {
2270             assert((uint64_t)newBuff + handle->rxBuffSizeAlign[ringId] - 1U <= UINT32_MAX);
2271             rxBuffer = &rxFrame->rxBuffArray[index];
2272 
2273 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
2274             address = MEMORY_ConvertMemoryMapAddress(curBuffDescrip->buffer, kMEMORY_DMA2Local);
2275 #else
2276             address = curBuffDescrip->buffer;
2277 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
2278 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
2279             if (handle->rxMaintainEnable[ringId])
2280             {
2281                 DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]);
2282             }
2283 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
2284 
2285             rxBuffer->buffer = (void *)(uint8_t *)address;
2286 
2287             /* The last buffer descriptor of a frame. */
2288             if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
2289             {
2290                 /* This is a valid frame. */
2291                 isLastBuff       = true;
2292                 rxFrame->totLen  = curBuffDescrip->length;
2293                 rxBuffer->length = curBuffDescrip->length - buffLen;
2294 
2295                 rxFrame->rxAttribute.promiscuous = false;
2296                 if (0U != (base->RCR & ENET_RCR_PROM_MASK))
2297                 {
2298                     if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_MISS_MASK))
2299                     {
2300                         rxFrame->rxAttribute.promiscuous = true;
2301                     }
2302                 }
2303 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2304                 rxFrame->rxAttribute.timestamp = curBuffDescrip->timestamp;
2305 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
2306             }
2307             else
2308             {
2309                 rxBuffer->length = curBuffDescrip->length;
2310                 buffLen += rxBuffer->length;
2311             }
2312 
2313             /* Give new buffer from application to BD */
2314 
2315 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
2316             buffer = MEMORY_ConvertMemoryMapAddress(newBuff, kMEMORY_Local2DMA);
2317 #else
2318             buffer  = newBuff;
2319 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
2320 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
2321             if (handle->rxMaintainEnable[ringId])
2322             {
2323                 DCACHE_InvalidateByRange(buffer, handle->rxBuffSizeAlign[ringId]);
2324             }
2325 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
2326 
2327             curBuffDescrip->buffer = (uint32_t)buffer;
2328 
2329             /* Clears status including the owner flag. */
2330             curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
2331             /* Sets the receive buffer descriptor with the empty flag. */
2332             curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
2333 
2334             /* Increase Rx array index and the buffer descriptor address. */
2335             index++;
2336             rxBdRing->rxGenIdx = ENET_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
2337             curBuffDescrip     = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
2338         }
2339         else
2340         {
2341             /* Drop frame if there's no new buffer memory */
2342 
2343             /* Free the incomplete frame buffers. */
2344             while (index-- != 0U)
2345             {
2346                 handle->rxBuffFree(base, rxFrame->rxBuffArray[index].buffer, handle->userData, ringId);
2347             }
2348 
2349             /* Update left buffers as ready for next coming frame */
2350             do
2351             {
2352                 /* The last buffer descriptor of a frame. */
2353                 if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
2354                 {
2355                     isLastBuff = true;
2356                 }
2357 
2358                 /* Clears status including the owner flag. */
2359                 curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
2360                 /* Sets the receive buffer descriptor with the empty flag. */
2361                 curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
2362 
2363                 /* Increase current buffer descriptor to the next one. */
2364                 rxBdRing->rxGenIdx = ENET_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
2365                 curBuffDescrip     = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
2366             } while (!isLastBuff);
2367 
2368             result = kStatus_ENET_RxFrameDrop;
2369             break;
2370         }
2371     } while (!isLastBuff);
2372 
2373     ENET_ActiveReadRing(base, ringId);
2374 
2375     return result;
2376 }
2377 
2378 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
ENET_PrepareTxDesc(volatile enet_tx_bd_struct_t * txDesc,enet_tx_config_struct_t * txConfig)2379 static inline void ENET_PrepareTxDesc(volatile enet_tx_bd_struct_t *txDesc, enet_tx_config_struct_t *txConfig)
2380 {
2381     uint16_t controlExtend1 = 0U;
2382 
2383     /* For enable the timestamp. */
2384     if (txConfig->intEnable)
2385     {
2386         controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK;
2387     }
2388     if (txConfig->tsEnable)
2389     {
2390         controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
2391     }
2392     if (txConfig->autoProtocolChecksum)
2393     {
2394         controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_PROTOCHECKSUM_MASK;
2395     }
2396     if (txConfig->autoIPChecksum)
2397     {
2398         controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_IPCHECKSUM_MASK;
2399     }
2400 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
2401     if (txConfig->tltEnable)
2402     {
2403         controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_USETXLAUNCHTIME_MASK;
2404         txDesc->txLaunchTimeLow |= txConfig->tltLow;
2405         txDesc->txLaunchTimeHigh |= txConfig->tltHigh;
2406     }
2407     controlExtend1 |= (uint16_t)ENET_BD_FTYPE(txConfig->AVBFrameType);
2408 #endif /* FSL_FEATURE_ENET_HAS_AVB */
2409 
2410     txDesc->controlExtend1 = controlExtend1;
2411 }
2412 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
2413 
2414 /*!
2415  * brief Sends one frame in specified BD ring with zero copy.
2416  *
2417  * This function supports scattered buffer transmit, user needs to provide the buffer array.
2418  * note Tx reclaim should be enabled to ensure the Tx buffer ownership can be given back to
2419  * application after Tx is over.
2420  *
2421  * param base   ENET peripheral base address.
2422  * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
2423  * param txFrame The Tx frame structure.
2424  * param ringId The ring index or ring number.
2425  * retval kStatus_Success  Succeed to send one frame.
2426  * retval kStatus_ENET_TxFrameBusy  The BD is not ready for Tx or the reclaim operation still not finishs.
2427  * retval kStatus_ENET_TxFrameOverLen  The Tx frame length is over max ethernet frame length.
2428  */
ENET_StartTxFrame(ENET_Type * base,enet_handle_t * handle,enet_tx_frame_struct_t * txFrame,uint8_t ringId)2429 status_t ENET_StartTxFrame(ENET_Type *base, enet_handle_t *handle, enet_tx_frame_struct_t *txFrame, uint8_t ringId)
2430 {
2431     assert(handle != NULL);
2432     assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
2433     assert(txFrame->txBuffArray != NULL);
2434     assert(txFrame->txBuffNum != 0U);
2435     assert(handle->txReclaimEnable[ringId]);
2436 
2437     volatile enet_tx_bd_struct_t *curBuffDescrip;
2438     enet_tx_bd_ring_t *txBdRing       = &handle->txBdRing[ringId];
2439     enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
2440     status_t result                   = kStatus_Success;
2441     enet_buffer_struct_t *txBuff      = txFrame->txBuffArray;
2442     uint32_t txBuffNum                = txFrame->txBuffNum;
2443     enet_frame_info_t *txDirty        = NULL;
2444     uint32_t frameLen                 = 0;
2445     uint32_t idleDescNum              = 0;
2446     uint16_t index                    = 0;
2447     uint32_t configVal;
2448     uint32_t primask;
2449     uintptr_t buffer;
2450 
2451     /* Calculate frame length and Tx data buffer number. */
2452     do
2453     {
2454         frameLen += txBuff->length;
2455         txBuff++;
2456     } while (--txBuffNum != 0U);
2457     txBuffNum = txFrame->txBuffNum;
2458 
2459     /* Check whether the available BD number is enough for Tx data buffer. */
2460     curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
2461     index          = txBdRing->txGenIdx;
2462     do
2463     {
2464         if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
2465         {
2466             break;
2467         }
2468 
2469         /* Idle BD number is enough */
2470         if (++idleDescNum >= txBuffNum)
2471         {
2472             break;
2473         }
2474         index          = ENET_IncreaseIndex(index, txBdRing->txRingLen);
2475         curBuffDescrip = txBdRing->txBdBase + index;
2476     } while (index != txBdRing->txGenIdx);
2477 
2478     /* Check the frame length. */
2479     if (frameLen > ENET_FRAME_TX_LEN_LIMITATION(base))
2480     {
2481         result = kStatus_ENET_TxFrameOverLen;
2482     }
2483     /* Return busy if idle BD is not enough. */
2484     else if (txBuffNum > idleDescNum)
2485     {
2486         result = kStatus_ENET_TxFrameBusy;
2487     }
2488     /* Check txDirtyRing if need frameinfo in tx interrupt callback. */
2489     else if (!ENET_TxDirtyRingAvailable(txDirtyRing))
2490     {
2491         result = kStatus_ENET_TxFrameBusy;
2492     }
2493     else
2494     {
2495         txBuff = txFrame->txBuffArray;
2496         do
2497         {
2498             assert(txBuff->buffer != NULL);
2499             assert((uint64_t)(uintptr_t)(uint8_t *)txBuff->buffer + txBuff->length - 1U <= UINT32_MAX);
2500 
2501 #if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
2502             if (handle->txMaintainEnable[ringId])
2503             {
2504                 DCACHE_CleanByRange((uintptr_t)(uint8_t *)txBuff->buffer, txBuff->length);
2505             }
2506 #endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
2507 #if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
2508             /* Map loacl memory address to DMA for special platform. */
2509             buffer = MEMORY_ConvertMemoryMapAddress((uintptr_t)(uint8_t *)txBuff->buffer, kMEMORY_Local2DMA);
2510 #else
2511             buffer  = (uintptr_t)(uint8_t *)txBuff->buffer;
2512 #endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
2513 
2514             /* Set data buffer and length. */
2515             curBuffDescrip         = txBdRing->txBdBase + txBdRing->txGenIdx;
2516             curBuffDescrip->buffer = (uint32_t)buffer;
2517             curBuffDescrip->length = txBuff->length;
2518 
2519             /* Increase txBuffer array address and the buffer descriptor address. */
2520             txBuff++;
2521             txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
2522 
2523 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2524             ENET_PrepareTxDesc(curBuffDescrip, &txFrame->txConfig);
2525 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
2526 
2527             /* Linked buffers */
2528             if (--txBuffNum != 0U)
2529             {
2530                 /* Set BD ready flag and clean last BD flag. */
2531                 configVal = (uint32_t)curBuffDescrip->control;
2532                 configVal &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
2533                 configVal |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
2534                 curBuffDescrip->control = (uint16_t)configVal;
2535 
2536                 primask = DisableGlobalIRQ();
2537                 txBdRing->txDescUsed++;
2538                 EnableGlobalIRQ(primask);
2539             }
2540             else
2541             {
2542                 curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
2543 
2544                 /* Add context to frame info ring */
2545                 txDirty               = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
2546                 txDirty->context      = txFrame->context;
2547                 txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
2548                 if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
2549                 {
2550                     txDirtyRing->isFull = true;
2551                 }
2552                 primask = DisableGlobalIRQ();
2553                 txBdRing->txDescUsed++;
2554                 EnableGlobalIRQ(primask);
2555             }
2556             /* Active Tx BD everytime to speed up transfer */
2557             ENET_ActiveSendRing(base, ringId);
2558         } while (txBuffNum != 0U);
2559     }
2560     return result;
2561 }
2562 
2563 /*!
2564  * brief Adds the ENET device to a multicast group.
2565  *
2566  * param base    ENET peripheral base address.
2567  * param address The six-byte multicast group address which is provided by application.
2568  */
ENET_AddMulticastGroup(ENET_Type * base,uint8_t * address)2569 void ENET_AddMulticastGroup(ENET_Type *base, uint8_t *address)
2570 {
2571     assert(address != NULL);
2572 
2573     enet_handle_t *handle = s_ENETHandle[ENET_GetInstance(base)];
2574     uint32_t crc          = 0xFFFFFFFFU;
2575     uint32_t count1       = 0;
2576     uint32_t count2       = 0;
2577     uint32_t configVal    = 0;
2578 
2579     /* Calculates the CRC-32 polynomial on the multicast group address. */
2580     for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
2581     {
2582         uint8_t c = address[count1];
2583         for (count2 = 0; count2 < 0x08U; count2++)
2584         {
2585             if (0U != ((c ^ crc) & 1U))
2586             {
2587                 crc >>= 1U;
2588                 c >>= 1U;
2589                 crc ^= 0xEDB88320U;
2590             }
2591             else
2592             {
2593                 crc >>= 1U;
2594                 c >>= 1U;
2595             }
2596         }
2597     }
2598 
2599     crc = crc >> 26U;
2600 
2601     handle->multicastCount[crc]++;
2602 
2603     /* Enable a multicast group address. */
2604     configVal = ((uint32_t)1U << (crc & 0x1FU));
2605 
2606     if (0U != (crc & 0x20U))
2607     {
2608         base->GAUR |= configVal;
2609     }
2610     else
2611     {
2612         base->GALR |= configVal;
2613     }
2614 }
2615 
2616 /*!
2617  * brief Moves the ENET device from a multicast group.
2618  *
2619  * param base  ENET peripheral base address.
2620  * param address The six-byte multicast group address which is provided by application.
2621  */
ENET_LeaveMulticastGroup(ENET_Type * base,uint8_t * address)2622 void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address)
2623 {
2624     assert(address != NULL);
2625 
2626     enet_handle_t *handle = s_ENETHandle[ENET_GetInstance(base)];
2627     uint32_t crc          = 0xFFFFFFFFU;
2628     uint32_t count1       = 0;
2629     uint32_t count2       = 0;
2630     uint32_t configVal    = 0;
2631 
2632     /* Calculates the CRC-32 polynomial on the multicast group address. */
2633     for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
2634     {
2635         uint8_t c = address[count1];
2636         for (count2 = 0; count2 < 0x08U; count2++)
2637         {
2638             if (0U != ((c ^ crc) & 1U))
2639             {
2640                 crc >>= 1U;
2641                 c >>= 1U;
2642                 crc ^= 0xEDB88320U;
2643             }
2644             else
2645             {
2646                 crc >>= 1U;
2647                 c >>= 1U;
2648             }
2649         }
2650     }
2651 
2652     crc = crc >> 26U;
2653 
2654     handle->multicastCount[crc]--;
2655 
2656     /* Set the hash table if no collisions */
2657     if (0U == handle->multicastCount[crc])
2658     {
2659         configVal = ~((uint32_t)1U << (crc & 0x1FU));
2660 
2661         if (0U != (crc & 0x20U))
2662         {
2663             base->GAUR &= configVal;
2664         }
2665         else
2666         {
2667             base->GALR &= configVal;
2668         }
2669     }
2670 }
2671 
2672 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
2673 /*!
2674  * brief Gets the ENET transmit frame statistics after the data send for specified ring.
2675  *
2676  * This interface gets the error statistics of the transmit frame.
2677  * Because the error information is reported by the uDMA after the data delivery, this interface
2678  * should be called after the data transmit API. It is recommended to call this function on
2679  * transmit interrupt handler. After calling the ENET_SendFrame, the
2680  * transmit interrupt notifies the transmit completion.
2681  *
2682  * param handle The PTP handler pointer. This is the same handler pointer used in the ENET_Init.
2683  * param eErrorStatic The error statistics structure pointer.
2684  * param ringId The ring index, range from 0 ~ (FSL_FEATURE_ENET_INSTANCE_QUEUEn(x) - 1).
2685  * return The execute status.
2686  */
ENET_GetTxErrAfterSendFrame(enet_handle_t * handle,enet_data_error_stats_t * eErrorStatic,uint8_t ringId)2687 status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic, uint8_t ringId)
2688 {
2689     assert(handle != NULL);
2690     assert(eErrorStatic != NULL);
2691     assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
2692 
2693     uint16_t control                             = 0;
2694     uint16_t controlExt                          = 0;
2695     status_t result                              = kStatus_Success;
2696     bool isReturn                                = false;
2697     enet_tx_bd_ring_t *txBdRing                  = &handle->txBdRing[ringId];
2698     volatile enet_tx_bd_struct_t *curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
2699 
2700     do
2701     {
2702         /* Get the current dirty transmit buffer descriptor. */
2703         control    = handle->txBdDirtyStatic[ringId]->control;
2704         controlExt = handle->txBdDirtyStatic[ringId]->controlExtend0;
2705 
2706         /* Get the control status data, If the buffer descriptor has not been processed break out. */
2707         if (0U != (control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
2708         {
2709             result   = kStatus_ENET_TxFrameBusy;
2710             isReturn = true;
2711             break;
2712         }
2713 
2714         /* Increase the transmit dirty static pointer. */
2715         if (0U != (handle->txBdDirtyStatic[ringId]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK))
2716         {
2717             handle->txBdDirtyStatic[ringId] = txBdRing->txBdBase;
2718         }
2719         else
2720         {
2721             handle->txBdDirtyStatic[ringId]++;
2722         }
2723 
2724         /* If the transmit buffer descriptor is ready and the last buffer descriptor, store packet statistic. */
2725         if (0U != (control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK))
2726         {
2727             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_ERR_MASK))
2728             {
2729                 /* Transmit error. */
2730                 eErrorStatic->statsTxErr++;
2731             }
2732             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK))
2733             {
2734                 /* Transmit excess collision error. */
2735                 eErrorStatic->statsTxExcessCollisionErr++;
2736             }
2737             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK))
2738             {
2739                 /* Transmit late collision error. */
2740                 eErrorStatic->statsTxLateCollisionErr++;
2741             }
2742             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK))
2743             {
2744                 /* Transmit under flow error. */
2745                 eErrorStatic->statsTxUnderFlowErr++;
2746             }
2747             if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK))
2748             {
2749                 /* Transmit over flow error. */
2750                 eErrorStatic->statsTxOverFlowErr++;
2751             }
2752             isReturn = true;
2753             break;
2754         }
2755 
2756     } while (handle->txBdDirtyStatic[ringId] != curBuffDescrip);
2757 
2758     if (isReturn == false)
2759     {
2760         result = kStatus_ENET_TxFrameFail;
2761     }
2762     return result;
2763 }
2764 
ENET_Ptp1588ConfigureHandler(ENET_Type * base,enet_handle_t * handle,enet_ptp_config_t * ptpConfig)2765 void ENET_Ptp1588ConfigureHandler(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig)
2766 {
2767     assert(handle != NULL);
2768     assert(ptpConfig != NULL);
2769     uint8_t count;
2770 
2771     uint32_t mask = (uint32_t)kENET_TxBufferInterrupt;
2772 #if FSL_FEATURE_ENET_QUEUE > 1
2773     mask |= (uint32_t)kENET_TxBuffer1Interrupt | (uint32_t)kENET_TxBuffer2Interrupt;
2774 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
2775 
2776     for (count = 0; count < handle->ringNum; count++)
2777     {
2778         handle->txBdDirtyStatic[count] = handle->txBdRing[count].txBdBase;
2779     }
2780 
2781     /* Setting the receive and transmit state for transaction. */
2782     handle->msTimerSecond = 0;
2783 
2784 #if defined(FSL_FEATURE_ENET_TIMESTAMP_CAPTURE_BIT_INVALID) && FSL_FEATURE_ENET_TIMESTAMP_CAPTURE_BIT_INVALID
2785     uint32_t refClock;
2786 
2787     /* The minimum time is defined by the greater of either six register clock cycles or six ptp clock cycles. */
2788     if (handle->enetClock <= ptpConfig->ptp1588ClockSrc_Hz)
2789     {
2790         /* Caculate how many core cycles delay is needed. */
2791         /* In the cases with this IP design issue, core clock = enetClock */
2792         handle->tsDelayCount = 6U * handle->enetClock;
2793     }
2794     else
2795     {
2796         refClock = ptpConfig->ptp1588ClockSrc_Hz;
2797 
2798         /* Caculate how many core cycles delay is needed. */
2799         /* In the cases with this IP design issue, core clock = enetClock */
2800         handle->tsDelayCount = 6U * ((handle->enetClock + refClock - 1U) / refClock);
2801     }
2802 
2803 #endif
2804 
2805     ENET_DisableInterrupts(base, mask);
2806 
2807     /* Set the IRQ handler when the interrupt is enabled. */
2808     ENET_SetTsISRHandler(base, ENET_TimeStampIRQHandler);
2809     ENET_SetTxISRHandler(base, ENET_TransmitIRQHandler);
2810 
2811     /* Enables the time stamp interrupt and transmit frame interrupt to
2812      * handle the time-stamp . */
2813     ENET_EnableInterrupts(base, (ENET_TS_INTERRUPT | ENET_TX_INTERRUPT));
2814 }
2815 
2816 /*!
2817  * brief Configures the ENET PTP IEEE 1588 feature with the basic configuration.
2818  * The function sets the clock for PTP 1588 timer and enables
2819  * time stamp interrupts and transmit interrupts for PTP 1588 features.
2820  * This API should be called when the 1588 feature is enabled
2821  * or the ENET_ENHANCEDBUFFERDESCRIPTOR_MODE is defined.
2822  * ENET_Init should be called before calling this API.
2823  *
2824  * note The PTP 1588 time-stamp second increase though time-stamp interrupt handler
2825  *  and the transmit time-stamp store is done through transmit interrupt handler.
2826  *  As a result, the TS interrupt and TX interrupt are enabled when you call this API.
2827  *
2828  * param base    ENET peripheral base address.
2829  * param handle  ENET handler pointer.
2830  * param ptpConfig The ENET PTP1588 configuration.
2831  */
ENET_Ptp1588Configure(ENET_Type * base,enet_handle_t * handle,enet_ptp_config_t * ptpConfig)2832 void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig)
2833 {
2834     assert(handle != NULL);
2835     assert(ptpConfig != NULL);
2836 
2837     /* Start the 1588 timer. */
2838     ENET_Ptp1588StartTimer(base, ptpConfig->ptp1588ClockSrc_Hz);
2839 
2840     ENET_Ptp1588ConfigureHandler(base, handle, ptpConfig);
2841 }
2842 
2843 /*!
2844  * brief Starts the ENET PTP 1588 Timer.
2845  * This function is used to initialize the PTP timer. After the PTP starts,
2846  * the PTP timer starts running.
2847  *
2848  * param base  ENET peripheral base address.
2849  * param ptpClkSrc The clock source of the PTP timer.
2850  */
ENET_Ptp1588StartTimer(ENET_Type * base,uint32_t ptpClkSrc)2851 void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc)
2852 {
2853     /* Restart PTP 1588 timer, master clock. */
2854     base->ATCR = ENET_ATCR_RESTART_MASK;
2855 
2856     /* Initializes PTP 1588 timer. */
2857     base->ATINC = ENET_ATINC_INC(ENET_NANOSECOND_ONE_SECOND / ptpClkSrc);
2858     base->ATPER = ENET_NANOSECOND_ONE_SECOND;
2859     /* Sets periodical event and the event signal output assertion and Actives PTP 1588 timer.  */
2860     base->ATCR = ENET_ATCR_PEREN_MASK | ENET_ATCR_PINPER_MASK | ENET_ATCR_EN_MASK;
2861 }
2862 
2863 /*!
2864  * brief Gets the current ENET time from the PTP 1588 timer.
2865  *       Interrupts are not disabled.
2866  *
2867  * param base  ENET peripheral base address.
2868  * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
2869  * param ptpTime The PTP timer structure.
2870  */
ENET_Ptp1588GetTimerNoIrqDisable(ENET_Type * base,enet_handle_t * handle,enet_ptp_time_t * ptpTime)2871 void ENET_Ptp1588GetTimerNoIrqDisable(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
2872 {
2873     /* Get the current PTP time. */
2874     ptpTime->second = handle->msTimerSecond;
2875     /* Get the nanosecond from the master timer. */
2876     base->ATCR |= ENET_ATCR_CAPTURE_MASK;
2877 
2878 #if defined(FSL_FEATURE_ENET_TIMESTAMP_CAPTURE_BIT_INVALID) && FSL_FEATURE_ENET_TIMESTAMP_CAPTURE_BIT_INVALID
2879     /* The whole while loop includes at least three instructions(subs, nop and bne). */
2880     uint32_t count = (handle->tsDelayCount + 3U - 1U) / 3U;
2881 
2882     while (0U != (count--))
2883     {
2884         __NOP();
2885     }
2886 #else
2887     /* Wait for capture over */
2888     while (0U != (base->ATCR & ENET_ATCR_CAPTURE_MASK))
2889     {
2890     }
2891 #endif
2892 
2893     /* Get the captured time. */
2894     ptpTime->nanosecond = base->ATVR;
2895 }
2896 
2897 /*!
2898  * brief Gets the current ENET time from the PTP 1588 timer.
2899  *
2900  * param base  ENET peripheral base address.
2901  * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
2902  * param ptpTime The PTP timer structure.
2903  */
ENET_Ptp1588GetTimer(ENET_Type * base,enet_handle_t * handle,enet_ptp_time_t * ptpTime)2904 void ENET_Ptp1588GetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
2905 {
2906     assert(handle != NULL);
2907     assert(ptpTime != NULL);
2908     uint32_t primask;
2909 
2910     /* Disables the interrupt. */
2911     primask = DisableGlobalIRQ();
2912 
2913     ENET_Ptp1588GetTimerNoIrqDisable(base, handle, ptpTime);
2914 
2915     /* Get PTP timer wrap event. */
2916     if (0U != (base->EIR & (uint32_t)kENET_TsTimerInterrupt))
2917     {
2918         ptpTime->second++;
2919     }
2920 
2921     /* Enables the interrupt. */
2922     EnableGlobalIRQ(primask);
2923 }
2924 
2925 /*!
2926  * brief Sets the ENET PTP 1588 timer to the assigned time.
2927  *
2928  * param base  ENET peripheral base address.
2929  * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
2930  * param ptpTime The timer to be set to the PTP timer.
2931  */
ENET_Ptp1588SetTimer(ENET_Type * base,enet_handle_t * handle,enet_ptp_time_t * ptpTime)2932 void ENET_Ptp1588SetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
2933 {
2934     assert(handle != NULL);
2935     assert(ptpTime != NULL);
2936 
2937     uint32_t primask;
2938 
2939     /* Disables the interrupt. */
2940     primask = DisableGlobalIRQ();
2941 
2942     /* Sets PTP timer. */
2943     handle->msTimerSecond = ptpTime->second;
2944     base->ATVR            = ptpTime->nanosecond;
2945 
2946     /* Enables the interrupt. */
2947     EnableGlobalIRQ(primask);
2948 }
2949 
2950 /*!
2951  * brief Adjusts the ENET PTP 1588 timer.
2952  *
2953  * param base  ENET peripheral base address.
2954  * param corrIncrease The correction increment value. This value is added every time the correction
2955  *       timer expires. A value less than the PTP timer frequency(1/ptpClkSrc) slows down the timer,
2956  *        a value greater than the 1/ptpClkSrc speeds up the timer.
2957  * param corrPeriod The PTP timer correction counter wrap-around value. This defines after how
2958  *       many timer clock the correction counter should be reset and trigger a correction
2959  *       increment on the timer. A value of 0 disables the correction counter and no correction occurs.
2960  */
ENET_Ptp1588AdjustTimer(ENET_Type * base,uint32_t corrIncrease,uint32_t corrPeriod)2961 void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod)
2962 {
2963     /* Set correction for PTP timer increment. */
2964     base->ATINC = (base->ATINC & ~ENET_ATINC_INC_CORR_MASK) | (corrIncrease << ENET_ATINC_INC_CORR_SHIFT);
2965     /* Set correction for PTP timer period. */
2966     base->ATCOR = (base->ATCOR & ~ENET_ATCOR_COR_MASK) | (corrPeriod << ENET_ATCOR_COR_SHIFT);
2967 }
2968 
2969 #if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
2970 /*!
2971  * brief Sets the ENET AVB feature.
2972  *
2973  * ENET AVB feature configuration, set the Receive classification match and transmit
2974  * bandwidth. This API is called when the AVB feature is required.
2975  *
2976  * Note: The AVB frames transmission scheme is credit-based tx scheme and it's only supported
2977  * with the Enhanced buffer descriptors. so the AVB configuration should only done with
2978  * Enhanced buffer descriptor. so when the AVB feature is required, please make sure the
2979  * the "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" is defined.
2980  *
2981  * param base ENET peripheral base address.
2982  * param handle ENET handler pointer.
2983  * param config The ENET AVB feature configuration structure.
2984  */
ENET_AVBConfigure(ENET_Type * base,enet_handle_t * handle,const enet_avb_config_t * config)2985 void ENET_AVBConfigure(ENET_Type *base, enet_handle_t *handle, const enet_avb_config_t *config)
2986 {
2987     assert(config != NULL);
2988     assert(FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) != -1);
2989 
2990     uint8_t count = 0;
2991 
2992     for (count = 0; count < (uint8_t)FSL_FEATURE_ENET_INSTANCE_QUEUEn(base) - 1U; count++)
2993     {
2994         /* Set the AVB receive ring classification match when the match is not 0. */
2995         if (0U != (config->rxClassifyMatch[count]))
2996         {
2997             base->RCMR[count] = ((uint32_t)config->rxClassifyMatch[count] & 0xFFFFU) | ENET_RCMR_MATCHEN_MASK;
2998         }
2999         /* Set the dma controller for the extended ring. */
3000         base->DMACFG[count] |= ENET_DMACFG_IDLE_SLOPE(config->idleSlope[count]);
3001     }
3002 
3003     /* Shall use the credit-based scheme for avb. */
3004     base->QOS &= ~ENET_QOS_TX_SCHEME_MASK;
3005     base->QOS |= ENET_QOS_RX_FLUSH0_MASK;
3006 }
3007 #endif /* FSL_FEATURE_ENET_HAS_AVB */
3008 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
3009 
3010 #if FSL_FEATURE_ENET_QUEUE > 1
3011 /*!
3012  * brief The transmit IRQ handler.
3013  *
3014  * param base  ENET peripheral base address.
3015  * param handle The ENET handler pointer.
3016  */
ENET_TransmitIRQHandler(ENET_Type * base,enet_handle_t * handle,uint32_t ringId)3017 void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
3018 #else
3019 /*!
3020  * brief The transmit IRQ handler.
3021  *
3022  * param base  ENET peripheral base address.
3023  * param handle The ENET handler pointer.
3024  */
3025 void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
3026 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3027 {
3028     assert(handle != NULL);
3029     uint32_t mask  = (uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt;
3030     uint32_t index = 0;
3031     uint32_t irq;
3032 
3033 /* Check if the transmit interrupt happen. */
3034 #if FSL_FEATURE_ENET_QUEUE > 1
3035     switch (ringId)
3036     {
3037         case kENET_Ring1:
3038             mask = ((uint32_t)kENET_TxFrame1Interrupt | (uint32_t)kENET_TxBuffer1Interrupt);
3039             break;
3040         case kENET_Ring2:
3041             mask = ((uint32_t)kENET_TxFrame2Interrupt | (uint32_t)kENET_TxBuffer2Interrupt);
3042             break;
3043         default:
3044             mask = (uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt;
3045             break;
3046     }
3047     index = ringId;
3048 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3049 
3050     while (0U != (mask & base->EIR))
3051     {
3052         irq = base->EIR;
3053 
3054         /* Clear the transmit interrupt event. */
3055         base->EIR = mask;
3056 
3057         /* Callback Handler. */
3058         if (handle->txReclaimEnable[index] && (0U != (irq & (uint32_t)kENET_TxFrameInterrupt)))
3059         {
3060             ENET_ReclaimTxDescriptor(base, handle, (uint8_t)index);
3061         }
3062         else
3063         {
3064             if (NULL != handle->callback)
3065             {
3066 #if FSL_FEATURE_ENET_QUEUE > 1
3067                 handle->callback(base, handle, index, kENET_TxEvent, NULL, handle->userData);
3068 #else
3069                 handle->callback(base, handle, kENET_TxEvent, NULL, handle->userData);
3070 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3071             }
3072         }
3073     }
3074 }
3075 
3076 /*!
3077  * brief The receive IRQ handler.
3078  *
3079  * param base  ENET peripheral base address.
3080  * param handle The ENET handler pointer.
3081  */
3082 #if FSL_FEATURE_ENET_QUEUE > 1
ENET_ReceiveIRQHandler(ENET_Type * base,enet_handle_t * handle,uint32_t ringId)3083 void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
3084 #else
3085 void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
3086 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3087 {
3088     assert(handle != NULL);
3089     uint32_t mask = (uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt;
3090 
3091 /* Check if the receive interrupt happen. */
3092 #if FSL_FEATURE_ENET_QUEUE > 1
3093     switch (ringId)
3094     {
3095         case kENET_Ring1:
3096             mask = ((uint32_t)kENET_RxFrame1Interrupt | (uint32_t)kENET_RxBuffer1Interrupt);
3097             break;
3098         case kENET_Ring2:
3099             mask = ((uint32_t)kENET_RxFrame2Interrupt | (uint32_t)kENET_RxBuffer2Interrupt);
3100             break;
3101         default:
3102             mask = (uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt;
3103             break;
3104     }
3105 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3106 
3107     while (0U != (mask & base->EIR))
3108     {
3109         /* Clear the transmit interrupt event. */
3110         base->EIR = mask;
3111 
3112         /* Callback function. */
3113         if (NULL != handle->callback)
3114         {
3115 #if FSL_FEATURE_ENET_QUEUE > 1
3116             handle->callback(base, handle, ringId, kENET_RxEvent, NULL, handle->userData);
3117 #else
3118             handle->callback(base, handle, kENET_RxEvent, NULL, handle->userData);
3119 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3120         }
3121     }
3122 }
3123 
3124 /*!
3125  * brief Some special IRQ handler including the error, mii, wakeup irq handler.
3126  *
3127  * param base  ENET peripheral base address.
3128  * param handle The ENET handler pointer.
3129  */
ENET_ErrorIRQHandler(ENET_Type * base,enet_handle_t * handle)3130 void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
3131 {
3132     assert(handle != NULL);
3133 
3134     uint32_t errMask = (uint32_t)kENET_BabrInterrupt | (uint32_t)kENET_BabtInterrupt | (uint32_t)kENET_EBusERInterrupt |
3135                        (uint32_t)kENET_PayloadRxInterrupt | (uint32_t)kENET_LateCollisionInterrupt |
3136                        (uint32_t)kENET_RetryLimitInterrupt | (uint32_t)kENET_UnderrunInterrupt;
3137 
3138     /* Check if the error interrupt happen. */
3139     if (0U != ((uint32_t)kENET_WakeupInterrupt & base->EIR))
3140     {
3141         /* Clear the wakeup interrupt. */
3142         base->EIR = (uint32_t)kENET_WakeupInterrupt;
3143         /* wake up and enter the normal mode. */
3144         ENET_EnableSleepMode(base, false);
3145         /* Callback function. */
3146         if (NULL != handle->callback)
3147         {
3148 #if FSL_FEATURE_ENET_QUEUE > 1
3149             handle->callback(base, handle, 0, kENET_WakeUpEvent, NULL, handle->userData);
3150 #else
3151             handle->callback(base, handle, kENET_WakeUpEvent, NULL, handle->userData);
3152 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3153         }
3154     }
3155     else
3156     {
3157         /* Clear the error interrupt event status. */
3158         errMask &= base->EIR;
3159         base->EIR = errMask;
3160         /* Callback function. */
3161         if (NULL != handle->callback)
3162         {
3163 #if FSL_FEATURE_ENET_QUEUE > 1
3164             handle->callback(base, handle, 0, kENET_ErrEvent, NULL, handle->userData);
3165 #else
3166             handle->callback(base, handle, kENET_ErrEvent, NULL, handle->userData);
3167 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3168         }
3169     }
3170 }
3171 
3172 #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
3173 /*!
3174  * brief The IEEE 1588 PTP time stamp interrupt handler.
3175  *
3176  * param base  ENET peripheral base address.
3177  * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
3178  */
ENET_TimeStampIRQHandler(ENET_Type * base,enet_handle_t * handle)3179 void ENET_TimeStampIRQHandler(ENET_Type *base, enet_handle_t *handle)
3180 {
3181     assert(handle != NULL);
3182 
3183     /* Check if the PTP time stamp interrupt happen. */
3184     if (0U != ((uint32_t)kENET_TsTimerInterrupt & base->EIR))
3185     {
3186         /* Clear the time stamp interrupt. */
3187         base->EIR = (uint32_t)kENET_TsTimerInterrupt;
3188 
3189         /* Increase timer second counter. */
3190         handle->msTimerSecond++;
3191 
3192         /* Callback function. */
3193         if (NULL != handle->callback)
3194         {
3195 #if FSL_FEATURE_ENET_QUEUE > 1
3196             handle->callback(base, handle, 0, kENET_TimeStampEvent, NULL, handle->userData);
3197 #else
3198             handle->callback(base, handle, kENET_TimeStampEvent, NULL, handle->userData);
3199 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3200         }
3201     }
3202 
3203     if (0U != ((uint32_t)kENET_TsAvailInterrupt & base->EIR))
3204     {
3205         /* Clear the time stamp interrupt. */
3206         base->EIR = (uint32_t)kENET_TsAvailInterrupt;
3207         /* Callback function. */
3208         if (NULL != handle->callback)
3209         {
3210 #if FSL_FEATURE_ENET_QUEUE > 1
3211             handle->callback(base, handle, 0, kENET_TimeStampAvailEvent, NULL, handle->userData);
3212 #else
3213             handle->callback(base, handle, kENET_TimeStampAvailEvent, NULL, handle->userData);
3214 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3215         }
3216     }
3217 }
3218 #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
3219 
3220 /*!
3221  * brief the common IRQ handler for the tx/rx/error etc irq handler.
3222  *
3223  * This is used for the combined tx/rx/error interrupt for single/mutli-ring (frame 0).
3224  *
3225  * param base  ENET peripheral base address.
3226  */
ENET_CommonFrame0IRQHandler(ENET_Type * base)3227 void ENET_CommonFrame0IRQHandler(ENET_Type *base)
3228 {
3229     uint32_t event    = base->EIR;
3230     uint32_t instance = ENET_GetInstance(base);
3231 
3232     event &= base->EIMR;
3233     if (0U != (event & ((uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt)))
3234     {
3235         if (s_enetTxIsr[instance] != NULL)
3236         {
3237 #if FSL_FEATURE_ENET_QUEUE > 1
3238             s_enetTxIsr[instance](base, s_ENETHandle[instance], 0);
3239 #else
3240             s_enetTxIsr[instance](base, s_ENETHandle[instance]);
3241 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3242         }
3243     }
3244 
3245     if (0U != (event & ((uint32_t)kENET_RxBufferInterrupt | (uint32_t)kENET_RxFrameInterrupt)))
3246     {
3247         if (s_enetRxIsr[instance] != NULL)
3248         {
3249 #if FSL_FEATURE_ENET_QUEUE > 1
3250             s_enetRxIsr[instance](base, s_ENETHandle[instance], 0);
3251 #else
3252             s_enetRxIsr[instance](base, s_ENETHandle[instance]);
3253 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3254         }
3255     }
3256 
3257     if (0U != (event & ENET_TS_INTERRUPT) && (NULL != s_enetTsIsr[instance]))
3258     {
3259         s_enetTsIsr[instance](base, s_ENETHandle[instance]);
3260     }
3261     if (0U != (event & ENET_ERR_INTERRUPT) && (NULL != s_enetErrIsr[instance]))
3262     {
3263         s_enetErrIsr[instance](base, s_ENETHandle[instance]);
3264     }
3265 }
3266 
3267 #if FSL_FEATURE_ENET_QUEUE > 1
3268 /*!
3269  * brief the common IRQ handler for the tx/rx irq handler.
3270  *
3271  * This is used for the combined tx/rx interrupt for multi-ring (frame 1).
3272  *
3273  * param base  ENET peripheral base address.
3274  */
ENET_CommonFrame1IRQHandler(ENET_Type * base)3275 void ENET_CommonFrame1IRQHandler(ENET_Type *base)
3276 {
3277     uint32_t event    = base->EIR;
3278     uint32_t instance = ENET_GetInstance(base);
3279 
3280     event &= base->EIMR;
3281     if (0U != (event & ((uint32_t)kENET_TxBuffer1Interrupt | (uint32_t)kENET_TxFrame1Interrupt)))
3282     {
3283         if (s_enetTxIsr[instance] != NULL)
3284         {
3285             s_enetTxIsr[instance](base, s_ENETHandle[instance], 1);
3286         }
3287     }
3288 
3289     if (0U != (event & ((uint32_t)kENET_RxBuffer1Interrupt | (uint32_t)kENET_RxFrame1Interrupt)))
3290     {
3291         if (s_enetRxIsr[instance] != NULL)
3292         {
3293             s_enetRxIsr[instance](base, s_ENETHandle[instance], 1);
3294         }
3295     }
3296 }
3297 
3298 /*!
3299  * brief the common IRQ handler for the tx/rx irq handler.
3300  *
3301  * This is used for the combined tx/rx interrupt for multi-ring (frame 2).
3302  *
3303  * param base  ENET peripheral base address.
3304  */
ENET_CommonFrame2IRQHandler(ENET_Type * base)3305 void ENET_CommonFrame2IRQHandler(ENET_Type *base)
3306 {
3307     uint32_t event    = base->EIR;
3308     uint32_t instance = ENET_GetInstance(base);
3309 
3310     event &= base->EIMR;
3311     if (0U != (event & ((uint32_t)kENET_TxBuffer2Interrupt | (uint32_t)kENET_TxFrame2Interrupt)))
3312     {
3313         if (s_enetTxIsr[instance] != NULL)
3314         {
3315             s_enetTxIsr[instance](base, s_ENETHandle[instance], 2);
3316         }
3317     }
3318 
3319     if (0U != (event & ((uint32_t)kENET_RxBuffer2Interrupt | (uint32_t)kENET_RxFrame2Interrupt)))
3320     {
3321         if (s_enetRxIsr[instance] != NULL)
3322         {
3323             s_enetRxIsr[instance](base, s_ENETHandle[instance], 2);
3324         }
3325     }
3326 }
3327 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3328 
ENET_Ptp1588IRQHandler(ENET_Type * base)3329 void ENET_Ptp1588IRQHandler(ENET_Type *base)
3330 {
3331     uint32_t instance = ENET_GetInstance(base);
3332 
3333 #if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
3334     /* In some platforms, the 1588 event uses same irq with timestamp event. */
3335     if ((s_enetTsIrqId[instance] == s_enet1588TimerIrqId[instance]) && (s_enetTsIrqId[instance] != NotAvail_IRQn))
3336     {
3337         uint32_t event = base->EIR;
3338         event &= base->EIMR;
3339         if (0U != (event & ((uint32_t)kENET_TsTimerInterrupt | (uint32_t)kENET_TsAvailInterrupt)))
3340         {
3341             if (s_enetTsIsr[instance] != NULL)
3342             {
3343                 s_enetTsIsr[instance](base, s_ENETHandle[instance]);
3344             }
3345         }
3346     }
3347 #endif
3348 
3349     if (s_enet1588TimerIsr[instance] != NULL)
3350     {
3351         s_enet1588TimerIsr[instance](base, s_ENETHandle[instance]);
3352     }
3353 }
3354 
3355 #if defined(ENET)
3356 #if FSL_FEATURE_ENET_QUEUE < 2
3357 void ENET_TxIRQHandler(ENET_Type *base);
ENET_TxIRQHandler(ENET_Type * base)3358 void ENET_TxIRQHandler(ENET_Type *base)
3359 {
3360     uint32_t instance = ENET_GetInstance(base);
3361 
3362     if (s_enetTxIsr[instance] != NULL)
3363     {
3364         s_enetTxIsr[instance](base, s_ENETHandle[instance]);
3365     }
3366     SDK_ISR_EXIT_BARRIER;
3367 }
3368 
3369 void ENET_RxIRQHandler(ENET_Type *base);
ENET_RxIRQHandler(ENET_Type * base)3370 void ENET_RxIRQHandler(ENET_Type *base)
3371 {
3372     uint32_t instance = ENET_GetInstance(base);
3373 
3374     if (s_enetRxIsr[instance] != NULL)
3375     {
3376         s_enetRxIsr[instance](base, s_ENETHandle[instance]);
3377     }
3378 }
3379 
3380 void ENET_ErrIRQHandler(ENET_Type *base);
ENET_ErrIRQHandler(ENET_Type * base)3381 void ENET_ErrIRQHandler(ENET_Type *base)
3382 {
3383     uint32_t instance = ENET_GetInstance(base);
3384 
3385     if (s_enetErrIsr[instance] != NULL)
3386     {
3387         s_enetErrIsr[instance](base, s_ENETHandle[instance]);
3388     }
3389 }
3390 
3391 void ENET_Transmit_DriverIRQHandler(void);
ENET_Transmit_DriverIRQHandler(void)3392 void ENET_Transmit_DriverIRQHandler(void)
3393 {
3394     ENET_TxIRQHandler(ENET);
3395     SDK_ISR_EXIT_BARRIER;
3396 }
3397 
3398 void ENET_Receive_DriverIRQHandler(void);
ENET_Receive_DriverIRQHandler(void)3399 void ENET_Receive_DriverIRQHandler(void)
3400 {
3401     ENET_RxIRQHandler(ENET);
3402     SDK_ISR_EXIT_BARRIER;
3403 }
3404 
3405 void ENET_Error_DriverIRQHandler(void);
ENET_Error_DriverIRQHandler(void)3406 void ENET_Error_DriverIRQHandler(void)
3407 {
3408     ENET_ErrIRQHandler(ENET);
3409     SDK_ISR_EXIT_BARRIER;
3410 }
3411 #else
3412 
3413 void ENET_MAC0_Rx_Tx_Done1_DriverIRQHandler(void);
ENET_MAC0_Rx_Tx_Done1_DriverIRQHandler(void)3414 void ENET_MAC0_Rx_Tx_Done1_DriverIRQHandler(void)
3415 {
3416     ENET_CommonFrame1IRQHandler(ENET);
3417     SDK_ISR_EXIT_BARRIER;
3418 }
3419 void ENET_MAC0_Rx_Tx_Done2_DriverIRQHandler(void);
ENET_MAC0_Rx_Tx_Done2_DriverIRQHandler(void)3420 void ENET_MAC0_Rx_Tx_Done2_DriverIRQHandler(void)
3421 {
3422     ENET_CommonFrame2IRQHandler(ENET);
3423     SDK_ISR_EXIT_BARRIER;
3424 }
3425 #endif
3426 
3427 void ENET_DriverIRQHandler(void);
ENET_DriverIRQHandler(void)3428 void ENET_DriverIRQHandler(void)
3429 {
3430     ENET_CommonFrame0IRQHandler(ENET);
3431     SDK_ISR_EXIT_BARRIER;
3432 }
3433 
3434 void ENET_1588_Timer_DriverIRQHandler(void);
ENET_1588_Timer_DriverIRQHandler(void)3435 void ENET_1588_Timer_DriverIRQHandler(void)
3436 {
3437     ENET_Ptp1588IRQHandler(ENET);
3438     SDK_ISR_EXIT_BARRIER;
3439 }
3440 
3441 void ENET_TIMER_DriverIRQHandler(void);
ENET_TIMER_DriverIRQHandler(void)3442 void ENET_TIMER_DriverIRQHandler(void)
3443 {
3444     ENET_Ptp1588IRQHandler(ENET);
3445     SDK_ISR_EXIT_BARRIER;
3446 }
3447 #endif /* ENET */
3448 
3449 #if defined(ENET1)
3450 void ENET1_DriverIRQHandler(void);
ENET1_DriverIRQHandler(void)3451 void ENET1_DriverIRQHandler(void)
3452 {
3453     ENET_CommonFrame0IRQHandler(ENET1);
3454     SDK_ISR_EXIT_BARRIER;
3455 }
3456 #endif /* ENET1 */
3457 
3458 #if defined(ENET2)
3459 void ENET2_DriverIRQHandler(void);
ENET2_DriverIRQHandler(void)3460 void ENET2_DriverIRQHandler(void)
3461 {
3462     ENET_CommonFrame0IRQHandler(ENET2);
3463     SDK_ISR_EXIT_BARRIER;
3464 }
3465 
3466 void ENET2_1588_Timer_DriverIRQHandler(void);
ENET2_1588_Timer_DriverIRQHandler(void)3467 void ENET2_1588_Timer_DriverIRQHandler(void)
3468 {
3469     ENET_Ptp1588IRQHandler(ENET2);
3470     SDK_ISR_EXIT_BARRIER;
3471 }
3472 #endif /* ENET2 */
3473 
3474 #if defined(CONNECTIVITY__ENET0)
3475 void CONNECTIVITY_ENET0_FRAME0_EVENT_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET0_FRAME0_EVENT_INT_DriverIRQHandler(void)3476 void CONNECTIVITY_ENET0_FRAME0_EVENT_INT_DriverIRQHandler(void)
3477 {
3478     ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET0);
3479     SDK_ISR_EXIT_BARRIER;
3480 }
3481 #if FSL_FEATURE_ENET_QUEUE > 1
3482 void CONNECTIVITY_ENET0_FRAME1_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET0_FRAME1_INT_DriverIRQHandler(void)3483 void CONNECTIVITY_ENET0_FRAME1_INT_DriverIRQHandler(void)
3484 {
3485     ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET0);
3486     SDK_ISR_EXIT_BARRIER;
3487 }
3488 void CONNECTIVITY_ENET0_FRAME2_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET0_FRAME2_INT_DriverIRQHandler(void)3489 void CONNECTIVITY_ENET0_FRAME2_INT_DriverIRQHandler(void)
3490 {
3491     ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET0);
3492     SDK_ISR_EXIT_BARRIER;
3493 }
3494 void CONNECTIVITY_ENET0_TIMER_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET0_TIMER_INT_DriverIRQHandler(void)3495 void CONNECTIVITY_ENET0_TIMER_INT_DriverIRQHandler(void)
3496 {
3497     ENET_Ptp1588IRQHandler(CONNECTIVITY__ENET0);
3498     SDK_ISR_EXIT_BARRIER;
3499 }
3500 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3501 #endif /* CONNECTIVITY__ENET0 */
3502 #if defined(CONNECTIVITY__ENET1)
3503 void CONNECTIVITY_ENET1_FRAME0_EVENT_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET1_FRAME0_EVENT_INT_DriverIRQHandler(void)3504 void CONNECTIVITY_ENET1_FRAME0_EVENT_INT_DriverIRQHandler(void)
3505 {
3506     ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET1);
3507     SDK_ISR_EXIT_BARRIER;
3508 }
3509 #if FSL_FEATURE_ENET_QUEUE > 1
3510 void CONNECTIVITY_ENET1_FRAME1_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET1_FRAME1_INT_DriverIRQHandler(void)3511 void CONNECTIVITY_ENET1_FRAME1_INT_DriverIRQHandler(void)
3512 {
3513     ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET1);
3514     SDK_ISR_EXIT_BARRIER;
3515 }
3516 void CONNECTIVITY_ENET1_FRAME2_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET1_FRAME2_INT_DriverIRQHandler(void)3517 void CONNECTIVITY_ENET1_FRAME2_INT_DriverIRQHandler(void)
3518 {
3519     ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET1);
3520     SDK_ISR_EXIT_BARRIER;
3521 }
3522 void CONNECTIVITY_ENET1_TIMER_INT_DriverIRQHandler(void);
CONNECTIVITY_ENET1_TIMER_INT_DriverIRQHandler(void)3523 void CONNECTIVITY_ENET1_TIMER_INT_DriverIRQHandler(void)
3524 {
3525     ENET_Ptp1588IRQHandler(CONNECTIVITY__ENET1);
3526     SDK_ISR_EXIT_BARRIER;
3527 }
3528 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3529 #endif /* CONNECTIVITY__ENET1 */
3530 #if FSL_FEATURE_ENET_QUEUE > 1
3531 #if defined(ENET_1G)
3532 void ENET_1G_DriverIRQHandler(void);
ENET_1G_DriverIRQHandler(void)3533 void ENET_1G_DriverIRQHandler(void)
3534 {
3535     ENET_CommonFrame0IRQHandler(ENET_1G);
3536     SDK_ISR_EXIT_BARRIER;
3537 }
3538 void ENET_1G_MAC0_Tx_Rx_1_DriverIRQHandler(void);
ENET_1G_MAC0_Tx_Rx_1_DriverIRQHandler(void)3539 void ENET_1G_MAC0_Tx_Rx_1_DriverIRQHandler(void)
3540 {
3541     ENET_CommonFrame1IRQHandler(ENET_1G);
3542     SDK_ISR_EXIT_BARRIER;
3543 }
3544 void ENET_1G_MAC0_Tx_Rx_2_DriverIRQHandler(void);
ENET_1G_MAC0_Tx_Rx_2_DriverIRQHandler(void)3545 void ENET_1G_MAC0_Tx_Rx_2_DriverIRQHandler(void)
3546 {
3547     ENET_CommonFrame2IRQHandler(ENET_1G);
3548     SDK_ISR_EXIT_BARRIER;
3549 }
3550 void ENET_1G_1588_Timer_DriverIRQHandler(void);
ENET_1G_1588_Timer_DriverIRQHandler(void)3551 void ENET_1G_1588_Timer_DriverIRQHandler(void)
3552 {
3553     ENET_Ptp1588IRQHandler(ENET_1G);
3554     SDK_ISR_EXIT_BARRIER;
3555 }
3556 #endif /* ENET_1G */
3557 
3558 #if defined(ENET1)
3559 void ENET1_MAC0_Rx_Tx_Done1_DriverIRQHandler(void);
ENET1_MAC0_Rx_Tx_Done1_DriverIRQHandler(void)3560 void ENET1_MAC0_Rx_Tx_Done1_DriverIRQHandler(void)
3561 {
3562     ENET_CommonFrame1IRQHandler(ENET1);
3563     SDK_ISR_EXIT_BARRIER;
3564 }
3565 void ENET1_MAC0_Rx_Tx_Done2_DriverIRQHandler(void);
ENET1_MAC0_Rx_Tx_Done2_DriverIRQHandler(void)3566 void ENET1_MAC0_Rx_Tx_Done2_DriverIRQHandler(void)
3567 {
3568     ENET_CommonFrame2IRQHandler(ENET1);
3569     SDK_ISR_EXIT_BARRIER;
3570 }
3571 void ENET1_1588_Timer_DriverIRQHandler(void);
ENET1_1588_Timer_DriverIRQHandler(void)3572 void ENET1_1588_Timer_DriverIRQHandler(void)
3573 {
3574     ENET_Ptp1588IRQHandler(ENET1);
3575     SDK_ISR_EXIT_BARRIER;
3576 }
3577 #endif /* ENET1 */
3578 #endif /* FSL_FEATURE_ENET_QUEUE > 1 */
3579