optimize ethernet

Signed-off-by: Hongpeng Huo <hongpeng.huo@hpmicro.com>
This commit is contained in:
Hongpeng Huo
2022-09-27 00:45:36 +08:00
parent 6294d3dfc7
commit 3bb2b429b2
4 changed files with 92 additions and 95 deletions
+74 -83
View File
@@ -78,64 +78,67 @@ static void low_level_init(struct netif *netif)
static err_t low_level_output(struct netif *netif, struct pbuf *p)
{
struct HpmEnetDevice *dev = (struct HpmEnetDevice *)netif->state;
__IO enet_desc_t *desc = &dev->desc;
__IO uint32_t enet_tx_buff_size = desc->tx_buff_cfg.size;
enet_desc_t *desc = &dev->desc;
uint32_t tx_buff_size = desc->tx_buff_cfg.size;
struct pbuf *q;
uint8_t *buffer;
__IO enet_tx_desc_t *dma_tx_desc;
uint16_t frame_length = 0;
uint32_t frame_length = 0;
uint32_t buffer_offset = 0;
uint32_t bytes_left_to_copy = 0;
uint32_t payload_offset = 0;
enet_tx_desc_t *tx_desc_list_cur = desc->tx_desc_list_cur;
dma_tx_desc = tx_desc_list_cur;
buffer = (uint8_t *)(dma_tx_desc->tdes2_bm.buffer1);
buffer_offset = 0;
for (q = p; q != NULL; q = q->next) {
/* Get bytes in current lwIP buffer */
/* copy frame from pbufs to driver buffers */
for (q = p; q != NULL; q = q->next)
{
/* Get bytes in current lwIP buffer */
bytes_left_to_copy = q->len;
payload_offset = 0;
if (dma_tx_desc->tdes0_bm.own != 0) {
return ERR_BUF;
}
/* Check if the length of data to copy is bigger than Tx buffer size*/
while ((bytes_left_to_copy + buffer_offset) > enet_tx_buff_size) {
while ((bytes_left_to_copy + buffer_offset) > tx_buff_size)
{
/* Copy data to Tx buffer*/
memcpy((uint8_t *)((uint8_t *)buffer + buffer_offset),
(uint8_t *)((uint8_t *)q->payload + payload_offset),
enet_tx_buff_size - buffer_offset);
tx_buff_size - buffer_offset);
/* Point to next descriptor */
dma_tx_desc = (enet_tx_desc_t *)(dma_tx_desc->tdes3_bm.next_desc);
/* Check if the buffer is available */
if (dma_tx_desc->tdes0_bm.own != 0) {
return ERR_BUF;
if (dma_tx_desc->tdes0_bm.own != 0)
{
printf("DMA tx desc buffer is not valid\n");
return ERR_USE;
}
buffer = (uint8_t *)(dma_tx_desc->tdes2_bm.buffer1);
bytes_left_to_copy = bytes_left_to_copy - (enet_tx_buff_size - buffer_offset);
payload_offset = payload_offset + (enet_tx_buff_size - buffer_offset);
frame_length = frame_length + (enet_tx_buff_size - buffer_offset);
bytes_left_to_copy = bytes_left_to_copy - (tx_buff_size - buffer_offset);
payload_offset = payload_offset + (tx_buff_size - buffer_offset);
frame_length = frame_length + (tx_buff_size - buffer_offset);
buffer_offset = 0;
}
/* pass payload to buffer */
desc->tx_desc_list_cur->tdes2_bm.buffer1 = (uint32_t)q->payload;
/* Copy the remaining bytes */
memcpy((uint8_t *)((uint8_t *)buffer + buffer_offset),
(uint8_t *)((uint8_t *)q->payload + payload_offset),
bytes_left_to_copy);
buffer_offset = buffer_offset + bytes_left_to_copy;
frame_length = frame_length + bytes_left_to_copy;
}
/* Prepare transmit descriptors to give to DMA*/
/* Prepare transmit descriptors to give to DMA */
frame_length += 4;
__asm volatile("fence.i");
enet_prepare_transmission_descriptors(dev->base, &desc->tx_desc_list_cur, frame_length, desc->tx_buff_cfg.size);
return ERR_OK;
@@ -152,78 +155,80 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p)
static struct pbuf *low_level_input(struct netif *netif)
{
struct HpmEnetDevice *dev = (struct HpmEnetDevice *)netif->state;
__IO enet_desc_t *desc = &dev->desc;
__IO uint32_t enet_rx_buff_size = desc->rx_buff_cfg.size;
struct pbuf *p = NULL, *q;
u32_t len;
enet_desc_t *desc = &dev->desc;
struct pbuf *p = NULL, *q = NULL;
uint32_t rx_buff_size = desc->rx_buff_cfg.size;
uint16_t len = 0;
uint8_t *buffer;
enet_frame_t frame = {0, 0, 0};
__IO enet_rx_desc_t*dma_rx_desc;
enet_rx_desc_t *dma_rx_desc;
uint32_t buffer_offset = 0;
uint32_t payload_offset = 0;
uint32_t bytes_left_to_copy = 0;
uint32_t i = 0;
#ifndef LWIP_RECV_INTERRUPT_MODE
/* Check and get a received frame */
if (enet_check_received_frame(&desc->rx_desc_list_cur, &desc->rx_frame_info) == 1) {
frame = enet_get_received_frame(&desc->rx_desc_list_cur, &desc->rx_frame_info);
}
#else
frame = enet_get_received_frame_interrupt(&desc->rx_desc_list_cur, &desc->rx_frame_info,
/* Get a received frame */
frame = enet_get_received_frame_interrupt(&desc->rx_desc_list_cur,
&desc->rx_frame_info,
desc->rx_buff_cfg.count);
#endif
/* Obtain the size of the packet and put it into the "len" variable. */
len = frame.length;
buffer = (uint8_t *)frame.buffer;
if (len > 0) {
/* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
if (len > 0)
{
/* allocate a pbuf chain of pbufs from the Lwip buffer pool */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
}
if (p != NULL) {
if (p != NULL)
{
dma_rx_desc = frame.rx_desc;
buffer_offset = 0;
for (q = p; q != NULL; q = q->next) {
for (q = p; q != NULL; q = q->next)
{
bytes_left_to_copy = q->len;
payload_offset = 0;
/* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/
while ((bytes_left_to_copy + buffer_offset) > enet_rx_buff_size) {
/* Copy data to pbuf*/
memcpy((uint8_t *)((uint8_t *)q->payload + payload_offset), (uint8_t *)((uint8_t *)buffer + buffer_offset), (ENET_RX_BUFF_SIZE - buffer_offset));
while ((bytes_left_to_copy + buffer_offset) > rx_buff_size)
{
/* Copy data to pbuf */
memcpy((uint8_t *)((uint8_t *)q->payload + payload_offset), (uint8_t *)((uint8_t *)buffer + buffer_offset), (rx_buff_size - buffer_offset));
/* Point to next descriptor */
dma_rx_desc = (enet_rx_desc_t*)(dma_rx_desc->rdes3_bm.next_desc);
dma_rx_desc = (enet_rx_desc_t *)(dma_rx_desc->rdes3_bm.next_desc);
buffer = (uint8_t *)(dma_rx_desc->rdes2_bm.buffer1);
bytes_left_to_copy = bytes_left_to_copy - (enet_rx_buff_size - buffer_offset);
payload_offset = payload_offset + (enet_rx_buff_size - buffer_offset);
bytes_left_to_copy = bytes_left_to_copy - (rx_buff_size - buffer_offset);
payload_offset = payload_offset + (rx_buff_size - buffer_offset);
buffer_offset = 0;
}
/* pass the buffer to pbuf */
q->payload = (void *)buffer;
/* Copy remaining data in pbuf */
memcpy((uint8_t *)((uint8_t *)q->payload + payload_offset), (uint8_t *)((uint8_t *)buffer + buffer_offset), bytes_left_to_copy);
buffer_offset = buffer_offset + bytes_left_to_copy;
}
} else {
}
else
{
return NULL;
}
/* Release descriptors to DMA */
/* Point to first descriptor */
dma_rx_desc = frame.rx_desc;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i = 0; i < desc->rx_frame_info.seg_count; i++) {
for (i = 0; i < desc->rx_frame_info.seg_count; i++)
{
dma_rx_desc->rdes0_bm.own = 1;
dma_rx_desc = (enet_rx_desc_t*)(dma_rx_desc->rdes3_bm.next_desc);
}
/* Clear Segment_Count */
desc->rx_frame_info.seg_count = 0;
__asm volatile("fence.i");
return p;
}
@@ -246,66 +251,52 @@ err_t ethernetif_input(struct netif *netif)
err_t err;
struct pbuf *p = NULL;
/* move received packet into a new pbuf */
p = low_level_input(netif);
while ((p = low_level_input(netif)) != NULL) {
/* no packet could be read, silently ignore this */
if (p == NULL) {
return ERR_MEM;
}
/* no packet could be read, silently ignore this */
if (p == NULL) {
#ifndef LWIP_RECV_INTERRUPT_MODE
LOS_Msleep(1);
#endif
return ERR_MEM;
}
/* entry point to the LwIP stack */
err = netif->input(p, netif);
/* entry point to the LwIP stack */
err = netif->input(p, netif);
if (err != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
if (err != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
}
return err;
}
static VOID *ethernetif_recv_thread(UINT32 arg)
{
struct netif *netif = (struct netif *)arg;
#ifdef LWIP_RECV_INTERRUPT_MODE
struct HpmEnetDevice *dev = (struct HpmEnetDevice *)netif->state;
#endif
while (1) {
#ifdef LWIP_RECV_INTERRUPT_MODE
LOS_SemPend(dev->rxSemHandle, 0xffffffff);
#endif
ethernetif_input(netif);
}
}
#ifdef LWIP_RECV_INTERRUPT_MODE
static __attribute__((section(".interrupt.text"))) VOID hpm_enet_isr(VOID *parm)
{
struct netif *netif = (struct netif *)parm;
struct HpmEnetDevice *dev = (struct HpmEnetDevice *)netif->state;
uint32_t status = dev->base->DMA_STATUS;
uint32_t istatus = dev->base->INTR_STATUS;
if (ENET_DMA_STATUS_GLPII_GET(status)) {
dev->base->DMA_STATUS |= ENET_DMA_STATUS_GLPII_SET(ENET_DMA_STATUS_GLPII_GET(status));
printf("ENET_DMA_STATUS_GLPII_GET = 0x%X\n", status);
printf("dev->base->INTR_MASK = 0x%X\n", dev->base->INTR_MASK);
}
dev->base->DMA_STATUS |= 0xffffffff;
if (ENET_DMA_STATUS_RI_GET(status)) {
dev->base->DMA_STATUS |= ENET_DMA_STATUS_RI_SET(ENET_DMA_STATUS_RI_GET(status));
LOS_SemPost(dev->rxSemHandle);
} else {
printf("error ---status = 0x%X\n", status);
}
}
#endif
void ethernetif_recv_start(struct netif *netif)
{
@@ -313,19 +304,19 @@ void ethernetif_recv_start(struct netif *netif)
UINT32 taskID = LOS_ERRNO_TSK_ID_INVALID;
UINT32 ret;
TSK_INIT_PARAM_S task = {0};
#ifdef LWIP_RECV_INTERRUPT_MODE
LOS_SemCreate(1000, &dev->rxSemHandle);
LOS_SemCreate(0, &dev->rxSemHandle);
HwiIrqParam irqParam;
irqParam.pDevId = netif;
LOS_HwiCreate(HPM2LITEOS_IRQ(dev->irqNum), 1, 0, (HWI_PROC_FUNC)hpm_enet_isr, &irqParam);
LOS_HwiEnable(HPM2LITEOS_IRQ(dev->irqNum));
#endif
/* Create host Task */
task.pfnTaskEntry = (TSK_ENTRY_FUNC)ethernetif_recv_thread;
task.uwStackSize = 4096;
task.pcName = (char *)(dev->name);
task.usTaskPrio = 20;
task.usTaskPrio = 3;
task.uwArg = (UINTPTR)netif;
task.uwResved = LOS_TASK_STATUS_DETACHED;
ret = LOS_TaskCreate(&taskID, &task);
+6 -10
View File
@@ -48,8 +48,8 @@ __RW uint8_t txBuff1[ENET_TX_BUFF_COUNT][ENET_TX_BUFF_SIZE]; /* Ethernet Transmi
struct HpmEnetDevice enetDev[2] = {
[0] = {
.isEnable = 1,
.isDefault = 1,
.isEnable = 0,
.isDefault = 0,
.name = "geth",
.base = BOARD_ENET_RGMII,
.irqNum = IRQn_ENET0,
@@ -76,7 +76,7 @@ struct HpmEnetDevice enetDev[2] = {
},
[1] = {
.isEnable = 1,
.isDefault = 0,
.isDefault = 1,
.name = "eth",
.base = BOARD_ENET_RMII,
.irqNum = IRQn_ENET1,
@@ -137,17 +137,13 @@ void enetDevInit(struct HpmEnetDevice *dev)
macCfg.mac_addr_low[0] |= dev->macAddr[0];
macCfg.valid_max_count = 1;
uint32_t dmaIntEnable = 0;
uint32_t dmaIntEnable = 0;
#ifdef LWIP_RECV_INTERRUPT_MODE
dmaIntEnable = ENET_DMA_INTR_EN_NIE_SET(1) /* Enable normal interrupt summary */
| ENET_DMA_INTR_EN_RIE_SET(1); /* Enable receive interrupt */
dev->base->INTR_MASK |= 0xFFFFFFFF;
dev->base->MMC_INTR_MASK_RX |= 0xFFFFFFFF;
dev->base->MMC_INTR_MASK_TX |= 0xFFFFFFFF;
dev->base->MMC_IPC_INTR_MASK_RX |= 0xFFFFFFFF;
#endif
enet_controller_init(dev->base, dev->infType, &dev->desc, &macCfg, dmaIntEnable);
+1 -1
View File
@@ -24,7 +24,7 @@
#include "lwip/err.h"
#include "lwip/netif.h"
#define ENET_TX_BUFF_COUNT (8)
#define ENET_TX_BUFF_COUNT (10)
#define ENET_RX_BUFF_COUNT (64)
#define ENET_RX_BUFF_SIZE ENET_MAX_FRAME_SIZE
#define ENET_TX_BUFF_SIZE ENET_MAX_FRAME_SIZE
+11 -1
View File
@@ -21,7 +21,7 @@
#undef ETH_PAD_SIZE
#define ETH_PAD_SIZE 0
#define LWIP_TCPIP_CORE_LOCKING_INPUT 1
/*
--------------------------------------
---------- Checksum options ----------
@@ -30,6 +30,16 @@
#undef LWIP_CHECKSUM_ON_COPY
#define LWIP_CHECKSUM_ON_COPY 0
#undef TCP_WND
#define TCP_WND 8192
#undef TCPIP_THREAD_STACKSIZE
#define TCPIP_THREAD_STACKSIZE 4096
#undef LWIP_CONFIG_NUM_SOCKETS
#define LWIP_CONFIG_NUM_SOCKETS 16
/*
Some MCUs allow computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.