From 4dc849ea8ececa9f91b00181ca08296fd55f6d0f Mon Sep 17 00:00:00 2001 From: Sravan Kumar Kairam Date: Fri, 15 Jun 2018 15:07:11 +0530 Subject: [PATCH] qcacld-3.0: Clean up IPA interface when SAP stop bss fails In case of rmmod if stop bss fails SAP IPA interface is not deleted. So again at next driver load IPA will be holding the stale IPA header and new IPA header will not be added at IPA interface creation. In this change clean IPA interface when SAP stop bss fails. Change-Id: I3a1bf891752308ba1a29d6768f24880d8514d5bf CRs-Fixed: 2224307 --- ipa/core/inc/wlan_ipa_core.h | 22 +++++++ ipa/core/inc/wlan_ipa_main.h | 23 +++++++ ipa/core/src/wlan_ipa_core.c | 86 ++++++++++++++++++++++++-- ipa/core/src/wlan_ipa_main.c | 34 ++++++++-- ipa/dispatcher/inc/wlan_ipa_ucfg_api.h | 35 +++++++++++ ipa/dispatcher/src/wlan_ipa_ucfg_api.c | 12 ++++ 6 files changed, 200 insertions(+), 12 deletions(-) diff --git a/ipa/core/inc/wlan_ipa_core.h b/ipa/core/inc/wlan_ipa_core.h index be6e77a4b6..25eb583424 100644 --- a/ipa/core/inc/wlan_ipa_core.h +++ b/ipa/core/inc/wlan_ipa_core.h @@ -620,5 +620,27 @@ int wlan_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr); * Return: true if FW WDI actived, false otherwise */ bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx); + +/** + * wlan_ipa_uc_disconnect_ap() - send ap disconnect event + * @ipa_ctx: IPA context + * @net_dev: Interface net device + * + * Send disconnect ap event to IPA driver + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx, + qdf_netdev_t net_dev); + +/** + * wlan_ipa_cleanup_dev_iface() - Clean up net dev IPA interface + * @ipa_ctx: IPA context + * @net_dev: Interface net device + * + * Return: None + */ +void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx, + qdf_netdev_t net_dev); #endif /* IPA_OFFLOAD */ #endif /* _WLAN_IPA_CORE_H_ */ diff --git a/ipa/core/inc/wlan_ipa_main.h b/ipa/core/inc/wlan_ipa_main.h index d65df3927a..1f766d8e21 100644 --- a/ipa/core/inc/wlan_ipa_main.h +++ b/ipa/core/inc/wlan_ipa_main.h @@ -367,5 +367,28 @@ int ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr); * Return: true if FW WDI activated, false otherwise */ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev); + +/** + * ipa_uc_disconnect_ap() - send ap disconnect event + * @pdev: pdev obj + * @net_dev: Interface net device + * + * Send disconnect ap event to IPA driver + * + * Return: QDF_STATUS + */ +QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev); + +/** + * ipa_cleanup_dev_iface() - Clean up net dev IPA interface + * @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); #endif /* IPA_OFFLOAD */ #endif /* end of _WLAN_IPA_MAIN_H_ */ diff --git a/ipa/core/src/wlan_ipa_core.c b/ipa/core/src/wlan_ipa_core.c index 33be842cdd..56af3ba0d2 100644 --- a/ipa/core/src/wlan_ipa_core.c +++ b/ipa/core/src/wlan_ipa_core.c @@ -22,6 +22,7 @@ #include #include "cdp_txrx_ipa.h" #include "wal_rx_desc.h" +#include "qdf_str.h" static struct wlan_ipa_priv *gp_ipa; @@ -2765,14 +2766,87 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) return status; } -/** - * wlan_ipa_is_fw_wdi_activated() - Is FW WDI actived? - * @ipa_ctx: IPA contex - * - * Return: true if FW WDI actived, false otherwise - */ bool wlan_ipa_is_fw_wdi_activated(struct wlan_ipa_priv *ipa_ctx) { return (WLAN_IPA_UC_NUM_WDI_PIPE == ipa_ctx->activated_fw_pipe); } +/** + * wlan_ipa_uc_send_evt() - send event to ipa + * @net_dev: Interface net device + * @type: event type + * @mac_addr: pointer to mac address + * + * Send event to IPA driver + * + * Return: QDF_STATUS + */ +static QDF_STATUS wlan_ipa_uc_send_evt(qdf_netdev_t net_dev, + qdf_ipa_wlan_event type, + uint8_t *mac_addr) +{ + struct wlan_ipa_priv *ipa_ctx = gp_ipa; + qdf_ipa_msg_meta_t meta; + qdf_ipa_wlan_msg_t *msg; + + QDF_IPA_MSG_META_MSG_LEN(&meta) = sizeof(qdf_ipa_wlan_msg_t); + msg = qdf_mem_malloc(QDF_IPA_MSG_META_MSG_LEN(&meta)); + if (!msg) { + ipa_err("msg allocation failed"); + return QDF_STATUS_E_NOMEM; + } + + QDF_IPA_SET_META_MSG_TYPE(&meta, type); + qdf_str_lcopy(QDF_IPA_WLAN_MSG_NAME(msg), net_dev->name, + IPA_RESOURCE_NAME_MAX); + qdf_mem_copy(QDF_IPA_WLAN_MSG_MAC_ADDR(msg), mac_addr, QDF_NET_ETH_LEN); + + if (qdf_ipa_send_msg(&meta, msg, wlan_ipa_msg_free_fn)) { + ipa_err("%s: Evt: %d fail", + QDF_IPA_WLAN_MSG_NAME(msg), + QDF_IPA_MSG_META_MSG_TYPE(&meta)); + qdf_mem_free(msg); + + return QDF_STATUS_E_FAILURE; + } + + ipa_ctx->stats.num_send_msg++; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_ipa_uc_disconnect_ap(struct wlan_ipa_priv *ipa_ctx, + qdf_netdev_t net_dev) +{ + struct wlan_ipa_iface_context *iface_ctx; + QDF_STATUS status; + + ipa_debug("enter"); + + iface_ctx = wlan_ipa_get_iface(ipa_ctx, QDF_SAP_MODE); + if (iface_ctx) + status = wlan_ipa_uc_send_evt(net_dev, QDF_IPA_AP_DISCONNECT, + net_dev->dev_addr); + else + return QDF_STATUS_E_INVAL; + + ipa_debug("exit :%d", status); + + return status; +} + +void wlan_ipa_cleanup_dev_iface(struct wlan_ipa_priv *ipa_ctx, + qdf_netdev_t net_dev) +{ + struct wlan_ipa_iface_context *iface_ctx; + int i; + + for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { + iface_ctx = &ipa_ctx->iface_context[i]; + if (iface_ctx->dev == net_dev) + break; + } + + if (iface_ctx) + wlan_ipa_cleanup_iface(iface_ctx); +} diff --git a/ipa/core/src/wlan_ipa_main.c b/ipa/core/src/wlan_ipa_main.c index 0a12a3331c..80edf6ed31 100644 --- a/ipa/core/src/wlan_ipa_main.c +++ b/ipa/core/src/wlan_ipa_main.c @@ -531,12 +531,6 @@ int ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr) return wlan_ipa_uc_smmu_map(map, num_buf, buf_arr); } -/** - * ipa_is_fw_wdi_activated - Is FW WDI activated? - * @pdev: pdev obj - * - * Return: true if FW WDI activated, false otherwise - */ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev) { struct wlan_ipa_priv *ipa_obj; @@ -554,3 +548,31 @@ bool ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev) return wlan_ipa_is_fw_wdi_activated(ipa_obj); } + +QDF_STATUS ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev) +{ + struct wlan_ipa_priv *ipa_obj; + + ipa_obj = ipa_pdev_get_priv_obj(pdev); + if (!ipa_obj) { + ipa_err("IPA object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + return wlan_ipa_uc_disconnect_ap(ipa_obj, net_dev); +} + +void ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev) +{ + 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_cleanup_dev_iface(ipa_obj, net_dev); +} diff --git a/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h b/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h index 8f41a93e8a..84b874c937 100644 --- a/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h +++ b/ipa/dispatcher/inc/wlan_ipa_ucfg_api.h @@ -290,6 +290,28 @@ int ucfg_ipa_uc_smmu_map(bool map, uint32_t num_buf, qdf_mem_info_t *buf_arr); */ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev); +/** + * ucfg_ipa_uc_disconnect_ap() - send ap disconnect event + * @pdev: pdev obj + * @net_dev: Interface net device + * + * Send disconnect ap event to IPA driver during SSR + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev); + +/** + * ucfg_ipa_cleanup_dev_iface() - Clean up net dev IPA interface + * @pdev: pdev obj + * @net_dev: Interface net device + * + * + * Return: None + */ +void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev); #else static inline bool ucfg_ipa_is_present(void) @@ -452,5 +474,18 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev) { return false; } + +static inline +QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline +void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev) +{ +} #endif /* IPA_OFFLOAD */ #endif /* _WLAN_IPA_UCFG_API_H_ */ diff --git a/ipa/dispatcher/src/wlan_ipa_ucfg_api.c b/ipa/dispatcher/src/wlan_ipa_ucfg_api.c index 4433db007c..2df81efba4 100644 --- a/ipa/dispatcher/src/wlan_ipa_ucfg_api.c +++ b/ipa/dispatcher/src/wlan_ipa_ucfg_api.c @@ -174,3 +174,15 @@ bool ucfg_ipa_is_fw_wdi_activated(struct wlan_objmgr_pdev *pdev) { return ipa_is_fw_wdi_activated(pdev); } + +QDF_STATUS ucfg_ipa_uc_disconnect_ap(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev) +{ + return ipa_uc_disconnect_ap(pdev, net_dev); +} + +void ucfg_ipa_cleanup_dev_iface(struct wlan_objmgr_pdev *pdev, + qdf_netdev_t net_dev) +{ + return ipa_cleanup_dev_iface(pdev, net_dev); +}