ethernet: multi-call failure in esp_eth_init
Because of incomplete state machine, ethernet driver will broken if esp_eth_init is called twice. Detailed information here: https://ezredmine.espressif.cn:8765/issues/27332
This commit is contained in:
parent
a7db0e2291
commit
2885ec3831
2 changed files with 37 additions and 16 deletions
|
@ -21,7 +21,7 @@ config DMA_TX_BUF_NUM
|
||||||
|
|
||||||
config EMAC_L2_TO_L3_RX_BUF_MODE
|
config EMAC_L2_TO_L3_RX_BUF_MODE
|
||||||
bool "Enable copy between Layer2 and Layer3"
|
bool "Enable copy between Layer2 and Layer3"
|
||||||
default n
|
default y
|
||||||
help
|
help
|
||||||
If this options is selected, a copy of each received buffer will be created when
|
If this options is selected, a copy of each received buffer will be created when
|
||||||
passing it from the Ethernet MAC (L2) to the IP stack (L3). Otherwise, IP stack
|
passing it from the Ethernet MAC (L2) to the IP stack (L3). Otherwise, IP stack
|
||||||
|
|
|
@ -1066,8 +1066,19 @@ esp_err_t IRAM_ATTR emac_post(emac_sig_t sig, emac_par_t par)
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_eth_init(eth_config_t *config)
|
esp_err_t esp_eth_init(eth_config_t *config)
|
||||||
|
{
|
||||||
|
esp_event_set_default_eth_handlers();
|
||||||
|
return esp_eth_init_internal(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) {
|
||||||
|
goto _initialised;
|
||||||
|
}
|
||||||
|
|
||||||
/* dynamically alloc memory for ethernet dma */
|
/* dynamically alloc memory for ethernet dma */
|
||||||
emac_dma_rx_chain_buf = (dma_extended_desc_t *)heap_caps_malloc(sizeof(dma_extended_desc_t) * DMA_RX_BUF_NUM, MALLOC_CAP_DMA);
|
emac_dma_rx_chain_buf = (dma_extended_desc_t *)heap_caps_malloc(sizeof(dma_extended_desc_t) * DMA_RX_BUF_NUM, MALLOC_CAP_DMA);
|
||||||
emac_dma_tx_chain_buf = (dma_extended_desc_t *)heap_caps_malloc(sizeof(dma_extended_desc_t) * DMA_TX_BUF_NUM, MALLOC_CAP_DMA);
|
emac_dma_tx_chain_buf = (dma_extended_desc_t *)heap_caps_malloc(sizeof(dma_extended_desc_t) * DMA_TX_BUF_NUM, MALLOC_CAP_DMA);
|
||||||
|
@ -1077,16 +1088,6 @@ esp_err_t esp_eth_init(eth_config_t *config)
|
||||||
for (i = 0; i < DMA_TX_BUF_NUM; i++) {
|
for (i = 0; i < DMA_TX_BUF_NUM; i++) {
|
||||||
emac_dma_tx_buf[i] = (uint8_t *)heap_caps_malloc(DMA_TX_BUF_SIZE, MALLOC_CAP_DMA);
|
emac_dma_tx_buf[i] = (uint8_t *)heap_caps_malloc(DMA_TX_BUF_SIZE, MALLOC_CAP_DMA);
|
||||||
}
|
}
|
||||||
esp_event_set_default_eth_handlers();
|
|
||||||
return esp_eth_init_internal(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t esp_eth_init_internal(eth_config_t *config)
|
|
||||||
{
|
|
||||||
esp_err_t ret = ESP_OK;
|
|
||||||
if (emac_config.emac_status != EMAC_RUNTIME_NOT_INIT) {
|
|
||||||
goto _exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
emac_init_default_data();
|
emac_init_default_data();
|
||||||
|
|
||||||
|
@ -1097,7 +1098,7 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||||
ret = emac_verify_args();
|
ret = emac_verify_args();
|
||||||
|
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
goto _exit;
|
goto _verify_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
emac_config.emac_phy_power_enable(true);
|
emac_config.emac_phy_power_enable(true);
|
||||||
|
@ -1110,7 +1111,7 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||||
if (esp_spiram_is_initialized()) {
|
if (esp_spiram_is_initialized()) {
|
||||||
ESP_LOGE(TAG, "GPIO16 and GPIO17 has been occupied by PSRAM, Only ETH_CLOCK_GPIO_IN is supported!");
|
ESP_LOGE(TAG, "GPIO16 and GPIO17 has been occupied by PSRAM, Only ETH_CLOCK_GPIO_IN is supported!");
|
||||||
ret = ESP_FAIL;
|
ret = ESP_FAIL;
|
||||||
goto _exit;
|
goto _verify_err;
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "GPIO16/17 is used for clock of EMAC, Please Make Sure you're not using PSRAM.");
|
ESP_LOGW(TAG, "GPIO16/17 is used for clock of EMAC, Please Make Sure you're not using PSRAM.");
|
||||||
}
|
}
|
||||||
|
@ -1173,15 +1174,36 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
||||||
|
|
||||||
emac_config.emac_status = EMAC_RUNTIME_INIT;
|
emac_config.emac_status = EMAC_RUNTIME_INIT;
|
||||||
|
|
||||||
_exit:
|
return ESP_OK;
|
||||||
|
|
||||||
|
_verify_err:
|
||||||
|
free(emac_dma_rx_chain_buf);
|
||||||
|
free(emac_dma_tx_chain_buf);
|
||||||
|
emac_dma_rx_chain_buf = NULL;
|
||||||
|
emac_dma_tx_chain_buf = NULL;
|
||||||
|
for (i = 0; i < DMA_RX_BUF_NUM; i++) {
|
||||||
|
free(emac_dma_rx_buf[i]);
|
||||||
|
emac_dma_rx_buf[i] = NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < DMA_TX_BUF_NUM; i++) {
|
||||||
|
free(emac_dma_tx_buf[i]);
|
||||||
|
emac_dma_tx_buf[i] = NULL;
|
||||||
|
}
|
||||||
|
_initialised:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_eth_deinit(void)
|
esp_err_t esp_eth_deinit(void)
|
||||||
{
|
{
|
||||||
esp_err_t ret = ESP_FAIL;
|
esp_err_t ret = ESP_OK;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
if (emac_config.emac_status == EMAC_RUNTIME_NOT_INIT) {
|
||||||
|
goto _exit;
|
||||||
|
}
|
||||||
|
if (emac_config.emac_status == EMAC_RUNTIME_START) {
|
||||||
|
esp_eth_disable();
|
||||||
|
}
|
||||||
if (!emac_task_hdl) {
|
if (!emac_task_hdl) {
|
||||||
ret = ESP_ERR_INVALID_STATE;
|
ret = ESP_ERR_INVALID_STATE;
|
||||||
goto _exit;
|
goto _exit;
|
||||||
|
@ -1213,7 +1235,6 @@ esp_err_t esp_eth_deinit(void)
|
||||||
emac_dma_tx_buf[i] = NULL;
|
emac_dma_tx_buf[i] = NULL;
|
||||||
}
|
}
|
||||||
esp_intr_free(eth_intr_handle);
|
esp_intr_free(eth_intr_handle);
|
||||||
ret = ESP_OK;
|
|
||||||
_exit:
|
_exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue