summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaresh Eswari Lankaraman <c_heswar@qca.qualcomm.com>2014-08-07 18:26:11 -0700
committerAkash Patel <c_akashp@qca.qualcomm.com>2014-08-21 19:27:57 -0700
commitece4d7442771152b65b733ace069c65e5f1ee7db (patch)
treee191efe732ca48f004623feeed8043dc8378fd34
parentdc768322c185f5471c8872d9bee7fbac6e66c852 (diff)
qcacld: Add Support for ramdump across SDIO
When there is a firmware assert,firmware dump will be copied to a specific memory location on host through SDIO interface. Device will be put to download mode after collecting dump. Change-Id: Ia2eeaa265c358b333dad306d4403f4b8f5a71134 CRs-Fixed: 679707
-rw-r--r--CORE/SERVICES/BMI/ol_fw.c35
-rw-r--r--CORE/SERVICES/COMMON/ol_if_athvar.h2
-rw-r--r--CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c9
-rw-r--r--CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h2
4 files changed, 42 insertions, 6 deletions
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c
index 085fec3bff33..920a26a7857b 100644
--- a/CORE/SERVICES/BMI/ol_fw.c
+++ b/CORE/SERVICES/BMI/ol_fw.c
@@ -857,7 +857,7 @@ int dump_CE_register(struct ol_softc *scn)
}
#endif
-#if defined(CONFIG_CNSS)
+#if defined(CONFIG_CNSS) || defined(HIF_SDIO)
static struct ol_softc *ramdump_scn;
int ol_copy_ramdump(struct ol_softc *scn)
@@ -879,7 +879,9 @@ out:
static void ramdump_work_handler(struct work_struct *ramdump)
{
+#if !defined(HIF_SDIO)
int ret;
+#endif
u_int32_t host_interest_address;
u_int32_t dram_dump_values[4];
@@ -887,7 +889,7 @@ static void ramdump_work_handler(struct work_struct *ramdump)
printk("No RAM dump will be collected since ramdump_scn is NULL!\n");
goto out_fail;
}
-
+#if !defined(HIF_SDIO)
#ifdef DEBUG
ret = hif_pci_check_soc_status(ramdump_scn->hif_sc);
if (ret)
@@ -899,14 +901,17 @@ static void ramdump_work_handler(struct work_struct *ramdump)
dump_CE_debug_register(ramdump_scn->hif_sc);
#endif
+#endif
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(KERN_ERR "HifDiagReadiMem FW Dump Area Pointer failed!\n");
+#if !defined(HIF_SDIO)
dump_CE_register(ramdump_scn);
dump_CE_debug_register(ramdump_scn->hif_sc);
+#endif
goto out_fail;
}
@@ -926,18 +931,28 @@ static void ramdump_work_handler(struct work_struct *ramdump)
printk("%s: RAM dump collecting completed!\n", __func__);
msleep(250);
-
+#if defined(HIF_SDIO)
+ panic("CNSS Ram dump collected\n");
+#else
/* Notify SSR framework the target has crashed. */
cnss_device_crashed();
+#endif
return;
out_fail:
/* Silent SSR on dump failure */
#ifdef CNSS_SELF_RECOVERY
+#if !defined(HIF_SDIO)
cnss_device_self_recovery();
+#endif
+#else
+
+#if defined(HIF_SDIO)
+ panic("CNSS Ram dump collection failed \n");
#else
cnss_device_crashed();
#endif
+#endif
return;
}
@@ -951,7 +966,9 @@ void ol_schedule_ramdump_work(struct ol_softc *scn)
static void fw_indication_work_handler(struct work_struct *fw_indication)
{
+#if !defined(HIF_SDIO)
cnss_device_self_recovery();
+#endif
}
static DECLARE_WORK(fw_indication_work, fw_indication_work_handler);
@@ -1213,7 +1230,7 @@ void ol_target_failure(void *instance, A_STATUS status)
}
#endif
-#if defined(CONFIG_CNSS)
+#if defined(CONFIG_CNSS) || defined(HIF_SDIO)
/* Collect the RAM dump through a workqueue */
ol_schedule_ramdump_work(scn);
#endif
@@ -1956,7 +1973,7 @@ int ol_download_firmware(struct ol_softc *scn)
return status;
}
-#ifdef HIF_PCI
+#if defined(HIF_PCI) || defined(HIF_SDIO)
int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer,
u_int32_t pos, size_t count)
{
@@ -1966,6 +1983,7 @@ int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer,
result = HIFDiagReadAccess(scn->hif_hdl, pos,
(u_int32_t*)buffer);
} else {
+#ifdef HIF_PCI
size_t amountRead = 0;
size_t readSize = PCIE_READ_LIMIT;
size_t remainder = 0;
@@ -1983,9 +2001,12 @@ int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer,
}
}
} else {
+#endif
result = HIFDiagReadMem(scn->hif_hdl, pos,
buffer, count);
+#ifdef HIF_PCI
}
+#endif
}
if (!result) {
@@ -1995,6 +2016,7 @@ int ol_diag_read(struct ol_softc *scn, u_int8_t *buffer,
}
}
+#if defined(HIF_PCI)
static int ol_ath_get_reg_table(A_UINT32 target_version,
tgt_reg_table *reg_table)
{
@@ -2091,6 +2113,7 @@ static int ol_diag_read_reg_loc(struct ol_softc *scn, u_int8_t *buffer,
out:
return result;
}
+#endif
/**---------------------------------------------------------------------------
* \brief ol_target_coredump
@@ -2152,10 +2175,12 @@ int ol_target_coredump(void *inst, void *memoryBlock, u_int32_t blockLength)
}
if ((blockLength - amountRead) >= readLen) {
+#if !defined(HIF_SDIO)
if (pos == REGISTER_LOCATION)
result = ol_diag_read_reg_loc(scn, bufferLoc,
blockLength - amountRead);
else
+#endif
result = ol_diag_read(scn, bufferLoc,
pos, readLen);
if (result != -EIO) {
diff --git a/CORE/SERVICES/COMMON/ol_if_athvar.h b/CORE/SERVICES/COMMON/ol_if_athvar.h
index 8b9408e8896e..967e2cc561e1 100644
--- a/CORE/SERVICES/COMMON/ol_if_athvar.h
+++ b/CORE/SERVICES/COMMON/ol_if_athvar.h
@@ -273,7 +273,7 @@ struct ol_softc {
#elif defined(HIF_SDIO)
struct ol_fw_files fw_files;
#endif
-#ifdef CONFIG_CNSS
+#if defined(CONFIG_CNSS) || defined(HIF_SDIO)
void __iomem *ramdump_base;
unsigned long ramdump_address;
unsigned long ramdump_size;
diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c
index dbbe6a95a960..588fb89e431f 100644
--- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c
+++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c
@@ -147,6 +147,13 @@ ath_hif_sdio_probe(void *context, void *hif_handle)
ol_sc->max_no_of_peers = 1;
ol_sc->hif_hdl = hif_handle;
+
+ ol_sc->ramdump_base = ioremap(RAMDUMP_ADDR, RAMDUMP_SIZE);
+ ol_sc->ramdump_size = RAMDUMP_SIZE;
+ if (ol_sc->ramdump_base == NULL) {
+ ol_sc->ramdump_base = 0;
+ ol_sc->ramdump_size = 0;
+ }
init_waitqueue_head(&ol_sc->sc_osdev->event_queue);
if (athdiag_procfs_init(sc) != 0) {
@@ -218,6 +225,8 @@ ath_hif_sdio_remove(void *context, void *hif_handle)
athdiag_procfs_remove();
+ iounmap(sc->ol_sc->ramdump_base);
+
#ifndef REMOVE_PKT_LOG
if (vos_get_conparam() != VOS_FTM_MODE &&
!WLAN_IS_EPPING_ENABLED(vos_get_conparam())){
diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h
index 5512e6e33f04..8de7217ad844 100644
--- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h
+++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h
@@ -46,6 +46,8 @@
#define ATH_DBG_DEFAULT 0
+#define RAMDUMP_ADDR 0x8F000000
+#define RAMDUMP_SIZE 0x700000
struct ath_hif_sdio_softc {
struct device *dev;