From 5b0746560d29ea2ea73c40fdae1e40bbcedc94a8 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Wed, 12 Feb 2020 21:33:08 +0800 Subject: [PATCH] qcacld-3.0: suspend scan before scheduler thread suspended Scan cmd still can be exist after scheduler thread is suspended when host suspend, the scan cmd can't be removed from serialization list by either complete or cancel any more since both depends on scheduler thread, suspend thread blocked 30s to wait scan cmd cleared. Roam sync event from F/W can't be handled and Roam sync complete can't be sent to F/W since scheduler thread suspended, then F/W assert for roam sync cmd timeout. After receive F/W down event, host will try SSR, but blocked by unfinished suspend thread too. Fix: suspend all components including scan before suspend scheduler thread, make sure scan cmd is cleared and no new scan is allowed any more before scheduler thread suspended. Change-Id: I7a3badeedea018e4d92bbe8660692e42923852aa CRs-Fixed: 2620650 --- .../pmo/core/src/wlan_pmo_suspend_resume.c | 16 -------- .../pmo/dispatcher/inc/wlan_pmo_ucfg_api.h | 40 ++++++++++++++++++- .../pmo/dispatcher/src/wlan_pmo_ucfg_api.c | 15 ++++++- core/hdd/src/wlan_hdd_power.c | 22 ++++++++-- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/components/pmo/core/src/wlan_pmo_suspend_resume.c b/components/pmo/core/src/wlan_pmo_suspend_resume.c index c96c58a07b..ad6a46d9d9 100644 --- a/components/pmo/core/src/wlan_pmo_suspend_resume.c +++ b/components/pmo/core/src/wlan_pmo_suspend_resume.c @@ -531,18 +531,10 @@ QDF_STATUS pmo_core_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc, goto out; } - /* Suspend all components before sending target suspend command */ - status = pmo_suspend_all_components(psoc, type); - if (status != QDF_STATUS_SUCCESS) { - pmo_err("Failed to suspend all component"); - goto dec_psoc_ref; - } - status = pmo_core_psoc_configure_suspend(psoc, false); if (status != QDF_STATUS_SUCCESS) pmo_err("Failed to configure suspend"); -dec_psoc_ref: pmo_psoc_put_ref(psoc); out: pmo_exit(); @@ -712,18 +704,10 @@ QDF_STATUS pmo_core_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc, goto out; } - /* Resume all components */ - status = pmo_resume_all_components(psoc, type); - if (status != QDF_STATUS_SUCCESS) { - pmo_err("Failed to resume all the components"); - goto dec_psoc_ref; - } - status = pmo_core_psoc_configure_resume(psoc, false); if (status != QDF_STATUS_SUCCESS) pmo_err("Failed to configure resume"); -dec_psoc_ref: pmo_psoc_put_ref(psoc); out: pmo_exit(); diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index 7c91c1c8c1..4dea747e7d 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -824,6 +824,30 @@ QDF_STATUS ucfg_pmo_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_pmo_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc, enum qdf_suspend_type type); +/** + * ucfg_pmo_suspend_all_components() - Suspend all components + * @psoc: objmgr psoc handle + * @type: type of suspend + * + * Suspend all components registered to pmo + * + * Return: QDF status + */ +QDF_STATUS ucfg_pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc, + enum qdf_suspend_type type); + +/** + * ucfg_pmo_resume_all_components() - Resume all components + * @psoc: objmgr psoc handle + * @type: type of suspend from which resume needed + * + * Resume all components registered to pmo + * + * Return: QDF status + */ +QDF_STATUS ucfg_pmo_resume_all_components(struct wlan_objmgr_psoc *psoc, + enum qdf_suspend_type type); + /** * ucfg_pmo_psoc_bus_suspend_req(): handles bus suspend for psoc * @psoc: objmgr psoc @@ -1458,6 +1482,20 @@ ucfg_pmo_psoc_user_space_resume_req( return QDF_STATUS_SUCCESS; } +static inline QDF_STATUS +ucfg_pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc, + enum qdf_suspend_type type) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +ucfg_pmo_resume_all_components(struct wlan_objmgr_psoc *psoc, + enum qdf_suspend_type type) +{ + return QDF_STATUS_SUCCESS; +} + static inline QDF_STATUS ucfg_pmo_psoc_bus_suspend_req( struct wlan_objmgr_psoc *psoc, diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 43ef27b79f..617882c897 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -388,7 +388,6 @@ ucfg_pmo_psoc_user_space_suspend_req(struct wlan_objmgr_psoc *psoc, return pmo_core_psoc_user_space_suspend_req(psoc, type); } - QDF_STATUS ucfg_pmo_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc, enum qdf_suspend_type type) @@ -396,6 +395,18 @@ ucfg_pmo_psoc_user_space_resume_req(struct wlan_objmgr_psoc *psoc, return pmo_core_psoc_user_space_resume_req(psoc, type); } +QDF_STATUS ucfg_pmo_suspend_all_components(struct wlan_objmgr_psoc *psoc, + enum qdf_suspend_type type) +{ + return pmo_suspend_all_components(psoc, type); +} + +QDF_STATUS ucfg_pmo_resume_all_components(struct wlan_objmgr_psoc *psoc, + enum qdf_suspend_type type) +{ + return pmo_resume_all_components(psoc, type); +} + QDF_STATUS ucfg_pmo_psoc_bus_suspend_req(struct wlan_objmgr_psoc *psoc, enum qdf_suspend_type type, diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 2447c94377..3b073b6e13 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1789,7 +1789,13 @@ static int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy) scheduler_resume(); hdd_ctx->is_scheduler_suspended = false; } - + /* Resume all components registered to pmo */ + status = ucfg_pmo_resume_all_components(hdd_ctx->psoc, + QDF_SYSTEM_SUSPEND); + if (status != QDF_STATUS_SUCCESS) { + exit_code = 0; + goto exit_with_code; + } /* Resume tlshim Rx thread */ if (hdd_ctx->enable_rxthread) wlan_hdd_rx_thread_resume(hdd_ctx); @@ -1953,16 +1959,24 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, return -EINVAL; } - /* abort ongoing scan and flush any pending powersave timers */ + /* flush any pending powersave timers */ hdd_for_each_adapter(hdd_ctx, adapter) { - wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID, - adapter->vdev_id, INVALID_SCAN_ID, false); if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) continue; sme_ps_timer_flush_sync(mac_handle, adapter->vdev_id); } + /* + * Suspend all components registered to pmo, abort ongoing scan and + * don't allow new scan any more before scheduler thread suspended. + */ + if (ucfg_pmo_suspend_all_components(hdd_ctx->psoc, + QDF_SYSTEM_SUSPEND)) { + hdd_err("Some components not ready to suspend!"); + return -EAGAIN; + } + /* * Suspend IPA early before proceeding to suspend other entities like * firmware to avoid any race conditions.