ethernet: set DMA owner after all descriptors have configured

This commit is contained in:
morris
2020-07-28 20:58:00 +08:00
parent d918e7ad8a
commit c54d599d0d

View File

@ -451,44 +451,55 @@ uint32_t emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
if (lastlen) { if (lastlen) {
bufcount++; 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 */ /* 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) */ /* 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; goto err;
} }
/* Clear FIRST and LAST segment bits */ /* Clear FIRST and LAST segment bits */
hal->tx_desc->TDES0.FirstSegment = 0; desc_iter->TDES0.FirstSegment = 0;
hal->tx_desc->TDES0.LastSegment = 0; desc_iter->TDES0.LastSegment = 0;
desc_iter->TDES0.InterruptOnComplete = 0;
if (i == 0) { if (i == 0) {
/* Setting the first segment bit */ /* Setting the first segment bit */
hal->tx_desc->TDES0.FirstSegment = 1; desc_iter->TDES0.FirstSegment = 1;
} }
if (i == (bufcount - 1)) { if (i == (bufcount - 1)) {
/* Setting the last segment bit */ /* Setting the last segment bit */
hal->tx_desc->TDES0.LastSegment = 1; desc_iter->TDES0.LastSegment = 1;
/* Enable transmit interrupt */ /* Enable transmit interrupt */
hal->tx_desc->TDES0.InterruptOnComplete = 1; desc_iter->TDES0.InterruptOnComplete = 1;
/* Program size */ /* Program size */
hal->tx_desc->TDES1.TransmitBuffer1Size = lastlen; desc_iter->TDES1.TransmitBuffer1Size = lastlen;
/* copy data from uplayer stack buffer */ /* 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; sentout += lastlen;
} else { } else {
/* Program size */ /* 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 */ /* 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; 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 */ /* 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); hal->tx_desc = (eth_dma_tx_descriptor_t *)(hal->tx_desc->Buffer2NextDescAddr);
} }
err:
hal->dma_regs->dmatxpolldemand = 0; hal->dma_regs->dmatxpolldemand = 0;
return sentout; 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 emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t size, uint32_t *frames_remain)