summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath10k/pci.c
diff options
context:
space:
mode:
authorBen Greear <greearb@candelatech.com>2014-08-25 08:37:32 +0300
committerKalle Valo <kvalo@qca.qualcomm.com>2014-08-25 11:23:24 +0300
commit384914b2e5566dfce25f3f38d992708a9ef6f51b (patch)
treeea8a24b4201fb97cf562fd2c6f9e8e87d5ab9ba0 /drivers/net/wireless/ath/ath10k/pci.c
parent3d29a3e04298e3883625c677f62f7f1e634eec10 (diff)
downloadlwn-384914b2e5566dfce25f3f38d992708a9ef6f51b.tar.gz
lwn-384914b2e5566dfce25f3f38d992708a9ef6f51b.zip
ath10k: provide firmware crash info via debugfs
Store the firmware registers and other relevant data to a firmware crash dump file and provide it to user-space via debugfs. Should help with figuring out why the firmware crashed. kvalo: remove dbglog support, rework and refactor the code to avoid ifdefs and otherwise simplify it as well Signed-off-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/pci.c')
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index b4ae4bb3fc09..36c4f4130027 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -832,16 +832,13 @@ static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl);
}
-static void ath10k_pci_hif_dump_area(struct ath10k *ar)
+static void ath10k_pci_dump_registers(struct ath10k *ar,
+ struct ath10k_fw_crash_data *crash_data)
{
- u32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {};
+ u32 i, reg_dump_values[REG_DUMP_COUNT_QCA988X] = {};
int ret;
- u32 i;
- ath10k_err("firmware crashed!\n");
- ath10k_err("hardware name %s version 0x%x\n",
- ar->hw_params.name, ar->target_version);
- ath10k_err("firmware version: %s\n", ar->hw->wiphy->fw_version);
+ lockdep_assert_held(&ar->data_lock);
ret = ath10k_pci_diag_read_hi(ar, &reg_dump_values[0],
hi_failure_state,
@@ -862,6 +859,38 @@ static void ath10k_pci_hif_dump_area(struct ath10k *ar)
reg_dump_values[i + 2],
reg_dump_values[i + 3]);
+ /* crash_data is in little endian */
+ for (i = 0; i < REG_DUMP_COUNT_QCA988X; i++)
+ crash_data->registers[i] = cpu_to_le32(reg_dump_values[i]);
+}
+
+static void ath10k_pci_hif_dump_area(struct ath10k *ar)
+{
+ struct ath10k_fw_crash_data *crash_data;
+ char uuid[50];
+
+ spin_lock_bh(&ar->data_lock);
+
+ crash_data = ath10k_debug_get_new_fw_crash_data(ar);
+
+ if (crash_data)
+ scnprintf(uuid, sizeof(uuid), "%pUl", &crash_data->uuid);
+ else
+ scnprintf(uuid, sizeof(uuid), "n/a");
+
+ ath10k_err("firmware crashed! (uuid %s)\n", uuid);
+ ath10k_err("hardware name %s version 0x%x\n",
+ ar->hw_params.name, ar->target_version);
+ ath10k_err("firmware version: %s\n", ar->hw->wiphy->fw_version);
+
+ if (!crash_data)
+ goto exit;
+
+ ath10k_pci_dump_registers(ar, crash_data);
+
+exit:
+ spin_unlock_bh(&ar->data_lock);
+
queue_work(ar->workqueue, &ar->restart_work);
}