diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 4fdde5fc5a..cd4f0784fd 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -737,6 +737,34 @@ static inline bool wmi_get_runtime_pm_inprogress(wmi_unified_t wmi_handle) } #endif +/** + * wmi_set_wow_enable_ack_failed() - set wow enable ack failed status + * if wow enable ack failed, which means host and fw have some problem + * to exchange wmi cmd. set indication here and block wmi cmds. + * the cmds can be sent again after wmi re-init in subsystem recovery. + * @wmi_handle: wmi context + * + * return: none + */ +void wmi_set_wow_enable_ack_failed(wmi_unified_t wmi_handle); + +/** + * wmi_clear_wow_enable_ack_failed() - clear wow enable ack failed status + * explicitly clear this status when wmi close of SSR + * @wmi_handle: wmi context + * + * return: none + */ +void wmi_clear_wow_enable_ack_failed(wmi_unified_t wmi_handle); + +/** + * wmi_has_wow_enable_ack_failed() - get wow enable ack failed status + * @wmi_handle: wmi context + * + * Return: true if wow enable ack already failed. other false + */ +bool wmi_has_wow_enable_ack_failed(wmi_unified_t wmi_handle); + /** * wmi_unified_get_soc_handle: Get WMI SoC handle * @wmi_handle: WMI context got from wmi_attach diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 2e5a4e5e63..1a9d066f2f 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -3381,6 +3381,7 @@ struct wmi_unified { qdf_atomic_t runtime_pm_inprogress; #endif qdf_atomic_t is_wow_bus_suspended; + qdf_atomic_t is_wow_enable_ack_failed; bool tag_crash_inject; bool tgt_force_assert_enable; enum wmi_target_type target_type; diff --git a/wmi/src/wmi_unified.c b/wmi/src/wmi_unified.c index 3d36f77eca..e2b72f061f 100644 --- a/wmi/src/wmi_unified.c +++ b/wmi/src/wmi_unified.c @@ -2099,6 +2099,12 @@ QDF_STATUS wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf, return QDF_STATUS_E_INVAL; } + if (wmi_has_wow_enable_ack_failed(wmi_handle)) { + wmi_nofl_err("wow enable ack already failed(via %s:%u)", + func, line); + return QDF_STATUS_E_INVAL; + } + #ifndef WMI_NON_TLV_SUPPORT /* Do sanity check on the TLV parameter structure */ if (wmi_handle->target_type == WMI_TLV_TARGET) { @@ -3068,6 +3074,21 @@ static void wmi_runtime_pm_init(struct wmi_unified *wmi_handle) } #endif +void wmi_set_wow_enable_ack_failed(wmi_unified_t wmi_handle) +{ + qdf_atomic_set(&wmi_handle->is_wow_enable_ack_failed, 1); +} + +void wmi_clear_wow_enable_ack_failed(wmi_unified_t wmi_handle) +{ + qdf_atomic_set(&wmi_handle->is_wow_enable_ack_failed, 0); +} + +bool wmi_has_wow_enable_ack_failed(wmi_unified_t wmi_handle) +{ + return qdf_atomic_read(&wmi_handle->is_wow_enable_ack_failed); +} + void *wmi_unified_get_soc_handle(struct wmi_unified *wmi_handle) { return wmi_handle->soc; @@ -3159,6 +3180,7 @@ void *wmi_unified_get_pdev_handle(struct wmi_soc *soc, uint32_t pdev_idx) wmi_interface_logging_init(wmi_handle, pdev_idx); qdf_atomic_init(&wmi_handle->pending_cmds); qdf_atomic_init(&wmi_handle->is_target_suspended); + qdf_atomic_init(&wmi_handle->is_wow_enable_ack_failed); wmi_handle->target_type = soc->target_type; wmi_handle->wmi_max_cmds = soc->wmi_max_cmds; @@ -3288,6 +3310,7 @@ void *wmi_unified_attach(void *scn_handle, qdf_atomic_init(&wmi_handle->is_target_suspended); qdf_atomic_init(&wmi_handle->is_target_suspend_acked); qdf_atomic_init(&wmi_handle->num_stats_over_qmi); + qdf_atomic_init(&wmi_handle->is_wow_enable_ack_failed); wmi_runtime_pm_init(wmi_handle); wmi_interface_logging_init(wmi_handle, WMI_HOST_PDEV_ID_0); @@ -3392,6 +3415,8 @@ void wmi_unified_detach(struct wmi_unified *wmi_handle) soc->wmi_ext2_service_bitmap = NULL; } + wmi_clear_wow_enable_ack_failed(wmi_handle); + /* Decrease the ref count once refcount infra is present */ soc->wmi_psoc = NULL; qdf_mem_free(soc);