aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/mvm/utils.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-03-18 15:15:06 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-03-18 15:15:06 -0400
commit1bd3cbc1a0e9ed977a6bd470c5bc7bd36fd87e26 (patch)
treee630bfe41212778b8358c86f6d603fb5a90546ec /drivers/net/wireless/iwlwifi/mvm/utils.c
parent8bd22e7bb0b02c24b3c9997670bbb65e0e0a7371 (diff)
iwlwifi: mvm: send udev event upon firmware error to dump logs
When the firmware asserts, the driver will dump the firmware state to an internal buffer. This buffer is kept aside until it is dumped through debugfs. Once an external application fetched the data, the buffer is freed and a new buffer can be allocated in case another assert occurs. A udev event is sent to trigger an external application. A simple rule like: DRIVER=="iwlwifi", ACTION=="change", RUN+="/sbin/dump_sram.sh" can fetch the data from debugfs. Here is my dump_sram.sh: phyname=$(basename ${DEVPATH}) date=$(date +%F_%H_%M) filename=/var/log/iwl-sram-${phyname}-${date}.bin cat /sys/kernel/debug/ieee80211/${phyname}/iwlwifi/iwlmvm/fw_error_dump > ${filename} The current SRAM size is 80KB so, currently: $ ls -lh iwl-sram-phy0-2014-03-16_13_14.bin -rw-r--r-- 1 emmanuel emmanuel 81K Mar 16 13:15 iwl-sram-phy0-2014-03-16_13_14.bin and after compression: $ ls -lh iwl-sram-phy0-2014-03-16_13_14.bin.xz -rw-r--r-- 1 emmanuel emmanuel 13K Mar 16 13:15 iwl-sram-phy0-2014-03-16_13_14.bin.xz Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/utils.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index bbfe529d7b64..e9de033d6b9e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -516,33 +516,26 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
516 iwl_mvm_dump_umac_error_log(mvm); 516 iwl_mvm_dump_umac_error_log(mvm);
517} 517}
518 518
519void iwl_mvm_dump_sram(struct iwl_mvm *mvm) 519void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm)
520{ 520{
521 const struct fw_img *img; 521 const struct fw_img *img;
522 int ofs, len = 0; 522 u32 ofs, sram_len;
523 int i; 523 void *sram;
524 __le32 *buf;
525 524
526 if (!mvm->ucode_loaded) 525 if (!mvm->ucode_loaded || mvm->fw_error_sram)
527 return; 526 return;
528 527
529 img = &mvm->fw->img[mvm->cur_ucode]; 528 img = &mvm->fw->img[mvm->cur_ucode];
530 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 529 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
531 len = img->sec[IWL_UCODE_SECTION_DATA].len; 530 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
532 531
533 buf = kzalloc(len, GFP_ATOMIC); 532 sram = kzalloc(sram_len, GFP_ATOMIC);
534 if (!buf) 533 if (!sram)
535 return; 534 return;
536 535
537 iwl_trans_read_mem_bytes(mvm->trans, ofs, buf, len); 536 iwl_trans_read_mem_bytes(mvm->trans, ofs, sram, sram_len);
538 len = len >> 2; 537 mvm->fw_error_sram = sram;
539 for (i = 0; i < len; i++) { 538 mvm->fw_error_sram_len = sram_len;
540 IWL_ERR(mvm, "0x%08X\n", le32_to_cpu(buf[i]));
541 /* Add a small delay to let syslog catch up */
542 udelay(10);
543 }
544
545 kfree(buf);
546} 539}
547 540
548/** 541/**