diff --git a/components/ipa/core/inc/wlan_ipa_priv.h b/components/ipa/core/inc/wlan_ipa_priv.h index 040adaebfb3a..fcf22a5601ec 100644 --- a/components/ipa/core/inc/wlan_ipa_priv.h +++ b/components/ipa/core/inc/wlan_ipa_priv.h @@ -709,6 +709,7 @@ struct wlan_ipa_priv { bool is_smmu_enabled; /* IPA caps returned from ipa_wdi_init */ qdf_atomic_t stats_quota; uint8_t curr_bw_level; + qdf_atomic_t deinit_in_prog; }; #define WLAN_IPA_WLAN_FRAG_HEADER sizeof(struct frag_header) diff --git a/components/ipa/core/src/wlan_ipa_core.c b/components/ipa/core/src/wlan_ipa_core.c index 2826ae88ce16..f5973ebd553e 100644 --- a/components/ipa/core/src/wlan_ipa_core.c +++ b/components/ipa/core/src/wlan_ipa_core.c @@ -168,7 +168,13 @@ static void wlan_ipa_uc_loaded_uc_cb(void *priv_ctxt) goto done; uc_op_work->msg = msg; - qdf_sched_work(0, &uc_op_work->work); + + if (!qdf_atomic_read(&ipa_ctx->deinit_in_prog)) { + qdf_sched_work(0, &uc_op_work->work); + } else { + uc_op_work->msg = NULL; + goto done; + } /* work handler will free the msg buffer */ return; @@ -3167,6 +3173,7 @@ QDF_STATUS wlan_ipa_setup(struct wlan_ipa_priv *ipa_ctx, qdf_list_create(&ipa_ctx->pending_event, 1000); qdf_mutex_create(&ipa_ctx->event_lock); qdf_mutex_create(&ipa_ctx->ipa_lock); + qdf_atomic_init(&ipa_ctx->deinit_in_prog); status = wlan_ipa_wdi_setup_rm(ipa_ctx); if (status != QDF_STATUS_SUCCESS) @@ -3724,6 +3731,15 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) wlan_ipa_uc_disable_pipes(ipa_ctx, true); + cdp_ipa_deregister_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); + qdf_atomic_set(&ipa_ctx->deinit_in_prog, 1); + + for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { + qdf_cancel_work(&ipa_ctx->uc_op_work[i].work); + qdf_mem_free(ipa_ctx->uc_op_work[i].msg); + ipa_ctx->uc_op_work[i].msg = NULL; + } + if (true == ipa_ctx->uc_loaded) { cdp_ipa_tx_buf_smmu_unmapping(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); @@ -3740,14 +3756,6 @@ QDF_STATUS wlan_ipa_uc_ol_deinit(struct wlan_ipa_priv *ipa_ctx) wlan_ipa_cleanup_pending_event(ipa_ctx); qdf_mutex_release(&ipa_ctx->ipa_lock); - cdp_ipa_deregister_op_cb(ipa_ctx->dp_soc, ipa_ctx->dp_pdev_id); - - for (i = 0; i < WLAN_IPA_UC_OPCODE_MAX; i++) { - qdf_cancel_work(&ipa_ctx->uc_op_work[i].work); - qdf_mem_free(ipa_ctx->uc_op_work[i].msg); - ipa_ctx->uc_op_work[i].msg = NULL; - } - ipa_debug("exit: ret=%d", status); return status; }