Merge branch 'bugfix/several_ethernet_bugfix_from_4.1' into 'release/v4.0'

Ethenret driver bugfix and optimization (4.0)

See merge request espressif/esp-idf!7426
This commit is contained in:
Angus Gratton 2020-02-06 14:38:47 +08:00
commit 3f76083e8c
6 changed files with 69 additions and 44 deletions

View file

@ -24,7 +24,6 @@ extern "C" {
#include "driver/spi_master.h" #include "driver/spi_master.h"
#endif #endif
/** /**
* @brief Ethernet MAC * @brief Ethernet MAC
* *
@ -248,8 +247,11 @@ typedef struct {
uint32_t rx_task_prio; /*!< Priority of the receive task */ uint32_t rx_task_prio; /*!< Priority of the receive task */
int smi_mdc_gpio_num; /*!< SMI MDC GPIO number */ int smi_mdc_gpio_num; /*!< SMI MDC GPIO number */
int smi_mdio_gpio_num; /*!< SMI MDIO GPIO number */ int smi_mdio_gpio_num; /*!< SMI MDIO GPIO number */
uint32_t flags; /*!< Flags that specify extra capability for mac driver */
} eth_mac_config_t; } eth_mac_config_t;
#define ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE (1 << 0) /*!< MAC driver can work when cache is disabled */
/** /**
* @brief Default configuration for Ethernet MAC object * @brief Default configuration for Ethernet MAC object
* *
@ -261,6 +263,7 @@ typedef struct {
.rx_task_prio = 15, \ .rx_task_prio = 15, \
.smi_mdc_gpio_num = 23, \ .smi_mdc_gpio_num = 23, \
.smi_mdio_gpio_num = 18, \ .smi_mdio_gpio_num = 18, \
.flags = 0, \
} }
#if CONFIG_ETH_USE_ESP32_EMAC #if CONFIG_ETH_USE_ESP32_EMAC

View file

@ -169,7 +169,8 @@ esp_err_t esp_eth_driver_install(const esp_eth_config_t *config, esp_eth_handle_
esp_eth_mac_t *mac = config->mac; esp_eth_mac_t *mac = config->mac;
esp_eth_phy_t *phy = config->phy; esp_eth_phy_t *phy = config->phy;
ETH_CHECK(mac && phy, "can't set eth->mac or eth->phy to null", err, ESP_ERR_INVALID_ARG); ETH_CHECK(mac && phy, "can't set eth->mac or eth->phy to null", err, ESP_ERR_INVALID_ARG);
esp_eth_driver_t *eth_driver = calloc(1, sizeof(esp_eth_driver_t)); // eth_driver contains an atomic variable, which should not be put in PSRAM
esp_eth_driver_t *eth_driver = heap_caps_calloc(1, sizeof(esp_eth_driver_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
ETH_CHECK(eth_driver, "request memory for eth_driver failed", err, ESP_ERR_NO_MEM); ETH_CHECK(eth_driver, "request memory for eth_driver failed", err, ESP_ERR_NO_MEM);
atomic_init(&eth_driver->ref_count, 1); atomic_init(&eth_driver->ref_count, 1);
eth_driver->mac = mac; eth_driver->mac = mac;
@ -275,6 +276,8 @@ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, uint8_t *buf, uint32_t length)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(buf, "can't set buf to null", err, ESP_ERR_INVALID_ARG);
ETH_CHECK(length, "buf length can't be zero", err, ESP_ERR_INVALID_ARG);
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
esp_eth_mac_t *mac = eth_driver->mac; esp_eth_mac_t *mac = eth_driver->mac;
return mac->transmit(mac, buf, length); return mac->transmit(mac, buf, length);
@ -286,6 +289,8 @@ esp_err_t esp_eth_receive(esp_eth_handle_t hdl, uint8_t *buf, uint32_t *length)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl; esp_eth_driver_t *eth_driver = (esp_eth_driver_t *)hdl;
ETH_CHECK(buf && length, "can't set buf and length to null", err, ESP_ERR_INVALID_ARG);
ETH_CHECK(*length > 60, "length can't be less than 60", err, ESP_ERR_INVALID_ARG);
ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG); ETH_CHECK(eth_driver, "ethernet driver handle can't be null", err, ESP_ERR_INVALID_ARG);
esp_eth_mac_t *mac = eth_driver->mac; esp_eth_mac_t *mac = eth_driver->mac;
return mac->receive(mac, buf, length); return mac->receive(mac, buf, length);

View file

@ -397,8 +397,10 @@ static void emac_dm9051_task(void *arg)
if (status & ISR_PR) { if (status & ISR_PR) {
do { do {
length = ETH_MAX_PACKET_SIZE; length = ETH_MAX_PACKET_SIZE;
buffer = (uint8_t *)heap_caps_malloc(length, MALLOC_CAP_DMA); buffer = heap_caps_malloc(length, MALLOC_CAP_DMA);
if (emac->parent.receive(&emac->parent, buffer, &length) == ESP_OK) { if (!buffer) {
ESP_LOGE(TAG, "no mem for receive buffer");
} else if (emac->parent.receive(&emac->parent, buffer, &length) == ESP_OK) {
/* pass the buffer to stack (e.g. TCP/IP layer) */ /* pass the buffer to stack (e.g. TCP/IP layer) */
if (length) { if (length) {
emac->eth->stack_input(emac->eth, buffer, length); emac->eth->stack_input(emac->eth, buffer, length);
@ -597,8 +599,6 @@ static esp_err_t emac_dm9051_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
MAC_CHECK(buf, "can't set buf to null", err, ESP_ERR_INVALID_ARG);
MAC_CHECK(length, "buf length can't be zero", err, ESP_ERR_INVALID_ARG);
/* Check if last transmit complete */ /* Check if last transmit complete */
uint8_t tcr = 0; uint8_t tcr = 0;
MAC_CHECK(dm9051_register_read(emac, DM9051_TCR, &tcr) == ESP_OK, "read TCR failed", err, ESP_FAIL); MAC_CHECK(dm9051_register_read(emac, DM9051_TCR, &tcr) == ESP_OK, "read TCR failed", err, ESP_FAIL);
@ -620,7 +620,6 @@ static esp_err_t emac_dm9051_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent); emac_dm9051_t *emac = __containerof(mac, emac_dm9051_t, parent);
MAC_CHECK(buf && length, "can't set buf and length to null", err, ESP_ERR_INVALID_ARG);
uint8_t rxbyte = 0; uint8_t rxbyte = 0;
uint16_t rx_len = 0; uint16_t rx_len = 0;
__attribute__((aligned(4))) dm9051_rx_header_t header; // SPI driver needs the rx buffer 4 byte align __attribute__((aligned(4))) dm9051_rx_header_t header; // SPI driver needs the rx buffer 4 byte align

View file

@ -214,12 +214,8 @@ static esp_err_t emac_esp32_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
MAC_CHECK(buf, "can't set buf to null", err, ESP_ERR_INVALID_ARG); uint32_t sent_len = emac_hal_transmit_frame(&emac->hal, buf, length);
MAC_CHECK(length, "buf length can't be zero", err, ESP_ERR_INVALID_ARG); MAC_CHECK(sent_len == length, "insufficient TX buffer size", err, ESP_ERR_INVALID_SIZE);
/* Check if the descriptor is owned by the Ethernet DMA (when 1) or CPU (when 0) */
MAC_CHECK(emac_hal_get_tx_desc_owner(&emac->hal) == EMAC_DMADESC_OWNER_CPU,
"CPU doesn't own the Tx Descriptor", err, ESP_ERR_INVALID_STATE);
emac_hal_transmit_frame(&emac->hal, buf, length);
return ESP_OK; return ESP_OK;
err: err:
return ret; return ret;
@ -228,20 +224,17 @@ err:
static esp_err_t emac_esp32_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t *length) static esp_err_t emac_esp32_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t *length)
{ {
esp_err_t ret = ESP_OK; esp_err_t ret = ESP_OK;
uint32_t expected_len = *length;
emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent);
MAC_CHECK(buf && length, "can't set buf and length to null", err, ESP_ERR_INVALID_ARG); MAC_CHECK(buf && length, "can't set buf and length to null", err, ESP_ERR_INVALID_ARG);
uint32_t receive_len = emac_hal_receive_frame(&emac->hal, buf, *length, &emac->frames_remain); uint32_t receive_len = emac_hal_receive_frame(&emac->hal, buf, expected_len, &emac->frames_remain);
/* we need to check the return value in case the buffer size is not enough */ /* we need to check the return value in case the buffer size is not enough */
if (*length < receive_len) { ESP_LOGD(TAG, "receive len= %d", receive_len);
ESP_LOGE(TAG, "buffer size too small"); MAC_CHECK(expected_len >= receive_len, "received buffer longer than expected", err, ESP_ERR_INVALID_SIZE);
/* tell upper layer the size we need */
*length = receive_len;
ret = ESP_ERR_INVALID_SIZE;
goto err;
}
*length = receive_len; *length = receive_len;
return ESP_OK; return ESP_OK;
err: err:
*length = expected_len;
return ret; return ret;
} }
@ -255,8 +248,10 @@ static void emac_esp32_rx_task(void *arg)
ulTaskNotifyTake(pdFALSE, portMAX_DELAY); ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
do { do {
length = ETH_MAX_PACKET_SIZE; length = ETH_MAX_PACKET_SIZE;
buffer = (uint8_t *)malloc(length); buffer = malloc(length);
if (emac_esp32_receive(&emac->parent, buffer, &length) == ESP_OK) { if (!buffer) {
ESP_LOGE(TAG, "no mem for receive buffer");
} else if (emac_esp32_receive(&emac->parent, buffer, &length) == ESP_OK) {
/* pass the buffer to stack (e.g. TCP/IP layer) */ /* pass the buffer to stack (e.g. TCP/IP layer) */
if (length) { if (length) {
emac->eth->stack_input(emac->eth, buffer, length); emac->eth->stack_input(emac->eth, buffer, length);
@ -291,9 +286,9 @@ static esp_err_t emac_esp32_init(esp_eth_mac_t *mac)
esp_eth_mediator_t *eth = emac->eth; esp_eth_mediator_t *eth = emac->eth;
/* enable peripheral clock */ /* enable peripheral clock */
periph_module_enable(PERIPH_EMAC_MODULE); periph_module_enable(PERIPH_EMAC_MODULE);
/* enable clock, config gpio, etc */ /* init clock, config gpio, etc */
emac_hal_lowlevel_init(&emac->hal); emac_hal_lowlevel_init(&emac->hal);
/* init gpio used by gpio */ /* init gpio used by smi interface */
emac_esp32_init_smi_gpio(emac); emac_esp32_init_smi_gpio(emac);
MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL); MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, "lowlevel init failed", err, ESP_FAIL);
/* software reset */ /* software reset */
@ -363,6 +358,7 @@ static esp_err_t emac_esp32_del(esp_eth_mac_t *mac)
return ESP_OK; return ESP_OK;
} }
// To achieve a better performance, we put the ISR always in IRAM
IRAM_ATTR void emac_esp32_isr_handler(void *args) IRAM_ATTR void emac_esp32_isr_handler(void *args)
{ {
emac_hal_context_t *hal = (emac_hal_context_t *)args; emac_hal_context_t *hal = (emac_hal_context_t *)args;
@ -376,11 +372,16 @@ IRAM_ATTR void emac_esp32_isr_handler(void *args)
esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config) esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
{ {
esp_err_t ret_code = ESP_OK;
esp_eth_mac_t *ret = NULL; esp_eth_mac_t *ret = NULL;
void *descriptors = NULL; void *descriptors = NULL;
emac_esp32_t *emac = NULL; emac_esp32_t *emac = NULL;
MAC_CHECK(config, "can't set mac config to null", err, NULL); MAC_CHECK(config, "can't set mac config to null", err, NULL);
if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) {
emac = heap_caps_calloc(1, sizeof(emac_esp32_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
} else {
emac = calloc(1, sizeof(emac_esp32_t)); emac = calloc(1, sizeof(emac_esp32_t));
}
MAC_CHECK(emac, "calloc emac failed", err, NULL); MAC_CHECK(emac, "calloc emac failed", err, NULL);
/* alloc memory for ethernet dma descriptor */ /* alloc memory for ethernet dma descriptor */
uint32_t desc_size = CONFIG_ETH_DMA_RX_BUFFER_NUM * sizeof(eth_dma_rx_descriptor_t) + uint32_t desc_size = CONFIG_ETH_DMA_RX_BUFFER_NUM * sizeof(eth_dma_rx_descriptor_t) +
@ -421,9 +422,14 @@ esp_eth_mac_t *esp_eth_mac_new_esp32(const eth_mac_config_t *config)
emac->parent.transmit = emac_esp32_transmit; emac->parent.transmit = emac_esp32_transmit;
emac->parent.receive = emac_esp32_receive; emac->parent.receive = emac_esp32_receive;
/* Interrupt configuration */ /* Interrupt configuration */
MAC_CHECK(esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM, emac_esp32_isr_handler, if (config->flags & ETH_MAC_FLAG_WORK_WITH_CACHE_DISABLE) {
&emac->hal, &(emac->intr_hdl)) == ESP_OK, ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, ESP_INTR_FLAG_IRAM,
"alloc emac interrupt failed", err, NULL); emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl));
} else {
ret_code = esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0,
emac_esp32_isr_handler, &emac->hal, &(emac->intr_hdl));
}
MAC_CHECK(ret_code == ESP_OK, "alloc emac interrupt failed", err, NULL);
#ifdef CONFIG_PM_ENABLE #ifdef CONFIG_PM_ENABLE
MAC_CHECK(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "emac_esp32", &emac->pm_lock) == ESP_OK, MAC_CHECK(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "emac_esp32", &emac->pm_lock) == ESP_OK,
"create pm lock failed", err, NULL); "create pm lock failed", err, NULL);

View file

@ -438,11 +438,12 @@ uint32_t emac_hal_get_tx_desc_owner(emac_hal_context_t *hal)
return hal->tx_desc->TDES0.Own; return hal->tx_desc->TDES0.Own;
} }
void emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t length) uint32_t emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t length)
{ {
/* Get the number of Tx buffers to use for the frame */ /* Get the number of Tx buffers to use for the frame */
uint32_t bufcount = 0; uint32_t bufcount = 0;
uint32_t lastlen = length; uint32_t lastlen = length;
uint32_t sentout = 0;
while (lastlen > CONFIG_ETH_DMA_BUFFER_SIZE) { while (lastlen > CONFIG_ETH_DMA_BUFFER_SIZE) {
lastlen -= CONFIG_ETH_DMA_BUFFER_SIZE; lastlen -= CONFIG_ETH_DMA_BUFFER_SIZE;
bufcount++; bufcount++;
@ -452,6 +453,10 @@ void emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t len
} }
/* A frame is transmitted in multiple descriptor */ /* A frame is transmitted in multiple descriptor */
for (uint32_t i = 0; i < bufcount; i++) { for (uint32_t 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) {
goto err;
}
/* Clear FIRST and LAST segment bits */ /* Clear FIRST and LAST segment bits */
hal->tx_desc->TDES0.FirstSegment = 0; hal->tx_desc->TDES0.FirstSegment = 0;
hal->tx_desc->TDES0.LastSegment = 0; hal->tx_desc->TDES0.LastSegment = 0;
@ -468,18 +473,22 @@ void emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t len
hal->tx_desc->TDES1.TransmitBuffer1Size = lastlen; hal->tx_desc->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 *)(hal->tx_desc->Buffer1Addr), buf + i * CONFIG_ETH_DMA_BUFFER_SIZE, lastlen);
sentout += lastlen;
} else { } else {
/* Program size */ /* Program size */
hal->tx_desc->TDES1.TransmitBuffer1Size = CONFIG_ETH_DMA_BUFFER_SIZE; hal->tx_desc->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 *)(hal->tx_desc->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 */ /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
hal->tx_desc->TDES0.Own = EMAC_DMADESC_OWNER_DMA; hal->tx_desc->TDES0.Own = EMAC_DMADESC_OWNER_DMA;
/* Point to next descriptor */ /* Point to next descriptor */
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;
} }
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)
@ -488,7 +497,9 @@ uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
eth_dma_rx_descriptor_t *first_desc = NULL; eth_dma_rx_descriptor_t *first_desc = NULL;
uint32_t iter = 0; uint32_t iter = 0;
uint32_t seg_count = 0; uint32_t seg_count = 0;
uint32_t len = 0; uint32_t ret_len = 0;
uint32_t copy_len = 0;
uint32_t write_len = 0;
uint32_t frame_count = 0; uint32_t frame_count = 0;
first_desc = hal->rx_desc; first_desc = hal->rx_desc;
@ -500,13 +511,9 @@ uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
/* Last segment in frame */ /* Last segment in frame */
if (desc_iter->RDES0.LastDescriptor) { if (desc_iter->RDES0.LastDescriptor) {
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */ /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
len = desc_iter->RDES0.FrameLength - ETH_CRC_LENGTH; ret_len = desc_iter->RDES0.FrameLength - ETH_CRC_LENGTH;
/* check if the buffer can store the whole frame */ /* packets larger than expected will be truncated */
if (len > size) { copy_len = ret_len > size ? size : ret_len;
/* return the real size that we want */
/* user need to compare the return value to the size they prepared when this function returned */
return len;
}
/* update unhandled frame count */ /* update unhandled frame count */
frame_count++; frame_count++;
} }
@ -530,15 +537,16 @@ uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
} }
desc_iter = first_desc; desc_iter = first_desc;
for (iter = 0; iter < seg_count - 1; iter++) { for (iter = 0; iter < seg_count - 1; iter++) {
write_len = copy_len < CONFIG_ETH_DMA_BUFFER_SIZE ? copy_len : CONFIG_ETH_DMA_BUFFER_SIZE;
/* copy data to buffer */ /* copy data to buffer */
memcpy(buf + iter * CONFIG_ETH_DMA_BUFFER_SIZE, memcpy(buf, (void *)(desc_iter->Buffer1Addr), write_len);
(void *)(desc_iter->Buffer1Addr), CONFIG_ETH_DMA_BUFFER_SIZE); buf += write_len;
copy_len -= write_len;
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */ /* Set Own bit in Rx descriptors: gives the buffers back to DMA */
desc_iter->RDES0.Own = EMAC_DMADESC_OWNER_DMA; desc_iter->RDES0.Own = EMAC_DMADESC_OWNER_DMA;
desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); desc_iter = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr);
} }
memcpy(buf + iter * CONFIG_ETH_DMA_BUFFER_SIZE, memcpy(buf, (void *)(desc_iter->Buffer1Addr), copy_len);
(void *)(desc_iter->Buffer1Addr), len % CONFIG_ETH_DMA_BUFFER_SIZE);
desc_iter->RDES0.Own = EMAC_DMADESC_OWNER_DMA; desc_iter->RDES0.Own = EMAC_DMADESC_OWNER_DMA;
/* update rxdesc */ /* update rxdesc */
hal->rx_desc = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr); hal->rx_desc = (eth_dma_rx_descriptor_t *)(desc_iter->Buffer2NextDescAddr);
@ -547,7 +555,7 @@ uint32_t emac_hal_receive_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t
frame_count--; frame_count--;
} }
*frames_remain = frame_count; *frames_remain = frame_count;
return len; return ret_len;
} }
IRAM_ATTR void emac_hal_isr(void *arg) IRAM_ATTR void emac_hal_isr(void *arg)

View file

@ -242,6 +242,8 @@ typedef struct {
#define EMAC_DMATXDESC_CHECKSUM_TCPUDPICMPSEGMENT 2 /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */ #define EMAC_DMATXDESC_CHECKSUM_TCPUDPICMPSEGMENT 2 /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */
#define EMAC_DMATXDESC_CHECKSUM_TCPUDPICMPFULL 3 /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */ #define EMAC_DMATXDESC_CHECKSUM_TCPUDPICMPFULL 3 /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */
_Static_assert(sizeof(eth_dma_tx_descriptor_t) == 32, "eth_dma_tx_descriptor_t should occupy 32 bytes in memory");
/** /**
* @brief Ethernet DMA RX Descriptor * @brief Ethernet DMA RX Descriptor
* *
@ -328,6 +330,8 @@ typedef struct {
#define EMAC_DMADESC_OWNER_CPU (0) #define EMAC_DMADESC_OWNER_CPU (0)
#define EMAC_DMADESC_OWNER_DMA (1) #define EMAC_DMADESC_OWNER_DMA (1)
_Static_assert(sizeof(eth_dma_rx_descriptor_t) == 32, "eth_dma_rx_descriptor_t should occupy 32 bytes in memory");
typedef struct { typedef struct {
emac_mac_dev_t *mac_regs; emac_mac_dev_t *mac_regs;
emac_dma_dev_t *dma_regs; emac_dma_dev_t *dma_regs;
@ -378,7 +382,7 @@ void emac_hal_stop(emac_hal_context_t *hal);
uint32_t emac_hal_get_tx_desc_owner(emac_hal_context_t *hal); uint32_t emac_hal_get_tx_desc_owner(emac_hal_context_t *hal);
void emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t length); uint32_t emac_hal_transmit_frame(emac_hal_context_t *hal, uint8_t *buf, uint32_t length);
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);