diff --git a/drivers/wifi/nrf_wifi/inc/fmac_main.h b/drivers/wifi/nrf_wifi/inc/fmac_main.h index 0d37a2f2371..23f96089eb6 100644 --- a/drivers/wifi/nrf_wifi/inc/fmac_main.h +++ b/drivers/wifi/nrf_wifi/inc/fmac_main.h @@ -85,6 +85,7 @@ struct nrf_wifi_vif_ctx_zep { #endif /* CONFIG_NRF70_AP_MODE */ #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY struct k_work nrf_wifi_rpu_recovery_work; + struct k_work_delayable nrf_wifi_rpu_recovery_bringup_work; #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */ int rts_threshold_value; }; diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index aff943127a5..fc8b01b17cb 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -73,7 +73,6 @@ static void nrf_wifi_rpu_recovery_work_handler(struct k_work *work) nrf_wifi_rpu_recovery_work); struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL; int ret; - bool recovery_fail = false; if (!vif_ctx_zep) { LOG_ERR("%s: vif_ctx_zep is NULL", __func__); @@ -144,11 +143,27 @@ static void nrf_wifi_rpu_recovery_work_handler(struct k_work *work) ret = net_if_down(vif_ctx_zep->zep_net_if_ctx); if (ret) { rpu_ctx_zep->rpu_recovery_failure++; - recovery_fail = true; LOG_ERR("%s: net_if_down failed: %d", __func__, ret); /* Continue with the recovery */ + } else { + rpu_ctx_zep->rpu_recovery_success++; } - k_msleep(CONFIG_NRF_WIFI_RPU_RECOVERY_PROPAGATION_DELAY_MS); + /* Continue recovery process after delay without blocking system workqueue. + * Mutex is released in the next phase. + */ + k_work_reschedule(&vif_ctx_zep->nrf_wifi_rpu_recovery_bringup_work, + K_MSEC(CONFIG_NRF_WIFI_RPU_RECOVERY_PROPAGATION_DELAY_MS)); +} + +static void nrf_wifi_rpu_recovery_bringup_work_handler(struct k_work *work) +{ + struct k_work_delayable *dwork = k_work_delayable_from_work(work); + struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = CONTAINER_OF(dwork, + struct nrf_wifi_vif_ctx_zep, + nrf_wifi_rpu_recovery_bringup_work); + struct nrf_wifi_ctx_zep *rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep; + int ret; + #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG LOG_ERR("%s: Bringing the interface up", __func__); #else @@ -160,9 +175,6 @@ static void nrf_wifi_rpu_recovery_work_handler(struct k_work *work) } rpu_ctx_zep->rpu_recovery_in_progress = false; rpu_ctx_zep->last_rpu_recovery_time_ms = k_uptime_get(); - if (!recovery_fail) { - rpu_ctx_zep->rpu_recovery_success++; - } k_mutex_unlock(&rpu_ctx_zep->rpu_lock); #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG LOG_ERR("%s: RPU recovery done", __func__); @@ -669,6 +681,8 @@ void nrf_wifi_if_init_zep(struct net_if *iface) #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY k_work_init(&vif_ctx_zep->nrf_wifi_rpu_recovery_work, nrf_wifi_rpu_recovery_work_handler); + k_work_init_delayable(&vif_ctx_zep->nrf_wifi_rpu_recovery_bringup_work, + nrf_wifi_rpu_recovery_bringup_work_handler); #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */ #if !defined(CONFIG_NRF_WIFI_IF_AUTO_START)