fix(wifi): fix modem sleep flag clear failed

This commit is contained in:
sibeibei
2026-05-12 19:22:54 +08:00
committed by BOT
parent 58ae4daa56
commit 86a9823e5e
12 changed files with 147 additions and 15 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -54,6 +54,31 @@ static inline void pau_ll_set_regdma_entry_link_backup_start_enable(pau_dev_t *d
dev->regdma_conf.start = enable;
}
static inline void pau_ll_set_regdma_select_wifimac_link(pau_dev_t *dev)
{
dev->regdma_conf.sel_mac = 1;
}
static inline void pau_ll_set_regdma_deselect_wifimac_link(pau_dev_t *dev)
{
dev->regdma_conf.sel_mac = 0;
}
static inline void pau_ll_set_regdma_wifimac_link_backup_direction(pau_dev_t *dev, bool to_mem)
{
dev->regdma_conf.to_mem_mac = to_mem ? 1 : 0;
}
static inline void pau_ll_set_regdma_wifimac_link_backup_start_enable(pau_dev_t *dev)
{
dev->regdma_conf.start_mac = 1;
}
static inline void pau_ll_set_regdma_wifimac_link_backup_start_disable(pau_dev_t *dev)
{
dev->regdma_conf.start_mac = 0;
}
static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev)
{
return dev->regdma_current_link_addr.val;
+20 -1
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -32,6 +32,25 @@ void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal)
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
}
#if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
void IRAM_ATTR pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore)
{
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
pau_ll_set_regdma_select_wifimac_link(hal->dev);
pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore);
pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev);
while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW));
}
void IRAM_ATTR pau_hal_stop_regdma_wifimac_link(pau_hal_context_t *hal)
{
pau_ll_set_regdma_wifimac_link_backup_start_disable(hal->dev);
pau_ll_set_regdma_deselect_wifimac_link(hal->dev);
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
}
#endif
void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore)
{
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
+18 -1
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -61,6 +61,23 @@ void pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_rest
* @param hal regdma hal context
*/
void pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal);
#if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
/**
* @brief Start transmission on regdma WiFi MAC SEL link
*
* @param hal regdma hal context
* @param backup_or_restore false: restore, true: backup
*/
void pau_hal_start_regdma_wifimac_link(pau_hal_context_t *hal, bool backup_or_restore);
/**
* @brief Stop transmission on regdma WiFi MAC SEL link
*
* @param hal regdma hal context
*/
void pau_hal_stop_regdma_wifimac_link(pau_hal_context_t *hal);
#endif
#endif
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -41,6 +41,18 @@ void pau_regdma_trigger_modem_link_backup(void);
* @brief Software trigger regdma to perform modem link restore
*/
void pau_regdma_trigger_modem_link_restore(void);
#if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
/**
* @brief Software trigger REGDMA backup on WiFi MAC SEL link
*/
void pau_regdma_trigger_wifimac_link_backup(void);
/**
* @brief Software trigger REGDMA restore on WiFi MAC SEL link
*/
void pau_regdma_trigger_wifimac_link_restore(void);
#endif
#endif
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
@@ -83,8 +83,9 @@ void sleep_modem_mac_bb_power_up_prepare(void);
* @brief The retention action in the modem state of WiFi PHY module
*
* @param restore true for restore the PHY context, false for backup the PHY context
* @param wifimac_link_is_sel true to trigger REGDMA via WiFi MAC link
*/
void sleep_modem_wifi_do_phy_retention(bool restore);
void sleep_modem_wifi_do_phy_retention(bool restore, bool wifimac_link_is_sel);
/**
* @brief Get WiFi modem state
@@ -293,8 +293,10 @@ void sleep_retention_do_system_retention(bool backup_or_restore);
*
* @param backup_or_restore true for backup register context to memory
* or false for restore to register from memory
* @param wifimac_link_is_sel true to use dedicated WiFi MAC link,
* false to use modem entry link
*/
void sleep_retention_do_phy_retention(bool backup_or_restore);
void sleep_retention_do_phy_retention(bool backup_or_restore, bool wifimac_link_is_sel);
#endif /*SOC_PM_SUPPORT_PMU_MODEM_STATE */
#endif // SOC_PAU_SUPPORTED
+15 -1
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -87,6 +87,20 @@ void IRAM_ATTR pau_regdma_trigger_modem_link_restore(void)
pau_hal_start_regdma_modem_link(PAU_instance()->hal, false);
pau_hal_stop_regdma_modem_link(PAU_instance()->hal);
}
#if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
void IRAM_ATTR pau_regdma_trigger_wifimac_link_backup(void)
{
pau_hal_start_regdma_wifimac_link(PAU_instance()->hal, true);
pau_hal_stop_regdma_wifimac_link(PAU_instance()->hal);
}
void IRAM_ATTR pau_regdma_trigger_wifimac_link_restore(void)
{
pau_hal_start_regdma_wifimac_link(PAU_instance()->hal, false);
pau_hal_stop_regdma_wifimac_link(PAU_instance()->hal);
}
#endif
#endif
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
+2 -2
View File
@@ -171,10 +171,10 @@ __attribute__((unused)) void sleep_modem_wifi_modem_state_deinit(void)
}
}
void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore)
void IRAM_ATTR sleep_modem_wifi_do_phy_retention(bool restore, bool wifimac_link_is_sel)
{
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 1);
sleep_retention_do_phy_retention(!restore);
sleep_retention_do_phy_retention(!restore, wifimac_link_is_sel);
sleep_modem_state_phy_link_config(s_sleep_modem.wifi.phy_link, 0);
if (!restore) {
s_sleep_modem.wifi.modem_state_phy_done = 1;
+18 -4
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -1007,7 +1007,7 @@ void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore)
#endif
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore)
void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore, bool wifimac_link_is_sel)
{
/* since the PHY link and other module links are within the sleep-retention entry (4) context,
* add mutex protection to avoid data race.
@@ -1016,9 +1016,23 @@ void IRAM_ATTR sleep_retention_do_phy_retention(bool backup_or_restore)
_lock_acquire_recursive(&s_retention.lock);
#endif
if (backup_or_restore) {
pau_regdma_trigger_modem_link_backup();
#if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
if (wifimac_link_is_sel) {
pau_regdma_trigger_wifimac_link_backup();
} else
#endif
{
pau_regdma_trigger_modem_link_backup();
}
} else {
pau_regdma_trigger_modem_link_restore();
#if SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
if (wifimac_link_is_sel) {
pau_regdma_trigger_wifimac_link_restore();
} else
#endif
{
pau_regdma_trigger_modem_link_restore();
}
}
#if SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY
_lock_release_recursive(&s_retention.lock);
+24 -2
View File
@@ -23,6 +23,7 @@
#include "esp_private/esp_sleep_internal.h"
#include "esp_check.h"
#include "sdkconfig.h"
#include "soc/soc_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "endian.h"
@@ -73,6 +74,9 @@ extern wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb;
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
extern void pm_mac_modem_clear_rf_power_state(void);
extern bool pm_mac_modem_rf_already_enabled(void);
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC
extern bool pm_get_wifimac_regdma_link_selection(void);
#endif
#endif
static const char* TAG = "phy_init";
@@ -341,9 +345,23 @@ void esp_phy_enable(esp_phy_modem_t modem)
s_is_phy_calibrated = true;
} else {
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
bool wifimac_link_is_sel = false;
if (!pm_mac_modem_rf_already_enabled()) {
if (sleep_modem_wifi_modem_state_enabled() && sleep_modem_wifi_modem_link_done()) {
sleep_modem_wifi_do_phy_retention(true);
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC && SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
/*
* A race exists between SoC wakeup and modem state sleep. After modem initiates sleep,
* SoC may wake up before REGDMA completes RF close, leaving mac_modem_sleep_flag uncleared
* (it depends on regdma done). The stale flag can incorrectly trigger a sleep request
* on the next modem entry, causing abnormal sleep behavior.
*
* Therefore, this workaround ensures that mac_modem_sleep_flag is properly
* cleared by regdma closing RF with wifimac link.
* See WIFI-7246 for details.
*/
wifimac_link_is_sel = pm_get_wifimac_regdma_link_selection();
#endif
sleep_modem_wifi_do_phy_retention(true, wifimac_link_is_sel);
} else {
// TODO: IDF-15338
#if CONFIG_IDF_TARGET_ESP32C5
@@ -419,7 +437,11 @@ void esp_phy_disable(esp_phy_modem_t modem)
#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP
pm_mac_modem_clear_rf_power_state();
if (sleep_modem_wifi_modem_state_enabled()) {
sleep_modem_wifi_do_phy_retention(false);
bool wifimac_link_is_sel = false;
#if SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC && SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
wifimac_link_is_sel = pm_get_wifimac_regdma_link_selection();
#endif
sleep_modem_wifi_do_phy_retention(false, wifimac_link_is_sel);
} else
#endif /* SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_ENHANCED_LIGHT_SLEEP */
{
@@ -1503,6 +1503,10 @@ config SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY
bool
default y
config SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND
bool
default y
config SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED
bool
default y
@@ -608,6 +608,8 @@
#define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1)
#define SOC_PM_PAU_REGDMA_LINK_IDX_WIFIMAC (4) // The range of values for the link index is [0, SOC_PM_PAU_LINK_NUM)
#define SOC_PM_PAU_REGDMA_COMMON_PHY_LINK_ENTRY (1)
/** Workaround: software-triggered modem PHY retention uses dedicated WiFi MAC REGDMA, not entry link_sel */
#define SOC_PM_PAU_REGDMA_MODEM_WIFIMAC_WORKAROUND (1)
#define SOC_PM_PMU_MIN_SLP_SLOW_CLK_CYCLE_FIXED (1)