qcacld-3.0: Prevent ping loss due to runtime suspend

Scenario:
1) FW sends roam start to the host, and host disables the netif
queues. Therefore, the ping from the stack does not reach the
driver.
3) The driver goes into runtime suspend, and the firmware aborts
roaming due to pmf assoc retry.
4) After assoc comeback timeout, the firmware successfully roams.
However, both roam abort and roam sync are not wakeable events.
5) Therefore, the host stays in runtime suspend until the timeout
as part of the serialization command queued during roam start.
6) Netif queues are enabled back after roam start timeout and ping
resumes.

This results in a data loss for a longer time, eventhough the
firmware has aborted the roaming. Currently, the host driver prevents
runtime suspend only from roam sync event until roam sync completion.

To fix this issue, prevent the runtime suspend from the roam start
until roam sync completion/roam abort/roam ho-failure.

Change-Id: I9d63dd6af09d17e90d7d2d6a63a8aaa59297a047
CRs-Fixed: 4413987
This commit is contained in:
Surya Prakash Sivaraj 2026-01-28 23:24:10 -08:00
commit 3a3ead7c31
4 changed files with 14 additions and 0 deletions

View file

@ -911,6 +911,7 @@ struct wma_wlm_stats_data {
* @wma_fw_time_sync_timer: timer used for firmware time sync
* @fw_therm_throt_support: FW Supports thermal throttling?
* @roam_sync_runtime_lock: roam sync runtime lock
* @is_roam_lock_acquired: Is roam_sync_runtime_lock acquired
*
* This structure is the global wma context. It contains global wma
* module parameters and handles of other modules.
@ -1046,6 +1047,7 @@ typedef struct {
bool fw_therm_throt_support;
bool enable_tx_compl_tsf64;
qdf_runtime_lock_t roam_sync_runtime_lock;
bool is_roam_lock_acquired;
} t_wma_handle, *tp_wma_handle;
/**

View file

@ -3429,6 +3429,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc,
qdf_runtime_lock_init(&wma_handle->wmi_cmd_rsp_runtime_lock);
qdf_runtime_lock_init(&wma_handle->sap_prevent_runtime_pm_lock);
qdf_runtime_lock_init(&wma_handle->roam_sync_runtime_lock);
wma_handle->is_roam_lock_acquired = false;
/* Register peer assoc conf event handler */
wmi_unified_register_event_handler(wma_handle->wmi_handle,

View file

@ -4558,10 +4558,12 @@ static void wma_invalid_roam_reason_handler(tp_wma_handle wma_handle,
if (notif == WMI_ROAM_NOTIF_ROAM_START) {
wma_handle->interfaces[vdev_id].roaming_in_progress = true;
op_code = SIR_ROAMING_START;
wma_prevent_pm_during_roam_sync(wma_handle);
} else if (notif == WMI_ROAM_NOTIF_ROAM_ABORT) {
wma_handle->interfaces[vdev_id].roaming_in_progress = false;
op_code = SIR_ROAMING_ABORT;
lim_sae_auth_cleanup_retry(wma_handle->mac_context, vdev_id);
wma_allow_pm_after_roam_sync(wma_handle);
} else {
wma_debug("Invalid notif %d", notif);
return;
@ -4737,6 +4739,7 @@ int wma_roam_event_callback(WMA_HANDLE handle, uint8_t *event_buf,
= false;
lim_sae_auth_cleanup_retry(wma_handle->mac_context,
wmi_event->vdev_id);
wma_allow_pm_after_roam_sync(wma_handle);
break;
#endif
case WMI_ROAM_REASON_INVALID:

View file

@ -3827,7 +3827,11 @@ void wma_prevent_pm_during_roam_sync(t_wma_handle *wma)
if (!wma)
return;
if (wma->is_roam_lock_acquired)
return;
qdf_runtime_pm_prevent_suspend(&wma->roam_sync_runtime_lock);
wma->is_roam_lock_acquired = true;
}
void wma_allow_pm_after_roam_sync(t_wma_handle *wma)
@ -3835,7 +3839,11 @@ void wma_allow_pm_after_roam_sync(t_wma_handle *wma)
if (!wma)
return;
if (!wma->is_roam_lock_acquired)
return;
qdf_runtime_pm_allow_suspend(&wma->roam_sync_runtime_lock);
wma->is_roam_lock_acquired = false;
}
QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id)