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