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