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