summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c39
-rw-r--r--CORE/SERVICES/BMI/ol_fw.h4
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.c9
-rw-r--r--CORE/SERVICES/HIF/PCIe/if_pci.h2
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