1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2023 NXP
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef _FSL_ENET_H_
8 #define _FSL_ENET_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup lpc_enet
14  * @{
15  */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*! @name Driver version */
22 /*@{*/
23 /*! @brief Defines the driver version. */
24 #define FSL_ENET_DRIVER_VERSION (MAKE_VERSION(2, 3, 2))
25 /*@}*/
26 
27 /*! @name Control and status region bit masks of the receive buffer descriptor. */
28 /*@{*/
29 /*! @brief Defines for read format. */
30 #define ENET_RXDESCRIP_RD_BUFF1VALID_MASK (1UL << 24) /*!< Buffer1 address valid. */
31 #define ENET_RXDESCRIP_RD_BUFF2VALID_MASK (1UL << 25) /*!< Buffer2 address valid. */
32 #define ENET_RXDESCRIP_RD_IOC_MASK        (1UL << 30) /*!< Interrupt enable on complete. */
33 #define ENET_RXDESCRIP_RD_OWN_MASK        (1UL << 31) /*!< Own bit. */
34 
35 /*! @brief Defines for write back format. */
36 #define ENET_RXDESCRIP_WR_ERR_MASK        ((1UL << 3) | (1UL << 7))
37 #define ENET_RXDESCRIP_WR_PYLOAD_MASK     (0x7U)
38 #define ENET_RXDESCRIP_WR_PTPMSGTYPE_MASK (0xF00U)
39 #define ENET_RXDESCRIP_WR_PTPTYPE_MASK    (1UL << 12)
40 #define ENET_RXDESCRIP_WR_PTPVERSION_MASK (1UL << 13)
41 #define ENET_RXDESCRIP_WR_PTPTSA_MASK     (1UL << 14)
42 #define ENET_RXDESCRIP_WR_PACKETLEN_MASK  (0x7FFFU)
43 #define ENET_RXDESCRIP_WR_ERRSUM_MASK     (1UL << 15)
44 #define ENET_RXDESCRIP_WR_TYPE_MASK       (0x30000U)
45 #define ENET_RXDESCRIP_WR_DE_MASK         (1UL << 19)
46 #define ENET_RXDESCRIP_WR_RE_MASK         (1UL << 20)
47 #define ENET_RXDESCRIP_WR_OE_MASK         (1UL << 21)
48 #define ENET_RXDESCRIP_WR_RS0V_MASK       (1UL << 25)
49 #define ENET_RXDESCRIP_WR_RS1V_MASK       (1UL << 26)
50 #define ENET_RXDESCRIP_WR_RS2V_MASK       (1UL << 27)
51 #define ENET_RXDESCRIP_WR_LD_MASK         (1UL << 28)
52 #define ENET_RXDESCRIP_WR_FD_MASK         (1UL << 29)
53 #define ENET_RXDESCRIP_WR_CTXT_MASK       (1UL << 30)
54 #define ENET_RXDESCRIP_WR_OWN_MASK        (1UL << 31)
55 /*@}*/
56 
57 /*! @name Control and status bit masks of the transmit buffer descriptor. */
58 /*@{*/
59 /*! @brief Defines for read format. */
60 #define ENET_TXDESCRIP_RD_BL1_MASK  (0x3fffU)
61 #define ENET_TXDESCRIP_RD_BL2_MASK  (ENET_TXDESCRIP_RD_BL1_MASK << 16)
62 #define ENET_TXDESCRIP_RD_BL1(n)    ((uint32_t)(n)&ENET_TXDESCRIP_RD_BL1_MASK)
63 #define ENET_TXDESCRIP_RD_BL2(n)    (((uint32_t)(n)&ENET_TXDESCRIP_RD_BL1_MASK) << 16)
64 #define ENET_TXDESCRIP_RD_TTSE_MASK (1UL << 30)
65 #define ENET_TXDESCRIP_RD_IOC_MASK  (1UL << 31)
66 
67 #define ENET_TXDESCRIP_RD_FL_MASK   (0x7FFFU)
68 #define ENET_TXDESCRIP_RD_FL(n)     ((uint32_t)(n)&ENET_TXDESCRIP_RD_FL_MASK)
69 #define ENET_TXDESCRIP_RD_CIC(n)    (((uint32_t)(n)&0x3U) << 16)
70 #define ENET_TXDESCRIP_RD_TSE_MASK  (1UL << 18)
71 #define ENET_TXDESCRIP_RD_SLOT(n)   (((uint32_t)(n)&0x0fU) << 19)
72 #define ENET_TXDESCRIP_RD_SAIC(n)   (((uint32_t)(n)&0x07U) << 23)
73 #define ENET_TXDESCRIP_RD_CPC(n)    (((uint32_t)(n)&0x03U) << 26)
74 #define ENET_TXDESCRIP_RD_LDFD(n)   (((uint32_t)(n)&0x03U) << 28)
75 #define ENET_TXDESCRIP_RD_LD_MASK   (1UL << 28)
76 #define ENET_TXDESCRIP_RD_FD_MASK   (1UL << 29)
77 #define ENET_TXDESCRIP_RD_CTXT_MASK (1UL << 30)
78 #define ENET_TXDESCRIP_RD_OWN_MASK  (1UL << 31)
79 
80 /*! @brief Defines for write back format. */
81 #define ENET_TXDESCRIP_WB_TTSS_MASK (1UL << 17)
82 /*@}*/
83 
84 /*! @name Bit mask for interrupt enable type. */
85 /*@{*/
86 #define ENET_ABNORM_INT_MASK                                                      \
87     (ENET_DMA_CH_DMA_CHX_INT_EN_TSE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_RBUE_MASK | \
88      ENET_DMA_CH_DMA_CHX_INT_EN_RSE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_RWTE_MASK | \
89      ENET_DMA_CH_DMA_CHX_INT_EN_FBEE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_ETIE_MASK)
90 #define ENET_NORM_INT_MASK                                                        \
91     (ENET_DMA_CH_DMA_CHX_INT_EN_TIE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_TBUE_MASK | \
92      ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_ERIE_MASK)
93 /*@}*/
94 
95 /*! @name Defines some Ethernet parameters. */
96 /*@{*/
97 #define ENET_FRAME_MAX_FRAMELEN      (1518U) /*!< Default maximum ethernet frame size. */
98 #define ENET_FCS_LEN                 (4U)    /*!< Ethernet Rx frame FCS length. */
99 #define ENET_ADDR_ALIGNMENT          (0x3U)  /*!< Recommended ethernet buffer alignment. */
100 #define ENET_BUFF_ALIGNMENT          (4U)    /*!< Receive buffer alignment shall be 4bytes-aligned. */
101 #define ENET_RING_NUM_MAX            (2U)    /*!< The maximum number of Tx/Rx descriptor rings. */
102 #define ENET_MTL_RXFIFOSIZE          (2048U) /*!< The Rx fifo size. */
103 #define ENET_MTL_TXFIFOSIZE          (2048U) /*!< The Tx fifo size. */
104 #define ENET_MACINT_ENUM_OFFSET      (16U)   /*!< The offset for mac interrupt in enum type. */
105 #define ENET_FRAME_TX_LEN_LIMITATION (ENET_TXDESCRIP_RD_BL1_MASK) /*!< The Tx frame length software limitation. */
106 #define ENET_FRAME_RX_ERROR_BITS(x)  (((x) >> 19U) & 0x3FU)       /*!< The Rx frame error bits field. */
107 /*@}*/
108 
109 /*! @brief Defines the status return codes for transaction. */
110 enum
111 {
112     kStatus_ENET_InitMemoryFail =
113         MAKE_STATUS(kStatusGroup_ENET, 0U), /*!< Status code 4000. Init failed since buffer memory was not enough. */
114     kStatus_ENET_RxFrameError =
115         MAKE_STATUS(kStatusGroup_ENET, 1U), /*!< Status code 4001. A frame received but data error occurred. */
116     kStatus_ENET_RxFrameFail  = MAKE_STATUS(kStatusGroup_ENET, 2U), /*!< Status code 4002. Failed to receive a frame. */
117     kStatus_ENET_RxFrameEmpty = MAKE_STATUS(kStatusGroup_ENET, 3U), /*!< Status code 4003. No frame arrived. */
118     kStatus_ENET_RxFrameDrop  = MAKE_STATUS(
119         kStatusGroup_ENET, 4U), /*!< Status code 4004. Rx frame was dropped since there's no buffer memory. */
120     kStatus_ENET_TxFrameBusy =
121         MAKE_STATUS(kStatusGroup_ENET, 5U), /*!< Status code 4005. There were no resources for Tx operation. */
122     kStatus_ENET_TxFrameFail = MAKE_STATUS(kStatusGroup_ENET, 6U), /*!< Status code 4006. Transmit frame failed. */
123     kStatus_ENET_TxFrameOverLen =
124         MAKE_STATUS(kStatusGroup_ENET, 7U) /*!< Status code 4007. Failed to send an oversize frame. */
125 };
126 
127 /*! @brief Defines the MII/RMII mode for data interface between the MAC and the PHY. */
128 typedef enum _enet_mii_mode
129 {
130     kENET_MiiMode  = 0U, /*!< MII mode for data interface. */
131     kENET_RmiiMode = 1U  /*!< RMII mode for data interface. */
132 } enet_mii_mode_t;
133 
134 /*! @brief Defines the 10/100 Mbps speed for the MII data interface. */
135 typedef enum _enet_mii_speed
136 {
137     kENET_MiiSpeed10M  = 0U, /*!< Speed 10 Mbps. */
138     kENET_MiiSpeed100M = 1U, /*!< Speed 100 Mbps. */
139 } enet_mii_speed_t;
140 
141 /*! @brief Defines the half or full duplex for the MII data interface. */
142 typedef enum _enet_mii_duplex
143 {
144     kENET_MiiHalfDuplex = 0U, /*!< Half duplex mode. */
145     kENET_MiiFullDuplex       /*!< Full duplex mode. */
146 } enet_mii_duplex_t;
147 
148 /*! @brief Define the MII opcode for normal MDIO_CLAUSES_22 Frame. */
149 typedef enum _enet_mii_normal_opcode
150 {
151     kENET_MiiWriteFrame = 1U, /*!< Write frame operation for a valid MII management frame. */
152     kENET_MiiReadFrame  = 3U  /*!< Read frame operation for a valid MII management frame. */
153 } enet_mii_normal_opcode_t;
154 
155 /*! @brief Define the DMA maximum transmit burst length. */
156 typedef enum _enet_dma_burstlen
157 {
158     kENET_BurstLen1   = 0x00001U, /*!< DMA burst length 1. */
159     kENET_BurstLen2   = 0x00002U, /*!< DMA burst length 2. */
160     kENET_BurstLen4   = 0x00004U, /*!< DMA burst length 4. */
161     kENET_BurstLen8   = 0x00008U, /*!< DMA burst length 8. */
162     kENET_BurstLen16  = 0x00010U, /*!< DMA burst length 16. */
163     kENET_BurstLen32  = 0x00020U, /*!< DMA burst length 32. */
164     kENET_BurstLen64  = 0x10008U, /*!< DMA burst length 64. eight times enabled. */
165     kENET_BurstLen128 = 0x10010U, /*!< DMA burst length 128. eight times enabled. */
166     kENET_BurstLen256 = 0x10020U, /*!< DMA burst length 256. eight times enabled. */
167 } enet_dma_burstlen_t;
168 
169 /*! @brief Define the flag for the descriptor. */
170 typedef enum _enet_desc_flag
171 {
172     kENET_MiddleFlag = 0, /*!< It's a middle descriptor of the frame. */
173     kENET_LastFlagOnly,   /*!< It's the last descriptor of the frame. */
174     kENET_FirstFlagOnly,  /*!< It's the first descriptor of the frame. */
175     kENET_FirstLastFlag   /*!< It's the first and last descriptor of the frame. */
176 } enet_desc_flag_t;
177 
178 /*! @brief Define the system time adjust operation control. */
179 typedef enum _enet_systime_op
180 {
181     kENET_SystimeAdd      = 0U, /*!< System time add to. */
182     kENET_SystimeSubtract = 1U  /*!< System time subtract. */
183 } enet_systime_op_t;
184 
185 /*! @brief Define the system time rollover control. */
186 typedef enum _enet_ts_rollover_type
187 {
188     kENET_BinaryRollover  = 0, /*!< System time binary rollover.*/
189     kENET_DigitalRollover = 1  /*!< System time digital rollover.*/
190 } enet_ts_rollover_type_t;
191 
192 /*! @brief Defines some special configuration for ENET.
193  *
194  * These control flags are provided for special user requirements.
195  * Normally, these is no need to set this control flags for ENET initialization.
196  * But if you have some special requirements, set the flags to specialControl
197  * in the enet_config_t.
198  * @note "kENET_StoreAndForward" is recommended to be set when the
199  * ENET_PTP1588FEATURE_REQUIRED is defined or else the timestamp will be mess-up
200  * when the overflow happens.
201  */
202 typedef enum _enet_special_config
203 {
204     /***********************DMA CONFGI**********************************************/
205     kENET_DescDoubleBuffer = 0x0001U, /*!< The double buffer is used in the Tx/Rx descriptor. */
206     /**************************MTL************************************/
207     kENET_StoreAndForward = 0x0002U, /*!< The Rx/Tx store and forward enable. */
208     /***********************MAC****************************************/
209     kENET_PromiscuousEnable       = 0x0004U, /*!< The promiscuous enabled. */
210     kENET_FlowControlEnable       = 0x0008U, /*!< The flow control enabled. */
211     kENET_BroadCastRxDisable      = 0x0010U, /*!< The broadcast disabled. */
212     kENET_MulticastAllEnable      = 0x0020U, /*!< All multicast are passed. */
213     kENET_8023AS2KPacket          = 0x0040U, /*!< 8023as support for 2K packets. */
214     kENET_RxChecksumOffloadEnable = 0x0080U, /*!< The Rx checksum offload enabled. */
215 } enet_special_config_t;
216 
217 /*! @brief List of DMA interrupts supported by the ENET interrupt. This
218  * enumeration uses one-hot encoding to allow a logical OR of multiple
219  * members.
220  */
221 typedef enum _enet_dma_interrupt_enable
222 {
223     kENET_DmaTx                = ENET_DMA_CH_DMA_CHX_INT_EN_TIE_MASK,  /*!< Tx interrupt. */
224     kENET_DmaTxStop            = ENET_DMA_CH_DMA_CHX_INT_EN_TSE_MASK,  /*!< Tx stop interrupt. */
225     kENET_DmaTxBuffUnavail     = ENET_DMA_CH_DMA_CHX_INT_EN_TBUE_MASK, /*!< Tx buffer unavailable. */
226     kENET_DmaRx                = ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK,  /*!< Rx interrupt. */
227     kENET_DmaRxBuffUnavail     = ENET_DMA_CH_DMA_CHX_INT_EN_RBUE_MASK, /*!< Rx buffer unavailable. */
228     kENET_DmaRxStop            = ENET_DMA_CH_DMA_CHX_INT_EN_RSE_MASK,  /*!< Rx stop. */
229     kENET_DmaRxWatchdogTimeout = ENET_DMA_CH_DMA_CHX_INT_EN_RWTE_MASK, /*!< Rx watchdog timeout. */
230     kENET_DmaEarlyTx           = ENET_DMA_CH_DMA_CHX_INT_EN_ETIE_MASK, /*!< Early transmit. */
231     kENET_DmaEarlyRx           = ENET_DMA_CH_DMA_CHX_INT_EN_ERIE_MASK, /*!< Early receive. */
232     kENET_DmaBusErr            = ENET_DMA_CH_DMA_CHX_INT_EN_FBEE_MASK, /*!< Fatal bus error. */
233 } enet_dma_interrupt_enable_t;
234 
235 /*! @brief List of mac interrupts supported by the ENET interrupt. This
236  * enumeration uses one-hot encoding to allow a logical OR of multiple
237  * members.
238  */
239 typedef enum _enet_mac_interrupt_enable
240 {
241     kENET_MacPmt       = (ENET_MAC_INTR_EN_PMTIE_MASK << ENET_MACINT_ENUM_OFFSET),
242     kENET_MacTimestamp = (ENET_MAC_INTR_EN_TSIE_MASK << ENET_MACINT_ENUM_OFFSET),
243 } enet_mac_interrupt_enable_t;
244 
245 /*! @brief Defines the common interrupt event for callback use. */
246 typedef enum _enet_event
247 {
248     kENET_RxIntEvent,        /*!< Receive interrupt event. */
249     kENET_TxIntEvent,        /*!< Transmit interrupt event. */
250     kENET_WakeUpIntEvent,    /*!< Wake up interrupt event. */
251     kENET_TimeStampIntEvent, /*!< Time stamp interrupt event. */
252 } enet_event_t;
253 
254 /*! @brief Define the DMA transmit arbitration for multi-queue. */
255 typedef enum _enet_dma_tx_sche
256 {
257     kENET_FixPri = 0,      /*!< Fixed priority. channel 0 has lower priority than channel 1. */
258     kENET_WeightStrPri,    /*!< Weighted(burst length) strict priority. */
259     kENET_WeightRoundRobin /*!< Weighted (weight factor) round robin. */
260 } enet_dma_tx_sche_t;
261 
262 /*! @brief Define the MTL Tx scheduling algorithm for multiple queues/rings. */
263 typedef enum _enet_mtl_multiqueue_txsche
264 {
265     kENET_txWeightRR = 0U, /*!< Tx weight round-robin. */
266     kENET_txStrPrio  = 3U, /*!< Tx strict priority. */
267 } enet_mtl_multiqueue_txsche_t;
268 
269 /*! @brief Define the MTL Rx scheduling algorithm for multiple queues/rings. */
270 typedef enum _enet_mtl_multiqueue_rxsche
271 {
272     kENET_rxStrPrio = 0U,  /*!< Tx weight round-robin, Rx strict priority. */
273     kENET_rxWeightStrPrio, /*!< Tx strict priority, Rx weight strict priority. */
274 } enet_mtl_multiqueue_rxsche_t;
275 
276 /*! @brief Define the MTL Rx queue and DMA channel mapping. */
277 typedef enum _enet_mtl_rxqueuemap
278 {
279     kENET_StaticDirctMap = 0x100U, /*!< The received fame in Rx Qn(n = 0,1) direclty map to dma channel n. */
280     kENET_DynamicMap =
281         0x1010U, /*!< The received frame in Rx Qn(n = 0,1) map to the dma channel m(m = 0,1) related with the same Mac.
282                   */
283 } enet_mtl_rxqueuemap_t;
284 
285 /*! @brief Defines the ENET PTP message related constant. */
286 typedef enum _enet_ptp_event_type
287 {
288     kENET_PtpEventMsgType = 3U,   /*!< PTP event message type. */
289     kENET_PtpSrcPortIdLen = 10U,  /*!< PTP message sequence id length. */
290     kENET_PtpEventPort    = 319U, /*!< PTP event port number. */
291     kENET_PtpGnrlPort     = 320U  /*!< PTP general port number. */
292 } enet_ptp_event_type_t;
293 
294 /*! @brief Define the Tx checksum offload options. */
295 typedef enum _enet_tx_offload
296 {
297     kENET_TxOffloadDisable             = 0U, /*!< Disable Tx checksum offload. */
298     kENET_TxOffloadIPHeader            = 1U, /*!< Enable IP header checksum calculation and insertion. */
299     kENET_TxOffloadIPHeaderPlusPayload = 2U, /*!< Enable IP header and payload checksum calculation and insertion. */
300     kENET_TxOffloadAll = 3U, /*!< Enable IP header, payload and pseudo header checksum calculation and insertion. */
301 } enet_tx_offload_t;
302 
303 /*! @brief Defines the receive descriptor structure
304  *  It has the read-format and write-back format structures. They both
305  *  have the same size with different region definition. So we define
306  *  common name as the recive descriptor structure. When initialize
307  *  the buffer descriptors, read-format region mask bits should be used.
308  *  When Rx frame has been in the buffer descriptors, write-back format
309  *  region store the Rx result information.
310  */
311 typedef struct _enet_rx_bd_struct
312 {
313     __IO uint32_t rdes0; /*!< Receive descriptor 0 */
314     __IO uint32_t rdes1; /*!< Receive descriptor 1 */
315     __IO uint32_t rdes2; /*!< Receive descriptor 2 */
316     __IO uint32_t rdes3; /*!< Receive descriptor 3 */
317 } enet_rx_bd_struct_t;
318 
319 /*! @brief Defines the transmit descriptor structure
320  *  It has the read-format and write-back format structure. They both
321  *  has the same size with different region definition.  So we define
322  *  common name as the transmit descriptor structure. When initialize
323  *  the buffer descriptors for Tx, read-format region mask bits should
324  *  be used. When frame has been transmitted, write-back format region
325  *  store the Tx result information.
326  */
327 typedef struct _enet_tx_bd_struct
328 {
329     __IO uint32_t tdes0; /*!< Transmit descriptor 0 */
330     __IO uint32_t tdes1; /*!< Transmit descriptor 1 */
331     __IO uint32_t tdes2; /*!< Transmit descriptor 2 */
332     __IO uint32_t tdes3; /*!< Transmit descriptor 3 */
333 } enet_tx_bd_struct_t;
334 
335 /*! @brief Defines the Tx BD configuration structure. */
336 typedef struct _enet_tx_bd_config_struct
337 {
338     void *buffer1;                  /*!< The first buffer address in the descriptor. */
339     uint32_t bytes1;                /*!< The bytes in the fist buffer. */
340     void *buffer2;                  /*!< The second buffer address in the descriptor. */
341     uint32_t bytes2;                /*!< The bytes in the second buffer. */
342     uint32_t framelen;              /*!< The length of the frame to be transmitted. */
343     bool intEnable;                 /*!< Interrupt enable flag. */
344     bool tsEnable;                  /*!< The timestamp enable. */
345     enet_tx_offload_t txOffloadOps; /*!< The Tx checksum offload option, only vaild for Queue 0. */
346     enet_desc_flag_t flag;          /*!< The flag of this tx desciriptor, see "enet_qos_desc_flag". */
347     uint8_t slotNum;                /*!< The slot number used for AV mode only. */
348 } enet_tx_bd_config_struct_t;
349 
350 #ifdef ENET_PTP1588FEATURE_REQUIRED
351 /*! @brief Defines the ENET PTP configuration structure. */
352 typedef struct _enet_ptp_config
353 {
354     bool fineUpdateEnable;              /*!< Use the fine update. */
355     bool ptp1588V2Enable;               /*!< ptp 1588 version 2 is used. */
356     enet_ts_rollover_type_t tsRollover; /*!< 1588 time nanosecond rollover. */
357 } enet_ptp_config_t;
358 #endif /* ENET_PTP1588FEATURE_REQUIRED */
359 
360 /*! @brief Defines the ENET PTP time stamp structure. */
361 typedef struct _enet_ptp_time
362 {
363     uint64_t second;     /*!< Second. */
364     uint32_t nanosecond; /*!< Nanosecond. */
365 } enet_ptp_time_t;
366 
367 /*! @brief Defines the Tx reclaim information structure. */
368 typedef struct enet_tx_reclaim_info
369 {
370     void *context;             /*!< User specified data, could be buffer address for free */
371     bool isTsAvail;            /*!< Flag indicates timestamp available status */
372     enet_ptp_time_t timeStamp; /*!< Timestamp of frame */
373 } enet_tx_reclaim_info_t;
374 
375 /*! @brief Defines the ENET transmit dirty addresses ring/queue structure. */
376 typedef struct _enet_tx_dirty_ring
377 {
378     enet_tx_reclaim_info_t *txDirtyBase; /*!< Dirty buffer descriptor base address pointer. */
379     uint16_t txGenIdx;                   /*!< Tx generate index. */
380     uint16_t txConsumIdx;                /*!< Tx consume index. */
381     uint16_t txRingLen;                  /*!< Tx ring length. */
382     bool isFull;                         /*!< Tx ring is full flag, add this parameter to avoid waste one element. */
383 } enet_tx_dirty_ring_t;
384 
385 /*! @brief Defines the buffer descriptor configure structure.
386  *
387  * Notes:
388  * 1. The receive and transmit descriptor start address pointer and tail pointer must be word-aligned.
389  * 2. The recommended minimum Tx/Rx ring length is 4.
390  * 3. The Tx/Rx descriptor tail address shall be the address pointer to the address just after the end
391  *    of the last last descriptor. because only the descriptors between the start address and the
392  *    tail address will be used by DMA.
393  * 4. The decriptor address is the start address of all used contiguous memory.
394  *    for example, the rxDescStartAddrAlign is the start address of rxRingLen contiguous descriptor memorise
395  *    for Rx descriptor ring 0.
396  * 5. The "*rxBufferstartAddr" is the first element of  rxRingLen (2*rxRingLen for double buffers)
397  *    Rx buffers. It means the *rxBufferStartAddr is the Rx buffer for the first descriptor
398  *    the *rxBufferStartAddr + 1 is the Rx buffer for the second descriptor or the Rx buffer for
399  *    the second buffer in the first descriptor. So please make sure the rxBufferStartAddr is the
400  *    address of a rxRingLen or 2*rxRingLen array.
401  */
402 typedef struct _enet_buffer_config
403 {
404     uint8_t rxRingLen;                         /*!< The length of receive buffer descriptor ring. */
405     uint8_t txRingLen;                         /*!< The length of transmit buffer descriptor ring. */
406     enet_tx_bd_struct_t *txDescStartAddrAlign; /*!< Aligned transmit descriptor start address. */
407     enet_tx_bd_struct_t *txDescTailAddrAlign;  /*!< Aligned transmit descriptor tail address. */
408     enet_tx_reclaim_info_t *txDirtyStartAddr;  /*!< Start address of the dirty Tx frame information. */
409     enet_rx_bd_struct_t *rxDescStartAddrAlign; /*!< Aligned receive descriptor start address. */
410     enet_rx_bd_struct_t *rxDescTailAddrAlign;  /*!< Aligned receive descriptor tail address. */
411     uint32_t *rxBufferStartAddr;               /*!< Start address of the Rx buffers. */
412     uint32_t rxBuffSizeAlign;                  /*!< Aligned receive data buffer size. */
413 } enet_buffer_config_t;
414 
415 /*! @brief Defines the configuration when multi-queue is used. */
416 typedef struct enet_multiqueue_config
417 {
418     /***********************DMA block*******************************/
419     enet_dma_tx_sche_t dmaTxSche;              /*!< Transmit arbitation. */
420     enet_dma_burstlen_t burstLen;              /*!< Burset len for the queue 1. */
421     uint8_t txdmaChnWeight[ENET_RING_NUM_MAX]; /*!< Transmit channel weight. */
422     /***********************MTL block*******************************/
423     enet_mtl_multiqueue_txsche_t mtltxSche;  /*!< Transmit schedule for multi-queue. */
424     enet_mtl_multiqueue_rxsche_t mtlrxSche;  /*!< Receive schedule for multi-queue. */
425     uint8_t rxqueweight[ENET_RING_NUM_MAX];  /*!< Refer to the MTL RxQ Control register. */
426     uint32_t txqueweight[ENET_RING_NUM_MAX]; /*!< Refer to the MTL TxQ Quantum Weight register. */
427     uint8_t rxqueuePrio[ENET_RING_NUM_MAX];  /*!< Receive queue priority. */
428     uint8_t txqueuePrio[ENET_RING_NUM_MAX];  /*!< Refer to Transmit Queue Priority Mapping register. */
429     enet_mtl_rxqueuemap_t mtlrxQuemap;       /*!< Rx queue DMA Channel mapping. */
430 } enet_multiqueue_config_t;
431 
432 /*! @brief Defines the Rx memory buffer alloc function pointer. */
433 typedef void *(*enet_rx_alloc_callback_t)(ENET_Type *base, void *userData, uint8_t channel);
434 
435 /*! @brief Defines the Rx memory buffer free function pointer. */
436 typedef void (*enet_rx_free_callback_t)(ENET_Type *base, void *buffer, void *userData, uint8_t channel);
437 
438 /*! @brief Defines the basic configuration structure for the ENET device.
439  *
440  * Note:
441  *  1. Default the signal queue is used so the "multiqueueCfg" is set default
442  *  with NULL. Set the pointer with a valid configration pointer if the multiple
443  *  queues are required. If multiple queue is enabled, please make sure the
444  *  buffer configuration for all are prepared also.
445  */
446 typedef struct _enet_config
447 {
448     uint16_t specialControl;                 /*!< The logicl or of enet_special_config_t */
449     enet_multiqueue_config_t *multiqueueCfg; /*!< Use both Tx/Rx queue(dma channel) 0 and 1. */
450     uint32_t interrupt;                      /*!< MAC interrupt source. A logical OR of enet_dma_interrupt_enable_t and
451                                                 enet_mac_interrupt_enable_t. */
452     /* -----------------MAC block-------------------------------*/
453     enet_mii_mode_t miiMode;     /*!< MII mode. */
454     enet_mii_speed_t miiSpeed;   /*!< MII Speed. */
455     enet_mii_duplex_t miiDuplex; /*!< MII duplex. */
456     uint16_t pauseDuration; /*!< Used in the Tx flow control frame, only valid when kENET_FlowControlEnable is set. */
457     /* -----------------Timestamp-------------------------------*/
458 #ifdef ENET_PTP1588FEATURE_REQUIRED
459     enet_ptp_config_t *ptpConfig; /*!< PTP 1588 feature configuration */
460 #endif
461     /* -----------Rx zero copy buffer management----------------*/
462     enet_rx_alloc_callback_t rxBuffAlloc; /*!< Callback to alloc memory, must be provided for zero-copy Rx. */
463     enet_rx_free_callback_t rxBuffFree;   /*!< Callback to free memory, must be provided for zero-copy Rx. */
464 } enet_config_t;
465 
466 /* Forward declaration of the handle typedef. */
467 typedef struct _enet_handle enet_handle_t;
468 
469 /*! @brief ENET callback function. */
470 typedef void (*enet_callback_t)(ENET_Type *base,
471                                 enet_handle_t *handle,
472                                 enet_event_t event,
473                                 uint8_t channel,
474                                 enet_tx_reclaim_info_t *txReclaimInfo,
475                                 void *userData);
476 
477 /*! @brief Defines the ENET transmit buffer descriptor ring/queue structure. */
478 typedef struct _enet_tx_bd_ring
479 {
480     enet_tx_bd_struct_t *txBdBase; /*!< Buffer descriptor base address pointer. */
481     uint16_t txGenIdx;             /*!< Tx generate index. */
482     uint16_t txConsumIdx;          /*!< Tx consum index. */
483     volatile uint16_t txDescUsed;  /*!< Tx descriptor used number. */
484     uint16_t txRingLen;            /*!< Tx ring length. */
485 } enet_tx_bd_ring_t;
486 
487 /*! @brief Defines the ENET receive buffer descriptor ring/queue structure. */
488 typedef struct _enet_rx_bd_ring
489 {
490     enet_rx_bd_struct_t *rxBdBase; /*!< Buffer descriptor base address pointer. */
491     uint16_t rxGenIdx;             /*!< The current available receive buffer descriptor pointer. */
492     uint16_t rxRingLen;            /*!< Receive ring length. */
493     uint32_t rxBuffSizeAlign;      /*!< Receive buffer size. */
494 } enet_rx_bd_ring_t;
495 
496 /*! @brief Defines the ENET handler structure. */
497 struct _enet_handle
498 {
499     bool multiQueEnable;                                 /*!< Multi-queue enable status. */
500     bool doubleBuffEnable;                               /*!< The double buffer enable status. */
501     bool rxintEnable;                                    /*!< Rx interrupt enable status. */
502     enet_rx_bd_ring_t rxBdRing[ENET_RING_NUM_MAX];       /*!< Receive buffer descriptor.  */
503     enet_tx_bd_ring_t txBdRing[ENET_RING_NUM_MAX];       /*!< Transmit buffer descriptor.  */
504     enet_tx_dirty_ring_t txDirtyRing[ENET_RING_NUM_MAX]; /*!< Transmit dirty buffers addresses.  */
505     uint32_t *rxBufferStartAddr[ENET_RING_NUM_MAX];      /*!< The Init-Rx buffers used for reinit corrupted BD due to
506                                                             write-back operation. */
507     uint32_t txLenLimitation[ENET_RING_NUM_MAX];         /*!< Tx frame length limitation. */
508     enet_callback_t callback;                            /*!< Callback function. */
509     void *userData;                                      /*!< Callback function parameter.*/
510     enet_rx_alloc_callback_t rxBuffAlloc; /*!< Callback to alloc memory, must be provided for zero-copy Rx. */
511     enet_rx_free_callback_t rxBuffFree;   /*!< Callback to free memory, must be provided for zero-copy Rx. */
512 };
513 
514 typedef struct _enet_buffer_struct
515 {
516     void *buffer;    /*!< The buffer stores the whole or partial frame. */
517     uint16_t length; /*!< The byte length of this buffer. */
518 } enet_buffer_struct_t;
519 
520 /*! @brief Rx frame attribute structure. */
521 typedef struct _enet_rx_frame_attribute_struct
522 {
523     bool isTsAvail;            /*!< Rx frame timestamp is available or not. */
524     enet_ptp_time_t timestamp; /*!< The nanosecond part timestamp of this Rx frame. */
525 } enet_rx_frame_attribute_t;
526 
527 /*! @brief Defines the Rx frame error structure. */
528 typedef struct _enet_rx_frame_error
529 {
530     bool statsDribbleErr : 1;         /*!< The received packet has a non-integer multiple of bytes (odd nibbles). */
531     bool statsRxErr : 1;              /*!< Receive error. */
532     bool statsOverflowErr : 1;        /*!< Rx FIFO overflow error. */
533     bool statsWatchdogTimeoutErr : 1; /*!< Receive watchdog timeout. */
534     bool statsGaintPacketErr : 1;     /*!< Receive error. */
535     bool statsRxFcsErr : 1;           /*!< Receive CRC error. */
536 } enet_rx_frame_error_t;
537 
538 /*! @brief Defines the Rx frame data structure. */
539 typedef struct _enet_rx_frame_struct
540 {
541     enet_buffer_struct_t *rxBuffArray;     /*!< Rx frame buffer structure. */
542     uint16_t totLen;                       /*!< Rx frame total length. */
543     enet_rx_frame_attribute_t rxAttribute; /*!< Rx frame attribute structure. */
544     enet_rx_frame_error_t rxFrameError;    /*!< Rx frame error. */
545 } enet_rx_frame_struct_t;
546 
547 typedef struct _enet_tx_config_struct
548 {
549     uint8_t intEnable : 1;          /*!< Enable interrupt every time one BD is completed. */
550     uint8_t tsEnable : 1;           /*!< Transmit timestamp enable. */
551     uint8_t slotNum : 4;            /*!< Slot number control bits in AV mode. */
552     enet_tx_offload_t txOffloadOps; /*!< Tx checksum offload option. */
553 } enet_tx_config_struct_t;
554 
555 typedef struct _enet_tx_frame_struct
556 {
557     enet_buffer_struct_t *txBuffArray; /*!< Tx frame buffer structure. */
558     uint32_t txBuffNum;                /*!< Buffer number of this Tx frame. */
559     enet_tx_config_struct_t txConfig;  /*!< Tx extra configuation. */
560     void *context;                     /*!< Driver reclaims and gives it in Tx over callback. */
561 } enet_tx_frame_struct_t;
562 
563 /* Typedef for interrupt handler. */
564 typedef void (*enet_isr_t)(ENET_Type *base, enet_handle_t *handle);
565 
566 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
567 /*! @brief Pointers to enet clocks for each instance. */
568 extern const clock_ip_name_t s_enetClock[];
569 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
570 
571 /*******************************************************************************
572  * API
573  ******************************************************************************/
574 
575 #if defined(__cplusplus)
576 extern "C" {
577 #endif
578 
579 /*!
580  * @name Initialization and De-initialization
581  * @{
582  */
583 
584 /*!
585  * @brief Gets the ENET default configuration structure.
586  *
587  * The purpose of this API is to get the default ENET configure
588  * structure for ENET_Init(). User may use the initialized
589  * structure unchanged in ENET_Init(), or modify some fields of the
590  * structure before calling ENET_Init().
591  * Example:
592    @code
593    enet_config_t config;
594    ENET_GetDefaultConfig(&config);
595    @endcode
596  * @param config The ENET mac controller configuration structure pointer.
597  */
598 void ENET_GetDefaultConfig(enet_config_t *config);
599 
600 /*!
601  * @brief Initializes the ENET module.
602  *
603  * This function ungates the module clock and initializes it with the ENET basic
604  * configuration.
605  * @note As our transactional transmit API use the zero-copy transmit buffer.
606  * So there are two thing we emphasize here:
607  *  1. Tx buffer free/requeue for application should be done in the Tx
608  *  interrupt handler. Please set callback: kENET_TxIntEvent with Tx buffer free/requeue
609  *  process APIs.
610  *  2. The Tx interrupt is forced to open.
611  *
612  * @param base    ENET peripheral base address.
613  * @param config  ENET mac configuration structure pointer.
614  *        The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
615  *        can be used directly. It is also possible to verify the Mac configuration using other methods.
616  * @param macAddr  ENET mac address of Ethernet device. This MAC address should be
617  *        provided.
618  * @param refclkSrc_Hz ENET input reference clock.
619  */
620 void ENET_Init(ENET_Type *base, const enet_config_t *config, uint8_t *macAddr, uint32_t refclkSrc_Hz);
621 
622 /*!
623  * @brief Deinitializes the ENET module.
624 
625  * This function gates the module clock and disables the ENET module.
626  *
627  * @param base  ENET peripheral base address.
628  */
629 void ENET_Deinit(ENET_Type *base);
630 
631 /*!
632  * @brief Initialize for all ENET descriptors.
633  *
634  * @note This function finishes all Tx/Rx descriptors initialization. The descriptor initialization
635  * should be called after ENET_Init().
636  *
637  * @param base  ENET peripheral base address.
638  * @param config The configuration for ENET.
639  * @param bufferConfig All buffers configuration.
640  */
641 status_t ENET_DescriptorInit(ENET_Type *base, enet_config_t *config, enet_buffer_config_t *bufferConfig);
642 
643 /*!
644  * @brief Allocates Rx buffers for all BDs.
645  * It's used for zero copy Rx. In zero copy Rx case, Rx buffers are dynamic. This function
646  * will populate initial buffers in all BDs for receiving. Then ENET_GetRxFrame() is used
647  * to get Rx frame with zero copy, it will allocate new buffer to replace the buffer in BD taken
648  * by application, application should free those buffers after they're used.
649  *
650  * @note This function should be called after ENET_CreateHandler() and buffer allocating callback
651  * function should be ready.
652  *
653  * @param base  ENET peripheral base address.
654  * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
655  */
656 status_t ENET_RxBufferAllocAll(ENET_Type *base, enet_handle_t *handle);
657 
658 /*!
659  * @brief Frees Rx buffers in all BDs.
660  * It's used for zero copy Rx. In zero copy Rx case, Rx buffers are dynamic. This function
661  * will free left buffers in all BDs.
662  *
663  * @param base  ENET peripheral base address.
664  * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
665  */
666 void ENET_RxBufferFreeAll(ENET_Type *base, enet_handle_t *handle);
667 
668 /*!
669  * @brief Starts the ENET Tx/Rx.
670  * This function enable the Tx/Rx and starts the Tx/Rx DMA.
671  * This shall be set after ENET initialization and before
672  * starting to receive the data.
673  *
674  * @param base  ENET peripheral base address.
675  * @param rxRingNum  The number of the used Rx rings. It shall not be
676  * larger than the ENET_RING_NUM_MAX(2). If the ringNum is set with
677  * 1, the ring 0 will be used.
678  * @param txRingNum  The number of the used Tx rings. It shall not be
679  * larger than the ENET_RING_NUM_MAX(2). If the ringNum is set with
680  * 1, the ring 0 will be used.
681  *
682  * @note This must be called after all the ENET initilization.
683  * And should be called when the ENET receive/transmit is required.
684  */
685 void ENET_StartRxTx(ENET_Type *base, uint8_t txRingNum, uint8_t rxRingNum);
686 
687 /*!
688  * @brief Set the second level IRQ handler
689  *
690  * @param base ENET peripheral base address.
691  * @param ISRHandler The handler to install.
692  */
693 void ENET_SetISRHandler(ENET_Type *base, enet_isr_t ISRHandler);
694 
695 /* @} */
696 
697 /*!
698  * @name MII interface operation
699  * @{
700  */
701 
702 /*!
703  * @brief Sets the ENET MII speed and duplex.
704  *
705  * This API is provided to dynamically change the speed and dulpex for MAC.
706  *
707  * @param base  ENET peripheral base address.
708  * @param speed The speed of the RMII mode.
709  * @param duplex The duplex of the RMII mode.
710  */
ENET_SetMII(ENET_Type * base,enet_mii_speed_t speed,enet_mii_duplex_t duplex)711 static inline void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
712 {
713     uint32_t reg = base->MAC_CONFIG & ~(ENET_MAC_CONFIG_DM_MASK | ENET_MAC_CONFIG_FES_MASK);
714     reg |= ENET_MAC_CONFIG_DM(duplex) | ENET_MAC_CONFIG_FES(speed);
715 
716     base->MAC_CONFIG = reg;
717 }
718 
719 /*!
720  * @brief Sets the ENET SMI(serial management interface)- MII management interface.
721  *
722  * @param base  ENET peripheral base address.
723  */
724 void ENET_SetSMI(ENET_Type *base);
725 
726 /*!
727  * @brief Checks if the SMI is busy.
728  *
729  * @param base  ENET peripheral base address.
730  * @return The status of MII Busy status.
731  */
ENET_IsSMIBusy(ENET_Type * base)732 static inline bool ENET_IsSMIBusy(ENET_Type *base)
733 {
734     return ((base->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_MB_MASK) != 0U) ? true : false;
735 }
736 
737 /*!
738  * @brief Reads data from the PHY register through SMI interface.
739  *
740  * @param base  ENET peripheral base address.
741  * @return The data read from PHY
742  */
ENET_ReadSMIData(ENET_Type * base)743 static inline uint16_t ENET_ReadSMIData(ENET_Type *base)
744 {
745     return (uint16_t)(base->MAC_MDIO_DATA & ENET_MAC_MDIO_DATA_MD_MASK);
746 }
747 
748 /*!
749  * @brief Sends the MDIO IEEE802.3 Clause 22 format write command.
750  *
751  * @param base  ENET peripheral base address.
752  * @param phyAddr The PHY address.
753  * @param regAddr The PHY register.
754  * @param data The data written to PHY.
755  */
756 void ENET_StartSMIWrite(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data);
757 
758 /*!
759  * @brief Sends the MDIO IEEE802.3 Clause 22 format read command.
760  *
761  * @param base  ENET peripheral base address.
762  * @param phyAddr The PHY address.
763  * @param regAddr The PHY register.
764  */
765 void ENET_StartSMIRead(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr);
766 
767 /*!
768  * @brief MDIO write with IEEE802.3 Clause 22 format.
769  *
770  * @param base  ENET peripheral base address.
771  * @param phyAddr  The PHY address.
772  * @param regAddr  The PHY register.
773  * @param data  The data written to PHY.
774  * @return kStatus_Success  MDIO access succeeds.
775  * @return kStatus_Timeout  MDIO access timeout.
776  */
777 status_t ENET_MDIOWrite(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data);
778 
779 /*!
780  * @brief MDIO read with IEEE802.3 Clause 22 format.
781  *
782  * @param base  ENET peripheral base address.
783  * @param phyAddr  The PHY address.
784  * @param regAddr  The PHY register.
785  * @param pData  The data read from PHY.
786  * @return kStatus_Success  MDIO access succeeds.
787  * @return kStatus_Timeout  MDIO access timeout.
788  */
789 status_t ENET_MDIORead(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData);
790 /* @} */
791 
792 /*!
793  * @name Other basic operation
794  * @{
795  */
796 
797 /*!
798  * @brief Get the ENET instance from peripheral base address.
799  *
800  * @param base ENET peripheral base address.
801  * @return ENET instance.
802  */
803 uint32_t ENET_GetInstance(ENET_Type *base);
804 
805 /*!
806  * @brief Sets the ENET module Mac address.
807  *
808  * @param base  ENET peripheral base address.
809  * @param macAddr The six-byte Mac address pointer.
810  *        The pointer is allocated by application and input into the API.
811  */
ENET_SetMacAddr(ENET_Type * base,uint8_t * macAddr)812 static inline void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr)
813 {
814     assert(macAddr);
815 
816     uint32_t lowAddress = ((uint32_t)macAddr[3] << 24) | ((uint32_t)macAddr[2] << 16) | ((uint32_t)macAddr[1] << 8) |
817                           ((uint32_t)macAddr[0]);
818     uint32_t highAddress = ((uint32_t)macAddr[5] << 8) | ((uint32_t)macAddr[4]);
819     /* Set Macaddr, the MAC address registers are configured to be double-synchronized to the MII clock
820       domains, then the synchronization is triggered only when bits 31:24 (in little-endian mode)
821       or bits 7:0 (in Big-Endian mode) of the MAC address low register are written to.*/
822     base->MAC_ADDR_HIGH = highAddress;
823     base->MAC_ADDR_LOW  = lowAddress;
824 }
825 
826 /*!
827  * @brief Gets the ENET module Mac address.
828  *
829  * @param base  ENET peripheral base address.
830  * @param macAddr The six-byte Mac address pointer.
831  *        The pointer is allocated by application and input into the API.
832  */
833 void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr);
834 
835 /*!
836  * @brief Enable ENET device to accept all multicast frames.
837  *
838  * @param base    ENET peripheral base address.
839  */
ENET_AcceptAllMulticast(ENET_Type * base)840 static inline void ENET_AcceptAllMulticast(ENET_Type *base)
841 {
842     uint32_t reg = base->MAC_FRAME_FILTER;
843 
844     base->MAC_FRAME_FILTER = reg | ENET_MAC_FRAME_FILTER_PM_MASK;
845 }
846 
847 /*!
848  * @brief ENET device reject to accept all multicast frames.
849  *
850  * @param base  ENET peripheral base address.
851  */
ENET_RejectAllMulticast(ENET_Type * base)852 static inline void ENET_RejectAllMulticast(ENET_Type *base)
853 {
854     uint32_t reg = base->MAC_FRAME_FILTER;
855 
856     base->MAC_FRAME_FILTER = reg & ~ENET_MAC_FRAME_FILTER_PM_MASK;
857 }
858 
859 /*!
860  * @brief Set the MAC to enter into power down mode.
861  * the remote power wake up frame and magic frame can wake up
862  * the ENET from the power down mode.
863  *
864  * @param base    ENET peripheral base address.
865  * @param wakeFilter  The wakeFilter provided to configure the wake up frame fitlter.
866  *  Set the wakeFilter to NULL is not required. But if you have the filter requirement,
867  *  please make sure the wakeFilter pointer shall be eight continous
868  *  32-bits configuration.
869  */
870 void ENET_EnterPowerDown(ENET_Type *base, uint32_t *wakeFilter);
871 
872 /*!
873  * @brief Set the MAC to exit power down mode.
874  * Eixt from the power down mode and recover to normal work mode.
875  *
876  * @param base    ENET peripheral base address.
877  */
ENET_ExitPowerDown(ENET_Type * base)878 static inline void ENET_ExitPowerDown(ENET_Type *base)
879 {
880     /* Clear and status ans reset the power down. */
881     base->MAC_PMT_CRTL_STAT &= ~ENET_MAC_PMT_CRTL_STAT_PWRDWN_MASK;
882 
883     /* Restore the Tx which is disabled when enter power down mode. */
884     base->DMA_CH[0].DMA_CHX_TX_CTRL |= ENET_DMA_CH_DMA_CHX_TX_CTRL_ST_MASK;
885     base->DMA_CH[1].DMA_CHX_TX_CTRL |= ENET_DMA_CH_DMA_CHX_TX_CTRL_ST_MASK;
886     base->MAC_CONFIG |= ENET_MAC_CONFIG_TE_MASK;
887 }
888 
889 /* @} */
890 
891 /*!
892  * @name Interrupts.
893  * @{
894  */
895 
896 /*!
897  * @brief Enables the ENET DMA and MAC interrupts.
898  *
899  * This function enables the ENET interrupt according to the provided mask. The mask
900  * is a logical OR of enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t.
901  * For example, to enable the dma and mac interrupt, do the following.
902  * @code
903  *     ENET_EnableInterrupts(ENET, kENET_DmaRx | kENET_DmaTx | kENET_MacPmt);
904  * @endcode
905  *
906  * @param base  ENET peripheral base address.
907  * @param mask  ENET interrupts to enable. This is a logical OR of both
908  *             enumeration :: enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t.
909  */
910 void ENET_EnableInterrupts(ENET_Type *base, uint32_t mask);
911 
912 /*!
913  * @brief Disables the ENET DMA and MAC interrupts.
914  *
915  * This function disables the ENET interrupt according to the provided mask. The mask
916  * is a logical OR of enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t.
917  * For example, to disable the dma and mac interrupt, do the following.
918  * @code
919  *     ENET_DisableInterrupts(ENET, kENET_DmaRx | kENET_DmaTx | kENET_MacPmt);
920  * @endcode
921  *
922  * @param base  ENET peripheral base address.
923  * @param mask  ENET interrupts to disables. This is a logical OR of both
924  *             enumeration :: enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t.
925  */
926 void ENET_DisableInterrupts(ENET_Type *base, uint32_t mask);
927 
928 /*!
929  * @brief Gets the ENET DMA interrupt status flag.
930  *
931  * @param base  ENET peripheral base address.
932  * @param channel The DMA Channel. Shall not be larger than ENET_RING_NUM_MAX.
933  * @return The event status of the interrupt source. This is the logical OR of members
934  *         of the enumeration :: enet_dma_interrupt_enable_t.
935  */
ENET_GetDmaInterruptStatus(ENET_Type * base,uint8_t channel)936 static inline uint32_t ENET_GetDmaInterruptStatus(ENET_Type *base, uint8_t channel)
937 {
938     return base->DMA_CH[channel].DMA_CHX_STAT;
939 }
940 
941 /*!
942  * @brief Clear the ENET DMA interrupt status flag.
943  *
944  * @param base  ENET peripheral base address.
945  * @param channel The DMA Channel. Shall not be larger than ENET_RING_NUM_MAX.
946  * @param mask The event status of the interrupt source. This is the logical OR of members
947  *         of the enumeration :: enet_dma_interrupt_enable_t.
948  */
ENET_ClearDmaInterruptStatus(ENET_Type * base,uint8_t channel,uint32_t mask)949 static inline void ENET_ClearDmaInterruptStatus(ENET_Type *base, uint8_t channel, uint32_t mask)
950 {
951     /* Clear the dam interrupt status bit in dma channel interrupt status register. */
952     base->DMA_CH[channel].DMA_CHX_STAT = mask;
953 }
954 
955 /*!
956  * @brief Gets the ENET MAC interrupt status flag.
957  *
958  * @param base  ENET peripheral base address.
959  * @return The event status of the interrupt source.
960  *       Use the enum in enet_mac_interrupt_enable_t and right shift
961  *       ENET_MACINT_ENUM_OFFSET to mask the returned value to get the
962  *       exact interrupt status.
963  */
ENET_GetMacInterruptStatus(ENET_Type * base)964 static inline uint32_t ENET_GetMacInterruptStatus(ENET_Type *base)
965 {
966     return base->MAC_INTR_STAT;
967 }
968 
969 /*!
970  * @brief Clears the ENET mac interrupt events status flag.
971  *
972  * This function clears enabled ENET interrupts according to the provided mask. The mask
973  * is a logical OR of enumeration members. See the @ref enet_mac_interrupt_enable_t.
974  * For example, to clear the TX frame interrupt and RX frame interrupt, do the following.
975  * @code
976  *     ENET_ClearMacInterruptStatus(ENET, kENET_MacPmt);
977  * @endcode
978  *
979  * @param base  ENET peripheral base address.
980  * @param mask  ENET interrupt source to be cleared.
981  * This is the logical OR of members of the enumeration :: enet_mac_interrupt_enable_t.
982  */
983 void ENET_ClearMacInterruptStatus(ENET_Type *base, uint32_t mask);
984 
985 /* @} */
986 
987 /*!
988  * @name Functional operation.
989  * @{
990  */
991 
992 /*!
993  * @brief Get the Tx descriptor DMA Own flag.
994  *
995  * @param txDesc  The given Tx descriptor.
996  * @retval True the dma own Tx descriptor, false application own Tx descriptor.
997  *
998  */
ENET_IsTxDescriptorDmaOwn(enet_tx_bd_struct_t * txDesc)999 static inline bool ENET_IsTxDescriptorDmaOwn(enet_tx_bd_struct_t *txDesc)
1000 {
1001     return ((txDesc->tdes3 & ENET_TXDESCRIP_RD_OWN_MASK) != 0U) ? true : false;
1002 }
1003 
1004 /*!
1005  * @brief Setup a given Tx descriptor.
1006  *  This function is a low level functional API to setup or prepare
1007  *  a given Tx descriptor.
1008  *
1009  * @param txDesc  The given Tx descriptor.
1010  * @param buffer1  The first buffer address in the descriptor.
1011  * @param bytes1  The bytes in the fist buffer.
1012  * @param buffer2  The second buffer address in the descriptor.
1013  * @param bytes2  The bytes in the second buffer.
1014  * @param framelen  The length of the frame to be transmitted.
1015  * @param intEnable Interrupt enable flag.
1016  * @param tsEnable The timestamp enable.
1017  * @param flag The flag of this Tx desciriptor, see "enet_desc_flag_t" .
1018  * @param slotNum The slot num used for AV mode only.
1019  *
1020  * @note This must be called after all the ENET initilization.
1021  * And should be called when the ENET receive/transmit is required.
1022  * Transmit buffers are 'zero-copy' buffers, so the buffer must remain in
1023  * memory until the packet has been fully transmitted. The buffers
1024  * should be free or requeued in the transmit interrupt irq handler.
1025  */
1026 void ENET_SetupTxDescriptor(enet_tx_bd_struct_t *txDesc,
1027                             void *buffer1,
1028                             uint32_t bytes1,
1029                             void *buffer2,
1030                             uint32_t bytes2,
1031                             uint32_t framelen,
1032                             bool intEnable,
1033                             bool tsEnable,
1034                             enet_desc_flag_t flag,
1035                             uint8_t slotNum);
1036 
1037 /*!
1038  * @brief Update the Tx descriptor tail pointer.
1039  *  This function is a low level functional API to update the
1040  *  the Tx descriptor tail.
1041  *  This is called after you setup a new Tx descriptor to update
1042  *  the tail pointer to make the new descritor accessable by DMA.
1043  *
1044  * @param base    ENET peripheral base address.
1045  * @param channel  The Tx DMA channel.
1046  * @param txDescTailAddrAlign  The new Tx tail pointer address.
1047  *
1048  */
ENET_UpdateTxDescriptorTail(ENET_Type * base,uint8_t channel,uint32_t txDescTailAddrAlign)1049 static inline void ENET_UpdateTxDescriptorTail(ENET_Type *base, uint8_t channel, uint32_t txDescTailAddrAlign)
1050 {
1051     base->DMA_CH[channel].DMA_CHX_TXDESC_TAIL_PTR = txDescTailAddrAlign & ~ENET_ADDR_ALIGNMENT;
1052 }
1053 
1054 /*!
1055  * @brief Update the Rx descriptor tail pointer.
1056  *  This function is a low level functional API to update the
1057  *  the Rx descriptor tail.
1058  *  This is called after you setup a new Rx descriptor to update
1059  *  the tail pointer to make the new descritor accessable by DMA
1060  *  and to anouse the Rx poll command for DMA.
1061  *
1062  * @param base    ENET peripheral base address.
1063  * @param channel  The Rx DMA channel.
1064  * @param rxDescTailAddrAlign  The new Rx tail pointer address.
1065  *
1066  */
ENET_UpdateRxDescriptorTail(ENET_Type * base,uint8_t channel,uint32_t rxDescTailAddrAlign)1067 static inline void ENET_UpdateRxDescriptorTail(ENET_Type *base, uint8_t channel, uint32_t rxDescTailAddrAlign)
1068 {
1069     base->DMA_CH[channel].DMA_CHX_RXDESC_TAIL_PTR = rxDescTailAddrAlign & ~ENET_ADDR_ALIGNMENT;
1070 }
1071 
1072 /*!
1073  * @brief Gets the context in the ENET Rx descriptor.
1074  *  This function is a low level functional API to get the
1075  *  the status flag from a given Rx descriptor.
1076  *
1077  * @param rxDesc  The given Rx descriptor.
1078  * @retval The RDES3 regions for write-back format Rx buffer descriptor.
1079  *
1080  * @note This must be called after all the ENET initilization.
1081  * And should be called when the ENET receive/transmit is required.
1082  */
ENET_GetRxDescriptor(enet_rx_bd_struct_t * rxDesc)1083 static inline uint32_t ENET_GetRxDescriptor(enet_rx_bd_struct_t *rxDesc)
1084 {
1085     assert(rxDesc);
1086 
1087     return rxDesc->rdes3;
1088 }
1089 /*!
1090  * @brief Updates the buffers and the own status for a given Rx descriptor.
1091  *  This function is a low level functional API to Updates the
1092  *  buffers and the own status for a given Rx descriptor.
1093  *
1094  * @param rxDesc  The given Rx descriptor.
1095  * @param buffer1  The first buffer address in the descriptor.
1096  * @param buffer2  The second buffer address in the descriptor.
1097  * @param intEnable Interrupt enable flag.
1098  * @param doubleBuffEnable The double buffer enable flag.
1099  *
1100  * @note This must be called after all the ENET initilization.
1101  * And should be called when the ENET receive/transmit is required.
1102  */
1103 void ENET_UpdateRxDescriptor(
1104     enet_rx_bd_struct_t *rxDesc, void *buffer1, void *buffer2, bool intEnable, bool doubleBuffEnable);
1105 
1106 /* @} */
1107 
1108 /*!
1109  * @name Transactional operation
1110  * @{
1111  */
1112 
1113 /*!
1114  * @brief Create ENET Handler
1115  *
1116  * This is a transactional API and it's provided to store all datas which are needed
1117  * during the whole transactional process. This API should not be used when you use
1118  * functional APIs to do data Tx/Rx. This is funtion will store many data/flag for
1119  * transactional use.
1120  *
1121  * @param base  ENET peripheral base address.
1122  * @param handle ENET handler.
1123  * @param config ENET configuration.
1124  * @param bufferConfig ENET buffer configuration.
1125  * @param callback The callback function.
1126  * @param userData The application data.
1127  */
1128 void ENET_CreateHandler(ENET_Type *base,
1129                         enet_handle_t *handle,
1130                         enet_config_t *config,
1131                         enet_buffer_config_t *bufferConfig,
1132                         enet_callback_t callback,
1133                         void *userData);
1134 
1135 /*!
1136  * @brief Gets the size of the read frame.
1137  * This function gets a received frame size from the ENET buffer descriptors.
1138  * @note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS.
1139  * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the
1140  * receive buffers If the result is not "kStatus_ENET_RxFrameEmpty".
1141  *
1142  * @param base ENET peripheral base address.
1143  * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
1144  * @param length The length of the valid frame received.
1145  * @param channel The DMAC channel for the Rx.
1146  * @retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame.
1147  * @retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data
1148  *         and NULL length to update the receive buffers.
1149  * @retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame
1150  *         should be called with the right data buffer and the captured data length input.
1151  */
1152 status_t ENET_GetRxFrameSize(ENET_Type *base, enet_handle_t *handle, uint32_t *length, uint8_t channel);
1153 
1154 /*!
1155  * @brief Reads a frame from the ENET device.
1156  * This function reads a frame from the ENET DMA descriptors.
1157  * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer.
1158  * For example use Rx dma channel 0:
1159  * @code
1160  *       uint32_t length;
1161  *       enet_handle_t g_handle;
1162  *       Comment: Get the received frame size firstly.
1163  *       status = ENET_GetRxFrameSize(&g_handle, &length, 0);
1164  *       if (length != 0)
1165  *       {
1166  *           Comment: Allocate memory here with the size of "length"
1167  *           uint8_t *data = memory allocate interface;
1168  *           if (!data)
1169  *           {
1170  *               ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0);
1171  *           }
1172  *           else
1173  *           {
1174  *              status = ENET_ReadFrame(ENET, &g_handle, data, length, 0);
1175  *           }
1176  *       }
1177  *       else if (status == kStatus_ENET_RxFrameError)
1178  *       {
1179  *           Comment: Update the received buffer when a error frame is received.
1180  *           ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0);
1181  *       }
1182  * @endcode
1183  * @param base  ENET peripheral base address.
1184  * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
1185  * @param data The data buffer provided by user to store the frame which memory size should be at least "length".
1186  * @param length The size of the data buffer which is still the length of the received frame.
1187  * @param channel The Rx DMA channel. Shall not be larger than 2.
1188  * @param timestamp The timestamp address to store received timestamp.
1189  * @return The execute status, successful or failure.
1190  */
1191 status_t ENET_ReadFrame(ENET_Type *base,
1192                         enet_handle_t *handle,
1193                         uint8_t *data,
1194                         uint32_t length,
1195                         uint8_t channel,
1196                         enet_ptp_time_t *timestamp);
1197 
1198 /*!
1199  * @brief Receives one frame in specified BD ring with zero copy.
1200  *
1201  * This function will use the user-defined allocate and free callback. Every time application gets one frame through
1202  * this function, driver will allocate new buffers for the BDs whose buffers have been taken by application.
1203  * @note This function will drop current frame and update related BDs as available for DMA if new buffers allocating
1204  * fails. Application must provide a memory pool including at least BD number + 1 buffers(+2 if enable double buffer)
1205  * to make this function work normally. If user calls this function in Rx interrupt handler, be careful that this
1206  * function makes Rx BD ready with allocating new buffer(normal) or updating current BD(out of memory). If there's
1207  * always new Rx frame input, Rx interrupt will be triggered forever. Application need to disable Rx interrupt according
1208  * to specific design in this case.
1209  *
1210  * @param base   ENET peripheral base address.
1211  * @param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
1212  * @param rxFrame The received frame information structure provided by user.
1213  * @param channel The Rx DMA channel. Shall not be larger than 2.
1214  * @retval kStatus_Success  Succeed to get one frame and allocate new memory for Rx buffer.
1215  * @retval kStatus_ENET_RxFrameEmpty  There's no Rx frame in the BD.
1216  * @retval kStatus_ENET_RxFrameError  There's issue in this receiving. In this function, issue frame will be dropped.
1217  * @retval kStatus_ENET_RxFrameDrop  There's no new buffer memory for BD, dropped this frame.
1218  */
1219 status_t ENET_GetRxFrame(ENET_Type *base, enet_handle_t *handle, enet_rx_frame_struct_t *rxFrame, uint8_t channel);
1220 
1221 /*!
1222  * @brief Transmits an ENET frame.
1223  * @note The CRC is automatically appended to the data. Input the data
1224  * to send without the CRC. This API uses input buffer for Tx, application
1225  * should reclaim the buffer after Tx is over.
1226  *
1227  * @param base  ENET peripheral base address.
1228  * @param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
1229  * @param txFrame The Tx frame structure.
1230  * @param channel Channel to send the frame, same with queue index.
1231  * @retval kStatus_Success  Send frame succeed.
1232  * @retval kStatus_ENET_TxFrameBusy  Transmit buffer descriptor is busy under transmission.
1233  *         The transmit busy happens when the data send rate is over the MAC capacity.
1234  *         The waiting mechanism is recommended to be added after each call return with kStatus_ENET_TxFrameBusy.
1235  *         Also need to pay attention to reclaim Tx frame after Tx is over.
1236  * @retval kStatus_ENET_TxFrameOverLen  Transmit frme length exceeds the 0x3FFF limit defined by the driver.
1237  */
1238 status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, enet_tx_frame_struct_t *txFrame, uint8_t channel);
1239 
1240 /*!
1241  * @brief Reclaim Tx descriptors.
1242  *  This function is used to update the Tx descriptor status and
1243  *  store the Tx timestamp when the 1588 feature is enabled.
1244  *  This is called by the transmit interupt IRQ handler after the
1245  *  complete of a frame transmission.
1246  *
1247  * @param base    ENET peripheral base address.
1248  * @param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
1249  * @param channel  The Tx DMA channnel.
1250  *
1251  */
1252 void ENET_ReclaimTxDescriptor(ENET_Type *base, enet_handle_t *handle, uint8_t channel);
1253 
1254 /*!
1255  * @brief The ENET IRQ handler.
1256  *
1257  * @param base  ENET peripheral base address.
1258  * @param handle The ENET handler pointer.
1259  */
1260 void ENET_IRQHandler(ENET_Type *base, enet_handle_t *handle);
1261 
1262 /* @} */
1263 
1264 #ifdef ENET_PTP1588FEATURE_REQUIRED
1265 /*!
1266  * @name ENET Enhanced function operation
1267  * @{
1268  */
1269 
1270 /*!
1271  * @brief Coreect the ENET PTP 1588 timer in coarse method.
1272  *
1273  * @param base  ENET peripheral base address.
1274  * @param operation The system time operation, refer to "enet_systime_op_t"
1275  * @param second The correction second.
1276  * @param nanosecond The correction nanosecond.
1277  */
1278 void ENET_Ptp1588CorrectTimerInCoarse(ENET_Type *base,
1279                                       enet_systime_op_t operation,
1280                                       uint32_t second,
1281                                       uint32_t nanosecond);
1282 
1283 /*!
1284  * @brief Coreect the ENET PTP 1588 timer in fine method.
1285  *
1286  *
1287  * @param base  ENET peripheral base address.
1288  * @param addend The addend value to be set in the fine method
1289  * @note Should take refer to the chapter "System time corretion" and
1290  * see the description for the "fine correction method".
1291  */
ENET_Ptp1588CorrectTimerInFine(ENET_Type * base,uint32_t addend)1292 static inline void ENET_Ptp1588CorrectTimerInFine(ENET_Type *base, uint32_t addend)
1293 {
1294     /* Set the freqCompensation value. */
1295     base->MAC_SYS_TIMESTMP_ADDEND = addend;
1296     base->MAC_TIMESTAMP_CTRL |= ENET_MAC_TIMESTAMP_CTRL_TADDREG_MASK;
1297 }
1298 
1299 /*!
1300  * @brief Get the ENET Time stamp current addend value.
1301  *
1302  * @param base  ENET peripheral base address.
1303  * @return The addend value.
1304  */
ENET_Ptp1588GetAddend(ENET_Type * base)1305 static inline uint32_t ENET_Ptp1588GetAddend(ENET_Type *base)
1306 {
1307     return base->MAC_SYS_TIMESTMP_ADDEND;
1308 }
1309 
1310 /*!
1311  * @brief Gets the current ENET time from the PTP 1588 timer.
1312  *       Interrupts are not disabled.
1313  *
1314  * @param base  ENET peripheral base address.
1315  * @param second The PTP 1588 system timer second.
1316  * @param nanosecond The PTP 1588 system timer nanosecond.
1317  */
1318 void ENET_Ptp1588GetTimerNoIrqDisable(ENET_Type *base, uint64_t *second, uint32_t *nanosecond);
1319 
1320 /*!
1321  * @brief Gets the current ENET time from the PTP 1588 timer.
1322  *
1323  * @param base  ENET peripheral base address.
1324  * @param second The PTP 1588 system timer second.
1325  * @param nanosecond The PTP 1588 system timer nanosecond.
1326  * For the unit of the nanosecond is 1ns. So the nanosecond is the real nanosecond.
1327  */
1328 void ENET_Ptp1588GetTimer(ENET_Type *base, uint64_t *second, uint32_t *nanosecond);
1329 #endif /* ENET_PTP1588FEATURE_REQUIRED */
1330 /* @} */
1331 
1332 #if defined(__cplusplus)
1333 }
1334 #endif
1335 
1336 /*! @}*/
1337 
1338 #endif /* _FSL_ENET_H_ */
1339