From 3d05280c829f935e5c65ec342abb22ce875cd26b Mon Sep 17 00:00:00 2001 From: Li Feng Date: Fri, 18 Jun 2021 18:47:17 +0800 Subject: [PATCH] qcacld-3.0: Avoid fw crash in some wow case on third party Due to the limitation on third party platform, add ini to take special care of the below wow case to avoid fw crash. The sap/p2p_go shall kick out all the connected sta/p2p_gc and then go to suspend if d0wow/d3wow is not supported. Although there is wakelock try to prevent suspend after tdls link setup, it won't take effect because auto sleep mechanism is not supported on some third party platform, so teardown tdls link by force before suspend. Change-Id: I14bfe32f04cfc34d4f55a09820e42e65a1d9f925 CRs-Fixed: 2935295 --- components/pmo/core/src/wlan_pmo_main.c | 2 ++ .../pmo/dispatcher/inc/wlan_pmo_common_cfg.h | 26 ++++++++++++++++++- .../inc/wlan_pmo_common_public_struct.h | 2 ++ .../pmo/dispatcher/inc/wlan_pmo_ucfg_api.h | 16 ++++++++++++ .../pmo/dispatcher/src/wlan_pmo_ucfg_api.c | 8 ++++++ core/hdd/src/wlan_hdd_cfg80211.c | 10 ------- core/hdd/src/wlan_hdd_cfg80211.h | 13 ++++++++++ core/hdd/src/wlan_hdd_power.c | 26 +++++++++++++++++++ 8 files changed, 92 insertions(+), 11 deletions(-) diff --git a/components/pmo/core/src/wlan_pmo_main.c b/components/pmo/core/src/wlan_pmo_main.c index 2ddf5cec3b..4b8c5405bf 100644 --- a/components/pmo/core/src/wlan_pmo_main.c +++ b/components/pmo/core/src/wlan_pmo_main.c @@ -265,6 +265,8 @@ static void wlan_pmo_init_cfg(struct wlan_objmgr_psoc *psoc, wlan_pmo_ra_filtering_init_cfg(psoc, psoc_cfg); wlan_pmo_gpio_wakeup_init_cfg(psoc, psoc_cfg); wlan_pmo_get_igmp_offload_enable_cfg(psoc, psoc_cfg); + psoc_cfg->disconnect_sap_tdls_in_wow = + cfg_get(psoc, CFG_DISCONNECT_SAP_TDLS_IN_WOW); } QDF_STATUS pmo_psoc_open(struct wlan_objmgr_psoc *psoc) diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h b/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h index c955f62cbe..ba05852689 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_common_cfg.h @@ -546,6 +546,29 @@ CFG_VALUE_OR_DEFAULT, \ "configure igmp offload support version") +/* + * + * disconnect_sap_tdls_in_wow - disconnect sap tdls in wow + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * Due to the limitation on third party platform, add ini to take + * special care of the below wow case to avoid fw crash. + * The sap/p2p_go shall kick out all the connected sta/p2p_gc and + * then go to suspend considering d0wow/d3wow is not supported. + * Teardown tdls link proactively since auto sleep mechanism not + * supported. + * + * Usage: External + * + * + */ +#define CFG_DISCONNECT_SAP_TDLS_IN_WOW CFG_INI_BOOL( \ + "disconnect_sap_tdls_in_wow", \ + 0, \ + "disconnect sap tdls in wow") + #define CFG_PMO_COMMON_ALL \ CFG(CFG_ENABLE_SAP_SUSPEND) \ CFG(CFG_PMO_ENABLE_HOST_ARPOFFLOAD) \ @@ -568,6 +591,7 @@ CFG(CFG_PMO_MOD_DTIM_ON_SYS_SUSPEND) \ CFG(CFG_ENABLE_BUS_SUSPEND_IN_SAP_MODE) \ CFG(CFG_ENABLE_BUS_SUSPEND_IN_GO_MODE)\ - CFG(CFG_IGMP_VERSION_SUPPORT) + CFG(CFG_IGMP_VERSION_SUPPORT) \ + CFG(CFG_DISCONNECT_SAP_TDLS_IN_WOW) #endif /* WLAN_PMO_COMMON_CFG_H__ */ diff --git a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h index b8b2d36f82..65bf5ec814 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_common_public_struct.h @@ -348,6 +348,7 @@ enum pmo_gpio_wakeup_mode { * @gpio_wakeup_mode: gpio wakeup mode * @igmp_version_support: igmp version support * @igmp_offload_enable: enable/disable igmp offload feature to fw + * @disconnect_sap_tdls_in_wow: sap/p2p_go disconnect or teardown tdls link */ struct pmo_psoc_cfg { bool ptrn_match_enable_all_vdev; @@ -424,6 +425,7 @@ struct pmo_psoc_cfg { uint32_t igmp_version_support; bool igmp_offload_enable; #endif + bool disconnect_sap_tdls_in_wow; }; /** diff --git a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h index c79c777acf..df8fadf0fd 100644 --- a/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h +++ b/components/pmo/dispatcher/inc/wlan_pmo_ucfg_api.h @@ -1274,6 +1274,16 @@ bool ucfg_pmo_get_moddtim_user_active(struct wlan_objmgr_vdev *vdev); * Return: moddtim user value */ uint32_t ucfg_pmo_get_moddtim_user(struct wlan_objmgr_vdev *vdev); + +/* + * ucfg_pmo_get_disconnect_sap_tdls_in_wow: get if disconnect sap/p2p_go + * or tdls in wow + * @psoc: objmgr psoc + * + * Return: true in case support else false + */ +bool +ucfg_pmo_get_disconnect_sap_tdls_in_wow(struct wlan_objmgr_psoc *psoc); #else /* WLAN_POWER_MANAGEMENT_OFFLOAD */ static inline QDF_STATUS ucfg_pmo_psoc_open(struct wlan_objmgr_psoc *psoc) @@ -1976,6 +1986,12 @@ ucfg_pmo_get_moddtim_user(struct wlan_objmgr_vdev *vdev) { return 0; } + +static inline bool +ucfg_pmo_get_disconnect_sap_tdls_in_wow(struct wlan_objmgr_psoc *psoc) +{ + return false; +} #endif /* WLAN_POWER_MANAGEMENT_OFFLOAD */ #ifdef WLAN_FEATURE_EXTWOW_SUPPORT diff --git a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c index 5aef6d6e38..300c41fd3a 100644 --- a/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c +++ b/components/pmo/dispatcher/src/wlan_pmo_ucfg_api.c @@ -984,3 +984,11 @@ uint32_t ucfg_pmo_get_moddtim_user(struct wlan_objmgr_vdev *vdev) { return pmo_core_vdev_get_moddtim_user(vdev); } + +bool +ucfg_pmo_get_disconnect_sap_tdls_in_wow(struct wlan_objmgr_psoc *psoc) +{ + struct pmo_psoc_priv_obj *pmo_psoc_ctx = pmo_psoc_get_priv(psoc); + + return pmo_psoc_ctx->psoc_cfg.disconnect_sap_tdls_in_wow; +} diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 9055ee2910..f20ce3d70e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -19295,16 +19295,6 @@ QDF_STATUS hdd_softap_deauth_current_sta(struct hdd_adapter *adapter, return QDF_STATUS_SUCCESS; } -/** - * hdd_softap_deauth_all_sta() - Deauth all sta in the sta list - * @hdd_ctx: pointer to hdd context - * @adapter: pointer to adapter structure - * @hapd_state: pointer to hostapd state structure - * @param: pointer to del sta params - * - * Return: QDF_STATUS on success, corresponding QDF failure status on failure - */ -static QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter, struct hdd_hostapd_state *hapd_state, struct csr_del_sta_params *param) diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 3fdf4d121c..0866f38375 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -768,4 +768,17 @@ static inline void hdd_send_update_owe_info_event(struct hdd_adapter *adapter, */ bool hdd_is_legacy_connection(struct hdd_adapter *adapter); +struct hdd_hostapd_state; + +/** + * hdd_softap_deauth_all_sta() - Deauth all sta in the sta list + * @adapter: pointer to adapter structure + * @hapd_state: pointer to hostapd state structure + * @param: pointer to del sta params + * + * Return: QDF_STATUS on success, corresponding QDF failure status on failure + */ +QDF_STATUS hdd_softap_deauth_all_sta(struct hdd_adapter *adapter, + struct hdd_hostapd_state *hapd_state, + struct csr_del_sta_params *param); #endif diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 1656080618..db08d4a93e 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -2190,6 +2190,12 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, struct wlan_objmgr_vdev *vdev; int rc; wlan_net_dev_ref_dbgid dbgid = NET_DEV_HOLD_CFG80211_SUSPEND_WLAN; + struct hdd_hostapd_state *hapd_state; + struct csr_del_sta_params params = { + .peerMacAddr = QDF_MAC_ADDR_BCAST_INIT, + .reason_code = REASON_DEAUTH_NETWORK_LEAVING, + .subtype = SIR_MAC_MGMT_DEAUTH, + }; hdd_enter(); @@ -2252,6 +2258,14 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, hdd_adapter_dev_put_debug(next_adapter, dbgid); return -EOPNOTSUPP; + } else if (ucfg_pmo_get_disconnect_sap_tdls_in_wow( + hdd_ctx->psoc)) { + hapd_state = + WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + if (hapd_state) + hdd_softap_deauth_all_sta(adapter, + hapd_state, + ¶ms); } } else if (QDF_P2P_GO_MODE == adapter->device_mode) { if (!ucfg_pmo_get_enable_sap_suspend( @@ -2265,7 +2279,19 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, hdd_adapter_dev_put_debug(next_adapter, dbgid); return -EOPNOTSUPP; + } else if (ucfg_pmo_get_disconnect_sap_tdls_in_wow( + hdd_ctx->psoc)) { + hapd_state = + WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + if (hapd_state) + hdd_softap_deauth_all_sta(adapter, + hapd_state, + ¶ms); } + } else if (QDF_TDLS_MODE == adapter->device_mode) { + if (ucfg_pmo_get_disconnect_sap_tdls_in_wow( + hdd_ctx->psoc)) + ucfg_tdls_teardown_links_sync(hdd_ctx->psoc); } hdd_adapter_dev_put_debug(adapter, dbgid); }