From 8292dcb0ac1d12bbc3b670bf111b325c2897d396 Mon Sep 17 00:00:00 2001 From: Yun Park Date: Fri, 7 Oct 2016 16:46:06 -0700 Subject: [PATCH] qcacld-3.0: Check offload status before sending IPA enable_disable To avoid FW crash caused by sending the same IPA enable_disable WMI message twice, check the IPA offload enable status before sending it to FW. Fixed log to check both uc_op_code and stat_req_reason. Change-Id: I1fc5f4de8207872edf3c2c6ec908820ac819e4ae CRs-Fixed: 1073325 --- core/hdd/src/wlan_hdd_ipa.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index bb06854696..4bf1436322 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -244,6 +244,7 @@ struct hdd_ipa_iface_context { qdf_spinlock_t interface_lock; uint32_t ifa_address; struct hdd_ipa_iface_stats stats; + uint32_t offload_enabled; }; struct hdd_ipa_stats { @@ -1353,9 +1354,7 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt) hdd_ipa->pending_cons_req = false; } qdf_mutex_release(&hdd_ipa->ipa_lock); - } - - if ((HDD_IPA_UC_OPCODE_TX_SUSPEND == msg->op_code) || + } else if ((HDD_IPA_UC_OPCODE_TX_SUSPEND == msg->op_code) || (HDD_IPA_UC_OPCODE_RX_SUSPEND == msg->op_code)) { qdf_mutex_acquire(&hdd_ipa->ipa_lock); hdd_ipa->activated_fw_pipe--; @@ -1371,9 +1370,7 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt) hdd_ipa->pending_cons_req = false; } qdf_mutex_release(&hdd_ipa->ipa_lock); - } - - if ((HDD_IPA_UC_OPCODE_STATS == msg->op_code) && + } else if ((HDD_IPA_UC_OPCODE_STATS == msg->op_code) && (HDD_IPA_UC_STAT_REASON_DEBUG == hdd_ipa->stat_req_reason)) { struct ol_txrx_ipa_resources *res = &hdd_ipa->ipa_resource; /* STATs from host */ @@ -1572,8 +1569,8 @@ static void hdd_ipa_uc_op_cb(struct op_msg_type *op_msg, void *usr_ctxt) uc_fw_stat->rx_num_pkts_indicated); qdf_mutex_release(&hdd_ipa->ipa_lock); } else { - HDD_IPA_LOG(LOGE, "INVALID REASON %d", - hdd_ipa->stat_req_reason); + HDD_IPA_LOG(LOGE, "Invalid message: op_code=%d, reason=%d", + msg->op_code, hdd_ipa->stat_req_reason); } qdf_mem_free(op_msg); } @@ -1591,10 +1588,22 @@ static void hdd_ipa_uc_offload_enable_disable(hdd_adapter_t *adapter, uint32_t offload_type, uint32_t enable) { struct sir_ipa_offload_enable_disable ipa_offload_enable_disable; + struct hdd_ipa_iface_context *iface_context = NULL; if (!adapter) return; + iface_context = adapter->ipa_context; + + if (!iface_context || (enable == iface_context->offload_enabled)) { + /* IPA offload status is already set as desired */ + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, + "offload_type=%d, vdev_id=%d, enable=%d", + offload_type, adapter->sessionId, enable); + WARN_ON(1); + return; + } + /* Lower layer may send multiple START_BSS_EVENT in DFS mode or during * channel change indication. Since these indications are sent by lower * layer as SAP updates and IPA doesn't have to do anything for these @@ -1610,7 +1619,7 @@ static void hdd_ipa_uc_offload_enable_disable(hdd_adapter_t *adapter, ipa_offload_enable_disable.enable = enable; HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, - "%s: offload_type=%d, vdev_id=%d, enable=%d", __func__, + "offload_type=%d, vdev_id=%d, enable=%d", ipa_offload_enable_disable.offload_type, ipa_offload_enable_disable.vdev_id, ipa_offload_enable_disable.enable); @@ -1624,6 +1633,10 @@ static void hdd_ipa_uc_offload_enable_disable(hdd_adapter_t *adapter, ipa_offload_enable_disable.offload_type, ipa_offload_enable_disable.vdev_id, ipa_offload_enable_disable.enable); + } else { + /* Update the IPA offload status */ + iface_context->offload_enabled = + ipa_offload_enable_disable.enable; } } @@ -4107,6 +4120,7 @@ QDF_STATUS hdd_ipa_init(hdd_context_t *hdd_ctx) hdd_ipa_adapter_2_client[i].prod_client; iface_context->iface_id = i; iface_context->adapter = NULL; + iface_context->offload_enabled = 0; qdf_spinlock_create(&iface_context->interface_lock); }