From b47bf9e7428c5a2c005826126a489b1b853068e6 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 | 68 +++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index e0594aec94..034a845c09 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -23,6 +23,8 @@ #include "apps_private/wifi_apps_private.h" #endif +static bool s_wifi_inited = false; + #if (CONFIG_ESP_WIFI_RX_BA_WIN > CONFIG_ESP_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 @@ -116,7 +118,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; @@ -140,6 +142,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 wifi_beacon_monitor_config_t monitor_config = WIFI_BEACON_MONITOR_CONFIG_DEFAULT(false); @@ -163,7 +171,6 @@ 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(); @@ -174,9 +181,20 @@ esp_err_t esp_wifi_deinit(void) #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_ESP_WIFI_RX_BA_WIN @@ -218,21 +236,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 int min_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_LIGHT_SLEEP); @@ -288,6 +300,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 @@ -305,16 +318,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 wifi_beacon_monitor_config_t monitor_config = WIFI_BEACON_MONITOR_CONFIG_DEFAULT(true); @@ -328,6 +349,17 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) esp_nan_app_init(); #endif + 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; }