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