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); }