diff options
| -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 |
