diff options
| author | zhangq <zhangq@qti.qualcomm.com> | 2016-03-30 11:23:32 +0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-12 14:36:53 +0530 |
| commit | 41c48b8b73b50fd040c052ef848b5e9911daf5dc (patch) | |
| tree | 79f2e92025d3bc05efbb57c1cb3f9d67834929b3 | |
| parent | 92cf5477804f13ba2795d9bc0d3decf81dff924c (diff) | |
qcacld-2.0: Add self_recover for SDIO
In scenario such as AXI error, firmware will enter an un-recoverable
status. Cold reset is needed when that happens.
Firmware will set FW_IND_HELPER flag when it enters an un-recoverable
status. Host will check this flag when target asserts, If this is set
and self-recovery is enabled, host will start the self-recovery progress.
Change-Id: Ic15578fbbcfe8975096085c4a13abdd509d429e4
CRs-Fixed: 996500
| -rw-r--r-- | CORE/SERVICES/BMI/ol_fw.c | 14 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c | 41 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h | 1 |
3 files changed, 54 insertions, 2 deletions
diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index e1030d5ad3d9..151208a1784e 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -1160,7 +1160,7 @@ void ol_schedule_ramdump_work(struct ol_softc *scn) static void fw_indication_work_handler(struct work_struct *fw_indication) { -#if !defined(HIF_SDIO) +#ifndef HIF_USB struct device *dev = NULL; if (ramdump_scn && ramdump_scn->adf_dev @@ -1414,7 +1414,7 @@ void ol_target_failure(void *instance, A_STATUS status) struct ol_softc *scn = (struct ol_softc *)instance; void *vos_context = vos_get_global_context(VOS_MODULE_ID_WDA, NULL); tp_wma_handle wma = vos_get_context(VOS_MODULE_ID_WDA, vos_context); -#ifdef HIF_PCI +#ifndef HIF_USB int ret; #endif @@ -1475,6 +1475,16 @@ void ol_target_failure(void *instance, A_STATUS status) } #endif +#ifdef HIF_SDIO + ret = hif_sdio_check_fw_reg(scn); + if (0 == ret) { + if (scn->enable_self_recovery) { + ol_schedule_fw_indication_work(scn); + return; + } + } +#endif + printk("XXX TARGET ASSERTED XXX\n"); if (__ol_target_failure(scn, wma)) diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c index 7710a9b4faf9..602adf59432a 100644 --- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c +++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c @@ -49,6 +49,7 @@ #include "vos_sched.h" #include "regtable.h" #include "wlan_hdd_power.h" +#include "targaddrs.h" #ifndef REMOVE_PKT_LOG #include "ol_txrx_types.h" @@ -64,6 +65,12 @@ #endif /* CONFIG_PM */ #endif /* ATH_BUS_PM */ +#ifndef offsetof +#define offsetof(type, field) ((adf_os_size_t)(&((type *)0)->field)) +#endif + +#define FW_IND_HELPER 0x8000 + #ifndef REMOVE_PKT_LOG struct ol_pl_os_dep_funcs *g_ol_pl_os_dep_funcs = NULL; #endif @@ -482,3 +489,37 @@ void hif_set_fw_info(void *ol_sc, u32 target_fw_version) { ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; } + +/** + * hif_sdio_check_fw_reg() - Check wether a self recovery is needed + * @ol_sc: os layser software context + * + * For scenario such as AXI error, cold reset is needed to recover FW. + * FW will set FW_IND_HELPER in such a scenario. + * + */ +int hif_sdio_check_fw_reg(void * ol_sc) +{ + int ret = 1; + unsigned int addr = 0; + unsigned int fw_indication = 0; + struct ol_softc *scn = (struct ol_softc *) ol_sc; + + addr = host_interest_item_address(scn->target_type, + offsetof(struct host_interest_s, + hi_option_flag2)); + + if (HIFDiagReadMem(scn->hif_hdl, addr, + (unsigned char *)&fw_indication, + 4) != A_OK) { + printk("%s Get fw indication failed\n", __func__); + return -ENOENT; + } + + printk("%s: fw indication is 0x%x.\n", __func__, fw_indication); + + if (fw_indication & FW_IND_HELPER) + ret = 0; + + return ret; +} diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h index dfbbbc7d7ad9..391658b5091f 100644 --- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h +++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h @@ -107,4 +107,5 @@ void target_register_tbl_attach(u32 target_type); void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); void hif_set_fw_info(void *ol_sc, u32 target_fw_version); +int hif_sdio_check_fw_reg(void * ol_sc); #endif /* __IF_ATH_SDIO_H__*/ |
