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
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index bb06854..4bf1436 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -244,6 +244,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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);
}