From 9c17cd959776e028364e1e4b573a00358cc1af86 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 16 Nov 2025 01:29:08 +0530 Subject: [PATCH] Race free sleep design Signed-off-by: Chaitanya Tata --- hw_if/hal/src/common/hal_api_common.c | 12 +++++++++--- hw_if/hal/src/common/hal_mem.c | 16 ++++++++++++++++ hw_if/hal/src/common/hal_reg.c | 16 ++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/hw_if/hal/src/common/hal_api_common.c b/hw_if/hal/src/common/hal_api_common.c index c27b298..03e37a2 100644 --- a/hw_if/hal/src/common/hal_api_common.c +++ b/hw_if/hal/src/common/hal_api_common.c @@ -59,6 +59,15 @@ enum nrf_wifi_status hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) if (!hal_dev_ctx->rpu_fw_booted) return NRF_WIFI_STATUS_SUCCESS; + /* Cancel any pending sleep timer to prevent it from firing during the wake + * operation or subsequent register/memory access. + * + * Note: Timer scheduling is done by the caller after releasing + * the lock to prevent the timer from firing during subsequent + * operations (register/memory reads/writes). + */ + nrf_wifi_osal_timer_kill(hal_dev_ctx->rpu_ps_timer); + if (hal_dev_ctx->rpu_ps_state == RPU_PS_STATE_AWAKE) { status = NRF_WIFI_STATUS_SUCCESS; @@ -121,9 +130,6 @@ enum nrf_wifi_status hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) #endif /* NRF_WIFI_RPU_RECOVERY_PS_STATE_DEBUG */ out: - - nrf_wifi_osal_timer_schedule(hal_dev_ctx->rpu_ps_timer, - NRF70_RPU_PS_IDLE_TIMEOUT_MS); return status; } diff --git a/hw_if/hal/src/common/hal_mem.c b/hw_if/hal/src/common/hal_mem.c index e55a54f..81966c9 100644 --- a/hw_if/hal/src/common/hal_mem.c +++ b/hw_if/hal/src/common/hal_mem.c @@ -118,6 +118,14 @@ static enum nrf_wifi_status rpu_mem_read_ram(struct nrf_wifi_hal_dev_ctx *hal_de out: nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock, &flags); + + /* Schedule sleep timer after releasing the lock to prevent + * it from firing during the critical section. + */ + if (status == NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_timer_schedule(hal_dev_ctx->rpu_ps_timer, + NRF70_RPU_PS_IDLE_TIMEOUT_MS); + } #endif /* NRF_WIFI_LOW_POWER */ return status; @@ -169,6 +177,14 @@ static enum nrf_wifi_status rpu_mem_write_ram(struct nrf_wifi_hal_dev_ctx *hal_d out: nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock, &flags); + + /* Schedule sleep timer after releasing the lock to prevent + * it from firing during the critical section. + */ + if (status == NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_timer_schedule(hal_dev_ctx->rpu_ps_timer, + NRF70_RPU_PS_IDLE_TIMEOUT_MS); + } #endif /* NRF_WIFI_LOW_POWER */ return status; diff --git a/hw_if/hal/src/common/hal_reg.c b/hw_if/hal/src/common/hal_reg.c index 5918716..5ea5380 100644 --- a/hw_if/hal/src/common/hal_reg.c +++ b/hw_if/hal/src/common/hal_reg.c @@ -91,6 +91,14 @@ enum nrf_wifi_status hal_rpu_reg_read(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, #ifdef NRF_WIFI_LOW_POWER nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock, &flags); + + /* Schedule sleep timer after releasing the lock to prevent + * it from firing during the critical section. + */ + if (status == NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_timer_schedule(hal_dev_ctx->rpu_ps_timer, + NRF70_RPU_PS_IDLE_TIMEOUT_MS); + } #endif /* NRF_WIFI_LOW_POWER */ return status; @@ -151,6 +159,14 @@ enum nrf_wifi_status hal_rpu_reg_write(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, out: nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->rpu_ps_lock, &flags); + + /* Schedule sleep timer after releasing the lock to prevent + * it from firing during the critical section. + */ + if (status == NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_timer_schedule(hal_dev_ctx->rpu_ps_timer, + NRF70_RPU_PS_IDLE_TIMEOUT_MS); + } #endif /* NRF_WIFI_LOW_POWER */ return status;