/* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016-2023 NXP * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_ENET_H_ #define _FSL_ENET_H_ #include "fsl_common.h" /*! * @addtogroup lpc_enet * @{ */ /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ /*! @brief Defines the driver version. */ #define FSL_ENET_DRIVER_VERSION (MAKE_VERSION(2, 3, 2)) /*@}*/ /*! @name Control and status region bit masks of the receive buffer descriptor. */ /*@{*/ /*! @brief Defines for read format. */ #define ENET_RXDESCRIP_RD_BUFF1VALID_MASK (1UL << 24) /*!< Buffer1 address valid. */ #define ENET_RXDESCRIP_RD_BUFF2VALID_MASK (1UL << 25) /*!< Buffer2 address valid. */ #define ENET_RXDESCRIP_RD_IOC_MASK (1UL << 30) /*!< Interrupt enable on complete. */ #define ENET_RXDESCRIP_RD_OWN_MASK (1UL << 31) /*!< Own bit. */ /*! @brief Defines for write back format. */ #define ENET_RXDESCRIP_WR_ERR_MASK ((1UL << 3) | (1UL << 7)) #define ENET_RXDESCRIP_WR_PYLOAD_MASK (0x7U) #define ENET_RXDESCRIP_WR_PTPMSGTYPE_MASK (0xF00U) #define ENET_RXDESCRIP_WR_PTPTYPE_MASK (1UL << 12) #define ENET_RXDESCRIP_WR_PTPVERSION_MASK (1UL << 13) #define ENET_RXDESCRIP_WR_PTPTSA_MASK (1UL << 14) #define ENET_RXDESCRIP_WR_PACKETLEN_MASK (0x7FFFU) #define ENET_RXDESCRIP_WR_ERRSUM_MASK (1UL << 15) #define ENET_RXDESCRIP_WR_TYPE_MASK (0x30000U) #define ENET_RXDESCRIP_WR_DE_MASK (1UL << 19) #define ENET_RXDESCRIP_WR_RE_MASK (1UL << 20) #define ENET_RXDESCRIP_WR_OE_MASK (1UL << 21) #define ENET_RXDESCRIP_WR_RS0V_MASK (1UL << 25) #define ENET_RXDESCRIP_WR_RS1V_MASK (1UL << 26) #define ENET_RXDESCRIP_WR_RS2V_MASK (1UL << 27) #define ENET_RXDESCRIP_WR_LD_MASK (1UL << 28) #define ENET_RXDESCRIP_WR_FD_MASK (1UL << 29) #define ENET_RXDESCRIP_WR_CTXT_MASK (1UL << 30) #define ENET_RXDESCRIP_WR_OWN_MASK (1UL << 31) /*@}*/ /*! @name Control and status bit masks of the transmit buffer descriptor. */ /*@{*/ /*! @brief Defines for read format. */ #define ENET_TXDESCRIP_RD_BL1_MASK (0x3fffU) #define ENET_TXDESCRIP_RD_BL2_MASK (ENET_TXDESCRIP_RD_BL1_MASK << 16) #define ENET_TXDESCRIP_RD_BL1(n) ((uint32_t)(n)&ENET_TXDESCRIP_RD_BL1_MASK) #define ENET_TXDESCRIP_RD_BL2(n) (((uint32_t)(n)&ENET_TXDESCRIP_RD_BL1_MASK) << 16) #define ENET_TXDESCRIP_RD_TTSE_MASK (1UL << 30) #define ENET_TXDESCRIP_RD_IOC_MASK (1UL << 31) #define ENET_TXDESCRIP_RD_FL_MASK (0x7FFFU) #define ENET_TXDESCRIP_RD_FL(n) ((uint32_t)(n)&ENET_TXDESCRIP_RD_FL_MASK) #define ENET_TXDESCRIP_RD_CIC(n) (((uint32_t)(n)&0x3U) << 16) #define ENET_TXDESCRIP_RD_TSE_MASK (1UL << 18) #define ENET_TXDESCRIP_RD_SLOT(n) (((uint32_t)(n)&0x0fU) << 19) #define ENET_TXDESCRIP_RD_SAIC(n) (((uint32_t)(n)&0x07U) << 23) #define ENET_TXDESCRIP_RD_CPC(n) (((uint32_t)(n)&0x03U) << 26) #define ENET_TXDESCRIP_RD_LDFD(n) (((uint32_t)(n)&0x03U) << 28) #define ENET_TXDESCRIP_RD_LD_MASK (1UL << 28) #define ENET_TXDESCRIP_RD_FD_MASK (1UL << 29) #define ENET_TXDESCRIP_RD_CTXT_MASK (1UL << 30) #define ENET_TXDESCRIP_RD_OWN_MASK (1UL << 31) /*! @brief Defines for write back format. */ #define ENET_TXDESCRIP_WB_TTSS_MASK (1UL << 17) /*@}*/ /*! @name Bit mask for interrupt enable type. */ /*@{*/ #define ENET_ABNORM_INT_MASK \ (ENET_DMA_CH_DMA_CHX_INT_EN_TSE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_RBUE_MASK | \ ENET_DMA_CH_DMA_CHX_INT_EN_RSE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_RWTE_MASK | \ ENET_DMA_CH_DMA_CHX_INT_EN_FBEE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_ETIE_MASK) #define ENET_NORM_INT_MASK \ (ENET_DMA_CH_DMA_CHX_INT_EN_TIE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_TBUE_MASK | \ ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK | ENET_DMA_CH_DMA_CHX_INT_EN_ERIE_MASK) /*@}*/ /*! @name Defines some Ethernet parameters. */ /*@{*/ #define ENET_FRAME_MAX_FRAMELEN (1518U) /*!< Default maximum ethernet frame size. */ #define ENET_FCS_LEN (4U) /*!< Ethernet Rx frame FCS length. */ #define ENET_ADDR_ALIGNMENT (0x3U) /*!< Recommended ethernet buffer alignment. */ #define ENET_BUFF_ALIGNMENT (4U) /*!< Receive buffer alignment shall be 4bytes-aligned. */ #define ENET_RING_NUM_MAX (2U) /*!< The maximum number of Tx/Rx descriptor rings. */ #define ENET_MTL_RXFIFOSIZE (2048U) /*!< The Rx fifo size. */ #define ENET_MTL_TXFIFOSIZE (2048U) /*!< The Tx fifo size. */ #define ENET_MACINT_ENUM_OFFSET (16U) /*!< The offset for mac interrupt in enum type. */ #define ENET_FRAME_TX_LEN_LIMITATION (ENET_TXDESCRIP_RD_BL1_MASK) /*!< The Tx frame length software limitation. */ #define ENET_FRAME_RX_ERROR_BITS(x) (((x) >> 19U) & 0x3FU) /*!< The Rx frame error bits field. */ /*@}*/ /*! @brief Defines the status return codes for transaction. */ enum { kStatus_ENET_InitMemoryFail = MAKE_STATUS(kStatusGroup_ENET, 0U), /*!< Status code 4000. Init failed since buffer memory was not enough. */ kStatus_ENET_RxFrameError = MAKE_STATUS(kStatusGroup_ENET, 1U), /*!< Status code 4001. A frame received but data error occurred. */ kStatus_ENET_RxFrameFail = MAKE_STATUS(kStatusGroup_ENET, 2U), /*!< Status code 4002. Failed to receive a frame. */ kStatus_ENET_RxFrameEmpty = MAKE_STATUS(kStatusGroup_ENET, 3U), /*!< Status code 4003. No frame arrived. */ kStatus_ENET_RxFrameDrop = MAKE_STATUS( kStatusGroup_ENET, 4U), /*!< Status code 4004. Rx frame was dropped since there's no buffer memory. */ kStatus_ENET_TxFrameBusy = MAKE_STATUS(kStatusGroup_ENET, 5U), /*!< Status code 4005. There were no resources for Tx operation. */ kStatus_ENET_TxFrameFail = MAKE_STATUS(kStatusGroup_ENET, 6U), /*!< Status code 4006. Transmit frame failed. */ kStatus_ENET_TxFrameOverLen = MAKE_STATUS(kStatusGroup_ENET, 7U) /*!< Status code 4007. Failed to send an oversize frame. */ }; /*! @brief Defines the MII/RMII mode for data interface between the MAC and the PHY. */ typedef enum _enet_mii_mode { kENET_MiiMode = 0U, /*!< MII mode for data interface. */ kENET_RmiiMode = 1U /*!< RMII mode for data interface. */ } enet_mii_mode_t; /*! @brief Defines the 10/100 Mbps speed for the MII data interface. */ typedef enum _enet_mii_speed { kENET_MiiSpeed10M = 0U, /*!< Speed 10 Mbps. */ kENET_MiiSpeed100M = 1U, /*!< Speed 100 Mbps. */ } enet_mii_speed_t; /*! @brief Defines the half or full duplex for the MII data interface. */ typedef enum _enet_mii_duplex { kENET_MiiHalfDuplex = 0U, /*!< Half duplex mode. */ kENET_MiiFullDuplex /*!< Full duplex mode. */ } enet_mii_duplex_t; /*! @brief Define the MII opcode for normal MDIO_CLAUSES_22 Frame. */ typedef enum _enet_mii_normal_opcode { kENET_MiiWriteFrame = 1U, /*!< Write frame operation for a valid MII management frame. */ kENET_MiiReadFrame = 3U /*!< Read frame operation for a valid MII management frame. */ } enet_mii_normal_opcode_t; /*! @brief Define the DMA maximum transmit burst length. */ typedef enum _enet_dma_burstlen { kENET_BurstLen1 = 0x00001U, /*!< DMA burst length 1. */ kENET_BurstLen2 = 0x00002U, /*!< DMA burst length 2. */ kENET_BurstLen4 = 0x00004U, /*!< DMA burst length 4. */ kENET_BurstLen8 = 0x00008U, /*!< DMA burst length 8. */ kENET_BurstLen16 = 0x00010U, /*!< DMA burst length 16. */ kENET_BurstLen32 = 0x00020U, /*!< DMA burst length 32. */ kENET_BurstLen64 = 0x10008U, /*!< DMA burst length 64. eight times enabled. */ kENET_BurstLen128 = 0x10010U, /*!< DMA burst length 128. eight times enabled. */ kENET_BurstLen256 = 0x10020U, /*!< DMA burst length 256. eight times enabled. */ } enet_dma_burstlen_t; /*! @brief Define the flag for the descriptor. */ typedef enum _enet_desc_flag { kENET_MiddleFlag = 0, /*!< It's a middle descriptor of the frame. */ kENET_LastFlagOnly, /*!< It's the last descriptor of the frame. */ kENET_FirstFlagOnly, /*!< It's the first descriptor of the frame. */ kENET_FirstLastFlag /*!< It's the first and last descriptor of the frame. */ } enet_desc_flag_t; /*! @brief Define the system time adjust operation control. */ typedef enum _enet_systime_op { kENET_SystimeAdd = 0U, /*!< System time add to. */ kENET_SystimeSubtract = 1U /*!< System time subtract. */ } enet_systime_op_t; /*! @brief Define the system time rollover control. */ typedef enum _enet_ts_rollover_type { kENET_BinaryRollover = 0, /*!< System time binary rollover.*/ kENET_DigitalRollover = 1 /*!< System time digital rollover.*/ } enet_ts_rollover_type_t; /*! @brief Defines some special configuration for ENET. * * These control flags are provided for special user requirements. * Normally, these is no need to set this control flags for ENET initialization. * But if you have some special requirements, set the flags to specialControl * in the enet_config_t. * @note "kENET_StoreAndForward" is recommended to be set when the * ENET_PTP1588FEATURE_REQUIRED is defined or else the timestamp will be mess-up * when the overflow happens. */ typedef enum _enet_special_config { /***********************DMA CONFGI**********************************************/ kENET_DescDoubleBuffer = 0x0001U, /*!< The double buffer is used in the Tx/Rx descriptor. */ /**************************MTL************************************/ kENET_StoreAndForward = 0x0002U, /*!< The Rx/Tx store and forward enable. */ /***********************MAC****************************************/ kENET_PromiscuousEnable = 0x0004U, /*!< The promiscuous enabled. */ kENET_FlowControlEnable = 0x0008U, /*!< The flow control enabled. */ kENET_BroadCastRxDisable = 0x0010U, /*!< The broadcast disabled. */ kENET_MulticastAllEnable = 0x0020U, /*!< All multicast are passed. */ kENET_8023AS2KPacket = 0x0040U, /*!< 8023as support for 2K packets. */ kENET_RxChecksumOffloadEnable = 0x0080U, /*!< The Rx checksum offload enabled. */ } enet_special_config_t; /*! @brief List of DMA interrupts supported by the ENET interrupt. This * enumeration uses one-hot encoding to allow a logical OR of multiple * members. */ typedef enum _enet_dma_interrupt_enable { kENET_DmaTx = ENET_DMA_CH_DMA_CHX_INT_EN_TIE_MASK, /*!< Tx interrupt. */ kENET_DmaTxStop = ENET_DMA_CH_DMA_CHX_INT_EN_TSE_MASK, /*!< Tx stop interrupt. */ kENET_DmaTxBuffUnavail = ENET_DMA_CH_DMA_CHX_INT_EN_TBUE_MASK, /*!< Tx buffer unavailable. */ kENET_DmaRx = ENET_DMA_CH_DMA_CHX_INT_EN_RIE_MASK, /*!< Rx interrupt. */ kENET_DmaRxBuffUnavail = ENET_DMA_CH_DMA_CHX_INT_EN_RBUE_MASK, /*!< Rx buffer unavailable. */ kENET_DmaRxStop = ENET_DMA_CH_DMA_CHX_INT_EN_RSE_MASK, /*!< Rx stop. */ kENET_DmaRxWatchdogTimeout = ENET_DMA_CH_DMA_CHX_INT_EN_RWTE_MASK, /*!< Rx watchdog timeout. */ kENET_DmaEarlyTx = ENET_DMA_CH_DMA_CHX_INT_EN_ETIE_MASK, /*!< Early transmit. */ kENET_DmaEarlyRx = ENET_DMA_CH_DMA_CHX_INT_EN_ERIE_MASK, /*!< Early receive. */ kENET_DmaBusErr = ENET_DMA_CH_DMA_CHX_INT_EN_FBEE_MASK, /*!< Fatal bus error. */ } enet_dma_interrupt_enable_t; /*! @brief List of mac interrupts supported by the ENET interrupt. This * enumeration uses one-hot encoding to allow a logical OR of multiple * members. */ typedef enum _enet_mac_interrupt_enable { kENET_MacPmt = (ENET_MAC_INTR_EN_PMTIE_MASK << ENET_MACINT_ENUM_OFFSET), kENET_MacTimestamp = (ENET_MAC_INTR_EN_TSIE_MASK << ENET_MACINT_ENUM_OFFSET), } enet_mac_interrupt_enable_t; /*! @brief Defines the common interrupt event for callback use. */ typedef enum _enet_event { kENET_RxIntEvent, /*!< Receive interrupt event. */ kENET_TxIntEvent, /*!< Transmit interrupt event. */ kENET_WakeUpIntEvent, /*!< Wake up interrupt event. */ kENET_TimeStampIntEvent, /*!< Time stamp interrupt event. */ } enet_event_t; /*! @brief Define the DMA transmit arbitration for multi-queue. */ typedef enum _enet_dma_tx_sche { kENET_FixPri = 0, /*!< Fixed priority. channel 0 has lower priority than channel 1. */ kENET_WeightStrPri, /*!< Weighted(burst length) strict priority. */ kENET_WeightRoundRobin /*!< Weighted (weight factor) round robin. */ } enet_dma_tx_sche_t; /*! @brief Define the MTL Tx scheduling algorithm for multiple queues/rings. */ typedef enum _enet_mtl_multiqueue_txsche { kENET_txWeightRR = 0U, /*!< Tx weight round-robin. */ kENET_txStrPrio = 3U, /*!< Tx strict priority. */ } enet_mtl_multiqueue_txsche_t; /*! @brief Define the MTL Rx scheduling algorithm for multiple queues/rings. */ typedef enum _enet_mtl_multiqueue_rxsche { kENET_rxStrPrio = 0U, /*!< Tx weight round-robin, Rx strict priority. */ kENET_rxWeightStrPrio, /*!< Tx strict priority, Rx weight strict priority. */ } enet_mtl_multiqueue_rxsche_t; /*! @brief Define the MTL Rx queue and DMA channel mapping. */ typedef enum _enet_mtl_rxqueuemap { kENET_StaticDirctMap = 0x100U, /*!< The received fame in Rx Qn(n = 0,1) direclty map to dma channel n. */ kENET_DynamicMap = 0x1010U, /*!< The received frame in Rx Qn(n = 0,1) map to the dma channel m(m = 0,1) related with the same Mac. */ } enet_mtl_rxqueuemap_t; /*! @brief Defines the ENET PTP message related constant. */ typedef enum _enet_ptp_event_type { kENET_PtpEventMsgType = 3U, /*!< PTP event message type. */ kENET_PtpSrcPortIdLen = 10U, /*!< PTP message sequence id length. */ kENET_PtpEventPort = 319U, /*!< PTP event port number. */ kENET_PtpGnrlPort = 320U /*!< PTP general port number. */ } enet_ptp_event_type_t; /*! @brief Define the Tx checksum offload options. */ typedef enum _enet_tx_offload { kENET_TxOffloadDisable = 0U, /*!< Disable Tx checksum offload. */ kENET_TxOffloadIPHeader = 1U, /*!< Enable IP header checksum calculation and insertion. */ kENET_TxOffloadIPHeaderPlusPayload = 2U, /*!< Enable IP header and payload checksum calculation and insertion. */ kENET_TxOffloadAll = 3U, /*!< Enable IP header, payload and pseudo header checksum calculation and insertion. */ } enet_tx_offload_t; /*! @brief Defines the receive descriptor structure * It has the read-format and write-back format structures. They both * have the same size with different region definition. So we define * common name as the recive descriptor structure. When initialize * the buffer descriptors, read-format region mask bits should be used. * When Rx frame has been in the buffer descriptors, write-back format * region store the Rx result information. */ typedef struct _enet_rx_bd_struct { __IO uint32_t rdes0; /*!< Receive descriptor 0 */ __IO uint32_t rdes1; /*!< Receive descriptor 1 */ __IO uint32_t rdes2; /*!< Receive descriptor 2 */ __IO uint32_t rdes3; /*!< Receive descriptor 3 */ } enet_rx_bd_struct_t; /*! @brief Defines the transmit descriptor structure * It has the read-format and write-back format structure. They both * has the same size with different region definition. So we define * common name as the transmit descriptor structure. When initialize * the buffer descriptors for Tx, read-format region mask bits should * be used. When frame has been transmitted, write-back format region * store the Tx result information. */ typedef struct _enet_tx_bd_struct { __IO uint32_t tdes0; /*!< Transmit descriptor 0 */ __IO uint32_t tdes1; /*!< Transmit descriptor 1 */ __IO uint32_t tdes2; /*!< Transmit descriptor 2 */ __IO uint32_t tdes3; /*!< Transmit descriptor 3 */ } enet_tx_bd_struct_t; /*! @brief Defines the Tx BD configuration structure. */ typedef struct _enet_tx_bd_config_struct { void *buffer1; /*!< The first buffer address in the descriptor. */ uint32_t bytes1; /*!< The bytes in the fist buffer. */ void *buffer2; /*!< The second buffer address in the descriptor. */ uint32_t bytes2; /*!< The bytes in the second buffer. */ uint32_t framelen; /*!< The length of the frame to be transmitted. */ bool intEnable; /*!< Interrupt enable flag. */ bool tsEnable; /*!< The timestamp enable. */ enet_tx_offload_t txOffloadOps; /*!< The Tx checksum offload option, only vaild for Queue 0. */ enet_desc_flag_t flag; /*!< The flag of this tx desciriptor, see "enet_qos_desc_flag". */ uint8_t slotNum; /*!< The slot number used for AV mode only. */ } enet_tx_bd_config_struct_t; #ifdef ENET_PTP1588FEATURE_REQUIRED /*! @brief Defines the ENET PTP configuration structure. */ typedef struct _enet_ptp_config { bool fineUpdateEnable; /*!< Use the fine update. */ bool ptp1588V2Enable; /*!< ptp 1588 version 2 is used. */ enet_ts_rollover_type_t tsRollover; /*!< 1588 time nanosecond rollover. */ } enet_ptp_config_t; #endif /* ENET_PTP1588FEATURE_REQUIRED */ /*! @brief Defines the ENET PTP time stamp structure. */ typedef struct _enet_ptp_time { uint64_t second; /*!< Second. */ uint32_t nanosecond; /*!< Nanosecond. */ } enet_ptp_time_t; /*! @brief Defines the Tx reclaim information structure. */ typedef struct enet_tx_reclaim_info { void *context; /*!< User specified data, could be buffer address for free */ bool isTsAvail; /*!< Flag indicates timestamp available status */ enet_ptp_time_t timeStamp; /*!< Timestamp of frame */ } enet_tx_reclaim_info_t; /*! @brief Defines the ENET transmit dirty addresses ring/queue structure. */ typedef struct _enet_tx_dirty_ring { enet_tx_reclaim_info_t *txDirtyBase; /*!< Dirty buffer descriptor base address pointer. */ uint16_t txGenIdx; /*!< Tx generate index. */ uint16_t txConsumIdx; /*!< Tx consume index. */ uint16_t txRingLen; /*!< Tx ring length. */ bool isFull; /*!< Tx ring is full flag, add this parameter to avoid waste one element. */ } enet_tx_dirty_ring_t; /*! @brief Defines the buffer descriptor configure structure. * * Notes: * 1. The receive and transmit descriptor start address pointer and tail pointer must be word-aligned. * 2. The recommended minimum Tx/Rx ring length is 4. * 3. The Tx/Rx descriptor tail address shall be the address pointer to the address just after the end * of the last last descriptor. because only the descriptors between the start address and the * tail address will be used by DMA. * 4. The decriptor address is the start address of all used contiguous memory. * for example, the rxDescStartAddrAlign is the start address of rxRingLen contiguous descriptor memorise * for Rx descriptor ring 0. * 5. The "*rxBufferstartAddr" is the first element of rxRingLen (2*rxRingLen for double buffers) * Rx buffers. It means the *rxBufferStartAddr is the Rx buffer for the first descriptor * the *rxBufferStartAddr + 1 is the Rx buffer for the second descriptor or the Rx buffer for * the second buffer in the first descriptor. So please make sure the rxBufferStartAddr is the * address of a rxRingLen or 2*rxRingLen array. */ typedef struct _enet_buffer_config { uint8_t rxRingLen; /*!< The length of receive buffer descriptor ring. */ uint8_t txRingLen; /*!< The length of transmit buffer descriptor ring. */ enet_tx_bd_struct_t *txDescStartAddrAlign; /*!< Aligned transmit descriptor start address. */ enet_tx_bd_struct_t *txDescTailAddrAlign; /*!< Aligned transmit descriptor tail address. */ enet_tx_reclaim_info_t *txDirtyStartAddr; /*!< Start address of the dirty Tx frame information. */ enet_rx_bd_struct_t *rxDescStartAddrAlign; /*!< Aligned receive descriptor start address. */ enet_rx_bd_struct_t *rxDescTailAddrAlign; /*!< Aligned receive descriptor tail address. */ uint32_t *rxBufferStartAddr; /*!< Start address of the Rx buffers. */ uint32_t rxBuffSizeAlign; /*!< Aligned receive data buffer size. */ } enet_buffer_config_t; /*! @brief Defines the configuration when multi-queue is used. */ typedef struct enet_multiqueue_config { /***********************DMA block*******************************/ enet_dma_tx_sche_t dmaTxSche; /*!< Transmit arbitation. */ enet_dma_burstlen_t burstLen; /*!< Burset len for the queue 1. */ uint8_t txdmaChnWeight[ENET_RING_NUM_MAX]; /*!< Transmit channel weight. */ /***********************MTL block*******************************/ enet_mtl_multiqueue_txsche_t mtltxSche; /*!< Transmit schedule for multi-queue. */ enet_mtl_multiqueue_rxsche_t mtlrxSche; /*!< Receive schedule for multi-queue. */ uint8_t rxqueweight[ENET_RING_NUM_MAX]; /*!< Refer to the MTL RxQ Control register. */ uint32_t txqueweight[ENET_RING_NUM_MAX]; /*!< Refer to the MTL TxQ Quantum Weight register. */ uint8_t rxqueuePrio[ENET_RING_NUM_MAX]; /*!< Receive queue priority. */ uint8_t txqueuePrio[ENET_RING_NUM_MAX]; /*!< Refer to Transmit Queue Priority Mapping register. */ enet_mtl_rxqueuemap_t mtlrxQuemap; /*!< Rx queue DMA Channel mapping. */ } enet_multiqueue_config_t; /*! @brief Defines the Rx memory buffer alloc function pointer. */ typedef void *(*enet_rx_alloc_callback_t)(ENET_Type *base, void *userData, uint8_t channel); /*! @brief Defines the Rx memory buffer free function pointer. */ typedef void (*enet_rx_free_callback_t)(ENET_Type *base, void *buffer, void *userData, uint8_t channel); /*! @brief Defines the basic configuration structure for the ENET device. * * Note: * 1. Default the signal queue is used so the "multiqueueCfg" is set default * with NULL. Set the pointer with a valid configration pointer if the multiple * queues are required. If multiple queue is enabled, please make sure the * buffer configuration for all are prepared also. */ typedef struct _enet_config { uint16_t specialControl; /*!< The logicl or of enet_special_config_t */ enet_multiqueue_config_t *multiqueueCfg; /*!< Use both Tx/Rx queue(dma channel) 0 and 1. */ uint32_t interrupt; /*!< MAC interrupt source. A logical OR of enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t. */ /* -----------------MAC block-------------------------------*/ enet_mii_mode_t miiMode; /*!< MII mode. */ enet_mii_speed_t miiSpeed; /*!< MII Speed. */ enet_mii_duplex_t miiDuplex; /*!< MII duplex. */ uint16_t pauseDuration; /*!< Used in the Tx flow control frame, only valid when kENET_FlowControlEnable is set. */ /* -----------------Timestamp-------------------------------*/ #ifdef ENET_PTP1588FEATURE_REQUIRED enet_ptp_config_t *ptpConfig; /*!< PTP 1588 feature configuration */ #endif /* -----------Rx zero copy buffer management----------------*/ enet_rx_alloc_callback_t rxBuffAlloc; /*!< Callback to alloc memory, must be provided for zero-copy Rx. */ enet_rx_free_callback_t rxBuffFree; /*!< Callback to free memory, must be provided for zero-copy Rx. */ } enet_config_t; /* Forward declaration of the handle typedef. */ typedef struct _enet_handle enet_handle_t; /*! @brief ENET callback function. */ typedef void (*enet_callback_t)(ENET_Type *base, enet_handle_t *handle, enet_event_t event, uint8_t channel, enet_tx_reclaim_info_t *txReclaimInfo, void *userData); /*! @brief Defines the ENET transmit buffer descriptor ring/queue structure. */ typedef struct _enet_tx_bd_ring { enet_tx_bd_struct_t *txBdBase; /*!< Buffer descriptor base address pointer. */ uint16_t txGenIdx; /*!< Tx generate index. */ uint16_t txConsumIdx; /*!< Tx consum index. */ volatile uint16_t txDescUsed; /*!< Tx descriptor used number. */ uint16_t txRingLen; /*!< Tx ring length. */ } enet_tx_bd_ring_t; /*! @brief Defines the ENET receive buffer descriptor ring/queue structure. */ typedef struct _enet_rx_bd_ring { enet_rx_bd_struct_t *rxBdBase; /*!< Buffer descriptor base address pointer. */ uint16_t rxGenIdx; /*!< The current available receive buffer descriptor pointer. */ uint16_t rxRingLen; /*!< Receive ring length. */ uint32_t rxBuffSizeAlign; /*!< Receive buffer size. */ } enet_rx_bd_ring_t; /*! @brief Defines the ENET handler structure. */ struct _enet_handle { bool multiQueEnable; /*!< Multi-queue enable status. */ bool doubleBuffEnable; /*!< The double buffer enable status. */ bool rxintEnable; /*!< Rx interrupt enable status. */ enet_rx_bd_ring_t rxBdRing[ENET_RING_NUM_MAX]; /*!< Receive buffer descriptor. */ enet_tx_bd_ring_t txBdRing[ENET_RING_NUM_MAX]; /*!< Transmit buffer descriptor. */ enet_tx_dirty_ring_t txDirtyRing[ENET_RING_NUM_MAX]; /*!< Transmit dirty buffers addresses. */ uint32_t *rxBufferStartAddr[ENET_RING_NUM_MAX]; /*!< The Init-Rx buffers used for reinit corrupted BD due to write-back operation. */ uint32_t txLenLimitation[ENET_RING_NUM_MAX]; /*!< Tx frame length limitation. */ enet_callback_t callback; /*!< Callback function. */ void *userData; /*!< Callback function parameter.*/ enet_rx_alloc_callback_t rxBuffAlloc; /*!< Callback to alloc memory, must be provided for zero-copy Rx. */ enet_rx_free_callback_t rxBuffFree; /*!< Callback to free memory, must be provided for zero-copy Rx. */ }; typedef struct _enet_buffer_struct { void *buffer; /*!< The buffer stores the whole or partial frame. */ uint16_t length; /*!< The byte length of this buffer. */ } enet_buffer_struct_t; /*! @brief Rx frame attribute structure. */ typedef struct _enet_rx_frame_attribute_struct { bool isTsAvail; /*!< Rx frame timestamp is available or not. */ enet_ptp_time_t timestamp; /*!< The nanosecond part timestamp of this Rx frame. */ } enet_rx_frame_attribute_t; /*! @brief Defines the Rx frame error structure. */ typedef struct _enet_rx_frame_error { bool statsDribbleErr : 1; /*!< The received packet has a non-integer multiple of bytes (odd nibbles). */ bool statsRxErr : 1; /*!< Receive error. */ bool statsOverflowErr : 1; /*!< Rx FIFO overflow error. */ bool statsWatchdogTimeoutErr : 1; /*!< Receive watchdog timeout. */ bool statsGaintPacketErr : 1; /*!< Receive error. */ bool statsRxFcsErr : 1; /*!< Receive CRC error. */ } enet_rx_frame_error_t; /*! @brief Defines the Rx frame data structure. */ typedef struct _enet_rx_frame_struct { enet_buffer_struct_t *rxBuffArray; /*!< Rx frame buffer structure. */ uint16_t totLen; /*!< Rx frame total length. */ enet_rx_frame_attribute_t rxAttribute; /*!< Rx frame attribute structure. */ enet_rx_frame_error_t rxFrameError; /*!< Rx frame error. */ } enet_rx_frame_struct_t; typedef struct _enet_tx_config_struct { uint8_t intEnable : 1; /*!< Enable interrupt every time one BD is completed. */ uint8_t tsEnable : 1; /*!< Transmit timestamp enable. */ uint8_t slotNum : 4; /*!< Slot number control bits in AV mode. */ enet_tx_offload_t txOffloadOps; /*!< Tx checksum offload option. */ } enet_tx_config_struct_t; typedef struct _enet_tx_frame_struct { enet_buffer_struct_t *txBuffArray; /*!< Tx frame buffer structure. */ uint32_t txBuffNum; /*!< Buffer number of this Tx frame. */ enet_tx_config_struct_t txConfig; /*!< Tx extra configuation. */ void *context; /*!< Driver reclaims and gives it in Tx over callback. */ } enet_tx_frame_struct_t; /* Typedef for interrupt handler. */ typedef void (*enet_isr_t)(ENET_Type *base, enet_handle_t *handle); #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to enet clocks for each instance. */ extern const clock_ip_name_t s_enetClock[]; #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * API ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /*! * @name Initialization and De-initialization * @{ */ /*! * @brief Gets the ENET default configuration structure. * * The purpose of this API is to get the default ENET configure * structure for ENET_Init(). User may use the initialized * structure unchanged in ENET_Init(), or modify some fields of the * structure before calling ENET_Init(). * Example: @code enet_config_t config; ENET_GetDefaultConfig(&config); @endcode * @param config The ENET mac controller configuration structure pointer. */ void ENET_GetDefaultConfig(enet_config_t *config); /*! * @brief Initializes the ENET module. * * This function ungates the module clock and initializes it with the ENET basic * configuration. * @note As our transactional transmit API use the zero-copy transmit buffer. * So there are two thing we emphasize here: * 1. Tx buffer free/requeue for application should be done in the Tx * interrupt handler. Please set callback: kENET_TxIntEvent with Tx buffer free/requeue * process APIs. * 2. The Tx interrupt is forced to open. * * @param base ENET peripheral base address. * @param config ENET mac configuration structure pointer. * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig * can be used directly. It is also possible to verify the Mac configuration using other methods. * @param macAddr ENET mac address of Ethernet device. This MAC address should be * provided. * @param refclkSrc_Hz ENET input reference clock. */ void ENET_Init(ENET_Type *base, const enet_config_t *config, uint8_t *macAddr, uint32_t refclkSrc_Hz); /*! * @brief Deinitializes the ENET module. * This function gates the module clock and disables the ENET module. * * @param base ENET peripheral base address. */ void ENET_Deinit(ENET_Type *base); /*! * @brief Initialize for all ENET descriptors. * * @note This function finishes all Tx/Rx descriptors initialization. The descriptor initialization * should be called after ENET_Init(). * * @param base ENET peripheral base address. * @param config The configuration for ENET. * @param bufferConfig All buffers configuration. */ status_t ENET_DescriptorInit(ENET_Type *base, enet_config_t *config, enet_buffer_config_t *bufferConfig); /*! * @brief Allocates Rx buffers for all BDs. * It's used for zero copy Rx. In zero copy Rx case, Rx buffers are dynamic. This function * will populate initial buffers in all BDs for receiving. Then ENET_GetRxFrame() is used * to get Rx frame with zero copy, it will allocate new buffer to replace the buffer in BD taken * by application, application should free those buffers after they're used. * * @note This function should be called after ENET_CreateHandler() and buffer allocating callback * function should be ready. * * @param base ENET peripheral base address. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. */ status_t ENET_RxBufferAllocAll(ENET_Type *base, enet_handle_t *handle); /*! * @brief Frees Rx buffers in all BDs. * It's used for zero copy Rx. In zero copy Rx case, Rx buffers are dynamic. This function * will free left buffers in all BDs. * * @param base ENET peripheral base address. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. */ void ENET_RxBufferFreeAll(ENET_Type *base, enet_handle_t *handle); /*! * @brief Starts the ENET Tx/Rx. * This function enable the Tx/Rx and starts the Tx/Rx DMA. * This shall be set after ENET initialization and before * starting to receive the data. * * @param base ENET peripheral base address. * @param rxRingNum The number of the used Rx rings. It shall not be * larger than the ENET_RING_NUM_MAX(2). If the ringNum is set with * 1, the ring 0 will be used. * @param txRingNum The number of the used Tx rings. It shall not be * larger than the ENET_RING_NUM_MAX(2). If the ringNum is set with * 1, the ring 0 will be used. * * @note This must be called after all the ENET initilization. * And should be called when the ENET receive/transmit is required. */ void ENET_StartRxTx(ENET_Type *base, uint8_t txRingNum, uint8_t rxRingNum); /*! * @brief Set the second level IRQ handler * * @param base ENET peripheral base address. * @param ISRHandler The handler to install. */ void ENET_SetISRHandler(ENET_Type *base, enet_isr_t ISRHandler); /* @} */ /*! * @name MII interface operation * @{ */ /*! * @brief Sets the ENET MII speed and duplex. * * This API is provided to dynamically change the speed and dulpex for MAC. * * @param base ENET peripheral base address. * @param speed The speed of the RMII mode. * @param duplex The duplex of the RMII mode. */ static inline void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex) { uint32_t reg = base->MAC_CONFIG & ~(ENET_MAC_CONFIG_DM_MASK | ENET_MAC_CONFIG_FES_MASK); reg |= ENET_MAC_CONFIG_DM(duplex) | ENET_MAC_CONFIG_FES(speed); base->MAC_CONFIG = reg; } /*! * @brief Sets the ENET SMI(serial management interface)- MII management interface. * * @param base ENET peripheral base address. */ void ENET_SetSMI(ENET_Type *base); /*! * @brief Checks if the SMI is busy. * * @param base ENET peripheral base address. * @return The status of MII Busy status. */ static inline bool ENET_IsSMIBusy(ENET_Type *base) { return ((base->MAC_MDIO_ADDR & ENET_MAC_MDIO_ADDR_MB_MASK) != 0U) ? true : false; } /*! * @brief Reads data from the PHY register through SMI interface. * * @param base ENET peripheral base address. * @return The data read from PHY */ static inline uint16_t ENET_ReadSMIData(ENET_Type *base) { return (uint16_t)(base->MAC_MDIO_DATA & ENET_MAC_MDIO_DATA_MD_MASK); } /*! * @brief Sends the MDIO IEEE802.3 Clause 22 format write command. * * @param base ENET peripheral base address. * @param phyAddr The PHY address. * @param regAddr The PHY register. * @param data The data written to PHY. */ void ENET_StartSMIWrite(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data); /*! * @brief Sends the MDIO IEEE802.3 Clause 22 format read command. * * @param base ENET peripheral base address. * @param phyAddr The PHY address. * @param regAddr The PHY register. */ void ENET_StartSMIRead(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr); /*! * @brief MDIO write with IEEE802.3 Clause 22 format. * * @param base ENET peripheral base address. * @param phyAddr The PHY address. * @param regAddr The PHY register. * @param data The data written to PHY. * @return kStatus_Success MDIO access succeeds. * @return kStatus_Timeout MDIO access timeout. */ status_t ENET_MDIOWrite(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data); /*! * @brief MDIO read with IEEE802.3 Clause 22 format. * * @param base ENET peripheral base address. * @param phyAddr The PHY address. * @param regAddr The PHY register. * @param pData The data read from PHY. * @return kStatus_Success MDIO access succeeds. * @return kStatus_Timeout MDIO access timeout. */ status_t ENET_MDIORead(ENET_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData); /* @} */ /*! * @name Other basic operation * @{ */ /*! * @brief Get the ENET instance from peripheral base address. * * @param base ENET peripheral base address. * @return ENET instance. */ uint32_t ENET_GetInstance(ENET_Type *base); /*! * @brief Sets the ENET module Mac address. * * @param base ENET peripheral base address. * @param macAddr The six-byte Mac address pointer. * The pointer is allocated by application and input into the API. */ static inline void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr) { assert(macAddr); uint32_t lowAddress = ((uint32_t)macAddr[3] << 24) | ((uint32_t)macAddr[2] << 16) | ((uint32_t)macAddr[1] << 8) | ((uint32_t)macAddr[0]); uint32_t highAddress = ((uint32_t)macAddr[5] << 8) | ((uint32_t)macAddr[4]); /* Set Macaddr, the MAC address registers are configured to be double-synchronized to the MII clock domains, then the synchronization is triggered only when bits 31:24 (in little-endian mode) or bits 7:0 (in Big-Endian mode) of the MAC address low register are written to.*/ base->MAC_ADDR_HIGH = highAddress; base->MAC_ADDR_LOW = lowAddress; } /*! * @brief Gets the ENET module Mac address. * * @param base ENET peripheral base address. * @param macAddr The six-byte Mac address pointer. * The pointer is allocated by application and input into the API. */ void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr); /*! * @brief Enable ENET device to accept all multicast frames. * * @param base ENET peripheral base address. */ static inline void ENET_AcceptAllMulticast(ENET_Type *base) { uint32_t reg = base->MAC_FRAME_FILTER; base->MAC_FRAME_FILTER = reg | ENET_MAC_FRAME_FILTER_PM_MASK; } /*! * @brief ENET device reject to accept all multicast frames. * * @param base ENET peripheral base address. */ static inline void ENET_RejectAllMulticast(ENET_Type *base) { uint32_t reg = base->MAC_FRAME_FILTER; base->MAC_FRAME_FILTER = reg & ~ENET_MAC_FRAME_FILTER_PM_MASK; } /*! * @brief Set the MAC to enter into power down mode. * the remote power wake up frame and magic frame can wake up * the ENET from the power down mode. * * @param base ENET peripheral base address. * @param wakeFilter The wakeFilter provided to configure the wake up frame fitlter. * Set the wakeFilter to NULL is not required. But if you have the filter requirement, * please make sure the wakeFilter pointer shall be eight continous * 32-bits configuration. */ void ENET_EnterPowerDown(ENET_Type *base, uint32_t *wakeFilter); /*! * @brief Set the MAC to exit power down mode. * Eixt from the power down mode and recover to normal work mode. * * @param base ENET peripheral base address. */ static inline void ENET_ExitPowerDown(ENET_Type *base) { /* Clear and status ans reset the power down. */ base->MAC_PMT_CRTL_STAT &= ~ENET_MAC_PMT_CRTL_STAT_PWRDWN_MASK; /* Restore the Tx which is disabled when enter power down mode. */ base->DMA_CH[0].DMA_CHX_TX_CTRL |= ENET_DMA_CH_DMA_CHX_TX_CTRL_ST_MASK; base->DMA_CH[1].DMA_CHX_TX_CTRL |= ENET_DMA_CH_DMA_CHX_TX_CTRL_ST_MASK; base->MAC_CONFIG |= ENET_MAC_CONFIG_TE_MASK; } /* @} */ /*! * @name Interrupts. * @{ */ /*! * @brief Enables the ENET DMA and MAC interrupts. * * This function enables the ENET interrupt according to the provided mask. The mask * is a logical OR of enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t. * For example, to enable the dma and mac interrupt, do the following. * @code * ENET_EnableInterrupts(ENET, kENET_DmaRx | kENET_DmaTx | kENET_MacPmt); * @endcode * * @param base ENET peripheral base address. * @param mask ENET interrupts to enable. This is a logical OR of both * enumeration :: enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t. */ void ENET_EnableInterrupts(ENET_Type *base, uint32_t mask); /*! * @brief Disables the ENET DMA and MAC interrupts. * * This function disables the ENET interrupt according to the provided mask. The mask * is a logical OR of enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t. * For example, to disable the dma and mac interrupt, do the following. * @code * ENET_DisableInterrupts(ENET, kENET_DmaRx | kENET_DmaTx | kENET_MacPmt); * @endcode * * @param base ENET peripheral base address. * @param mask ENET interrupts to disables. This is a logical OR of both * enumeration :: enet_dma_interrupt_enable_t and enet_mac_interrupt_enable_t. */ void ENET_DisableInterrupts(ENET_Type *base, uint32_t mask); /*! * @brief Gets the ENET DMA interrupt status flag. * * @param base ENET peripheral base address. * @param channel The DMA Channel. Shall not be larger than ENET_RING_NUM_MAX. * @return The event status of the interrupt source. This is the logical OR of members * of the enumeration :: enet_dma_interrupt_enable_t. */ static inline uint32_t ENET_GetDmaInterruptStatus(ENET_Type *base, uint8_t channel) { return base->DMA_CH[channel].DMA_CHX_STAT; } /*! * @brief Clear the ENET DMA interrupt status flag. * * @param base ENET peripheral base address. * @param channel The DMA Channel. Shall not be larger than ENET_RING_NUM_MAX. * @param mask The event status of the interrupt source. This is the logical OR of members * of the enumeration :: enet_dma_interrupt_enable_t. */ static inline void ENET_ClearDmaInterruptStatus(ENET_Type *base, uint8_t channel, uint32_t mask) { /* Clear the dam interrupt status bit in dma channel interrupt status register. */ base->DMA_CH[channel].DMA_CHX_STAT = mask; } /*! * @brief Gets the ENET MAC interrupt status flag. * * @param base ENET peripheral base address. * @return The event status of the interrupt source. * Use the enum in enet_mac_interrupt_enable_t and right shift * ENET_MACINT_ENUM_OFFSET to mask the returned value to get the * exact interrupt status. */ static inline uint32_t ENET_GetMacInterruptStatus(ENET_Type *base) { return base->MAC_INTR_STAT; } /*! * @brief Clears the ENET mac interrupt events status flag. * * This function clears enabled ENET interrupts according to the provided mask. The mask * is a logical OR of enumeration members. See the @ref enet_mac_interrupt_enable_t. * For example, to clear the TX frame interrupt and RX frame interrupt, do the following. * @code * ENET_ClearMacInterruptStatus(ENET, kENET_MacPmt); * @endcode * * @param base ENET peripheral base address. * @param mask ENET interrupt source to be cleared. * This is the logical OR of members of the enumeration :: enet_mac_interrupt_enable_t. */ void ENET_ClearMacInterruptStatus(ENET_Type *base, uint32_t mask); /* @} */ /*! * @name Functional operation. * @{ */ /*! * @brief Get the Tx descriptor DMA Own flag. * * @param txDesc The given Tx descriptor. * @retval True the dma own Tx descriptor, false application own Tx descriptor. * */ static inline bool ENET_IsTxDescriptorDmaOwn(enet_tx_bd_struct_t *txDesc) { return ((txDesc->tdes3 & ENET_TXDESCRIP_RD_OWN_MASK) != 0U) ? true : false; } /*! * @brief Setup a given Tx descriptor. * This function is a low level functional API to setup or prepare * a given Tx descriptor. * * @param txDesc The given Tx descriptor. * @param buffer1 The first buffer address in the descriptor. * @param bytes1 The bytes in the fist buffer. * @param buffer2 The second buffer address in the descriptor. * @param bytes2 The bytes in the second buffer. * @param framelen The length of the frame to be transmitted. * @param intEnable Interrupt enable flag. * @param tsEnable The timestamp enable. * @param flag The flag of this Tx desciriptor, see "enet_desc_flag_t" . * @param slotNum The slot num used for AV mode only. * * @note This must be called after all the ENET initilization. * And should be called when the ENET receive/transmit is required. * Transmit buffers are 'zero-copy' buffers, so the buffer must remain in * memory until the packet has been fully transmitted. The buffers * should be free or requeued in the transmit interrupt irq handler. */ void ENET_SetupTxDescriptor(enet_tx_bd_struct_t *txDesc, void *buffer1, uint32_t bytes1, void *buffer2, uint32_t bytes2, uint32_t framelen, bool intEnable, bool tsEnable, enet_desc_flag_t flag, uint8_t slotNum); /*! * @brief Update the Tx descriptor tail pointer. * This function is a low level functional API to update the * the Tx descriptor tail. * This is called after you setup a new Tx descriptor to update * the tail pointer to make the new descritor accessable by DMA. * * @param base ENET peripheral base address. * @param channel The Tx DMA channel. * @param txDescTailAddrAlign The new Tx tail pointer address. * */ static inline void ENET_UpdateTxDescriptorTail(ENET_Type *base, uint8_t channel, uint32_t txDescTailAddrAlign) { base->DMA_CH[channel].DMA_CHX_TXDESC_TAIL_PTR = txDescTailAddrAlign & ~ENET_ADDR_ALIGNMENT; } /*! * @brief Update the Rx descriptor tail pointer. * This function is a low level functional API to update the * the Rx descriptor tail. * This is called after you setup a new Rx descriptor to update * the tail pointer to make the new descritor accessable by DMA * and to anouse the Rx poll command for DMA. * * @param base ENET peripheral base address. * @param channel The Rx DMA channel. * @param rxDescTailAddrAlign The new Rx tail pointer address. * */ static inline void ENET_UpdateRxDescriptorTail(ENET_Type *base, uint8_t channel, uint32_t rxDescTailAddrAlign) { base->DMA_CH[channel].DMA_CHX_RXDESC_TAIL_PTR = rxDescTailAddrAlign & ~ENET_ADDR_ALIGNMENT; } /*! * @brief Gets the context in the ENET Rx descriptor. * This function is a low level functional API to get the * the status flag from a given Rx descriptor. * * @param rxDesc The given Rx descriptor. * @retval The RDES3 regions for write-back format Rx buffer descriptor. * * @note This must be called after all the ENET initilization. * And should be called when the ENET receive/transmit is required. */ static inline uint32_t ENET_GetRxDescriptor(enet_rx_bd_struct_t *rxDesc) { assert(rxDesc); return rxDesc->rdes3; } /*! * @brief Updates the buffers and the own status for a given Rx descriptor. * This function is a low level functional API to Updates the * buffers and the own status for a given Rx descriptor. * * @param rxDesc The given Rx descriptor. * @param buffer1 The first buffer address in the descriptor. * @param buffer2 The second buffer address in the descriptor. * @param intEnable Interrupt enable flag. * @param doubleBuffEnable The double buffer enable flag. * * @note This must be called after all the ENET initilization. * And should be called when the ENET receive/transmit is required. */ void ENET_UpdateRxDescriptor( enet_rx_bd_struct_t *rxDesc, void *buffer1, void *buffer2, bool intEnable, bool doubleBuffEnable); /* @} */ /*! * @name Transactional operation * @{ */ /*! * @brief Create ENET Handler * * This is a transactional API and it's provided to store all datas which are needed * during the whole transactional process. This API should not be used when you use * functional APIs to do data Tx/Rx. This is funtion will store many data/flag for * transactional use. * * @param base ENET peripheral base address. * @param handle ENET handler. * @param config ENET configuration. * @param bufferConfig ENET buffer configuration. * @param callback The callback function. * @param userData The application data. */ void ENET_CreateHandler(ENET_Type *base, enet_handle_t *handle, enet_config_t *config, enet_buffer_config_t *bufferConfig, enet_callback_t callback, void *userData); /*! * @brief Gets the size of the read frame. * This function gets a received frame size from the ENET buffer descriptors. * @note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS. * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the * receive buffers If the result is not "kStatus_ENET_RxFrameEmpty". * * @param base ENET peripheral base address. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. * @param length The length of the valid frame received. * @param channel The DMAC channel for the Rx. * @retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame. * @retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data * and NULL length to update the receive buffers. * @retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame * should be called with the right data buffer and the captured data length input. */ status_t ENET_GetRxFrameSize(ENET_Type *base, enet_handle_t *handle, uint32_t *length, uint8_t channel); /*! * @brief Reads a frame from the ENET device. * This function reads a frame from the ENET DMA descriptors. * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer. * For example use Rx dma channel 0: * @code * uint32_t length; * enet_handle_t g_handle; * Comment: Get the received frame size firstly. * status = ENET_GetRxFrameSize(&g_handle, &length, 0); * if (length != 0) * { * Comment: Allocate memory here with the size of "length" * uint8_t *data = memory allocate interface; * if (!data) * { * ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0); * } * else * { * status = ENET_ReadFrame(ENET, &g_handle, data, length, 0); * } * } * else if (status == kStatus_ENET_RxFrameError) * { * Comment: Update the received buffer when a error frame is received. * ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0); * } * @endcode * @param base ENET peripheral base address. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. * @param data The data buffer provided by user to store the frame which memory size should be at least "length". * @param length The size of the data buffer which is still the length of the received frame. * @param channel The Rx DMA channel. Shall not be larger than 2. * @param timestamp The timestamp address to store received timestamp. * @return The execute status, successful or failure. */ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length, uint8_t channel, enet_ptp_time_t *timestamp); /*! * @brief Receives one frame in specified BD ring with zero copy. * * This function will use the user-defined allocate and free callback. Every time application gets one frame through * this function, driver will allocate new buffers for the BDs whose buffers have been taken by application. * @note This function will drop current frame and update related BDs as available for DMA if new buffers allocating * fails. Application must provide a memory pool including at least BD number + 1 buffers(+2 if enable double buffer) * to make this function work normally. If user calls this function in Rx interrupt handler, be careful that this * function makes Rx BD ready with allocating new buffer(normal) or updating current BD(out of memory). If there's * always new Rx frame input, Rx interrupt will be triggered forever. Application need to disable Rx interrupt according * to specific design in this case. * * @param base ENET peripheral base address. * @param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. * @param rxFrame The received frame information structure provided by user. * @param channel The Rx DMA channel. Shall not be larger than 2. * @retval kStatus_Success Succeed to get one frame and allocate new memory for Rx buffer. * @retval kStatus_ENET_RxFrameEmpty There's no Rx frame in the BD. * @retval kStatus_ENET_RxFrameError There's issue in this receiving. In this function, issue frame will be dropped. * @retval kStatus_ENET_RxFrameDrop There's no new buffer memory for BD, dropped this frame. */ status_t ENET_GetRxFrame(ENET_Type *base, enet_handle_t *handle, enet_rx_frame_struct_t *rxFrame, uint8_t channel); /*! * @brief Transmits an ENET frame. * @note The CRC is automatically appended to the data. Input the data * to send without the CRC. This API uses input buffer for Tx, application * should reclaim the buffer after Tx is over. * * @param base ENET peripheral base address. * @param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. * @param txFrame The Tx frame structure. * @param channel Channel to send the frame, same with queue index. * @retval kStatus_Success Send frame succeed. * @retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission. * The transmit busy happens when the data send rate is over the MAC capacity. * The waiting mechanism is recommended to be added after each call return with kStatus_ENET_TxFrameBusy. * Also need to pay attention to reclaim Tx frame after Tx is over. * @retval kStatus_ENET_TxFrameOverLen Transmit frme length exceeds the 0x3FFF limit defined by the driver. */ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, enet_tx_frame_struct_t *txFrame, uint8_t channel); /*! * @brief Reclaim Tx descriptors. * This function is used to update the Tx descriptor status and * store the Tx timestamp when the 1588 feature is enabled. * This is called by the transmit interupt IRQ handler after the * complete of a frame transmission. * * @param base ENET peripheral base address. * @param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. * @param channel The Tx DMA channnel. * */ void ENET_ReclaimTxDescriptor(ENET_Type *base, enet_handle_t *handle, uint8_t channel); /*! * @brief The ENET IRQ handler. * * @param base ENET peripheral base address. * @param handle The ENET handler pointer. */ void ENET_IRQHandler(ENET_Type *base, enet_handle_t *handle); /* @} */ #ifdef ENET_PTP1588FEATURE_REQUIRED /*! * @name ENET Enhanced function operation * @{ */ /*! * @brief Coreect the ENET PTP 1588 timer in coarse method. * * @param base ENET peripheral base address. * @param operation The system time operation, refer to "enet_systime_op_t" * @param second The correction second. * @param nanosecond The correction nanosecond. */ void ENET_Ptp1588CorrectTimerInCoarse(ENET_Type *base, enet_systime_op_t operation, uint32_t second, uint32_t nanosecond); /*! * @brief Coreect the ENET PTP 1588 timer in fine method. * * * @param base ENET peripheral base address. * @param addend The addend value to be set in the fine method * @note Should take refer to the chapter "System time corretion" and * see the description for the "fine correction method". */ static inline void ENET_Ptp1588CorrectTimerInFine(ENET_Type *base, uint32_t addend) { /* Set the freqCompensation value. */ base->MAC_SYS_TIMESTMP_ADDEND = addend; base->MAC_TIMESTAMP_CTRL |= ENET_MAC_TIMESTAMP_CTRL_TADDREG_MASK; } /*! * @brief Get the ENET Time stamp current addend value. * * @param base ENET peripheral base address. * @return The addend value. */ static inline uint32_t ENET_Ptp1588GetAddend(ENET_Type *base) { return base->MAC_SYS_TIMESTMP_ADDEND; } /*! * @brief Gets the current ENET time from the PTP 1588 timer. * Interrupts are not disabled. * * @param base ENET peripheral base address. * @param second The PTP 1588 system timer second. * @param nanosecond The PTP 1588 system timer nanosecond. */ void ENET_Ptp1588GetTimerNoIrqDisable(ENET_Type *base, uint64_t *second, uint32_t *nanosecond); /*! * @brief Gets the current ENET time from the PTP 1588 timer. * * @param base ENET peripheral base address. * @param second The PTP 1588 system timer second. * @param nanosecond The PTP 1588 system timer nanosecond. * For the unit of the nanosecond is 1ns. So the nanosecond is the real nanosecond. */ void ENET_Ptp1588GetTimer(ENET_Type *base, uint64_t *second, uint32_t *nanosecond); #endif /* ENET_PTP1588FEATURE_REQUIRED */ /* @} */ #if defined(__cplusplus) } #endif /*! @}*/ #endif /* _FSL_ENET_H_ */