diff options
| author | Sameer Thalappil <sameert@qca.qualcomm.com> | 2014-02-05 20:42:02 -0800 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-02-07 17:38:22 -0800 |
| commit | ded58968277eea8bcdcf2eafb11198c6b7deb538 (patch) | |
| tree | a216eeeb7310f60a2fd13ed874b2cbcb5aa7f342 | |
| parent | 84681c9150f591bdfda1f5ce7348b1cea5a29966 (diff) | |
qcacld: Silent recovery on FW dump failure
When host fails to collect dump on FW assert, there is no reason to put
device to download mode when SSR level is set to system. So instead of
going thru SSR framework, silently recover from this assert.
Change-Id: Ib8af1d25b3d0a66004984e1ffdbedfa19c71f175
CRs-Fixed: 612268
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.c | 39 | ||||
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.h | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 9 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.h | 2 |
4 files changed, 35 insertions, 19 deletions
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index 29e55d563dc5..515bdc81a3bf 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -492,7 +492,7 @@ 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) +int dump_CE_register(struct ol_softc *scn) { A_UINT32 CE_reg_address = CE7_LOCATION; A_UINT32 CE_reg_values[CE_USEFUL_SIZE>>2]; @@ -504,13 +504,14 @@ void dump_CE_register(struct ol_softc *scn) CE_reg_word_size * sizeof(A_UINT32)) != A_OK) { printk(KERN_ERR "Dumping CE register failed!\n"); - return; + return -EACCES; } printk("CE7 Register Dump:\n"); for (i = 0; i < CE_reg_word_size; i++) { printk("[%02d] : 0x%08X\n", i, CE_reg_values[i]); } + return EOK; } #endif @@ -522,15 +523,21 @@ static void ramdump_work_handler(struct work_struct *ramdump) void __iomem *ramdump_base; unsigned long address; unsigned long size; + int ret; u_int32_t host_interest_address; if (!ramdump_scn) { printk("No RAM dump will be collected since ramdump_scn is NULL!\n"); - goto out; + goto out_fail; } - hif_pci_check_soc_status(ramdump_scn->hif_sc); - dump_CE_register(ramdump_scn); + ret = hif_pci_check_soc_status(ramdump_scn->hif_sc); + if (ret) + goto out_fail; + + ret = dump_CE_register(ramdump_scn); + if (ret) + goto out_fail; if (HIFDiagReadMem(ramdump_scn->hif_hdl, host_interest_item_address(ramdump_scn->target_type, @@ -539,7 +546,7 @@ static void ramdump_work_handler(struct work_struct *ramdump) printk(KERN_ERR "HifDiagReadiMem FW Dump Area Pointer failed!\n"); dump_CE_register(ramdump_scn); - goto out; + goto out_fail; } printk("Host interest item address: 0x%08X\n", host_interest_address); @@ -547,25 +554,30 @@ static void ramdump_work_handler(struct work_struct *ramdump) if (cnss_get_ramdump_mem(&address, &size)) { printk("No RAM dump will be collected since failed to get " "memory address or size!\n"); - goto out; + goto out_fail; } ramdump_base = ioremap(address, size); if (!ramdump_base) { printk("No RAM dump will be collected since ramdump_base is NULL!\n"); - goto out; + goto out_fail; } - ol_target_coredump(ramdump_scn, ramdump_base, TOTAL_DUMP_SIZE); + ret = ol_target_coredump(ramdump_scn, ramdump_base, TOTAL_DUMP_SIZE); iounmap(ramdump_base); + if (ret) + goto out_fail; printk("%s: RAM dump collecting completed!\n", __func__); msleep(250); - -out: /* Notify SSR framework the target has crashed. */ cnss_device_crashed(); return; + +out_fail: + /* silent SSR on dump failure */ + cnss_device_self_recovery(); + return; } static DECLARE_WORK(ramdump_work, ramdump_work_handler); @@ -1003,11 +1015,12 @@ int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer, * * \return: None * --------------------------------------------------------------------------*/ -void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) +int ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) { struct ol_softc *scn = (struct ol_softc *)inst; char *bufferLoc = memoryBlock; int result = 0; + int ret = 0; u_int32_t amountRead = 0; u_int32_t sectionCount = 0; u_int32_t pos = 0; @@ -1055,6 +1068,7 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) } else { printk(KERN_ERR "Could not read dump section!\n"); dump_CE_register(scn); + ret = -EACCES; break; /* Could not read the section */ } } else { @@ -1062,6 +1076,7 @@ void ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength) break; /* Insufficient room in buffer */ } } + return ret; } #endif diff --git a/CORE/SERVICES/BMI/ol_fw.h b/CORE/SERVICES/BMI/ol_fw.h index 1b5f9f296269..f15e2d3b501f 100644 --- a/CORE/SERVICES/BMI/ol_fw.h +++ b/CORE/SERVICES/BMI/ol_fw.h @@ -1,5 +1,5 @@ /* - * 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. * @@ -68,7 +68,7 @@ #define TOTAL_DUMP_SIZE 0x00200000 #define PCIE_READ_LIMIT 0x00005000 -void ol_target_coredump(void *instance, void* memoryBlock, +int ol_target_coredump(void *instance, void* memoryBlock, u_int32_t blockLength); int ol_diag_read(struct ol_softc *scn, u_int8_t* buffer, u_int32_t pos, size_t count); diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 4b5e32bd863d..90b4ccab0b28 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -331,8 +331,8 @@ hif_pci_device_warm_reset(struct hif_pci_softc *sc) } -void -hif_pci_check_soc_status(struct hif_pci_softc *sc) + +int hif_pci_check_soc_status(struct hif_pci_softc *sc) { u_int16_t device_id; u_int32_t val; @@ -342,7 +342,7 @@ hif_pci_check_soc_status(struct hif_pci_softc *sc) 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; + return -EACCES; } /* Check PCIe local register for bar/memory access */ @@ -365,7 +365,7 @@ hif_pci_check_soc_status(struct hif_pci_softc *sc) 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; + return -EACCES; } A_PCI_WRITE32(sc->mem + PCIE_LOCAL_BASE_ADDRESS + @@ -378,6 +378,7 @@ hif_pci_check_soc_status(struct hif_pci_softc *sc) /* Check BAR + 0x10c register for SoC internal bus issues */ val = A_PCI_READ32(sc->mem + 0x10c); printk("BAR + 0x10c is %08x\n", val); + return EOK; } /* diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h index ee3fb120c040..d3955f7f0e5a 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.h +++ b/CORE/SERVICES/HIF/PCIe/if_pci.h @@ -121,7 +121,7 @@ extern int pktlogmod_init(void *context); extern void pktlogmod_exit(void *context); #endif -void hif_pci_check_soc_status(struct hif_pci_softc *sc); +int hif_pci_check_soc_status(struct hif_pci_softc *sc); /* * A firmware interrupt to the Host is indicated by the |
