summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGovind Singh <govinds@codeaurora.org>2016-11-23 10:02:56 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-11-29 23:15:11 -0800
commitadb5a919a12ff4c6fb5fe43a8c613bd0ceca1934 (patch)
tree251eb5088ba3413ce52abfede18f3683390b3b18
parent4412e96b1e29b677cfc1cadde2d8ea6c56c4ae7d (diff)
qcacld-2.0: Do not process the packets if hw read_idx is invalid
When SSR is injected on PCIE using iwpriv wlan0 crash_inject 7 0, fw brings down the PCIE link. PCIE root complex detects link down and notifies the link_down ops to the cnss platform driver. Platform driver link down ops disables the interrupts and then schedules the recovery. If rx data path is active, current running tasklet relies on HW index to calculate the ring delta. As hw index is 0xFFFFFFFF due to linkdown and host identifies this condition as infinity loop due to recursive tasklet design for interrupt mitigation and asserts. To fix the problem do not process the packets recursively if hw read_idx is invalid. Change-Id: Ieb170edb3ea6741b158db4aa9fd61b2ed0070fc7 CRs-Fixed: 1089360
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine.c11
-rw-r--r--CORE/SERVICES/HIF/PCIe/copy_engine_internal.h3
2 files changed, 11 insertions, 3 deletions
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c
index 9619e93d07f3..e7831136ffff 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine.c
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c
@@ -1043,20 +1043,27 @@ static inline bool ce_is_valid_entries(struct hif_pci_softc *sc,
{
bool status;
A_target_id_t targid = TARGID(sc);
+ unsigned int hw_index =
+ CE_DEST_RING_READ_IDX_GET(targid, ce_state->ctrl_addr);
/* check if difference between hw index and read index is with in
* nentries_mask limit.
*/
- if (ring_delta < ce_state->dest_ring->nentries_mask) {
+ if ((ring_delta < ce_state->dest_ring->nentries_mask) &&
+ (hw_index != CE_HW_INDEX_LINK_DOWN)) {
adf_os_print("%s: spent more time during rx proceesing for CE%d, allow other CE to process Rx packet.\n",
__func__, ce_state->id);
status = true;
+ } else if (hw_index == CE_HW_INDEX_LINK_DOWN) {
+ status = false;
+ adf_os_print("%s: hw index is invalid due to link down \n", __func__);
} else {
adf_os_print("%s:Potential infinite loop detected during rx processing for CE%d\n",
- __func__, ce_state->id);
+ __func__, ce_state->id);
VOS_BUG(0);
status = false;
}
+
adf_os_print("nentries_mask:0x%x sw read_idx:0x%x hw read_idx:0x%x ring_delta:0x%x\n",
ce_state->dest_ring->nentries_mask,
ce_state->dest_ring->sw_index,
diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h b/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h
index 65d505e43210..08db7ca11f6e 100644
--- a/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h
+++ b/CORE/SERVICES/HIF/PCIe/copy_engine_internal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -216,6 +216,7 @@ struct CE_sendlist_s {
#define CDC_WAR_MAGIC_STR 0xceef0000
#define CDC_WAR_DATA_CE 4
+#define CE_HW_INDEX_LINK_DOWN 0xFFFFFFFF
/* Additional internal-only CE_send flags */
#define CE_SEND_FLAG_GATHER 0x00010000 /* Use Gather */