mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
fix(esp_eth): improved SPI Ethernet _alloc_recv_buf error handling
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -789,6 +789,7 @@ static void emac_dm9051_task(void *arg)
|
|||||||
{
|
{
|
||||||
emac_dm9051_t *emac = (emac_dm9051_t *)arg;
|
emac_dm9051_t *emac = (emac_dm9051_t *)arg;
|
||||||
uint8_t status = 0;
|
uint8_t status = 0;
|
||||||
|
esp_err_t ret;
|
||||||
while (1) {
|
while (1) {
|
||||||
// check if the task receives any notification
|
// check if the task receives any notification
|
||||||
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ...
|
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ...
|
||||||
@ -804,31 +805,35 @@ static void emac_dm9051_task(void *arg)
|
|||||||
/* define max expected frame len */
|
/* define max expected frame len */
|
||||||
uint32_t frame_len = ETH_MAX_PACKET_SIZE;
|
uint32_t frame_len = ETH_MAX_PACKET_SIZE;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
dm9051_alloc_recv_buf(emac, &buffer, &frame_len);
|
if ((ret = dm9051_alloc_recv_buf(emac, &buffer, &frame_len)) == ESP_OK) {
|
||||||
/* we have memory to receive the frame of maximal size previously defined */
|
if (buffer != NULL) {
|
||||||
if (buffer != NULL) {
|
/* we have memory to receive the frame of maximal size previously defined */
|
||||||
uint32_t buf_len = DM9051_ETH_MAC_RX_BUF_SIZE_AUTO;
|
uint32_t buf_len = DM9051_ETH_MAC_RX_BUF_SIZE_AUTO;
|
||||||
if (emac->parent.receive(&emac->parent, buffer, &buf_len) == ESP_OK) {
|
if (emac->parent.receive(&emac->parent, buffer, &buf_len) == ESP_OK) {
|
||||||
if (buf_len == 0) {
|
if (buf_len == 0) {
|
||||||
|
dm9051_flush_recv_frame(emac);
|
||||||
|
free(buffer);
|
||||||
|
} else if (frame_len > buf_len) {
|
||||||
|
ESP_LOGE(TAG, "received frame was truncated");
|
||||||
|
free(buffer);
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "receive len=%u", buf_len);
|
||||||
|
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
||||||
|
emac->eth->stack_input(emac->eth, buffer, buf_len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "frame read from module failed");
|
||||||
dm9051_flush_recv_frame(emac);
|
dm9051_flush_recv_frame(emac);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
} else if (frame_len > buf_len) {
|
|
||||||
ESP_LOGE(TAG, "received frame was truncated");
|
|
||||||
free(buffer);
|
|
||||||
} else {
|
|
||||||
ESP_LOGD(TAG, "receive len=%u", buf_len);
|
|
||||||
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
|
||||||
emac->eth->stack_input(emac->eth, buffer, buf_len);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if (frame_len) {
|
||||||
ESP_LOGE(TAG, "frame read from module failed");
|
ESP_LOGE(TAG, "invalid combination of frame_len(%u) and buffer pointer(%p)", frame_len, buffer);
|
||||||
dm9051_flush_recv_frame(emac);
|
|
||||||
free(buffer);
|
|
||||||
}
|
}
|
||||||
/* if allocation failed and there is a waiting frame */
|
} else if (ret == ESP_ERR_NO_MEM) {
|
||||||
} else if (frame_len) {
|
|
||||||
ESP_LOGE(TAG, "no mem for receive buffer");
|
ESP_LOGE(TAG, "no mem for receive buffer");
|
||||||
dm9051_flush_recv_frame(emac);
|
dm9051_flush_recv_frame(emac);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "unexpected error 0x%x", ret);
|
||||||
}
|
}
|
||||||
} while (emac->packets_remain);
|
} while (emac->packets_remain);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
* SPDX-FileContributor: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileContributor: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -638,6 +638,7 @@ static esp_err_t emac_ksz8851_set_peer_pause_ability(esp_eth_mac_t *mac, uint32_
|
|||||||
static void emac_ksz8851snl_task(void *arg)
|
static void emac_ksz8851snl_task(void *arg)
|
||||||
{
|
{
|
||||||
emac_ksz8851snl_t *emac = (emac_ksz8851snl_t *)arg;
|
emac_ksz8851snl_t *emac = (emac_ksz8851snl_t *)arg;
|
||||||
|
esp_err_t ret;
|
||||||
while (1) {
|
while (1) {
|
||||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||||
|
|
||||||
@ -691,31 +692,35 @@ static void emac_ksz8851snl_task(void *arg)
|
|||||||
/* define max expected frame len */
|
/* define max expected frame len */
|
||||||
uint32_t frame_len = ETH_MAX_PACKET_SIZE;
|
uint32_t frame_len = ETH_MAX_PACKET_SIZE;
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
emac_ksz8851_alloc_recv_buf(emac, &buffer, &frame_len);
|
if ((ret = emac_ksz8851_alloc_recv_buf(emac, &buffer, &frame_len)) == ESP_OK) {
|
||||||
/* we have memory to receive the frame of maximal size previously defined */
|
if (buffer != NULL) {
|
||||||
if (buffer != NULL) {
|
/* we have memory to receive the frame of maximal size previously defined */
|
||||||
uint32_t buf_len = KSZ8851_ETH_MAC_RX_BUF_SIZE_AUTO;
|
uint32_t buf_len = KSZ8851_ETH_MAC_RX_BUF_SIZE_AUTO;
|
||||||
if (emac->parent.receive(&emac->parent, buffer, &buf_len) == ESP_OK) {
|
if (emac->parent.receive(&emac->parent, buffer, &buf_len) == ESP_OK) {
|
||||||
if (buf_len == 0) {
|
if (buf_len == 0) {
|
||||||
|
emac_ksz8851_flush_recv_queue(emac);
|
||||||
|
free(buffer);
|
||||||
|
} else if (frame_len > buf_len) {
|
||||||
|
ESP_LOGE(TAG, "received frame was truncated");
|
||||||
|
free(buffer);
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "receive len=%u", buf_len);
|
||||||
|
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
||||||
|
emac->eth->stack_input(emac->eth, buffer, buf_len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "frame read from module failed");
|
||||||
emac_ksz8851_flush_recv_queue(emac);
|
emac_ksz8851_flush_recv_queue(emac);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
} else if (frame_len > buf_len) {
|
|
||||||
ESP_LOGE(TAG, "received frame was truncated");
|
|
||||||
free(buffer);
|
|
||||||
} else {
|
|
||||||
ESP_LOGD(TAG, "receive len=%u", buf_len);
|
|
||||||
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
|
||||||
emac->eth->stack_input(emac->eth, buffer, buf_len);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if (frame_len) {
|
||||||
ESP_LOGE(TAG, "frame read from module failed");
|
ESP_LOGE(TAG, "invalid combination of frame_len(%u) and buffer pointer(%p)", frame_len, buffer);
|
||||||
emac_ksz8851_flush_recv_queue(emac);
|
|
||||||
free(buffer);
|
|
||||||
}
|
}
|
||||||
/* if allocation failed and there is a waiting frame */
|
} else if (ret == ESP_ERR_NO_MEM) {
|
||||||
} else if (frame_len) {
|
|
||||||
ESP_LOGE(TAG, "no mem for receive buffer");
|
ESP_LOGE(TAG, "no mem for receive buffer");
|
||||||
emac_ksz8851_flush_recv_queue(emac);
|
emac_ksz8851_flush_recv_queue(emac);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "unexpected error 0x%x", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ksz8851_write_reg(emac, KSZ8851_IER, ier);
|
ksz8851_write_reg(emac, KSZ8851_IER, ier);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -585,7 +585,7 @@ static esp_err_t emac_w5500_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t *
|
|||||||
remain_bytes -= rx_len + 2;
|
remain_bytes -= rx_len + 2;
|
||||||
emac->packets_remain = remain_bytes > 0;
|
emac->packets_remain = remain_bytes > 0;
|
||||||
|
|
||||||
*length = rx_len;
|
*length = copy_len;
|
||||||
return ret;
|
return ret;
|
||||||
err:
|
err:
|
||||||
*length = 0;
|
*length = 0;
|
||||||
@ -608,12 +608,13 @@ static esp_err_t emac_w5500_flush_recv_frame(emac_w5500_t *emac)
|
|||||||
// read head first
|
// read head first
|
||||||
ESP_GOTO_ON_ERROR(w5500_read_buffer(emac, &rx_len, sizeof(rx_len), offset), err, TAG, "read frame header failed");
|
ESP_GOTO_ON_ERROR(w5500_read_buffer(emac, &rx_len, sizeof(rx_len), offset), err, TAG, "read frame header failed");
|
||||||
// update read pointer
|
// update read pointer
|
||||||
offset = rx_len;
|
rx_len = __builtin_bswap16(rx_len);
|
||||||
|
offset += rx_len;
|
||||||
|
offset = __builtin_bswap16(offset);
|
||||||
ESP_GOTO_ON_ERROR(w5500_write(emac, W5500_REG_SOCK_RX_RD(0), &offset, sizeof(offset)), err, TAG, "write RX RD failed");
|
ESP_GOTO_ON_ERROR(w5500_write(emac, W5500_REG_SOCK_RX_RD(0), &offset, sizeof(offset)), err, TAG, "write RX RD failed");
|
||||||
/* issue RECV command */
|
/* issue RECV command */
|
||||||
ESP_GOTO_ON_ERROR(w5500_send_command(emac, W5500_SCR_RECV, 100), err, TAG, "issue RECV command failed");
|
ESP_GOTO_ON_ERROR(w5500_send_command(emac, W5500_SCR_RECV, 100), err, TAG, "issue RECV command failed");
|
||||||
// check if there're more data need to process
|
// check if there're more data need to process
|
||||||
rx_len = __builtin_bswap16(rx_len);
|
|
||||||
remain_bytes -= rx_len;
|
remain_bytes -= rx_len;
|
||||||
emac->packets_remain = remain_bytes > 0;
|
emac->packets_remain = remain_bytes > 0;
|
||||||
}
|
}
|
||||||
@ -639,6 +640,7 @@ static void emac_w5500_task(void *arg)
|
|||||||
uint8_t *buffer = NULL;
|
uint8_t *buffer = NULL;
|
||||||
uint32_t frame_len = 0;
|
uint32_t frame_len = 0;
|
||||||
uint32_t buf_len = 0;
|
uint32_t buf_len = 0;
|
||||||
|
esp_err_t ret;
|
||||||
while (1) {
|
while (1) {
|
||||||
/* check if the task receives any notification */
|
/* check if the task receives any notification */
|
||||||
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ...
|
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ...
|
||||||
@ -655,29 +657,33 @@ static void emac_w5500_task(void *arg)
|
|||||||
do {
|
do {
|
||||||
/* define max expected frame len */
|
/* define max expected frame len */
|
||||||
frame_len = ETH_MAX_PACKET_SIZE;
|
frame_len = ETH_MAX_PACKET_SIZE;
|
||||||
emac_w5500_alloc_recv_buf(emac, &buffer, &frame_len);
|
if ((ret = emac_w5500_alloc_recv_buf(emac, &buffer, &frame_len)) == ESP_OK) {
|
||||||
/* we have memory to receive the frame of maximal size previously defined */
|
if (buffer != NULL) {
|
||||||
if (buffer != NULL) {
|
/* we have memory to receive the frame of maximal size previously defined */
|
||||||
buf_len = W5500_ETH_MAC_RX_BUF_SIZE_AUTO;
|
buf_len = W5500_ETH_MAC_RX_BUF_SIZE_AUTO;
|
||||||
if (emac->parent.receive(&emac->parent, buffer, &buf_len) == ESP_OK) {
|
if (emac->parent.receive(&emac->parent, buffer, &buf_len) == ESP_OK) {
|
||||||
if (buf_len == 0) {
|
if (buf_len == 0) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
} else if (frame_len > buf_len) {
|
} else if (frame_len > buf_len) {
|
||||||
ESP_LOGE(TAG, "received frame was truncated");
|
ESP_LOGE(TAG, "received frame was truncated");
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "receive len=%u", buf_len);
|
||||||
|
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
||||||
|
emac->eth->stack_input(emac->eth, buffer, buf_len);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGD(TAG, "receive len=%u", buf_len);
|
ESP_LOGE(TAG, "frame read from module failed");
|
||||||
/* pass the buffer to stack (e.g. TCP/IP layer) */
|
free(buffer);
|
||||||
emac->eth->stack_input(emac->eth, buffer, buf_len);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if (frame_len) {
|
||||||
ESP_LOGE(TAG, "frame read from module failed");
|
ESP_LOGE(TAG, "invalid combination of frame_len(%u) and buffer pointer(%p)", frame_len, buffer);
|
||||||
free(buffer);
|
|
||||||
}
|
}
|
||||||
/* if allocation failed and there is a waiting frame */
|
} else if (ret == ESP_ERR_NO_MEM) {
|
||||||
} else if (frame_len) {
|
|
||||||
ESP_LOGE(TAG, "no mem for receive buffer");
|
ESP_LOGE(TAG, "no mem for receive buffer");
|
||||||
emac_w5500_flush_recv_frame(emac);
|
emac_w5500_flush_recv_frame(emac);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "unexpected error 0x%x", ret);
|
||||||
}
|
}
|
||||||
} while (emac->packets_remain);
|
} while (emac->packets_remain);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user