ath6kl: print firmware crashes always

Currently firmware crash dump is printed only if debug is enabled.
Change it so that the crash dump is always printed.

Also move the code from init.c to hif.c.

Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
Kalle Valo
2011-10-30 21:16:41 +02:00
parent 68469341f3
commit 6250aac6df
3 changed files with 61 additions and 64 deletions

View File

@@ -59,26 +59,79 @@ int ath6kl_hif_rw_comp_handler(void *context, int status)
return 0;
}
#define REG_DUMP_COUNT_AR6003 60
#define REGISTER_DUMP_LEN_MAX 60
static void ath6kl_hif_dump_fw_crash(struct ath6kl *ar)
{
__le32 regdump_val[REGISTER_DUMP_LEN_MAX];
u32 i, address, regdump_addr = 0;
int ret;
if (ar->target_type != TARGET_TYPE_AR6003)
return;
/* the reg dump pointer is copied to the host interest area */
address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
address = TARG_VTOP(ar->target_type, address);
/* read RAM location through diagnostic window */
ret = ath6kl_diag_read32(ar, address, &regdump_addr);
if (ret || !regdump_addr) {
ath6kl_warn("failed to get ptr to register dump area: %d\n",
ret);
return;
}
ath6kl_dbg(ATH6KL_DBG_IRQ, "register dump data address 0x%x\n",
regdump_addr);
regdump_addr = TARG_VTOP(ar->target_type, regdump_addr);
/* fetch register dump data */
ret = ath6kl_diag_read(ar, regdump_addr, (u8 *)&regdump_val[0],
REG_DUMP_COUNT_AR6003 * (sizeof(u32)));
if (ret) {
ath6kl_warn("failed to get register dump: %d\n", ret);
return;
}
ath6kl_info("crash dump:\n");
ath6kl_info("hw 0x%x fw %s\n", ar->wiphy->hw_version,
ar->wiphy->fw_version);
BUILD_BUG_ON(REG_DUMP_COUNT_AR6003 % 4);
for (i = 0; i < REG_DUMP_COUNT_AR6003 / 4; i++) {
ath6kl_info("%d: 0x%8.8x 0x%8.8x 0x%8.8x 0x%8.8x\n",
4 * i,
le32_to_cpu(regdump_val[i]),
le32_to_cpu(regdump_val[i + 1]),
le32_to_cpu(regdump_val[i + 2]),
le32_to_cpu(regdump_val[i + 3]));
}
}
static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev)
{
u32 dummy;
int status;
int ret;
ath6kl_err("target debug interrupt\n");
ath6kl_target_failure(dev->ar);
ath6kl_warn("firmware crashed\n");
/*
* read counter to clear the interrupt, the debug error interrupt is
* counter 0.
*/
status = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
ret = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
(u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC);
if (status)
WARN_ON(1);
if (ret)
ath6kl_warn("Failed to clear debug interrupt: %d\n", ret);
return status;
ath6kl_hif_dump_fw_crash(dev->ar);
return ret;
}
/* mailbox recv message polling */