diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 5474fe767d0f..787f5d3c3e6f 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -909,11 +909,11 @@ struct wma_wlm_stats_data { * @dynamic_nss_chains_update: per vdev nss, chains update * @ito_repeat_count: Indicates ito repeated count * @wma_fw_time_sync_timer: timer used for firmware time sync - * * @fw_therm_throt_support: FW Supports thermal throttling? + * @fw_therm_throt_support: FW Supports thermal throttling? + * @roam_sync_runtime_lock: roam sync runtime lock * * This structure is the global wma context. It contains global wma * module parameters and handles of other modules. - */ typedef struct { void *wmi_handle; @@ -1045,6 +1045,7 @@ typedef struct { qdf_mc_timer_t wma_fw_time_sync_timer; bool fw_therm_throt_support; bool enable_tx_compl_tsf64; + qdf_runtime_lock_t roam_sync_runtime_lock; } t_wma_handle, *tp_wma_handle; /** diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 1d7f88d5392c..45e2e678442b 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1587,6 +1587,23 @@ void wma_acquire_wakelock(qdf_wake_lock_t *wl, uint32_t msec); */ void wma_release_wakelock(qdf_wake_lock_t *wl); +/** + * wma_prevent_pm_during_roam_sync() - prevent runtime PM during roam sync + * @wma: a reference to the global WMA handle + * + * Return: None + */ +void wma_prevent_pm_during_roam_sync(t_wma_handle *wma); + +/** + * wma_allow_pm_after_roam_sync() - allow runtime PM after roam + * sync complete + * @wma: a reference to the global WMA handle + * + * Return: None + */ +void wma_allow_pm_after_roam_sync(t_wma_handle *wma); + /** * wma_send_vdev_stop_to_fw() - send the vdev stop command to firmware * @wma: a reference to the global WMA handle diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index b48b2729e9ae..6165e7fc31e2 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -3428,6 +3428,7 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, "wlan_fw_rsp_wakelock"); 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); /* Register peer assoc conf event handler */ wmi_unified_register_event_handler(wma_handle->wmi_handle, @@ -3538,6 +3539,7 @@ err_dbglog_init: qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock); qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock); + qdf_runtime_lock_deinit(&wma_handle->roam_sync_runtime_lock); err_event_init: wmi_unified_unregister_event_handler(wma_handle->wmi_handle, wmi_debug_print_event_id); @@ -4592,6 +4594,7 @@ QDF_STATUS wma_close(void) qdf_wake_lock_destroy(&wma_handle->wmi_cmd_rsp_wake_lock); qdf_runtime_lock_deinit(&wma_handle->sap_prevent_runtime_pm_lock); qdf_runtime_lock_deinit(&wma_handle->wmi_cmd_rsp_runtime_lock); + qdf_runtime_lock_deinit(&wma_handle->roam_sync_runtime_lock); qdf_spinlock_destroy(&wma_handle->wma_hold_req_q_lock); if (wma_handle->pGetRssiReq) { diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 702063ef6170..994e08c449d7 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -1617,21 +1617,23 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, return status; } + wma_prevent_pm_during_roam_sync(wma); + param_buf = (WMI_ROAM_SYNCH_EVENTID_param_tlvs *)event; if (!param_buf) { wma_err_rl("received null buf from target"); - return status; + goto fail; } synch_event = param_buf->fixed_param; if (!synch_event) { wma_err_rl("received null event data from target"); - return status; + goto fail; } if (synch_event->vdev_id >= wma->max_bssid) { wma_err_rl("received invalid vdev_id %d", synch_event->vdev_id); - return status; + goto fail; } iface = &wma->interfaces[synch_event->vdev_id]; @@ -1647,10 +1649,14 @@ int wma_roam_synch_event_handler(void *handle, uint8_t *event, if (QDF_IS_STATUS_ERROR(qdf_status)) { wma_err("Failed to send the EV_ROAM"); wma_post_roam_sync_failure(wma, synch_event->vdev_id); - return status; + goto fail; } wma_debug("Posted EV_ROAM to VDEV SM"); return 0; + +fail: + wma_allow_pm_after_roam_sync(wma); + return status; } int wma_roam_auth_offload_event_handler(WMA_HANDLE handle, uint8_t *event, @@ -2833,6 +2839,7 @@ void wma_process_roam_synch_complete(WMA_HANDLE handle, uint8_t vdev_id) wma_info("LFR3: vdev[%d] Sent ROAM_SYNCH_COMPLETE", vdev_id); wlan_roam_debug_log(vdev_id, DEBUG_ROAM_SYNCH_CNF, DEBUG_INVALID_PEER_ID, NULL, NULL, 0, 0); + wma_allow_pm_after_roam_sync(wma_handle); } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 68bd4241fd04..28c927fbcd41 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -3822,6 +3822,22 @@ void wma_release_wakelock(qdf_wake_lock_t *wl) qdf_runtime_pm_allow_suspend(&wma->wmi_cmd_rsp_runtime_lock); } +void wma_prevent_pm_during_roam_sync(t_wma_handle *wma) +{ + if (!wma) + return; + + qdf_runtime_pm_prevent_suspend(&wma->roam_sync_runtime_lock); +} + +void wma_allow_pm_after_roam_sync(t_wma_handle *wma) +{ + if (!wma) + return; + + qdf_runtime_pm_allow_suspend(&wma->roam_sync_runtime_lock); +} + QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE;