From d5f47d6464c79020b2c033858832e543c9905ca2 Mon Sep 17 00:00:00 2001 From: Ondrej Kosta Date: Fri, 18 Sep 2026 15:47:39 +0200 Subject: [PATCH] fix(esp_eth): reject zero-length scatter-gather transmit ESP EMAC now returns ESP_ERR_INVALID_ARG when the assembled frame is empty, and Tx docs list ESP_ERR_NO_MEM as the standard "cannot handle this frame" code so the IP stack can map it to ENOMEM. --- components/esp_eth/include/esp_eth_driver.h | 3 +++ components/esp_eth/include/esp_eth_mac.h | 11 +++++++---- components/esp_eth/src/mac/esp_eth_mac_esp.c | 5 ++++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/components/esp_eth/include/esp_eth_driver.h b/components/esp_eth/include/esp_eth_driver.h index a51bf1e1da9..f70b8350c2e 100644 --- a/components/esp_eth/include/esp_eth_driver.h +++ b/components/esp_eth/include/esp_eth_driver.h @@ -317,6 +317,7 @@ esp_err_t esp_eth_update_input_path_info( * - ESP_ERR_INVALID_ARG: transmit frame buffer failed because of some invalid argument * - ESP_ERR_INVALID_STATE: invalid driver state (e.i., driver is not started) * - ESP_ERR_TIMEOUT: transmit frame buffer failed because HW was not get available in predefined period +* - ESP_ERR_NO_MEM: insufficient memory to handle complete frame * - ESP_FAIL: transmit frame buffer failed because some other error occurred */ esp_err_t esp_eth_transmit(esp_eth_handle_t hdl, void *buf, size_t length); @@ -371,8 +372,10 @@ __attribute__((deprecated("Use esp_eth_transmit_ctrl_bufs() instead"))); * @param buf_count number of valid entries in @a bufs * @return * - ESP_OK: transmit successful + * - ESP_ERR_INVALID_ARG: invalid argument (e.g. total frame length is zero) * - ESP_ERR_INVALID_STATE: invalid driver state (e.i., driver is not started) * - ESP_ERR_TIMEOUT: transmit frame buffer failed because HW was not get available in predefined period + * - ESP_ERR_NO_MEM: insufficient memory to handle complete frame * - ESP_FAIL: transmit frame buffer failed because some other error occurred */ esp_err_t esp_eth_transmit_ctrl_bufs(esp_eth_handle_t hdl, void *ctrl, const esp_eth_buf_desc_t *bufs, size_t buf_count); diff --git a/components/esp_eth/include/esp_eth_mac.h b/components/esp_eth/include/esp_eth_mac.h index 2b3acfd3ec8..b3dd6670872 100644 --- a/components/esp_eth/include/esp_eth_mac.h +++ b/components/esp_eth/include/esp_eth_mac.h @@ -96,7 +96,7 @@ struct esp_eth_mac_s { * * @return * - ESP_OK: transmit packet successfully - * - ESP_ERR_INVALID_SIZE: number of actually sent bytes differs to expected + * - ESP_ERR_NO_MEM: insufficient memory to handle complete frame * - ESP_FAIL: transmit packet failed because some other error occurred * * @note Returned error codes may differ for each specific MAC chip. @@ -117,7 +117,8 @@ struct esp_eth_mac_s { * * @return * - ESP_OK: transmit packet successfully - * - ESP_ERR_INVALID_SIZE: number of actually sent bytes differs to expected + * - ESP_ERR_INVALID_ARG: invalid argument (e.g. total frame length is zero) + * - ESP_ERR_NO_MEM: insufficient memory to handle complete frame * - ESP_FAIL: transmit packet failed because some other error occurred * * @note Returned error codes may differ for each specific MAC chip. @@ -140,7 +141,8 @@ struct esp_eth_mac_s { * * @return * - ESP_OK: transmit packet successfully - * - ESP_ERR_INVALID_SIZE: number of actually sent bytes differs to expected + * - ESP_ERR_INVALID_ARG: invalid argument (e.g. total frame length is zero) + * - ESP_ERR_NO_MEM: insufficient memory to handle complete frame * - ESP_FAIL: transmit packet failed because some other error occurred * * @note Returned error codes may differ for each specific MAC chip. @@ -162,7 +164,8 @@ struct esp_eth_mac_s { * * @return * - ESP_OK: transmit packet successfully - * - ESP_ERR_INVALID_SIZE: number of actually sent bytes differs to expected + * - ESP_ERR_INVALID_ARG: invalid argument (e.g. total frame length is zero) + * - ESP_ERR_NO_MEM: insufficient memory to handle complete frame * - ESP_FAIL: transmit packet failed because some other error occurred * * @note Returned error codes may differ for each specific MAC chip. diff --git a/components/esp_eth/src/mac/esp_eth_mac_esp.c b/components/esp_eth/src/mac/esp_eth_mac_esp.c index 8415b4f65c4..b8ef5cd3d49 100644 --- a/components/esp_eth/src/mac/esp_eth_mac_esp.c +++ b/components/esp_eth/src/mac/esp_eth_mac_esp.c @@ -560,6 +560,7 @@ static esp_err_t emac_esp32_transmit_ctrl_bufs(esp_eth_mac_t *mac, void *ctrl, c { emac_esp32_t *emac = __containerof(mac, emac_esp32_t, parent); emac_esp_dma_transmit_buff_t buff_array[buf_count]; + esp_err_t ret = ESP_OK; uint32_t exp_len = 0; for (size_t i = 0; i < buf_count; i++) { @@ -567,6 +568,7 @@ static esp_err_t emac_esp32_transmit_ctrl_bufs(esp_eth_mac_t *mac, void *ctrl, c buff_array[i].size = bufs[i].len; exp_len += buff_array[i].size; } + ESP_GOTO_ON_FALSE(exp_len > 0, ESP_ERR_INVALID_ARG, err, TAG, "expected length is 0"); eth_mac_time_t *ts = (eth_mac_time_t *)ctrl; uint32_t sent_len = emac_esp_dma_transmit_frame_ext(emac->emac_dma_hndl, buff_array, (uint32_t)buf_count, ts); @@ -575,7 +577,8 @@ static esp_err_t emac_esp32_transmit_ctrl_bufs(esp_eth_mac_t *mac, void *ctrl, c ESP_LOGD(TAG, "insufficient TX buffer size"); return ESP_ERR_NO_MEM; } - return ESP_OK; +err: + return ret; } static esp_err_t emac_esp32_transmit_ctrl_vargs(esp_eth_mac_t *mac, void *ctrl, uint32_t argc, va_list args)