diff options
| author | Sean Lin <seanlin@qca.qualcomm.com> | 2014-06-11 16:41:23 +0800 |
|---|---|---|
| committer | Akash Patel <c_akashp@qca.qualcomm.com> | 2014-06-23 18:20:05 -0700 |
| commit | e2f210d0cd5ed22aa9bd4f5689de120121204613 (patch) | |
| tree | 03296ebc50610fc21ccf5e3820bc1c276d139855 | |
| parent | e5eed42828f905b8945f15621353727269fb4b68 (diff) | |
qcacld: HIF: complete firmware stack dump feature for usb interface.
Dump host driver version, target firmware version and target firmware stack
once occurring firmware crash for usb interface.
Change-Id: Ic55030642b5f7eea165c7438a197a2aa52be70f2
CRs-fixed: 678611
| -rwxr-xr-x | CORE/HDD/src/wlan_hdd_main.c | 7 | ||||
| -rw-r--r-- | CORE/SERVICES/COMMON/ol_if_athvar.h | 1 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.c | 7 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/PCIe/if_pci.h | 19 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/USB/if_usb.c | 7 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/USB/if_usb.h | 18 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/USB/usbdrv.c | 44 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c | 7 | ||||
| -rw-r--r-- | CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h | 1 |
9 files changed, 86 insertions, 25 deletions
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 2ad602b2f4de..4d3ee691eb7a 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -276,10 +276,6 @@ static int hdd_parse_reassoc_command_v1_data(const tANI_U8 *pValue, #if defined (QCA_WIFI_2_0) && \ !defined (QCA_WIFI_ISOC) struct completion wlan_start_comp; -extern void hif_init_adf_ctx(adf_os_device_t adf_ctx, v_VOID_t *hif_sc); -extern int hif_register_driver(void); -extern void hif_unregister_driver(void); -extern void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); #ifdef QCA_WIFI_FTM extern int hdd_ftm_start(hdd_context_t *pHddCtx); extern int hdd_ftm_stop(hdd_context_t *pHddCtx); @@ -11704,6 +11700,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) /* Get the wlan hw/fw version */ hdd_wlan_get_version(pAdapter, NULL, NULL); + + /* pass target_fw_version to HIF layer */ + hif_set_fw_info(hif_sc, pHddCtx->target_fw_version); #else /* Exchange capability info between Host and FW and also get versioning info from FW */ hdd_exchange_version_and_caps(pHddCtx); diff --git a/CORE/SERVICES/COMMON/ol_if_athvar.h b/CORE/SERVICES/COMMON/ol_if_athvar.h index 6518adc7cf0e..e5993250431b 100644 --- a/CORE/SERVICES/COMMON/ol_if_athvar.h +++ b/CORE/SERVICES/COMMON/ol_if_athvar.h @@ -132,6 +132,7 @@ struct ol_softc { struct ol_ath_stats pkt_stats; u_int32_t target_type; /* A_TARGET_TYPE_* */ + u_int32_t target_fw_version; u_int32_t target_version; u_int32_t target_revision; u_int8_t crm_version_string[64]; /* store pHalStartRsp->startRspParams.wcnssCrmVersionString */ diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 713e808e5263..50e2f94e829a 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -1987,6 +1987,7 @@ void hif_unregister_driver(void) #endif } +/* Function to set the TXRX handle in the ol_sc context */ void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle) { struct ol_softc *sc = (struct ol_softc *)ol_sc; @@ -2011,6 +2012,7 @@ void hif_disable_isr(void *ol_sc) tasklet_kill(&hif_sc->intr_tq); } +/* Function to reset SoC */ void hif_reset_soc(void *ol_sc) { struct ol_softc *scn = (struct ol_softc *)ol_sc; @@ -2070,3 +2072,8 @@ void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision) *version = ((struct ol_softc *)ol_sc)->target_version; *revision = ((struct ol_softc *)ol_sc)->target_revision; } + +void hif_set_fw_info(void *ol_sc, u32 target_fw_version) +{ + ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; +} diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.h b/CORE/SERVICES/HIF/PCIe/if_pci.h index 657a0e32e414..899686081460 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.h +++ b/CORE/SERVICES/HIF/PCIe/if_pci.h @@ -111,19 +111,9 @@ irqreturn_t HIF_fw_interrupt_handler(int irq, void *arg); */ adf_os_size_t initBufferCount(adf_os_size_t maxSize); -/* Function to set the TXRX handle in the ol_sc context */ -void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); -void hif_disable_isr(void *ol_sc); - -/* Function to reset SoC */ -void hif_reset_soc(void *ol_sc); - /* Function to disable ASPM */ void hif_disable_aspm(void); -void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc); -void hif_deinit_adf_ctx(void *ol_sc); - void hif_pci_save_htc_htt_config_endpoint(int htc_endpoint); #ifndef REMOVE_PKT_LOG @@ -135,7 +125,16 @@ int hif_pci_check_fw_reg(struct hif_pci_softc *sc); int hif_pci_check_soc_status(struct hif_pci_softc *sc); void dump_CE_debug_register(struct hif_pci_softc *sc); +/*These functions are exposed to HDD*/ +int hif_register_driver(void); +void hif_unregister_driver(void); +void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc); +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); +void hif_disable_isr(void *ol_sc); +void hif_reset_soc(void *ol_sc); +void hif_deinit_adf_ctx(void *ol_sc); void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); +void hif_set_fw_info(void *ol_sc, u32 target_fw_version); /* * A firmware interrupt to the Host is indicated by the diff --git a/CORE/SERVICES/HIF/USB/if_usb.c b/CORE/SERVICES/HIF/USB/if_usb.c index 48be9e824d67..b86156059535 100644 --- a/CORE/SERVICES/HIF/USB/if_usb.c +++ b/CORE/SERVICES/HIF/USB/if_usb.c @@ -445,6 +445,7 @@ void hif_unregister_driver(void) } } +/* Function to set the TXRX handle in the ol_sc context */ void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle) { struct ol_softc *sc = (struct ol_softc *)ol_sc; @@ -456,6 +457,7 @@ void hif_disable_isr(void *ol_sc) /* TODO */ } +/* Function to reset SoC */ void hif_reset_soc(void *ol_sc) { /* TODO */ @@ -467,4 +469,9 @@ void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision) /* Chip version should be supported, set to 0 for now */ *revision = 0; } + +void hif_set_fw_info(void *ol_sc, u32 target_fw_version) +{ + ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; +} MODULE_LICENSE("Dual BSD/GPL"); diff --git a/CORE/SERVICES/HIF/USB/if_usb.h b/CORE/SERVICES/HIF/USB/if_usb.h index 27fa2cd2f55d..a197f6238b2f 100644 --- a/CORE/SERVICES/HIF/USB/if_usb.h +++ b/CORE/SERVICES/HIF/USB/if_usb.h @@ -89,18 +89,20 @@ static inline int athdiag_procfs_init(void *scn) { return 0; } static inline void athdiag_procfs_remove(void) { return; } #endif -/* Function to set the TXRX handle in the ol_sc context */ -void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); -void hif_disable_isr(void *ol_sc); -void hif_reset_soc(void *ol_sc); -void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc); -void hif_deinit_adf_ctx(void *ol_sc); - #ifndef REMOVE_PKT_LOG extern int pktlogmod_init(void *context); extern void pktlogmod_exit(void *context); #endif -void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); +/*These functions are exposed to HDD*/ +int hif_register_driver(void); +void hif_unregister_driver(void); +void hif_init_adf_ctx(adf_os_device_t adf_dev, void *ol_sc); +void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle); +void hif_disable_isr(void *ol_sc); +void hif_reset_soc(void *ol_sc); +void hif_deinit_adf_ctx(void *ol_sc); +void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision); +void hif_set_fw_info(void *ol_sc, u32 target_fw_version); #endif /* __ATH_USB_H__ */ diff --git a/CORE/SERVICES/HIF/USB/usbdrv.c b/CORE/SERVICES/HIF/USB/usbdrv.c index 986c88f8ef35..4de4ff6a7319 100644 --- a/CORE/SERVICES/HIF/USB/usbdrv.c +++ b/CORE/SERVICES/HIF/USB/usbdrv.c @@ -39,6 +39,8 @@ #include "a_usb_defs.h" #include "htc.h" #include "htc_packet.h" +#include "qwlan_version.h" +#include "if_usb.h" #define IS_BULK_EP(attr) (((attr) & 3) == 0x02) #define IS_INT_EP(attr) (((attr) & 3) == 0x03) @@ -978,6 +980,11 @@ void usb_hif_io_comp_work(struct work_struct *work) A_UINT32 *reg; A_UINT32 len, i; static A_UINT32 assert_pattern = 0x0000c600; + static A_UINT32 reg_pattern = 0x0000d600; + static A_UINT32 regend_pattern = 0x0000e600; + A_UINT32 start_addr = 0; + static A_UINT32 stack_dumping = 0; + A_UINT32 MSPId = 0, mSPId = 0, SIId = 0, CRMId = 0; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+%s\n", __func__)); device = pipe->device; @@ -1007,10 +1014,41 @@ void usb_hif_io_comp_work(struct work_struct *work) buf)); adf_nbuf_peek_header(buf, &data, &len); if (!memcmp(data, &assert_pattern, sizeof(assert_pattern))) { - printk("Firmware crash detected... len %d\n", len); + MSPId = (device->sc->ol_sc->target_fw_version & 0xf0000000) >> 28; + mSPId = (device->sc->ol_sc->target_fw_version & 0xf000000) >> 24; + SIId = (device->sc->ol_sc->target_fw_version & 0xf00000) >> 20; + CRMId = device->sc->ol_sc->target_fw_version & 0x7fff; + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Firmware crash detected...\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Host SW version: %s\n", QWLAN_VERSIONSTR)); + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("FW version: %d.%d.%d.%d", MSPId, mSPId, SIId, CRMId)); reg = (A_UINT32 *) (data+4); - for (i = 0; i < 60; i++, reg++) { - printk("[%02d] : 0x%08X\n", i, *reg); + for (i = 0; i < 60; reg++, i++ ) { + if (i%4 == 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("%2d: ", i)); + } + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("0x%08x ", *reg)); + } + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("\n")); + dev_kfree_skb(buf); + } else if (!memcmp(data, ®_pattern, sizeof(reg_pattern))) { + reg = (A_UINT32 *) (data+4); + start_addr = *reg++; + if(stack_dumping == 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("Firmware stack dump:")); + stack_dumping = 1; + } + for (i = 0; i < (len>>2)-2; reg++, i++ ) { + if (*reg == regend_pattern && (i == (len>>2)-3)) { + stack_dumping = 0; + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("\n")); + break; + } + if (i%4 == 0) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("\n")); + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("0x%08X: ", start_addr + (i << 2))); + } + AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("0x%08X ", *reg)); } dev_kfree_skb(buf); } else { diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c index 9484cd060abc..9f674a066066 100644 --- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c +++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.c @@ -296,6 +296,7 @@ void hif_deinit_adf_ctx(void *ol_sc) sc->adf_dev = NULL; } +/* Function to set the TXRX handle in the ol_sc context */ void hif_init_pdev_txrx_handle(void *ol_sc, void *txrx_handle) { struct ol_softc *sc = (struct ol_softc *)ol_sc; @@ -321,6 +322,7 @@ HIFCancelDeferredTargetSleep(HIF_DEVICE *hif_device) } +/* Function to reset SoC */ void hif_reset_soc(void *ol_sc) { ENTER("- dummy function!"); @@ -332,3 +334,8 @@ void hif_get_hw_info(void *ol_sc, u32 *version, u32 *revision) /* Chip revision should be supported, set to 0 for now */ *revision = 0; } + +void hif_set_fw_info(void *ol_sc, u32 target_fw_version) +{ + ((struct ol_softc *)ol_sc)->target_fw_version = target_fw_version; +} diff --git a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h index d4847cc8b076..d326a919882e 100644 --- a/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h +++ b/CORE/SERVICES/HIF/sdio/linux/if_ath_sdio.h @@ -98,5 +98,6 @@ void hif_register_tbl_attach(u32 hif_type); 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); #endif /* __IF_ATH_SDIO_H__*/ |
