From ac5ce8d02dcff25b7309c42ff7dc71ccf154d0b7 Mon Sep 17 00:00:00 2001 From: liuning Date: Fri, 27 Oct 2023 14:27:11 +0800 Subject: [PATCH] fix(wifi): fix wifi init reentrant issue --- components/esp_wifi/src/wifi_init.c | 69 +++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index f23461999a..2887bf446e 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -19,6 +19,8 @@ #include "esp_phy_init.h" #include "phy.h" +static bool s_wifi_inited = false; + #if (CONFIG_ESP32_WIFI_RX_BA_WIN > CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM) #error "WiFi configuration check: WARNING, WIFI_RX_BA_WIN should not be larger than WIFI_DYNAMIC_RX_BUFFER_NUM!" #endif @@ -90,7 +92,7 @@ static void esp_wifi_set_log_level(void) esp_wifi_internal_set_log_level(wifi_log_level); } -esp_err_t esp_wifi_deinit(void) +static esp_err_t wifi_deinit_internal(void) { esp_err_t err = ESP_OK; @@ -110,6 +112,12 @@ esp_err_t esp_wifi_deinit(void) ESP_LOGE(TAG, "Failed to deinit Wi-Fi driver (0x%x)", err); return err; } +#ifdef CONFIG_PM_ENABLE + if (s_wifi_modem_sleep_lock) { + esp_pm_lock_delete(s_wifi_modem_sleep_lock); + } +#endif + esp_wifi_power_domain_off(); #if CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT esp_wifi_beacon_monitor_configure(false, 0, 0, 0, 0); @@ -129,16 +137,26 @@ esp_err_t esp_wifi_deinit(void) esp_unregister_mac_bb_pd_callback(pm_mac_sleep); esp_unregister_mac_bb_pu_callback(pm_mac_wakeup); #endif - esp_wifi_power_domain_off(); #if CONFIG_MAC_BB_PD esp_wifi_internal_set_mac_sleep(false); esp_mac_bb_pd_mem_deinit(); #endif esp_phy_modem_deinit(); + s_wifi_inited = false; + return err; } +esp_err_t esp_wifi_deinit(void) +{ + if (s_wifi_inited == false) { + return ESP_ERR_WIFI_NOT_INIT; + } + + return wifi_deinit_internal(); +} + static void esp_wifi_config_info(void) { #ifdef CONFIG_ESP32_WIFI_RX_BA_WIN @@ -180,21 +198,15 @@ static void esp_wifi_config_info(void) esp_err_t esp_wifi_init(const wifi_init_config_t *config) { + if (s_wifi_inited) { + return ESP_OK; + } + if ((config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) && (WIFI_CACHE_TX_BUFFER_NUM == 0)) { ESP_LOGE(TAG, "Number of WiFi cache TX buffers should not equal 0 when enable SPIRAM"); return ESP_ERR_NOT_SUPPORTED; } - esp_wifi_power_domain_on(); -#ifdef CONFIG_PM_ENABLE - if (s_wifi_modem_sleep_lock == NULL) { - esp_err_t err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi", - &s_wifi_modem_sleep_lock); - if (err != ESP_OK) { - return err; - } - } -#endif #if CONFIG_ESP_WIFI_SLP_IRAM_OPT esp_pm_register_light_sleep_default_params_config_callback(esp_wifi_internal_update_light_sleep_default_params); @@ -247,6 +259,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) coex_init(); #endif esp_wifi_set_log_level(); + esp_wifi_power_domain_on(); esp_err_t result = esp_wifi_init_internal(config); if (result == ESP_OK) { #if CONFIG_MAC_BB_PD @@ -258,16 +271,24 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) s_wifi_mac_time_update_cb = esp_wifi_internal_update_mac_time; #endif +#ifdef CONFIG_PM_ENABLE + if (s_wifi_modem_sleep_lock == NULL) { + result = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "wifi", + &s_wifi_modem_sleep_lock); + if (result != ESP_OK) { + ESP_LOGE(TAG, "Failed to create pm lock (0x%x)", result); + goto _deinit; + } + } +#endif + result = esp_supplicant_init(); if (result != ESP_OK) { ESP_LOGE(TAG, "Failed to init supplicant (0x%x)", result); - esp_err_t deinit_ret = esp_wifi_deinit(); - if (deinit_ret != ESP_OK) { - ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret); - } - - return result; + goto _deinit; } + } else { + goto _deinit; } #if CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT esp_wifi_beacon_monitor_configure(true, CONFIG_ESP_WIFI_SLP_BEACON_LOST_TIMEOUT, @@ -277,6 +298,18 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) adc2_cal_include(); //This enables the ADC2 calibration constructor at start up. esp_wifi_config_info(); + + s_wifi_inited = true; + + return result; + +_deinit: + ; + esp_err_t deinit_ret = wifi_deinit_internal(); + if (deinit_ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to deinit Wi-Fi (0x%x)", deinit_ret); + } + return result; }