Skip to content

Commit

Permalink
Merge branch 'bugfix/tw14130_fix_buf_err' into 'master'
Browse files Browse the repository at this point in the history
emac:fix rx buf err

See merge request !1073
  • Loading branch information
jack0c committed Aug 4, 2017
2 parents 886ea72 + 01a2c31 commit a92806b
Showing 1 changed file with 45 additions and 20 deletions.
65 changes: 45 additions & 20 deletions components/ethernet/emac_main.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,8 +54,8 @@

static struct emac_config_data emac_config;

static uint8_t emac_dma_rx_chain_buf[32 * DMA_RX_BUF_NUM];
static uint8_t emac_dma_tx_chain_buf[32 * DMA_TX_BUF_NUM];
static uint8_t emac_dma_rx_chain_buf[sizeof(struct dma_extended_desc) * DMA_RX_BUF_NUM];
static uint8_t emac_dma_tx_chain_buf[sizeof(struct dma_extended_desc) * DMA_TX_BUF_NUM];
static uint8_t emac_dma_rx_buf[DMA_RX_BUF_SIZE * DMA_RX_BUF_NUM];
static uint8_t emac_dma_tx_buf[DMA_TX_BUF_SIZE * DMA_TX_BUF_NUM];

Expand Down Expand Up @@ -115,6 +115,25 @@ static void emac_set_rx_base_reg(void)
REG_WRITE(EMAC_DMARXBASEADDR_REG, (uint32_t)(emac_config.dma_erx));
}

/*
* dirty_rx indicates the hardware has been fed with data packets and is the first node software needs to handle;
*
* cur_rx indicates the completion of software handling and is the last node hardware could use;
*
* cnt_rx is to count the numbers of packets handled by software, passed to protocol stack and not been freed.
*
* (1) Initializing the Linked List. Connect the numerable nodes to a circular linked list, appoint one of the nodes as the head node, mark* the dirty_rx and cur_rx into the node, and mount the node on the hardware base address. Initialize cnt_rx into 0.
*
* (2) When hardware receives packets, nodes of linked lists will be fed with data packets from the base address by turns, marks the node
* of linked lists as “HARDWARE UNUSABLE” and reports interrupts.
*
* (3) When the software receives the interrupts, it will handle the linked lists by turns from dirty_rx, send data packets to protocol
* stack. dirty_rx will deviate backwards by turns and cnt_rx will by turns ++.
*
* (4) After the protocol stack handles all the data and calls the free function, it will deviate backwards by turns from cur_rx, mark the * node of linked lists as “HARDWARE USABLE” and cnt_rx will by turns --.
*
* (5) Cycle from Step 2 to Step 4 without break and build up circular linked list handling.
*/
static void emac_reset_dma_chain(void)
{
emac_config.cnt_tx = 0;
Expand Down Expand Up @@ -450,16 +469,17 @@ static void emac_process_rx_unavail(void)
while (emac_config.cnt_rx < DMA_RX_BUF_NUM) {

emac_config.cnt_rx++;

//copy data to lwip
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
(((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);

if (emac_config.cnt_rx > DMA_RX_BUF_NUM) {
ESP_LOGE(TAG, "emac rx unavail buf err !!\n");
}
uint32_t tmp_dirty = emac_config.dirty_rx;
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
}

//copy data to lwip
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
(((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);

}
emac_enable_rx_intr();
emac_enable_rx_unavail_intr();
xSemaphoreGiveRecursive( emac_rx_xMutex );
Expand All @@ -479,16 +499,17 @@ static void emac_process_rx(void)

while (((uint32_t) & (emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) != cur_rx_desc) && emac_config.cnt_rx < DMA_RX_BUF_NUM ) {
emac_config.cnt_rx++;

//copy data to lwip
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
(((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);

if (emac_config.cnt_rx > DMA_RX_BUF_NUM ) {
ESP_LOGE(TAG, "emac rx buf err!!\n");
}
uint32_t tmp_dirty = emac_config.dirty_rx;
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;


//copy data to lwip
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
(((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);

cur_rx_desc = emac_read_rx_cur_reg();
}
} else {
Expand All @@ -497,16 +518,17 @@ static void emac_process_rx(void)
while (emac_config.cnt_rx < DMA_RX_BUF_NUM) {

emac_config.cnt_rx++;
//copy data to lwip
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[emac_config.dirty_rx].basic.desc2),
(((emac_config.dma_erx[emac_config.dirty_rx].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);

if (emac_config.cnt_rx > DMA_RX_BUF_NUM) {
ESP_LOGE(TAG, "emac rx buf err!!!\n");
}

uint32_t tmp_dirty = emac_config.dirty_rx;
emac_config.dirty_rx = (emac_config.dirty_rx + 1) % DMA_RX_BUF_NUM;
}

//copy data to lwip
emac_config.emac_tcpip_input((void *)(emac_config.dma_erx[tmp_dirty].basic.desc2),
(((emac_config.dma_erx[tmp_dirty].basic.desc0) >> EMAC_DESC_FRAME_LENGTH_S) & EMAC_DESC_FRAME_LENGTH) , NULL);

}
}
}
}
Expand Down Expand Up @@ -963,6 +985,9 @@ esp_err_t esp_eth_init(eth_config_t *config)
ret = ESP_FAIL;
goto _exit;
#endif
if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) {
goto _exit;
}

emac_init_default_data();

Expand Down

0 comments on commit a92806b

Please sign in to comment.