From 657f89e1e58d3a8871b6f027b3d5aa8f55ad1a4b Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Tue, 18 Sep 2018 10:13:37 +0530 Subject: [PATCH] qcacld-3.0: Send IPA UC disconnect events during SSR Currently during SSR IPA events such as AP DISCONNECT/ STA DISCONNECT are not sent and also wlan ipa interafces are not deregistered. After SSR when host sends AP CONNECT/ STA CONNECT and register interafce IPACM will reject as for previous events before SSR there are no disconnect events. This leads to data come via exception path instead taking IPA HW route as interface headers are not registered. In this fix send IPA UC disconnect events and deregister interafces during SSR. Change-Id: I6e617261ec53b7d572023613d212eae057b13b03 CRs-Fixed: 2315828 --- components/ipa/core/inc/wlan_ipa_core.h | 8 +++++++ components/ipa/core/inc/wlan_ipa_main.h | 9 +++++++- components/ipa/core/src/wlan_ipa_core.c | 23 +++++++++++++++++++ components/ipa/core/src/wlan_ipa_main.c | 13 +++++++++++ .../ipa/dispatcher/inc/wlan_ipa_ucfg_api.h | 16 +++++++++++++ .../ipa/dispatcher/src/wlan_ipa_ucfg_api.c | 5 ++++ core/hdd/src/wlan_hdd_power.c | 2 ++ 7 files changed, 75 insertions(+), 1 deletion(-) diff --git a/components/ipa/core/inc/wlan_ipa_core.h b/components/ipa/core/inc/wlan_ipa_core.h index f3cbd5b619e1..535f8f6cba9d 100644 --- a/components/ipa/core/inc/wlan_ipa_core.h +++ b/components/ipa/core/inc/wlan_ipa_core.h @@ -642,5 +642,13 @@ QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx, */ void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx, qdf_netdev_t net_dev); + +/** + * wlan_ipa_uc_ssr_cleanup() - handle IPA UC clean up during SSR + * @ipa_ctx: IPA context + * + * Return: None + */ +void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx); #endif /* IPA_OFFLOAD */ #endif /* _WLAN_IPA_CORE_H_ */ diff --git a/components/ipa/core/inc/wlan_ipa_main.h b/components/ipa/core/inc/wlan_ipa_main.h index 0ef98d58fe3c..596e69ae12c9 100644 --- a/components/ipa/core/inc/wlan_ipa_main.h +++ b/components/ipa/core/inc/wlan_ipa_main.h @@ -401,10 +401,17 @@ QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, * @pdev: pdev obj * @net_dev: Interface net device * - * * Return: None */ void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev); + +/** + * ipa_uc_ssr_cleanup() - handle IPA UC cleanup during SSR + * @pdev: pdev obj + * + * Return: None + */ +void ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev); #endif /* IPA_OFFLOAD */ #endif /* end of _WLAN_IPA_MAIN_H_ */ diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 542c70cef3dc..9f9bc1ceed10 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -2981,3 +2981,26 @@ void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx, if (iface_ctx) wlan_ipa_cleanup_iface(iface_ctx); } + +void wlan_ipa_uc_ssr_cleanup(struct wlan_ipa_priv *ipa_ctx) +{ + struct wlan_ipa_iface_context *iface; + int i; + + ipa_info("enter"); + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface = &ipa_ctx->iface_context[i]; + if (iface->dev) { + if (iface->device_mode == QDF_SAP_MODE) + wlan_ipa_uc_send_evt(iface->dev, + QDF_IPA_AP_DISCONNECT, + iface->dev->dev_addr); + else if (iface->device_mode == QDF_STA_MODE) + wlan_ipa_uc_send_evt(iface->dev, + QDF_IPA_STA_DISCONNECT, + iface->dev->dev_addr); + wlan_ipa_cleanup_iface(iface); + } + } +} diff --git a/components/ipa/core/src/wlan_ipa_main.c b/components/ipa/core/src/wlan_ipa_main.c index d242e7c74af0..31a20806840a 100644 --- a/components/ipa/core/src/wlan_ipa_main.c +++ b/components/ipa/core/src/wlan_ipa_main.c @@ -576,3 +576,16 @@ void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, return wlan_ipa_cleanup_dev_iface(ipa_obj, net_dev); } + +void ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_ipa_priv *ipa_obj; + + ipa_obj = ipa_pdev_get_priv_obj(pdev); + if (!ipa_obj) { + ipa_err("IPA object is NULL"); + return; + } + + return wlan_ipa_uc_ssr_cleanup(ipa_obj); +} diff --git a/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h b/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h index 84b874c9374b..b9a041c526bd 100644 --- a/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h +++ b/components/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h @@ -312,6 +312,17 @@ QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, */ void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev); + +/** + * ucfg_ipa_uc_ssr_cleanup() - Handle IPA cleanup for SSR + * @pdev: pdev obj + * + * From hostside do cleanup such as deregister IPA interafces + * and send disconnect events so that it will be sync after SSR + * + * Return: None + */ +void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev); #else static inline bool ucfg_ipa_is_present(void) @@ -487,5 +498,10 @@ void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, qdf_netdev_t net_dev) { } + +static inline +void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev) +{ +} #endif /* IPA_OFFLOAD */ #endif /* _WLAN_IPA_UCFG_API_H_ */ diff --git a/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c b/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c index 2df81efba43a..7bca1ec617ea 100644 --- a/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c +++ b/components/ipa/dispatcher/src/wlan_ipa_ucfg_api.c @@ -186,3 +186,8 @@ void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, { return ipa_cleanup_dev_iface(pdev, net_dev); } + +void ucfg_ipa_uc_ssr_cleanup(struct wlan_objmgr_pdev *pdev) +{ + return ipa_uc_ssr_cleanup(pdev); +} diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index fcc98c5bd3e4..03290e5534ca 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1232,6 +1232,8 @@ QDF_STATUS hdd_wlan_shutdown(void) hdd_reset_all_adapters(hdd_ctx); + ucfg_ipa_uc_ssr_cleanup(hdd_ctx->pdev); + /* Flush cached rx frame queue */ if (soc) cdp_flush_cache_rx_queue(soc);