diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index b40c5fac81..014d7f7aed 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -344,6 +344,12 @@ static const esp_err_msg_t esp_err_msg_table[] = { # endif # ifdef ESP_ERR_WIFI_STOP_STATE ERR_TBL_IT(ESP_ERR_WIFI_STOP_STATE), /* 12308 0x3014 Returned when WiFi is stopping */ +# endif +# ifdef ESP_ERR_WIFI_NOT_ASSOC + ERR_TBL_IT(ESP_ERR_WIFI_NOT_ASSOC), /* 12309 0x3015 The WiFi connection is not associated */ +# endif +# ifdef ESP_ERR_WIFI_TX_DISALLOW + ERR_TBL_IT(ESP_ERR_WIFI_TX_DISALLOW), /* 12310 0x3016 The WiFi TX is disallowed */ # endif // components/wpa_supplicant/include/esp_supplicant/esp_wps.h # ifdef ESP_ERR_WIFI_REGISTRAR diff --git a/components/esp_wifi/Kconfig b/components/esp_wifi/Kconfig index c71e57b676..79b13109b2 100644 --- a/components/esp_wifi/Kconfig +++ b/components/esp_wifi/Kconfig @@ -90,6 +90,19 @@ menu "Wi-Fi" layer can deliver frames faster than WiFi layer can transmit. In these cases, we may run out of TX buffers. + config ESP32_WIFI_CACHE_TX_BUFFER_NUM + int "Max number of WiFi cache TX buffers" + depends on (ESP32_SPIRAM_SUPPORT || ESP32S2_SPIRAM_SUPPORT) + range 16 128 + default 32 + help + Set the number of WiFi cache TX buffer number. + + For each TX packet from uplayer, such as LWIP etc, WiFi driver needs to allocate a static TX + buffer and makes a copy of uplayer packet. If WiFi driver fails to allocate the static TX buffer, + it caches the uplayer packets to a dedicated buffer queue, this option is used to configure the + size of the cached TX queue. + config ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM int "Max number of WiFi dynamic TX buffers" depends on ESP32_WIFI_DYNAMIC_TX_BUFFER @@ -139,8 +152,8 @@ menu "Wi-Fi" config ESP32_WIFI_RX_BA_WIN int "WiFi AMPDU RX BA window size" depends on ESP32_WIFI_AMPDU_RX_ENABLED - range 2 32 if !SPIRAM_TRY_ALLOCATE_WIFI_LWIP - range 16 32 if SPIRAM_TRY_ALLOCATE_WIFI_LWIP + range 2 32 + default 6 if !SPIRAM_TRY_ALLOCATE_WIFI_LWIP default 16 if SPIRAM_TRY_ALLOCATE_WIFI_LWIP help diff --git a/components/esp_wifi/include/esp_private/wifi.h b/components/esp_wifi/include/esp_private/wifi.h index 359f49d419..7abc36dace 100644 --- a/components/esp_wifi/include/esp_private/wifi.h +++ b/components/esp_wifi/include/esp_private/wifi.h @@ -120,15 +120,6 @@ esp_err_t esp_wifi_init_internal(const wifi_init_config_t *config); */ esp_err_t esp_wifi_deinit_internal(void); -/** - * @brief get whether the wifi driver is allowed to transmit data or not - * - * @return - * - true : upper layer should stop to transmit data to wifi driver - * - false : upper layer can transmit data to wifi driver - */ -bool esp_wifi_internal_tx_is_stop(void); - /** * @brief free the rx buffer which allocated by wifi driver * @@ -139,18 +130,79 @@ void esp_wifi_internal_free_rx_buffer(void* buffer); /** * @brief transmit the buffer via wifi driver * + * This API makes a copy of the input buffer and then forwards the buffer + * copy to WiFi driver. + * * @param wifi_interface_t wifi_if : wifi interface id * @param void *buffer : the buffer to be tansmit * @param uint16_t len : the length of buffer * * @return - * - ERR_OK : Successfully transmit the buffer to wifi driver - * - ERR_MEM : Out of memory - * - ERR_IF : WiFi driver error - * - ERR_ARG : Invalid argument + * - ESP_OK : Successfully transmit the buffer to wifi driver + * - ESP_ERR_NO_MEM: out of memory + * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_WIFI_IF : WiFi interface is invalid + * - ESP_ERR_WIFI_CONN : WiFi interface is not created, e.g. send the data to STA while WiFi mode is AP mode + * - ESP_ERR_WIFI_NOT_STARTED : WiFi is not started + * - ESP_ERR_WIFI_STATE : WiFi internal state is not ready, e.g. WiFi is not started + * - ESP_ERR_WIFI_NOT_ASSOC : WiFi is not associated + * - ESP_ERR_WIFI_TX_DISALLOW : WiFi TX is disallowed, e.g. WiFi hasn't pass the authentication + * - ESP_ERR_WIFI_POST : caller fails to post event to WiFi task */ int esp_wifi_internal_tx(wifi_interface_t wifi_if, void *buffer, uint16_t len); +/** + * @brief The net stack buffer reference counter callback function + * + */ +typedef void (*wifi_netstack_buf_ref_cb_t)(void *netstack_buf); + +/** + * @brief The net stack buffer free callback function + * + */ +typedef void (*wifi_netstack_buf_free_cb_t)(void *netstack_buf); + +/** + * @brief transmit the buffer by reference via wifi driver + * + * This API firstly increases the reference counter of the input buffer and + * then forwards the buffer to WiFi driver. The WiFi driver will free the buffer + * after processing it. Use esp_wifi_internal_tx() if the uplayer buffer doesn't + * supports reference counter. + * + * @param wifi_if : wifi interface id + * @param buffer : the buffer to be tansmit + * @param len : the length of buffer + * @param netstack_buf : the netstack buffer related to bufffer + * + * @return + * - ESP_OK : Successfully transmit the buffer to wifi driver + * - ESP_ERR_NO_MEM: out of memory + * - ESP_ERR_WIFI_ARG: invalid argument + * - ESP_ERR_WIFI_IF : WiFi interface is invalid + * - ESP_ERR_WIFI_CONN : WiFi interface is not created, e.g. send the data to STA while WiFi mode is AP mode + * - ESP_ERR_WIFI_NOT_STARTED : WiFi is not started + * - ESP_ERR_WIFI_STATE : WiFi internal state is not ready, e.g. WiFi is not started + * - ESP_ERR_WIFI_NOT_ASSOC : WiFi is not associated + * - ESP_ERR_WIFI_TX_DISALLOW : WiFi TX is disallowed, e.g. WiFi hasn't pass the authentication + * - ESP_ERR_WIFI_POST : caller fails to post event to WiFi task + */ +esp_err_t esp_wifi_internal_tx_by_ref(wifi_interface_t ifx, void *buffer, size_t len, void *netstack_buf); + +/** + * @brief register the net stack buffer reference increasing and free callback + * + * @param ref : net stack buffer reference callback + * @param free: net stack buffer free callback + * + * @return + * - ESP_OK : Successfully transmit the buffer to wifi driver + * - others : failed to register the callback + */ +esp_err_t esp_wifi_internal_reg_netstack_buf_cb(wifi_netstack_buf_ref_cb_t ref, wifi_netstack_buf_free_cb_t free); + + /** * @brief The WiFi RX callback function * diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 7c9cdb9e18..3f70a2be40 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -87,6 +87,8 @@ extern "C" { #define ESP_ERR_WIFI_POST (ESP_ERR_WIFI_BASE + 18) /*!< Failed to post the event to WiFi task */ #define ESP_ERR_WIFI_INIT_STATE (ESP_ERR_WIFI_BASE + 19) /*!< Invalid WiFi state when init/deinit is called */ #define ESP_ERR_WIFI_STOP_STATE (ESP_ERR_WIFI_BASE + 20) /*!< Returned when WiFi is stopping */ +#define ESP_ERR_WIFI_NOT_ASSOC (ESP_ERR_WIFI_BASE + 21) /*!< The WiFi connection is not associated */ +#define ESP_ERR_WIFI_TX_DISALLOW (ESP_ERR_WIFI_BASE + 22) /*!< The WiFi TX is disallowed */ /** * @brief WiFi stack configuration parameters passed to esp_wifi_init call. @@ -100,12 +102,12 @@ typedef struct { int tx_buf_type; /**< WiFi TX buffer type */ int static_tx_buf_num; /**< WiFi static TX buffer number */ int dynamic_tx_buf_num; /**< WiFi dynamic TX buffer number */ + int cache_tx_buf_num; /**< WiFi TX cache buffer number */ int csi_enable; /**< WiFi channel state information enable flag */ int ampdu_rx_enable; /**< WiFi AMPDU RX feature enable flag */ int ampdu_tx_enable; /**< WiFi AMPDU TX feature enable flag */ int nvs_enable; /**< WiFi NVS flash enable flag */ int nano_enable; /**< Nano option for printf/scan family enable flag */ - int tx_ba_win; /**< WiFi Block Ack TX window size */ int rx_ba_win; /**< WiFi Block Ack RX window size */ int wifi_task_core_id; /**< WiFi Task Core ID */ int beacon_max_len; /**< WiFi softAP maximum length of the beacon */ @@ -120,6 +122,12 @@ typedef struct { #define WIFI_STATIC_TX_BUFFER_NUM 0 #endif +#if (CONFIG_ESP32_SPIRAM_SUPPORT | CONFIG_ESP32S2_SPIRAM_SUPPORT) +#define WIFI_CACHE_TX_BUFFER_NUM CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM +#else +#define WIFI_CACHE_TX_BUFFER_NUM 0 +#endif + #ifdef CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM #define WIFI_DYNAMIC_TX_BUFFER_NUM CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM #else @@ -161,12 +169,6 @@ extern uint64_t g_wifi_feature_caps; #define WIFI_INIT_CONFIG_MAGIC 0x1F2F3F4F -#ifdef CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED -#define WIFI_DEFAULT_TX_BA_WIN CONFIG_ESP32_WIFI_TX_BA_WIN -#else -#define WIFI_DEFAULT_TX_BA_WIN 0 /* unused if ampdu_tx_enable == false */ -#endif - #ifdef CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED #define WIFI_DEFAULT_RX_BA_WIN CONFIG_ESP32_WIFI_RX_BA_WIN #else @@ -192,6 +194,7 @@ extern uint64_t g_wifi_feature_caps; #endif #define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0) +#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1) #define WIFI_INIT_CONFIG_DEFAULT() { \ .event_handler = &esp_event_send, \ @@ -202,12 +205,12 @@ extern uint64_t g_wifi_feature_caps; .tx_buf_type = CONFIG_ESP32_WIFI_TX_BUFFER_TYPE,\ .static_tx_buf_num = WIFI_STATIC_TX_BUFFER_NUM,\ .dynamic_tx_buf_num = WIFI_DYNAMIC_TX_BUFFER_NUM,\ + .cache_tx_buf_num = WIFI_CACHE_TX_BUFFER_NUM,\ .csi_enable = WIFI_CSI_ENABLED,\ .ampdu_rx_enable = WIFI_AMPDU_RX_ENABLED,\ .ampdu_tx_enable = WIFI_AMPDU_TX_ENABLED,\ .nvs_enable = WIFI_NVS_ENABLED,\ .nano_enable = WIFI_NANO_FORMAT_ENABLED,\ - .tx_ba_win = WIFI_DEFAULT_TX_BA_WIN,\ .rx_ba_win = WIFI_DEFAULT_RX_BA_WIN,\ .wifi_task_core_id = WIFI_TASK_CORE_ID,\ .beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \ @@ -1099,6 +1102,17 @@ esp_err_t esp_wifi_set_inactive_time(wifi_interface_t ifx, uint16_t sec); */ esp_err_t esp_wifi_get_inactive_time(wifi_interface_t ifx, uint16_t *sec); +/** + * @brief Dump WiFi statistics + * + * @param modules statistic modules to be dumped + * + * @return + * - ESP_OK: succeed + * - others: failed + */ +esp_err_t esp_wifi_statis_dump(uint32_t modules); + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 971eabbfb3..67cd3eaa6a 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -600,6 +600,12 @@ typedef struct { uint8_t mac[6]; /**< MAC address of the station which send probe request */ } wifi_event_ap_probe_req_rx_t; +#define WIFI_STATIS_BUFFER (1<<0) +#define WIFI_STATIS_RXTX (1<<1) +#define WIFI_STATIS_HW (1<<2) +#define WIFI_STATIS_DIAG (1<<3) +#define WIFI_STATIS_ALL (-1) + #ifdef __cplusplus } #endif diff --git a/components/esp_wifi/lib_esp32 b/components/esp_wifi/lib_esp32 index c4b9dd09a2..7a08106ea3 160000 --- a/components/esp_wifi/lib_esp32 +++ b/components/esp_wifi/lib_esp32 @@ -1 +1 @@ -Subproject commit c4b9dd09a274a0955589f68f556bb8069abf1682 +Subproject commit 7a08106ea32e565867aec3254d819dc533ae5c4a diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 29ceadb8df..6296cd2778 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -43,6 +43,9 @@ uint64_t g_wifi_feature_caps = #if CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE CONFIG_FEATURE_WPA3_SAE_BIT | #endif +#if (CONFIG_ESP32_SPIRAM_SUPPORT) + CONFIG_FEATURE_CACHE_TX_BUF_BIT | +#endif 0; static const char* TAG = "wifi_init"; @@ -127,6 +130,35 @@ esp_err_t esp_wifi_deinit(void) return err; } +static void esp_wifi_config_info(void) +{ +#ifdef CONFIG_ESP32_WIFI_RX_BA_WIN + ESP_LOGI(TAG, "rx ba win: %d", CONFIG_ESP32_WIFI_RX_BA_WIN); +#endif + ESP_LOGI(TAG, "tcpip mbox: %d", CONFIG_LWIP_TCPIP_RECVMBOX_SIZE); + ESP_LOGI(TAG, "udp mbox: %d", CONFIG_LWIP_UDP_RECVMBOX_SIZE); + ESP_LOGI(TAG, "tcp mbox: %d", CONFIG_LWIP_TCP_RECVMBOX_SIZE); + ESP_LOGI(TAG, "tcp tx win: %d", CONFIG_LWIP_TCP_SND_BUF_DEFAULT); + ESP_LOGI(TAG, "tcp rx win: %d", CONFIG_LWIP_TCP_WND_DEFAULT); + ESP_LOGI(TAG, "tcp mss: %d", CONFIG_LWIP_TCP_MSS); + +#ifdef CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP + ESP_LOGI(TAG, "WiFi/LWIP prefer SPIRAM"); +#endif + +#ifdef CONFIG_ESP32_WIFI_IRAM_OPT + ESP_LOGI(TAG, "WiFi IRAM OP enabled"); +#endif + +#ifdef CONFIG_ESP32_WIFI_RX_IRAM_OPT + ESP_LOGI(TAG, "WiFi RX IRAM OP enabled"); +#endif + +#ifdef CONFIG_LWIP_IRAM_OPTIMIZATION + ESP_LOGI(TAG, "LWIP IRAM OP enabled"); +#endif +} + esp_err_t esp_wifi_init(const wifi_init_config_t *config) { #ifdef CONFIG_PM_ENABLE @@ -158,7 +190,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) return result; } } - + esp_wifi_config_info(); return result; } diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index 71eed9dd04..bb021f3d6a 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -104,6 +104,15 @@ low_level_init(struct netif *netif) #endif } +static esp_err_t wifi_transmit_wrap(wifi_interface_t wifi_if, void *buffer, size_t len, void *netstack_buf) +{ +#if (CONFIG_ESP32_SPIRAM_SUPPORT) + return esp_wifi_internal_tx_by_ref(wifi_if, buffer, len, netstack_buf); +#else + return esp_wifi_internal_tx(wifi_if, buffer, len); +#endif +} + /** * This function should do the actual transmission of the packet. The packet is * contained in the pbuf that is passed to the function. This pbuf @@ -124,14 +133,14 @@ low_level_output(struct netif *netif, struct pbuf *p) { wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif); struct pbuf *q = p; - err_t ret; + esp_err_t ret; if (wifi_if >= ESP_IF_MAX) { return ERR_IF; } if(q->next == NULL) { - ret = esp_wifi_internal_tx(wifi_if, q->payload, q->len); + ret = wifi_transmit_wrap(wifi_if, q->payload, q->len, q); } else { LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); @@ -141,11 +150,19 @@ low_level_output(struct netif *netif, struct pbuf *p) } else { return ERR_MEM; } - ret = esp_wifi_internal_tx(wifi_if, q->payload, q->len); + ret = wifi_transmit_wrap(wifi_if, q->payload, q->len, q); pbuf_free(q); } - - return ret; + + if (ret == ESP_OK) { + return ERR_OK; + } else if (ret == ESP_ERR_NO_MEM) { + return ERR_MEM; + } else if (ret == ESP_ERR_INVALID_ARG) { + return ERR_ARG; + } else { + return ERR_IF; + } } /** diff --git a/components/tcpip_adapter/event_handlers.c b/components/tcpip_adapter/event_handlers.c index d22d18a051..95d5043872 100644 --- a/components/tcpip_adapter/event_handlers.c +++ b/components/tcpip_adapter/event_handlers.c @@ -123,6 +123,7 @@ static void handle_ap_start(void *arg, esp_event_base_t base, int32_t event_id, uint8_t ap_mac[6]; API_CALL_CHECK("esp_wifi_internal_reg_rxcb", esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_AP, (wifi_rxcb_t)tcpip_adapter_ap_input), ESP_OK); + API_CALL_CHECK("esp_wifi_internal_reg_netstack_buf_cb",esp_wifi_internal_reg_netstack_buf_cb(esp_netif_netstack_buf_ref, esp_netif_netstack_buf_free), ESP_OK); API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_AP, ap_mac), ESP_OK); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_AP, &ap_ip); @@ -141,6 +142,7 @@ static void handle_sta_start(void *arg, esp_event_base_t base, int32_t event_id, tcpip_adapter_ip_info_t sta_ip; uint8_t sta_mac[6]; + API_CALL_CHECK("esp_wifi_internal_reg_netstack_buf_cb",esp_wifi_internal_reg_netstack_buf_cb(esp_netif_netstack_buf_ref, esp_netif_netstack_buf_free), ESP_OK); API_CALL_CHECK("esp_wifi_mac_get", esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac), ESP_OK); tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &sta_ip); tcpip_adapter_sta_start(sta_mac, &sta_ip); diff --git a/components/tcpip_adapter/include/tcpip_adapter.h b/components/tcpip_adapter/include/tcpip_adapter.h index 75136f906c..caec2b3284 100644 --- a/components/tcpip_adapter/include/tcpip_adapter.h +++ b/components/tcpip_adapter/include/tcpip_adapter.h @@ -764,6 +764,22 @@ esp_err_t tcpip_adapter_clear_default_wifi_handlers(); */ int tcpip_adapter_get_netif_index(tcpip_adapter_if_t tcpip_if); +/** + * @brief increase the reference counter of net stack buffer + * + * @param[in] netstack_buf the net stack buffer + * + */ +void esp_netif_netstack_buf_ref(void *netstack_buf); + +/** + * @brief free the netstack buffer + * + * @param[in] netstack_buf the net stack buffer + * + */ +void esp_netif_netstack_buf_free(void *netstack_buf); + #ifdef __cplusplus } #endif diff --git a/components/tcpip_adapter/tcpip_adapter_lwip.c b/components/tcpip_adapter/tcpip_adapter_lwip.c index e00cf47ff4..fae54d0533 100644 --- a/components/tcpip_adapter/tcpip_adapter_lwip.c +++ b/components/tcpip_adapter/tcpip_adapter_lwip.c @@ -1312,4 +1312,14 @@ int tcpip_adapter_get_netif_index(tcpip_adapter_if_t tcpip_if) return netif_get_index(esp_netif[tcpip_if]); } +void esp_netif_netstack_buf_ref(void *pbuf) +{ + pbuf_ref(pbuf); +} + +void esp_netif_netstack_buf_free(void *pbuf) +{ + pbuf_free(pbuf); +} + #endif /* CONFIG_TCPIP_LWIP */