diff --git a/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/MIMXRT1176_cm7_features.h b/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/MIMXRT1176_cm7_features.h index 2db8bb585a015211a4e1bec52af7ffa186942bf2..81f75b6f414807b03b63c205172c3badd1a774b0 100644 --- a/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/MIMXRT1176_cm7_features.h +++ b/bsp/imxrt/libraries/MIMXRT1170/MIMXRT1176/MIMXRT1176_cm7_features.h @@ -340,9 +340,9 @@ /* @brief Support Interrupt Coalesce */ #define FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE (1) /* @brief Queue Size. */ -#define FSL_FEATURE_ENET_QUEUE (1) +#define FSL_FEATURE_ENET_QUEUE (3) /* @brief Has AVB Support. */ -#define FSL_FEATURE_ENET_HAS_AVB (0) +#define FSL_FEATURE_ENET_HAS_AVB (1) /* @brief Has Timer Pulse Width control. */ #define FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL (1) /* @brief Has Extend MDIO Support. */ diff --git a/bsp/imxrt/libraries/MIMXRT1170/SConscript b/bsp/imxrt/libraries/MIMXRT1170/SConscript index af8e330de51cda4f56480b808f01330688b0016e..232eadc268cf29b01e2919fb2aef4b3947b013cd 100644 --- a/bsp/imxrt/libraries/MIMXRT1170/SConscript +++ b/bsp/imxrt/libraries/MIMXRT1170/SConscript @@ -43,6 +43,9 @@ if GetDepend(['BSP_USING_SDIO']): if GetDepend(['BSP_USING_SDRAM']): src += ['MIMXRT1176/drivers/fsl_semc.c'] +if GetDepend(['BSP_USING_ETH']): + src += ['MIMXRT1176/drivers/fsl_enet.c'] + if rtconfig.PLATFORM in ['gcc']: group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, ASFLAGS = '$ASFLAGS -D __STARTUP_CLEAR_BSS') else: diff --git a/bsp/imxrt/libraries/drivers/drv_eth.c b/bsp/imxrt/libraries/drivers/drv_eth.c index d57419df947306971f5cb1f279c95f2ba97b4f38..6fa053337d8349317ec8abdafb4d5987d102ff8f 100644 --- a/bsp/imxrt/libraries/drivers/drv_eth.c +++ b/bsp/imxrt/libraries/drivers/drv_eth.c @@ -15,7 +15,7 @@ #include #ifdef RT_USING_FINSH - #include +#include #endif #include "fsl_enet.h" @@ -35,16 +35,45 @@ #define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN) /* debug option */ +#define ETH_RX_DUMP #undef ETH_RX_DUMP +#define ETH_TX_DUMP #undef ETH_TX_DUMP #define DBG_ENABLE -#define DBG_SECTION_NAME "[ETH]" +#define DBG_SECTION_NAME "[ETH]" #define DBG_COLOR -#define DBG_LEVEL DBG_INFO +#define DBG_LEVEL DBG_INFO #include #define MAX_ADDR_LEN 6 +#define ENET_RING_NUM 1U +#define RING_ID 0 + +typedef uint8_t rx_buffer_t[RT_ALIGN(ENET_TXBUFF_SIZE, ENET_BUFF_ALIGNMENT)]; +typedef uint8_t tx_buffer_t[RT_ALIGN(ENET_TXBUFF_SIZE, ENET_BUFF_ALIGNMENT)]; + +#ifndef ENET_RXBUFF_NUM +#define ENET_RXBUFF_NUM (ENET_RXBD_NUM * 2) +#endif + +typedef void (*pbuf_free_custom_fn)(struct pbuf *p); + +/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ +struct pbuf_custom +{ + /** The actual pbuf */ + struct pbuf pbuf; + /** This function is called when pbuf_free deallocates this pbuf(_custom) */ + pbuf_free_custom_fn custom_free_function; +}; + +typedef struct rx_pbuf_wrapper +{ + struct pbuf_custom p; /*!< Pbuf wrapper. Has to be first. */ + void *buffer; /*!< Original buffer wrapped by p. */ + volatile bool buffer_used; /*!< Wrapped buffer is used by ENET */ +} rx_pbuf_wrapper_t; struct rt_imxrt_eth { @@ -54,20 +83,29 @@ struct rt_imxrt_eth enet_handle_t enet_handle; ENET_Type *enet_base; enet_data_error_stats_t error_statistic; - rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ + rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ rt_bool_t tx_is_waiting; struct rt_semaphore tx_wait; + struct rt_semaphore buff_wait; enet_mii_speed_t speed; enet_mii_duplex_t duplex; + + enet_rx_bd_struct_t *RxBuffDescrip; + enet_tx_bd_struct_t *TxBuffDescrip; + rx_buffer_t *RxDataBuff; + tx_buffer_t *TxDataBuff; + rx_pbuf_wrapper_t RxPbufs[ENET_RXBUFF_NUM]; }; -AT_NONCACHEABLE_SECTION_ALIGN(enet_tx_bd_struct_t g_txBuffDescrip[ENET_TXBD_NUM], ENET_BUFF_ALIGNMENT); -ALIGN(ENET_BUFF_ALIGNMENT) rt_uint8_t g_txDataBuff[ENET_TXBD_NUM][RT_ALIGN(ENET_TXBUFF_SIZE, ENET_BUFF_ALIGNMENT)]; +AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t g_txBuffDescrip[ENET_TXBD_NUM], ENET_BUFF_ALIGNMENT); +ALIGN(ENET_BUFF_ALIGNMENT) +rt_uint8_t g_txDataBuff[ENET_TXBD_NUM][RT_ALIGN(ENET_TXBUFF_SIZE, ENET_BUFF_ALIGNMENT)]; -AT_NONCACHEABLE_SECTION_ALIGN(enet_rx_bd_struct_t g_rxBuffDescrip[ENET_RXBD_NUM], ENET_BUFF_ALIGNMENT); -ALIGN(ENET_BUFF_ALIGNMENT) rt_uint8_t g_rxDataBuff[ENET_RXBD_NUM][RT_ALIGN(ENET_RXBUFF_SIZE, ENET_BUFF_ALIGNMENT)]; +AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t g_rxBuffDescrip[ENET_RXBD_NUM], ENET_BUFF_ALIGNMENT); +ALIGN(ENET_BUFF_ALIGNMENT) +rt_uint8_t g_rxDataBuff[ENET_RXBD_NUM][RT_ALIGN(ENET_RXBUFF_SIZE, ENET_BUFF_ALIGNMENT)]; static struct rt_imxrt_eth imxrt_eth_device; @@ -91,7 +129,14 @@ void _enet_tx_callback(struct rt_imxrt_eth *eth) } } -void _enet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, void *userData) +static void _enet_callback(ENET_Type *base, + enet_handle_t *handle, +#if FSL_FEATURE_ENET_QUEUE > 1 + uint32_t ringId, +#endif /* FSL_FEATURE_ENET_QUEUE */ + enet_event_t event, + enet_frame_info_t *frameInfo, + void *userData) { switch (event) { @@ -101,6 +146,7 @@ void _enet_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event, break; case kENET_TxEvent: + _enet_tx_callback((struct rt_imxrt_eth *)userData); break; @@ -130,6 +176,17 @@ static void _enet_clk_init(void) { #ifdef SOC_IMXRT1170_SERIES +#ifdef PHY_USING_RTL8211F + const clock_sys_pll1_config_t sysPll1Config = { + .pllDiv2En = true, + }; + CLOCK_InitSysPll1(&sysPll1Config); + + clock_root_config_t rootCfg = {.mux = 4, .div = 4}; /* Generate 125M root clock. */ + CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg); + IOMUXC_GPR->GPR5 |= IOMUXC_GPR_GPR5_ENET1G_RGMII_EN_MASK; /* bit1:iomuxc_gpr_enet_clk_dir + bit0:GPR_ENET_TX_CLK_SEL(internal or OSC) */ +#else const clock_sys_pll1_config_t sysPll1Config = { .pllDiv2En = true, }; @@ -142,33 +199,116 @@ static void _enet_clk_init(void) rootCfg.mux = 7; rootCfg.div = 2; CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg); /* Generate 198M bus clock. */ - IOMUXC_GPR->GPR4 |= 0x3; + IOMUXC_GPR->GPR4 |= 0x3; +#endif #else const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1}; CLOCK_InitEnetPll(&config); IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true); - IOMUXC_GPR->GPR1|=1<<23; + IOMUXC_GPR->GPR1 |= 1 << 23; #endif } +static void *_enet_rx_alloc(ENET_Type *base, void *userData, uint8_t ringId) +{ + void *buffer = NULL; + int i; + + // dbg_log(DBG_LOG, "get buff_wait sem in %d\r\n", __LINE__); + rt_sem_take(&imxrt_eth_device.buff_wait, RT_WAITING_FOREVER); + + for (i = 0; i < ENET_RXBUFF_NUM; i++) + { + if (!imxrt_eth_device.RxPbufs[i].buffer_used) + { + imxrt_eth_device.RxPbufs[i].buffer_used = true; + buffer = &imxrt_eth_device.RxDataBuff[i]; + break; + } + } + + rt_sem_release(&imxrt_eth_device.buff_wait); + // dbg_log(DBG_LOG, "release buff_wait sem in %d\r\n", __LINE__); + + return buffer; +} + +static void _enet_rx_free(ENET_Type *base, void *buffer, void *userData, uint8_t ringId) +{ + int idx = ((rx_buffer_t *)buffer) - imxrt_eth_device.RxDataBuff; + if (!((idx >= 0) && (idx < ENET_RXBUFF_NUM))) + { + LOG_E("Freed buffer out of range\r\n"); + } + + // dbg_log(DBG_LOG, "get buff_wait sem in %d\r\n", __LINE__); + rt_sem_take(&imxrt_eth_device.buff_wait, RT_WAITING_FOREVER); + if (!(imxrt_eth_device.RxPbufs[idx].buffer_used)) + { + LOG_E("_enet_rx_free: freeing unallocated buffer\r\n"); + } + imxrt_eth_device.RxPbufs[idx].buffer_used = false; + rt_sem_release(&imxrt_eth_device.buff_wait); + // dbg_log(DBG_LOG, "release buff_wait sem in %d\r\n", __LINE__); +} + +/** + * Reclaims RX buffer held by the p after p is no longer used + * by the application / lwIP. + */ +static void _enet_rx_release(struct pbuf *p) +{ + rx_pbuf_wrapper_t *wrapper = (rx_pbuf_wrapper_t *)p; + _enet_rx_free(imxrt_eth_device.enet_base, wrapper->buffer, &imxrt_eth_device, 0); +} + static void _enet_config(void) { enet_config_t config; uint32_t sysClock; + enet_buffer_config_t buffConfig[ENET_RING_NUM]; + int i; + +#ifdef PHY_USING_RTL8211F + EnableIRQ(ENET_1G_MAC0_Tx_Rx_1_IRQn); + EnableIRQ(ENET_1G_MAC0_Tx_Rx_2_IRQn); +#endif + + imxrt_eth_device.RxBuffDescrip = &g_rxBuffDescrip[0]; + imxrt_eth_device.TxBuffDescrip = &g_txBuffDescrip[0]; + imxrt_eth_device.RxDataBuff = &g_rxDataBuff[0]; + imxrt_eth_device.TxDataBuff = &g_txDataBuff[0]; /* prepare the buffer configuration. */ - enet_buffer_config_t buffConfig = - { - ENET_RXBD_NUM, - ENET_TXBD_NUM, - SDK_SIZEALIGN(ENET_RXBUFF_SIZE, ENET_BUFF_ALIGNMENT), - SDK_SIZEALIGN(ENET_TXBUFF_SIZE, ENET_BUFF_ALIGNMENT), - &g_rxBuffDescrip[0], - &g_txBuffDescrip[0], - &g_rxDataBuff[0][0], - &g_txDataBuff[0][0], - }; + // enet_buffer_config_t buffConfig[RING_NUM] = + // { + // ENET_RXBD_NUM, + // ENET_TXBD_NUM, + // sizeof(rx_buffer_t), + // sizeof(tx_buffer_t), + // &imxrt_eth_device.RxBuffDescrip[0], + // &imxrt_eth_device.TxBuffDescrip[0], + // NULL, + // &imxrt_eth_device.TxDataBuff[0][0], + // true, + // true, + // NULL, + // }; + buffConfig[0].rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */ + buffConfig[0].txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */ + buffConfig[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */ + buffConfig[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */ + buffConfig[0].rxBdStartAddrAlign = + &(imxrt_eth_device.RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */ + buffConfig[0].txBdStartAddrAlign = + &(imxrt_eth_device.TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */ + buffConfig[0].rxBufferAlign = + NULL; /* Receive data buffer start address. NULL when buffers are allocated by callback for RX zero-copy. */ + buffConfig[0].txBufferAlign = &(imxrt_eth_device.TxDataBuff[0][0]); /* Transmit data buffer start address. */ + buffConfig[0].txFrameInfo = NULL; /* Transmit frame information start address. Set only if using zero-copy transmit. */ + buffConfig[0].rxMaintainEnable = true; /* Receive buffer cache maintain. */ + buffConfig[0].txMaintainEnable = true; /* Transmit buffer cache maintain. */ /* Get default configuration. */ /* @@ -178,10 +318,17 @@ static void _enet_config(void) * config.rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN; */ ENET_GetDefaultConfig(&config); - config.interrupt = kENET_TxFrameInterrupt | kENET_RxFrameInterrupt; + config.ringNum = ENET_RING_NUM; config.miiSpeed = imxrt_eth_device.speed; config.miiDuplex = imxrt_eth_device.duplex; - +#ifdef PHY_USING_RTL8211F + config.miiMode = kENET_RgmiiMode; +#else + config.miiMode = kENET_RmiiMode; +#endif + config.rxBuffAlloc = _enet_rx_alloc; + config.rxBuffFree = _enet_rx_free; + config.userData = &imxrt_eth_device; /* Set SMI to get PHY link status. */ #ifdef SOC_IMXRT1170_SERIES sysClock = CLOCK_GetRootClockFreq(kCLOCK_Root_Bus); @@ -189,17 +336,30 @@ static void _enet_config(void) sysClock = CLOCK_GetFreq(kCLOCK_AhbClk); #endif - dbg_log(DBG_LOG, "deinit\n"); - ENET_Deinit(imxrt_eth_device.enet_base); + // dbg_log(DBG_LOG, "deinit\n"); + // ENET_Deinit(imxrt_eth_device.enet_base); + + config.interrupt |= kENET_TxFrameInterrupt | kENET_RxFrameInterrupt | kENET_TxBufferInterrupt | kENET_LateCollisionInterrupt; + config.callback = _enet_callback; + + for (i = 0; i < ENET_RXBUFF_NUM; i++) + { + imxrt_eth_device.RxPbufs[i].p.custom_free_function = _enet_rx_release; + imxrt_eth_device.RxPbufs[i].buffer = &(imxrt_eth_device.RxDataBuff[i][0]); + imxrt_eth_device.RxPbufs[i].buffer_used = false; + } + + // dbg_log(DBG_LOG, "deinit\n"); + // ENET_Deinit(imxrt_eth_device.enet_base); dbg_log(DBG_LOG, "init\n"); - ENET_Init(imxrt_eth_device.enet_base, &imxrt_eth_device.enet_handle, &config, &buffConfig, &imxrt_eth_device.dev_addr[0], sysClock); - dbg_log(DBG_LOG, "set call back\n"); - ENET_SetCallback(&imxrt_eth_device.enet_handle, _enet_callback, &imxrt_eth_device); + ENET_Init(imxrt_eth_device.enet_base, &imxrt_eth_device.enet_handle, &config, &buffConfig[0], &imxrt_eth_device.dev_addr[0], sysClock); + // dbg_log(DBG_LOG, "set call back\n"); + // ENET_SetCallback(&imxrt_eth_device.enet_handle, _enet_callback, &imxrt_eth_device); dbg_log(DBG_LOG, "active read\n"); ENET_ActiveRead(imxrt_eth_device.enet_base); } -#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP) +#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP) static void packet_dump(const char *msg, const struct pbuf *p) { const struct pbuf *q; @@ -278,205 +438,25 @@ static rt_err_t rt_imxrt_eth_control(rt_device_t dev, int cmd, void *args) { case NIOCTL_GADDR: /* get mac address */ - if (args) rt_memcpy(args, imxrt_eth_device.dev_addr, 6); - else return -RT_ERROR; + if (args) + rt_memcpy(args, imxrt_eth_device.dev_addr, 6); + else + return -RT_ERROR; break; - default : + default: break; } return RT_EOK; } -static void _ENET_ActiveSend(ENET_Type *base, uint32_t ringId) -{ - assert(ringId < FSL_FEATURE_ENET_QUEUE); - - switch (ringId) - { - case 0: - base->TDAR = ENET_TDAR_TDAR_MASK; - break; -#if FSL_FEATURE_ENET_QUEUE > 1 - case 1: - base->TDAR1 = ENET_TDAR1_TDAR_MASK; - break; - case 2: - base->TDAR2 = ENET_TDAR2_TDAR_MASK; - break; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - default: - base->TDAR = ENET_TDAR_TDAR_MASK; - break; - } -} - -static status_t _ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, const uint8_t *data, uint32_t length) -{ - assert(handle); - assert(data); - - volatile enet_tx_bd_struct_t *curBuffDescrip; - uint32_t len = 0; - uint32_t sizeleft = 0; - uint32_t address; - - /* Check the frame length. */ - if (length > ENET_FRAME_MAX_FRAMELEN) - { - return kStatus_ENET_TxFrameOverLen; - } - - /* Check if the transmit buffer is ready. */ - curBuffDescrip = handle->txBdCurrent[0]; - if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK) - { - return kStatus_ENET_TxFrameBusy; - } -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - bool isPtpEventMessage = false; - /* Check PTP message with the PTP header. */ - isPtpEventMessage = ENET_Ptp1588ParseFrame(data, NULL, true); -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - /* One transmit buffer is enough for one frame. */ - if (handle->txBuffSizeAlign[0] >= length) - { - /* Copy data to the buffer for uDMA transfer. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer,kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - - pbuf_copy_partial((const struct pbuf *)data, (void *)address, length, 0); - - /* Set data length. */ - curBuffDescrip->length = length; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if (isPtpEventMessage) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); - - /* Increase the buffer descriptor address. */ - if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK) - { - handle->txBdCurrent[0] = handle->txBdBase[0]; - } - else - { - handle->txBdCurrent[0]++; - } -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - /* Add the cache clean maintain. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer,kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - DCACHE_CleanByRange(address, length); -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - /* Active the transmit buffer descriptor. */ - _ENET_ActiveSend(base, 0); - - return kStatus_Success; - } - else - { - /* One frame requires more than one transmit buffers. */ - do - { -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if (isPtpEventMessage) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* Increase the buffer descriptor address. */ - if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK) - { - handle->txBdCurrent[0] = handle->txBdBase[0]; - } - else - { - handle->txBdCurrent[0]++; - } - /* update the size left to be transmit. */ - sizeleft = length - len; - if (sizeleft > handle->txBuffSizeAlign[0]) - { - /* Data copy. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer,kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - memcpy((void *)address, data + len, handle->txBuffSizeAlign[0]); - /* Data length update. */ - curBuffDescrip->length = handle->txBuffSizeAlign[0]; - len += handle->txBuffSizeAlign[0]; - /* Sets the control flag. */ - curBuffDescrip->control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK; - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; - /* Active the transmit buffer descriptor*/ - _ENET_ActiveSend(base, 0); - } - else - { -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer,kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - memcpy((void *)address, data + len, sizeleft); - curBuffDescrip->length = sizeleft; - /* Set Last buffer wrap flag. */ - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK; -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - /* Add the cache clean maintain. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer,kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - DCACHE_CleanByRange(address, handle->txBuffSizeAlign[0]); -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - /* Active the transmit buffer descriptor. */ - _ENET_ActiveSend(base, 0); - - return kStatus_Success; - } - - /* Get the current buffer descriptor address. */ - curBuffDescrip = handle->txBdCurrent[0]; - - } while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)); - - return kStatus_ENET_TxFrameBusy; - } -} - /* ethernet device interface */ /* transmit packet. */ rt_err_t rt_imxrt_eth_tx(rt_device_t dev, struct pbuf *p) { rt_err_t result = RT_EOK; - enet_handle_t * enet_handle = &imxrt_eth_device.enet_handle; + enet_handle_t *enet_handle = &imxrt_eth_device.enet_handle; RT_ASSERT(p != NULL); RT_ASSERT(enet_handle != RT_NULL); @@ -489,7 +469,7 @@ rt_err_t rt_imxrt_eth_tx(rt_device_t dev, struct pbuf *p) do { - result = _ENET_SendFrame(imxrt_eth_device.enet_base, enet_handle, (const uint8_t *)p, p->tot_len); + result = ENET_SendFrame(imxrt_eth_device.enet_base, enet_handle, (const uint8_t *)p, p->tot_len, RING_ID, false, NULL); if (result == kStatus_ENET_TxFrameBusy) { @@ -497,8 +477,7 @@ rt_err_t rt_imxrt_eth_tx(rt_device_t dev, struct pbuf *p) rt_sem_take(&imxrt_eth_device.tx_wait, RT_WAITING_FOREVER); } - } - while (result == kStatus_ENET_TxFrameBusy); + } while (result == kStatus_ENET_TxFrameBusy); return RT_EOK; } @@ -515,7 +494,7 @@ struct pbuf *rt_imxrt_eth_rx(rt_device_t dev) enet_data_error_stats_t *error_statistic = &imxrt_eth_device.error_statistic; /* Get the Frame size */ - status = ENET_GetRxFrameSize(enet_handle, &length); + status = ENET_GetRxFrameSize(enet_handle, &length, RING_ID); /* Call ENET_ReadFrame when there is a received frame. */ if (length != 0) @@ -525,7 +504,7 @@ struct pbuf *rt_imxrt_eth_rx(rt_device_t dev) if (p != NULL) { - status = ENET_ReadFrame(enet_base, enet_handle, p->payload, length); + status = ENET_ReadFrame(enet_base, enet_handle, p->payload, length, RING_ID, NULL); if (status == kStatus_Success) { #ifdef ETH_RX_DUMP @@ -549,9 +528,9 @@ struct pbuf *rt_imxrt_eth_rx(rt_device_t dev) dbg_log(DBG_WARNING, "ENET_GetRxFrameSize: kStatus_ENET_RxFrameError\n"); /* Update the received buffer when error happened. */ /* Get the error information of the received g_frame. */ - ENET_GetRxErrBeforeReadFrame(enet_handle, error_statistic); + ENET_GetRxErrBeforeReadFrame(enet_handle, error_statistic, RING_ID); /* update the receive buffer. */ - ENET_ReadFrame(enet_base, enet_handle, NULL, 0); + ENET_ReadFrame(enet_base, enet_handle, NULL, 0, RING_ID, NULL); } ENET_EnableInterrupts(enet_base, kENET_RxFrameInterrupt); @@ -566,29 +545,54 @@ static void phy_monitor_thread_entry(void *parameter) rt_uint32_t duplex; rt_bool_t link = RT_FALSE; +#ifdef SOC_IMXRT1170_SERIES +#ifdef PHY_USING_RTL8211F + phy_dev = (struct rt_phy_device *)rt_device_find("rtl8211f"); + if ((RT_NULL == phy_dev) || (RT_NULL == phy_dev->ops)) + { + // TODO print warning information + LOG_E("Can not find phy device called \"rtl8211f\""); + return; + } +#else + phy_dev = (struct rt_phy_device *)rt_device_find("ksz8081"); + if ((RT_NULL == phy_dev) || (RT_NULL == phy_dev->ops)) + { + // TODO print warning information + LOG_E("Can not find phy device called \"ksz8081\""); + return; + } +#endif +#else phy_dev = (struct rt_phy_device *)rt_device_find("rtt-phy"); if ((RT_NULL == phy_dev) || (RT_NULL == phy_dev->ops)) { // TODO print warning information LOG_E("Can not find phy device called \"rtt-phy\""); - return ; + return; } +#endif + if (RT_NULL == phy_dev->ops->init) { LOG_E("phy driver error!"); - return ; + return; } #ifdef SOC_IMXRT1170_SERIES - rt_phy_status status = phy_dev->ops->init(imxrt_eth_device.enet_base, PHY_DEVICE_ADDRESS, CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)); +#ifdef PHY_USING_RTL8211F + rt_phy_status status = phy_dev->ops->init(imxrt_eth_device.enet_base, PHY_RTL8211F_ADDRESS, CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)); +#else + rt_phy_status status = phy_dev->ops->init(imxrt_eth_device.enet_base, PHY_KSZ8081_ADDRESS, CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)); +#endif #else rt_phy_status status = phy_dev->ops->init(imxrt_eth_device.enet_base, PHY_DEVICE_ADDRESS, CLOCK_GetFreq(kCLOCK_AhbClk)); #endif if (PHY_STATUS_OK != status) { LOG_E("Phy device initialize unsuccessful!\n"); - return ; + return; } - + LOG_I("Phy device initialize successfully!\n"); while (1) { rt_bool_t new_link = RT_FALSE; @@ -606,10 +610,14 @@ static void phy_monitor_thread_entry(void *parameter) { dbg_log(DBG_LOG, "10M\n"); } - else + else if (PHY_SPEED_100M == speed) { dbg_log(DBG_LOG, "100M\n"); } + else + { + dbg_log(DBG_LOG, "1000M\n"); + } if (PHY_HALF_DUPLEX == duplex) { @@ -653,6 +661,21 @@ static int rt_hw_imxrt_eth_init(void) _enet_clk_init(); +#ifdef PHY_USING_RTL8211F + /* NXP (Freescale) MAC OUI */ + imxrt_eth_device.dev_addr[0] = 0x54; + imxrt_eth_device.dev_addr[1] = 0x27; + imxrt_eth_device.dev_addr[2] = 0x8d; + /* generate MAC addr from 96bit unique ID (only for test). */ + imxrt_eth_device.dev_addr[3] = 0x11; + imxrt_eth_device.dev_addr[4] = 0x22; + imxrt_eth_device.dev_addr[5] = 0x33; + + imxrt_eth_device.speed = kENET_MiiSpeed1000M; + imxrt_eth_device.duplex = kENET_MiiFullDuplex; + + imxrt_eth_device.enet_base = ENET_1G; +#else /* NXP (Freescale) MAC OUI */ imxrt_eth_device.dev_addr[0] = 0x00; imxrt_eth_device.dev_addr[1] = 0x04; @@ -666,22 +689,26 @@ static int rt_hw_imxrt_eth_init(void) imxrt_eth_device.duplex = kENET_MiiFullDuplex; imxrt_eth_device.enet_base = ENET; +#endif + imxrt_eth_device.parent.parent.init = rt_imxrt_eth_init; + imxrt_eth_device.parent.parent.open = rt_imxrt_eth_open; + imxrt_eth_device.parent.parent.close = rt_imxrt_eth_close; + imxrt_eth_device.parent.parent.read = rt_imxrt_eth_read; + imxrt_eth_device.parent.parent.write = rt_imxrt_eth_write; + imxrt_eth_device.parent.parent.control = rt_imxrt_eth_control; + imxrt_eth_device.parent.parent.user_data = RT_NULL; - imxrt_eth_device.parent.parent.init = rt_imxrt_eth_init; - imxrt_eth_device.parent.parent.open = rt_imxrt_eth_open; - imxrt_eth_device.parent.parent.close = rt_imxrt_eth_close; - imxrt_eth_device.parent.parent.read = rt_imxrt_eth_read; - imxrt_eth_device.parent.parent.write = rt_imxrt_eth_write; - imxrt_eth_device.parent.parent.control = rt_imxrt_eth_control; - imxrt_eth_device.parent.parent.user_data = RT_NULL; - - imxrt_eth_device.parent.eth_rx = rt_imxrt_eth_rx; - imxrt_eth_device.parent.eth_tx = rt_imxrt_eth_tx; + imxrt_eth_device.parent.eth_rx = rt_imxrt_eth_rx; + imxrt_eth_device.parent.eth_tx = rt_imxrt_eth_tx; dbg_log(DBG_LOG, "sem init: tx_wait\r\n"); /* init tx semaphore */ rt_sem_init(&imxrt_eth_device.tx_wait, "tx_wait", 0, RT_IPC_FLAG_FIFO); + dbg_log(DBG_LOG, "sem init: buff_wait\r\n"); + /* init tx semaphore */ + rt_sem_init(&imxrt_eth_device.buff_wait, "buff_wait", 1, RT_IPC_FLAG_FIFO); + /* register eth device */ dbg_log(DBG_LOG, "eth_device_init start\r\n"); state = eth_device_init(&(imxrt_eth_device.parent), "e0"); @@ -698,17 +725,17 @@ static int rt_hw_imxrt_eth_init(void) /* start phy monitor */ { - #ifdef BSP_USING_PHY +#ifdef BSP_USING_PHY rt_thread_t tid; tid = rt_thread_create("phy", phy_monitor_thread_entry, RT_NULL, - 512, + 1024, RT_THREAD_PRIORITY_MAX - 2, 2); if (tid != RT_NULL) rt_thread_startup(tid); - #endif +#endif } return state; @@ -779,7 +806,7 @@ void enet_reg_dump(void) { ENET_Type *enet_base = imxrt_eth_device.enet_base; -#define DUMP_REG(__REG) \ +#define DUMP_REG(__REG) \ rt_kprintf("%s(%08X): %08X\n", #__REG, (uint32_t)&enet_base->__REG, enet_base->__REG) DUMP_REG(EIR); @@ -816,7 +843,7 @@ void enet_reg_dump(void) DUMP_REG(FTRL); DUMP_REG(TACC); DUMP_REG(RACC); - // DUMP_REG(RMON_T_DROP); + // DUMP_REG(RMON_T_DROP); DUMP_REG(RMON_T_PACKETS); DUMP_REG(RMON_T_BC_PKT); DUMP_REG(RMON_T_MC_PKT); @@ -854,7 +881,7 @@ void enet_reg_dump(void) DUMP_REG(RMON_R_OVERSIZE); DUMP_REG(RMON_R_FRAG); DUMP_REG(RMON_R_JAB); - // DUMP_REG(RMON_R_RESVD_0); + // DUMP_REG(RMON_R_RESVD_0); DUMP_REG(RMON_R_P64); DUMP_REG(RMON_R_P65TO127); DUMP_REG(RMON_R_P128TO255); @@ -889,7 +916,7 @@ void enet_rx_stat(void) { enet_data_error_stats_t *error_statistic = &imxrt_eth_device.error_statistic; -#define DUMP_STAT(__VAR) \ +#define DUMP_STAT(__VAR) \ rt_kprintf("%-25s: %08X\n", #__VAR, error_statistic->__VAR); DUMP_STAT(statsRxLenGreaterErr); @@ -912,7 +939,6 @@ void enet_rx_stat(void) DUMP_STAT(statsTxUnderFlowErr); DUMP_STAT(statsTxTsErr); #endif - } void enet_buf_info(void)