Skip to content

Commit

Permalink
ath6kl: print firmware crashes always
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kalle Valo committed Nov 11, 2011
1 parent 6846934 commit 6250aac
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 64 deletions.
1 change: 0 additions & 1 deletion drivers/net/wireless/ath/ath6kl/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,6 @@ void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid);
void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
u8 win_sz);
void ath6kl_wakeup_event(void *dev);
void ath6kl_target_failure(struct ath6kl *ar);

void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
bool wait_fot_compltn, bool cold_reset);
Expand Down
69 changes: 61 additions & 8 deletions drivers/net/wireless/ath/ath6kl/hif.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
55 changes: 0 additions & 55 deletions drivers/net/wireless/ath/ath6kl/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,61 +298,6 @@ static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
return status;
}

#define REG_DUMP_COUNT_AR6003 60
#define REGISTER_DUMP_LEN_MAX 60

static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
{
u32 address;
u32 regdump_loc = 0;
int status;
u32 regdump_val[REGISTER_DUMP_LEN_MAX];
u32 i;

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 */
status = ath6kl_diag_read32(ar, address, &regdump_loc);

if (status || !regdump_loc) {
ath6kl_err("failed to get ptr to register dump area\n");
return;
}

ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
regdump_loc);
regdump_loc = TARG_VTOP(ar->target_type, regdump_loc);

/* fetch register dump data */
status = ath6kl_diag_read(ar, regdump_loc, (u8 *)&regdump_val[0],
REG_DUMP_COUNT_AR6003 * (sizeof(u32)));

if (status) {
ath6kl_err("failed to get register dump\n");
return;
}
ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n");

for (i = 0; i < REG_DUMP_COUNT_AR6003; i++)
ath6kl_dbg(ATH6KL_DBG_TRC, " %d : 0x%8.8X\n",
i, regdump_val[i]);

}

void ath6kl_target_failure(struct ath6kl *ar)
{
ath6kl_err("target asserted\n");

/* try dumping target assertion information (if any) */
ath6kl_dump_target_assert_info(ar);

}

static int ath6kl_target_config_wlan_params(struct ath6kl *ar, int idx)
{
int status = 0;
Expand Down

0 comments on commit 6250aac

Please sign in to comment.