diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index 026f40f205..6c9b8a1a0e 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -577,6 +577,14 @@ static void hdd_ipa_uc_loaded_uc_cb(void *priv_ctxt) } hdd_ipa = (struct hdd_ipa_priv *)priv_ctxt; + hdd_ipa->uc_loaded = true; + + uc_op_work = &hdd_ipa->uc_op_work[HDD_IPA_UC_OPCODE_UC_READY]; + + if (!list_empty(&uc_op_work->work.entry)) + /* uc_op_work is not initialized yet */ + return; + msg = (struct op_msg_type *)qdf_mem_malloc(sizeof(*msg)); if (!msg) { HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "op_msg allocation fails"); @@ -585,8 +593,6 @@ static void hdd_ipa_uc_loaded_uc_cb(void *priv_ctxt) msg->op_code = HDD_IPA_UC_OPCODE_UC_READY; - uc_op_work = &hdd_ipa->uc_op_work[msg->op_code]; - /* When the same uC OPCODE is already pended, just return */ if (uc_op_work->msg) goto done; @@ -2141,7 +2147,6 @@ static void hdd_ipa_uc_loaded_handler(struct hdd_ipa_priv *hdd_ipa) } hdd_ctx = hdd_ipa->hdd_ctx; - hdd_ipa->uc_loaded = true; /* Connect pipe */ status = cdp_ipa_setup(soc, (struct cdp_pdev *)pdev, @@ -3194,7 +3199,7 @@ static void hdd_ipa_cleanup_pending_event(struct hdd_ipa_priv *hdd_ipa) int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx) { struct hdd_ipa_priv *hdd_ipa = hdd_ctx->hdd_ipa; - int ret = 0; + int i, ret = 0; QDF_STATUS status; HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "enter"); @@ -3213,7 +3218,7 @@ int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx) HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "Failure to cleanup IPA pipes (status=%d)", status); - return -EFAULT; + ret = -EFAULT; } } @@ -3221,6 +3226,12 @@ int hdd_ipa_uc_ol_deinit(struct hdd_context *hdd_ctx) hdd_ipa_cleanup_pending_event(hdd_ipa); qdf_mutex_release(&hdd_ipa->ipa_lock); + for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) { + cancel_work_sync(&hdd_ipa->uc_op_work[i].work); + qdf_mem_free(hdd_ipa->uc_op_work[i].msg); + hdd_ipa->uc_op_work[i].msg = NULL; + } + HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "exit: ret=%d", ret); return ret; } @@ -6091,6 +6102,7 @@ static QDF_STATUS __hdd_ipa_cleanup(struct hdd_context *hdd_ctx) for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) { cancel_work_sync(&hdd_ipa->uc_op_work[i].work); + qdf_mem_free(hdd_ipa->uc_op_work[i].msg); hdd_ipa->uc_op_work[i].msg = NULL; } }