diff --git a/dp/inc/cdp_txrx_ipa.h b/dp/inc/cdp_txrx_ipa.h index 2e33008c67..0c33ddc628 100644 --- a/dp/inc/cdp_txrx_ipa.h +++ b/dp/inc/cdp_txrx_ipa.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -81,6 +82,31 @@ cdp_ipa_set_doorbell_paddr(ol_txrx_soc_handle soc, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } +/** + * cdp_ipa_iounmap_doorbell_vaddr() - unmap IPA RX db vaddr + * @soc - data path soc handle + * @pdev_id - device instance id + * + * Unmap IPA RX db vaddr + * + * return QDF_STATUS_SUCCESS + */ +static inline QDF_STATUS +cdp_ipa_iounmap_doorbell_vaddr(ol_txrx_soc_handle soc, uint8_t pdev_id) +{ + if (!soc || !soc->ops || !soc->ops->ipa_ops) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_FATAL, + "%s invalid instance", __func__); + return QDF_STATUS_E_FAILURE; + } + + if (soc->ops->ipa_ops->ipa_iounmap_doorbell_vaddr) + return soc->ops->ipa_ops->ipa_iounmap_doorbell_vaddr( + soc, pdev_id); + + return QDF_STATUS_SUCCESS; +} + /** * cdp_ipa_set_active() - activate/de-ctivate IPA offload path * @soc - data path soc handle diff --git a/dp/inc/cdp_txrx_ops.h b/dp/inc/cdp_txrx_ops.h index 4a94b3ae51..718b0a55f7 100644 --- a/dp/inc/cdp_txrx_ops.h +++ b/dp/inc/cdp_txrx_ops.h @@ -1665,6 +1665,7 @@ struct cdp_throttle_ops { * struct cdp_ipa_ops - mcl ipa data path ops * @ipa_get_resource: * @ipa_set_doorbell_paddr: + * @ipa_iounmap_doorbell_vaddr: I/O unmap ipa doorbell vaddr * @ipa_set_active: * @ipa_op_response: * @ipa_register_op_cb: @@ -1679,6 +1680,8 @@ struct cdp_ipa_ops { uint8_t pdev_id); QDF_STATUS (*ipa_set_doorbell_paddr)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + QDF_STATUS (*ipa_iounmap_doorbell_vaddr)(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); QDF_STATUS (*ipa_set_active)(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool uc_active, bool is_tx); QDF_STATUS (*ipa_op_response)(struct cdp_soc_t *soc_hdl, diff --git a/dp/wifi3.0/dp_ipa.c b/dp/wifi3.0/dp_ipa.c index 259a0b889d..ffe6109bd4 100644 --- a/dp/wifi3.0/dp_ipa.c +++ b/dp/wifi3.0/dp_ipa.c @@ -1137,8 +1137,6 @@ static void dp_tx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned = NULL; ipa_res = &pdev->ipa_resource; - if (!ipa_res->is_db_ddr_mapped) - iounmap(ipa_res->tx_comp_doorbell_vaddr); qdf_mem_free_sgtable(&ipa_res->tx_ring.sgtable); qdf_mem_free_sgtable(&ipa_res->tx_comp_ring.sgtable); @@ -1603,6 +1601,29 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } +QDF_STATUS dp_ipa_iounmap_doorbell_vaddr(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id) +{ + struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); + struct dp_pdev *pdev = + dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); + struct dp_ipa_resources *ipa_res; + + if (!wlan_cfg_is_ipa_enabled(soc->wlan_cfg_ctx)) + return QDF_STATUS_SUCCESS; + + if (!pdev) { + dp_err("Invalid instance"); + return QDF_STATUS_E_FAILURE; + } + + ipa_res = &pdev->ipa_resource; + if (!ipa_res->is_db_ddr_mapped) + iounmap(ipa_res->tx_comp_doorbell_vaddr); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS dp_ipa_op_response(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, uint8_t *op_msg) { diff --git a/dp/wifi3.0/dp_ipa.h b/dp/wifi3.0/dp_ipa.h index 702db254bf..6c4902d7ae 100644 --- a/dp/wifi3.0/dp_ipa.h +++ b/dp/wifi3.0/dp_ipa.h @@ -86,6 +86,17 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); */ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id); + +/** + * dp_ipa_iounmap_doorbell_vaddr() - unmap ipa RX db vaddr + * @soc_hdl - data path soc handle + * @pdev_id - device instance id + * + * Return: none + */ +QDF_STATUS dp_ipa_iounmap_doorbell_vaddr(struct cdp_soc_t *soc_hdl, + uint8_t pdev_id); + QDF_STATUS dp_ipa_uc_set_active(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, bool uc_active, bool is_tx); diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 38f2cc5ebb..134684f3eb 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -12518,6 +12518,7 @@ static struct cdp_lflowctl_ops dp_ops_l_flowctl = { static struct cdp_ipa_ops dp_ops_ipa = { .ipa_get_resource = dp_ipa_get_resource, .ipa_set_doorbell_paddr = dp_ipa_set_doorbell_paddr, + .ipa_iounmap_doorbell_vaddr = dp_ipa_iounmap_doorbell_vaddr, .ipa_op_response = dp_ipa_op_response, .ipa_register_op_cb = dp_ipa_register_op_cb, .ipa_deregister_op_cb = dp_ipa_deregister_op_cb, diff --git a/ipa/core/src/wlan_ipa_core.c b/ipa/core/src/wlan_ipa_core.c index cb89c3ee2d..8b8fd05922 100644 --- a/ipa/core/src/wlan_ipa_core.c +++ b/ipa/core/src/wlan_ipa_core.c @@ -3705,6 +3705,7 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx) if (!ipa_cb_is_ready()) return QDF_STATUS_SUCCESS; + qdf_event_destroy(&ipa_ctx->ipa_resource_comp); if (!wlan_ipa_uc_is_enabled(ipa_ctx->config)) wlan_ipa_teardown_sys_pipe(ipa_ctx); @@ -3722,6 +3723,7 @@ QDF_STATUS wlan_ipa_cleanup(struct wlan_ipa_priv *ipa_ctx) qdf_spinlock_destroy(&ipa_ctx->pm_lock); qdf_spinlock_destroy(&ipa_ctx->q_lock); qdf_spinlock_destroy(&ipa_ctx->enable_disable_lock); + qdf_destroy_work(0, &ipa_ctx->pm_work); /* destroy the interface lock */ for (i = 0; i < WLAN_IPA_MAX_IFACE; i++) { @@ -4174,6 +4176,9 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) ipa_ctx->uc_op_work[i].msg = NULL; } + cdp_ipa_iounmap_doorbell_vaddr(ipa_ctx->dp_soc, + ipa_ctx->dp_pdev_id); + if (true == ipa_ctx->uc_loaded) { cdp_ipa_tx_buf_smmu_unmapping(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); diff --git a/ipa/core/src/wlan_ipa_main.c b/ipa/core/src/wlan_ipa_main.c index 138cde6cbe..4d0b57dfd7 100644 --- a/ipa/core/src/wlan_ipa_main.c +++ b/ipa/core/src/wlan_ipa_main.c @@ -25,6 +25,7 @@ #include "wlan_ipa_core.h" #include "wlan_ipa_tgt_api.h" #include "cfg_ucfg_api.h" +#include "wlan_ipa_obj_mgmt_api.h" static struct wlan_ipa_config *g_ipa_config; static bool g_ipa_hw_support; @@ -619,6 +620,8 @@ QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev) } status = wlan_ipa_uc_ol_deinit(ipa_obj); + ipa_obj_cleanup(ipa_obj); + ipa_disable_register_cb(); out: ipa_init_deinit_unlock(); diff --git a/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c b/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c index 898f91c5fe..d9a8ebb1cc 100644 --- a/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c +++ b/ipa/dispatcher/src/wlan_ipa_obj_mgmt_api.c @@ -67,6 +67,7 @@ ipa_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, QDF_STATUS status; struct wlan_ipa_priv *ipa_obj; + ipa_debug("ipa pdev destroyed"); if (!ipa_config_is_enabled()) { ipa_debug("IPA is disabled"); return QDF_STATUS_SUCCESS; @@ -85,9 +86,7 @@ ipa_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, if (QDF_IS_STATUS_ERROR(status)) ipa_err("Failed to detatch ipa pdev object"); - ipa_obj_cleanup(ipa_obj); qdf_mem_free(ipa_obj); - ipa_disable_register_cb(); return status; }