From a3da67a97a53c513d2a22b90b4b519976b71ed11 Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 28 Jul 2020 20:58:00 +0800 Subject: [PATCH] ethernet: set DMA owner after all descriptors have configured --- components/soc/src/esp32/emac_hal.c | 39 ++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/components/soc/src/esp32/emac_hal.c b/components/soc/src/esp32/emac_hal.c index e220003cb7..46bd1f4f50 100644 --- a/components/soc/src/esp32/emac_hal.c +++ b/components/soc/src/esp32/emac_hal.c @@ -467,44 +467,55 @@ uint32_t emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t if (lastlen) { bufcount++; } + if (bufcount > CONFIG_ETH_DMA_TX_BUFFER_NUM) { + goto err; + } + + eth_dma_tx_descriptor_t *desc_iter = hal->tx_desc; /* A frame is transmitted in multiple descriptor */ - for (uint32_t i = 0; i < bufcount; i++) { + for (int i = 0; i < bufcount; i++) { /* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */ - if (hal->tx_desc->TDES0.Own != EMAC_DMADESC_OWNER_CPU) { + if (desc_iter->TDES0.Own != EMAC_DMADESC_OWNER_CPU) { goto err; } /* Clear FIRST and LAST segment bits */ - hal->tx_desc->TDES0.FirstSegment = 0; - hal->tx_desc->TDES0.LastSegment = 0; + desc_iter->TDES0.FirstSegment = 0; + desc_iter->TDES0.LastSegment = 0; + desc_iter->TDES0.InterruptOnComplete = 0; if (i == 0) { /* Setting the first segment bit */ - hal->tx_desc->TDES0.FirstSegment = 1; + desc_iter->TDES0.FirstSegment = 1; } if (i == (bufcount - 1)) { /* Setting the last segment bit */ - hal->tx_desc->TDES0.LastSegment = 1; + desc_iter->TDES0.LastSegment = 1; /* Enable transmit interrupt */ - hal->tx_desc->TDES0.InterruptOnComplete = 1; + desc_iter->TDES0.InterruptOnComplete = 1; /* Program size */ - hal->tx_desc->TDES1.TransmitBuffer1Size = lastlen; + desc_iter->TDES1.TransmitBuffer1Size = lastlen; /* copy data from uplayer stack buffer */ - memcpy((void *)(hal->tx_desc->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, lastlen); + memcpy((void *)(desc_iter->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, lastlen); sentout += lastlen; } else { /* Program size */ - hal->tx_desc->TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE; + desc_iter->TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE; /* copy data from uplayer stack buffer */ - memcpy((void *)(hal->tx_desc->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, CONFIG_ETH_DMA_BUFFER_SIZE); + memcpy((void *)(desc_iter->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, CONFIG_ETH_DMA_BUFFER_SIZE); sentout += CONFIG_ETH_DMA_BUFFER_SIZE; } - /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ - hal->tx_desc->TDES0.Own = EMAC_DMADESC_OWNER_DMA; /* Point to next descriptor */ + desc_iter = (eth_dma_tx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); + } + + /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ + for (int i = 0; i < bufcount; i++) { + hal->tx_desc->TDES0.Own = EMAC_DMADESC_OWNER_DMA; hal->tx_desc = (eth_dma_tx_descriptor_t *)(hal->tx_desc->Buffer2NextDescAddr); } -err: hal->dma_regs->dmatxpolldemand = 0; return sentout; +err: + return 0; } uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t size, uint32_t *frames_remain, uint32_t *free_desc)