summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/mvm/debugfs.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-03-18 21:15:06 +0200
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-03-18 21:15:06 +0200
commit1bd3cbc1a0e9ed977a6bd470c5bc7bd36fd87e26 (patch)
treee630bfe41212778b8358c86f6d603fb5a90546ec /drivers/net/wireless/iwlwifi/mvm/debugfs.c
parent8bd22e7bb0b02c24b3c9997670bbb65e0e0a7371 (diff)
downloadlinux-1bd3cbc1a0e9ed977a6bd470c5bc7bd36fd87e26.tar.gz
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/debugfs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 21ef8daede05..cf1fa498e53e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -65,6 +65,7 @@
#include "iwl-io.h"
#include "iwl-prph.h"
#include "debugfs.h"
+#include "fw-error-dump.h"
static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
@@ -117,6 +118,51 @@ static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf,
return ret;
}
+static int iwl_dbgfs_fw_error_dump_open(struct inode *inode, struct file *file)
+{
+ struct iwl_mvm *mvm = inode->i_private;
+ int ret;
+
+ if (!mvm)
+ return -EINVAL;
+
+ mutex_lock(&mvm->mutex);
+ if (!mvm->fw_error_dump) {
+ ret = -ENODATA;
+ goto out;
+ }
+
+ file->private_data = mvm->fw_error_dump;
+ mvm->fw_error_dump = NULL;
+ kfree(mvm->fw_error_sram);
+ mvm->fw_error_sram = NULL;
+ mvm->fw_error_sram_len = 0;
+ ret = 0;
+
+out:
+ mutex_unlock(&mvm->mutex);
+ return ret;
+}
+
+static ssize_t iwl_dbgfs_fw_error_dump_read(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct iwl_fw_error_dump_file *dump_file = file->private_data;
+
+ return simple_read_from_buffer(user_buf, count, ppos,
+ dump_file,
+ le32_to_cpu(dump_file->file_len));
+}
+
+static int iwl_dbgfs_fw_error_dump_release(struct inode *inode,
+ struct file *file)
+{
+ vfree(file->private_data);
+
+ return 0;
+}
+
static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1042,6 +1088,12 @@ MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
+static const struct file_operations iwl_dbgfs_fw_error_dump_ops = {
+ .open = iwl_dbgfs_fw_error_dump_open,
+ .read = iwl_dbgfs_fw_error_dump_read,
+ .release = iwl_dbgfs_fw_error_dump_release,
+};
+
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
@@ -1064,6 +1116,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
+ MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)