diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 87b964943..1055760b1 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -395,6 +395,7 @@ void start_cpu0_default(void) #if CONFIG_SW_COEXIST_ENABLE esp_coex_adapter_register(&g_coex_adapter_funcs); + coex_pre_init(); #endif bootloader_flash_update_id(); diff --git a/components/esp32/esp_adapter.c b/components/esp32/esp_adapter.c index f464525f9..3da0d7e18 100644 --- a/components/esp32/esp_adapter.c +++ b/components/esp32/esp_adapter.c @@ -557,6 +557,8 @@ wifi_osi_funcs_t g_wifi_osi_funcs = { ._dport_access_stall_other_cpu_end_wrap = esp_dport_access_stall_other_cpu_end_wrap, ._phy_rf_deinit = esp_phy_rf_deinit, ._phy_load_cal_and_init = esp_phy_load_cal_and_init, + ._phy_common_clock_enable = esp_phy_common_clock_enable, + ._phy_common_clock_disable = esp_phy_common_clock_disable, ._read_mac = esp_read_mac, ._timer_arm = timer_arm_wrapper, ._timer_disarm = timer_disarm_wrapper, diff --git a/components/esp32/include/esp_coexist_internal.h b/components/esp32/include/esp_coexist_internal.h index 63f35666d..bdd023a93 100644 --- a/components/esp32/include/esp_coexist_internal.h +++ b/components/esp32/include/esp_coexist_internal.h @@ -31,6 +31,14 @@ typedef enum { typedef void (* coex_func_cb_t)(uint32_t event, int sched_cnt); +/** + * @brief Pre-Init software coexist + * extern function for internal use. + * + * @return Init ok or failed. + */ +esp_err_t coex_pre_init(void); + /** * @brief Init software coexist * extern function for internal use. diff --git a/components/esp32/include/esp_phy_init.h b/components/esp32/include/esp_phy_init.h index 2dfb7447d..63e19f184 100644 --- a/components/esp32/include/esp_phy_init.h +++ b/components/esp32/include/esp_phy_init.h @@ -190,6 +190,18 @@ esp_err_t esp_phy_rf_deinit(phy_rf_module_t module); */ void esp_phy_load_cal_and_init(phy_rf_module_t module); +/** +* @brief Enable WiFi/BT common clock +* +*/ +void esp_phy_common_clock_enable(void); + +/** +* @brief Disable WiFi/BT common clock +* +*/ +void esp_phy_common_clock_disable(void); + /** * @brief Module requires to enter modem sleep */ diff --git a/components/esp32/include/esp_wifi.h b/components/esp32/include/esp_wifi.h index 3285fd350..7dc13f437 100644 --- a/components/esp32/include/esp_wifi.h +++ b/components/esp32/include/esp_wifi.h @@ -542,8 +542,10 @@ esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw); /** * @brief Set primary/secondary channel of ESP32 * - * @attention 1. This is a special API for sniffer - * @attention 2. This API should be called after esp_wifi_start() and esp_wifi_set_promiscuous() + * @attention 1. This API should be called after esp_wifi_start() + * @attention 2. When ESP32 is in STA mode, this API should not be called when STA is scanning or connecting to an external AP + * @attention 3. When ESP32 is in softAP mode, this API should not be called when softAP has connected to external STAs + * @attention 4. When ESP32 is in STA+softAP mode, this API should not be called when in the scenarios described above * * @param primary for HT20, primary is the channel number, for HT40, primary is the primary channel * @param second for HT20, second is ignored, for HT40, second is the second channel diff --git a/components/esp32/include/esp_wifi_internal.h b/components/esp32/include/esp_wifi_internal.h index d41b099db..851d5ebfe 100644 --- a/components/esp32/include/esp_wifi_internal.h +++ b/components/esp32/include/esp_wifi_internal.h @@ -256,6 +256,43 @@ esp_err_t esp_wifi_internal_update_mac_time( uint32_t time_delta ); */ esp_err_t esp_wifi_internal_ioctl(int cmd, wifi_ioctl_config_t *cfg); +/** + * @brief Get the user-configured channel info + * + * @param ifx : WiFi interface + * @param primary : store the configured primary channel + * @param second : store the configured second channel + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_internal_get_config_channel(wifi_interface_t ifx, uint8_t *primary, uint8_t *second); + +/** + * @brief Get the negotiated channel info after WiFi connection established + * + * @param ifx : WiFi interface + * @param aid : the connection number when a STA connects to the softAP + * @param primary : store the negotiated primary channel + * @param second : store the negotiated second channel + * @attention the aid param is only works when the ESP32 in softAP/softAP+STA mode + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_internal_get_negotiated_channel(wifi_interface_t ifx, uint8_t aid, uint8_t *primary, uint8_t *second); + +/** + * @brief Get the negotiated bandwidth info after WiFi connection established + * + * @param ifx : WiFi interface + * @param bw : store the negotiated bandwidth + * + * @return + * - ESP_OK: succeed + */ +esp_err_t esp_wifi_internal_get_negotiated_bandwidth(wifi_interface_t ifx, uint8_t aid, uint8_t *bw); + #ifdef __cplusplus } #endif diff --git a/components/esp32/include/esp_wifi_os_adapter.h b/components/esp32/include/esp_wifi_os_adapter.h index c8b8766de..89778661a 100644 --- a/components/esp32/include/esp_wifi_os_adapter.h +++ b/components/esp32/include/esp_wifi_os_adapter.h @@ -78,6 +78,8 @@ typedef struct { void (* _dport_access_stall_other_cpu_end_wrap)(void); int32_t (* _phy_rf_deinit)(uint32_t module); void (* _phy_load_cal_and_init)(uint32_t module); + void (* _phy_common_clock_enable)(void); + void (* _phy_common_clock_disable)(void); int32_t (* _read_mac)(uint8_t* mac, uint32_t type); void (* _timer_arm)(void *timer, uint32_t tmout, bool repeat); void (* _timer_disarm)(void *timer); diff --git a/components/esp32/lib b/components/esp32/lib index a94d8b9b0..eea4c8027 160000 --- a/components/esp32/lib +++ b/components/esp32/lib @@ -1 +1 @@ -Subproject commit a94d8b9b04d304fb27e23a9e7155d611b2d1f1c2 +Subproject commit eea4c80276a9a665afebfe326051eabebab67190 diff --git a/components/esp32/phy_init.c b/components/esp32/phy_init.c index d1ce3ae6a..76ba14953 100644 --- a/components/esp32/phy_init.c +++ b/components/esp32/phy_init.c @@ -52,6 +52,12 @@ static uint32_t s_module_phy_rf_init = 0; /* Whether modem sleep is turned on */ static volatile bool s_is_phy_rf_en = false; +/* Whether WiFi/BT common clock enabled reference */ +static volatile int32_t s_common_clock_enable_ref = 0; + +/* PHY spinlock mux */ +static portMUX_TYPE s_phy_spin_lock = portMUX_INITIALIZER_UNLOCKED; + /* Bit mask of modules needing to enter modem sleep mode */ static uint32_t s_modem_sleep_module_enter = 0; @@ -115,6 +121,56 @@ static inline void phy_update_wifi_mac_time(bool en_clock_stopped, int64_t now) } } +IRAM_ATTR static inline void phy_spin_lock(void) +{ + if (xPortInIsrContext()) { + portENTER_CRITICAL_ISR(&s_phy_spin_lock); + } else { + portENTER_CRITICAL(&s_phy_spin_lock); + } +} + +IRAM_ATTR static inline void phy_spin_unlock(void) +{ + if (xPortInIsrContext()) { + portEXIT_CRITICAL_ISR(&s_phy_spin_lock); + } else { + portEXIT_CRITICAL(&s_phy_spin_lock); + } +} + +IRAM_ATTR void esp_phy_common_clock_enable(void) +{ + phy_spin_lock(); + + if (s_common_clock_enable_ref == 0) { + // Enable WiFi/BT common clock + periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); + } + + s_common_clock_enable_ref++; + phy_spin_unlock(); +} + +IRAM_ATTR void esp_phy_common_clock_disable(void) +{ + phy_spin_lock(); + + if (s_common_clock_enable_ref > 0) { + s_common_clock_enable_ref --; + + if (s_common_clock_enable_ref == 0) { + // Disable WiFi/BT common clock + periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE); + } + } else { + abort(); + } + + phy_spin_unlock(); +} + + esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data, phy_rf_module_t module) { @@ -163,7 +219,8 @@ esp_err_t esp_phy_rf_init(const esp_phy_init_data_t* init_data, esp_phy_calibrat // Update WiFi MAC time before WiFi/BT common clock is enabled phy_update_wifi_mac_time(false, s_phy_rf_en_ts); // Enable WiFi/BT common peripheral clock - periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); + //periph_module_enable(PERIPH_WIFI_BT_COMMON_MODULE); + esp_phy_common_clock_enable(); phy_set_wifi_mode_only(0); if (ESP_CAL_DATA_CHECK_FAIL == register_chipv7_phy(init_data, calibration_data, mode)) { @@ -248,7 +305,8 @@ esp_err_t esp_phy_rf_deinit(phy_rf_module_t module) // Update WiFi MAC time before disalbe WiFi/BT common peripheral clock phy_update_wifi_mac_time(true, esp_timer_get_time()); // Disable WiFi/BT common peripheral clock. Do not disable clock for hardware RNG - periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE); + //periph_module_disable(PERIPH_WIFI_BT_COMMON_MODULE); + esp_phy_common_clock_disable(); } } diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 6b6bdc0d6..ccf84731b 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -85,7 +85,7 @@ config LWIP_DHCP_MAX_NTP_SERVERS config LWIP_IP_FRAG bool "Enable fragment outgoing IP packets" - default n + default y help Enabling this option allows fragmenting outgoing IP packets if their size exceeds MTU. diff --git a/components/lwip/lwip b/components/lwip/lwip index 5d80af7d5..39f338547 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 5d80af7d59c10b7890f0fc862e4efe807ce5fb73 +Subproject commit 39f338547ab344e855f94eb922421036bee8e417