diff options
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.c | 36 | ||||
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.h | 3 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 50 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.h | 5 |
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. |
