mirror of
https://github.com/openharmony/device_board_hpmicro.git
synced 2026-07-01 21:54:00 -04:00
optimize ethernet
Signed-off-by: Hongpeng Huo <hongpeng.huo@hpmicro.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user