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