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