summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kvalo@qca.qualcomm.com>2011-10-30 21:16:41 +0200
committerKalle Valo <kvalo@qca.qualcomm.com>2011-11-11 12:58:59 +0200
commit6250aac6dfc01a0e3e02a8e1eef41d7fbfedb6c7 (patch)
tree7940206ded04fd6d1761f97c4e3b72982c0cb4e1
parent68469341f32b566481bfccb776ee03146b63bae5 (diff)
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>
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.c69
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c55
3 files changed, 61 insertions, 64 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 1ac0dd1a035..95aed7d0fab 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -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);
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c
index 309be9823e0..e57da35e59f 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.c
+++ b/drivers/net/wireless/ath/ath6kl/hif.c
@@ -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 */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 237b73c6f42..3f1f2547d14 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -298,61 +298,6 @@ out:
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;