summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c36
-rw-r--r--CORE/SERVICES/BMI/ol_fw.h3
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c50
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h5
4 files changed, 90 insertions, 4 deletions
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c
index e632876fa4f3..c18fc831a0b2 100644
--- a/CORE/SERVICES/BMI/ol_fw.c
+++ b/CORE/SERVICES/BMI/ol_fw.c
@@ -34,6 +34,7 @@
#include "vos_api.h"
#include "wma_api.h"
#include "wma.h"
+#include "if_pci.h"
#define ATH_MODULE_NAME bmi
#include "a_debug.h"
@@ -490,6 +491,29 @@ u_int32_t host_interest_item_address(u_int32_t target_type, u_int32_t item_offse
}
}
+#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC)
+void dump_CE_register(struct ol_softc *scn)
+{
+ A_UINT32 CE_reg_address = CE7_LOCATION;
+ A_UINT32 CE_reg_values[CE_USEFUL_SIZE>>2];
+ A_UINT32 CE_reg_word_size = CE_USEFUL_SIZE>>2;
+ A_UINT16 i;
+
+ if (HIFDiagReadMem(scn->hif_hdl, CE_reg_address,
+ (A_UCHAR*)&CE_reg_values[0],
+ CE_reg_word_size * sizeof(A_UINT32)) != A_OK)
+ {
+ printk(KERN_ERR "Dumping CE register failed!\n");
+ return;
+ }
+
+ printk("CE7 Register Dump:\n");
+ for (i = 0; i < CE_reg_word_size; i++) {
+ printk("[%02d] : 0x%08X\n", i, CE_reg_values[i]);
+ }
+}
+#endif
+
#if defined(QCA_WIFI_2_0) && !defined(QCA_WIFI_ISOC) && defined(CONFIG_CNSS)
static struct ol_softc *ramdump_scn;
@@ -505,11 +529,16 @@ static void ramdump_work_handler(struct work_struct *ramdump)
goto out;
}
+ hif_pci_check_soc_status(ramdump_scn->hif_sc);
+ dump_CE_register(ramdump_scn);
+
if (HIFDiagReadMem(ramdump_scn->hif_hdl,
host_interest_item_address(ramdump_scn->target_type,
offsetof(struct host_interest_s, hi_failure_state)),
(A_UCHAR*) &host_interest_address, sizeof(u_int32_t)) != A_OK) {
- printk("HifDiagReadiMem FW Dump Area Pointer failed!\n");
+ printk(KERN_ERR "HifDiagReadiMem FW Dump Area Pointer failed!\n");
+ dump_CE_register(ramdump_scn);
+
goto out;
}
printk("Host interest item address: 0x%08X\n", host_interest_address);
@@ -998,7 +1027,7 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength)
* LENGTH = 0x00018000
*/
- while ((sectionCount < 3) && (amountRead < blockLength)) {
+ while ((sectionCount < 2) && (amountRead < blockLength)) {
switch (sectionCount) {
case 0:
/* DRAM SECTION */
@@ -1024,9 +1053,12 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength)
bufferLoc += result;
sectionCount++;
} else {
+ printk(KERN_ERR "Could not read dump section!\n");
+ dump_CE_register(scn);
break; /* Could not read the section */
}
} else {
+ printk(KERN_ERR "Insufficient room in dump buffer!\n");
break; /* Insufficient room in buffer */
}
}
diff --git a/CORE/SERVICES/BMI/ol_fw.h b/CORE/SERVICES/BMI/ol_fw.h
index 18abf68cdb91..77c9bd19cdf1 100644
--- a/CORE/SERVICES/BMI/ol_fw.h
+++ b/CORE/SERVICES/BMI/ol_fw.h
@@ -62,6 +62,9 @@
#define AXI_LOCATION 0x000a0000
#define AXI_SIZE 0x00018000
+#define CE7_LOCATION 0x00036000
+#define CE_USEFUL_SIZE 0x00000058
+
#define TOTAL_DUMP_SIZE 0x00200000
#define PCIE_READ_LIMIT 0x00005000
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c
index 4be8c537dc6e..6de3a42c984c 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.c
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.c
@@ -64,6 +64,7 @@
#define AR6320_FW_2_0 (0x20)
#define MAX_NUM_OF_RECEIVES 1000 /* Maximum number of Rx buf to process before break out */
+#define PCIE_WAKE_TIMEOUT 1000 /* Maximum ms timeout for host to wake up target */
unsigned int msienable = 0;
module_param(msienable, int, 0644);
@@ -313,6 +314,55 @@ hif_pci_device_warm_reset(struct hif_pci_softc *sc)
}
+void
+hif_pci_check_soc_status(struct hif_pci_softc *sc)
+{
+ u_int16_t device_id;
+ u_int32_t val;
+ u_int16_t timeout_count = 0;
+
+ /* Check device ID from PCIe configuration space for link status */
+ pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &device_id);
+ if(device_id != sc->devid) {
+ printk(KERN_ERR "PCIe link is down!\n");
+ return;
+ }
+
+ /* Check PCIe local register for bar/memory access */
+ val = A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
+ RTC_STATE_ADDRESS);
+ printk("RTC_STATE_ADDRESS is %08x\n", val);
+
+ /* Try to wake up taget if it sleeps */
+ A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
+ PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
+ printk("PCIE_SOC_WAKE_ADDRESS is %08x\n",
+ A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
+ PCIE_SOC_WAKE_ADDRESS));
+
+ /* Check if taget can be woken up */
+ while(!hif_pci_targ_is_awake(sc, sc->mem)) {
+ if(timeout_count >= PCIE_WAKE_TIMEOUT) {
+ printk(KERN_ERR "Target cannot be woken up! "
+ "RTC_STATE_ADDRESS is %08x, PCIE_SOC_WAKE_ADDRESS is %08x\n",
+ A_PCI_READ32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
+ RTC_STATE_ADDRESS), A_PCI_READ32(sc->mem +
+ PCIE_LOCAL_BASE_ADDRESS + PCIE_SOC_WAKE_ADDRESS));
+ return;
+ }
+
+ A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS +
+ PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK);
+
+ A_MDELAY(100);
+ timeout_count += 100;
+ }
+
+ /* Check BAR + 0x10c register for SoC internal bus issues */
+ val = A_PCI_READ32(sc->mem + 0x10c);
+ printk("BAR + 0x10c is %08x\n", val);
+}
+
/*
* Handler for a per-engine interrupt on a PARTICULAR CE.
* This is used in cases where each CE has a private
diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h
index 74f7130e04c7..65719c74b58f 100644
--- a/CORE/SERVICES/HIF/PCIe/if_pci.h
+++ b/CORE/SERVICES/HIF/PCIe/if_pci.h
@@ -1,9 +1,8 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
- *
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
@@ -120,6 +119,8 @@ extern int pktlogmod_init(void *context);
extern void pktlogmod_exit(void *context);
#endif
+void hif_pci_check_soc_status(struct hif_pci_softc *sc);
+
/*
* A firmware interrupt to the Host is indicated by the
* low bit of SCRATCH_3_ADDRESS being set.