[kernel] r22029 - in dists/sid/linux/debian: . patches patches/features/all/iwlwifi-debug
Ben Hutchings
benh at moszumanska.debian.org
Tue Nov 4 00:06:12 UTC 2014
Author: benh
Date: Tue Nov 4 00:06:12 2014
New Revision: 22029
Log:
iwlwifi: Backport firmware monitor from 3.17 (Closes: #767088)
Added:
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-add-device-firmware-to-fw-error-dump-file.patch
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-don-t-collect-logs-in-the-interrupt-thread.patch
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-kill-iwl_mvm_fw_error_rxf_dump.patch
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-update-layout-of-firmware-error-dump.patch
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-pcie-add-firmware-monitor-capabilities.patch
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-remove-wrong-comment-about-alignment-in-iwl-fw-error-dump.h.patch
dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-rename-iwl_mvm_fw_error_next_data.patch
Modified:
dists/sid/linux/debian/changelog
dists/sid/linux/debian/patches/series
Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog Mon Nov 3 23:41:19 2014 (r22028)
+++ dists/sid/linux/debian/changelog Tue Nov 4 00:06:12 2014 (r22029)
@@ -158,6 +158,7 @@
* [hppa] Reduce SIGRTMIN from 37 to 32 to behave like other Linux
architectures (Closes: #766635)
* [hppa] udeb: Add many more module packages (Closes: #766793)
+ * iwlwifi: Backport firmware monitor from 3.17 (Closes: #767088)
[ Mauricio Faria de Oliveira ]
* [ppc64el] Disable CONFIG_CMDLINE{,_BOOL} usage for setting consoles
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-add-device-firmware-to-fw-error-dump-file.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-add-device-firmware-to-fw-error-dump-file.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,175 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:20 +0200
+Subject: iwlwifi: add device / firmware to fw-error-dump file
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/06ddbf5adac1fd2a031eade8a92239abfa6db93a
+Bug-Debian: https://bugs.debian.org/767088
+
+This can be useful later for parsing since the parsing may
+differ based on the device's family / bus.
+Also add the human readable version of the firmware.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/iwl-drv.c | 2 ++
+ drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 24 ++++++++++++++++++++++++
+ drivers/net/wireless/iwlwifi/iwl-fw-file.h | 5 +++--
+ drivers/net/wireless/iwlwifi/iwl-fw.h | 3 +++
+ drivers/net/wireless/iwlwifi/mvm/ops.c | 24 +++++++++++++++++++++---
+ 5 files changed, 53 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
+index f2a5c12..2967fce 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
++++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
+@@ -565,6 +565,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
+ }
+
+ drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
++ memcpy(drv->fw.human_readable, ucode->human_readable,
++ sizeof(drv->fw.human_readable));
+ build = le32_to_cpu(ucode->build);
+
+ if (build)
+diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+index 2953ffc..aa0f85e 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
++++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+@@ -74,12 +74,15 @@
+ * @IWL_FW_ERROR_DUMP_RXF:
+ * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
+ * &struct iwl_fw_error_dump_txcmd packets
++ * @IWL_FW_ERROR_DUMP_DEV_FW_INFO: struct %iwl_fw_error_dump_info
++ * info on the device / firmware.
+ */
+ enum iwl_fw_error_dump_type {
+ IWL_FW_ERROR_DUMP_SRAM = 0,
+ IWL_FW_ERROR_DUMP_REG = 1,
+ IWL_FW_ERROR_DUMP_RXF = 2,
+ IWL_FW_ERROR_DUMP_TXCMD = 3,
++ IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4,
+
+ IWL_FW_ERROR_DUMP_MAX,
+ };
+@@ -120,6 +123,27 @@ struct iwl_fw_error_dump_txcmd {
+ u8 data[];
+ } __packed;
+
++enum iwl_fw_error_dump_family {
++ IWL_FW_ERROR_DUMP_FAMILY_7 = 7,
++ IWL_FW_ERROR_DUMP_FAMILY_8 = 8,
++};
++
++/**
++ * struct iwl_fw_error_dump_info - info on the device / firmware
++ * @device_family: the family of the device (7 / 8)
++ * @hw_step: the step of the device
++ * @fw_human_readable: human readable FW version
++ * @dev_human_readable: name of the device
++ * @bus_human_readable: name of the bus used
++ */
++struct iwl_fw_error_dump_info {
++ __le32 device_family;
++ __le32 hw_step;
++ u8 fw_human_readable[FW_VER_HUMAN_READABLE_SZ];
++ u8 dev_human_readable[64];
++ u8 bus_human_readable[8];
++} __packed;
++
+ /**
+ * iwl_mvm_fw_error_next_data - advance fw error dump data pointer
+ * @data: previous data block
+diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+index b45e576..dc1b913 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
++++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+@@ -136,7 +136,8 @@ struct iwl_ucode_tlv {
+ u8 data[0];
+ };
+
+-#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
++#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
++#define FW_VER_HUMAN_READABLE_SZ 64
+
+ struct iwl_tlv_ucode_header {
+ /*
+@@ -147,7 +148,7 @@ struct iwl_tlv_ucode_header {
+ */
+ __le32 zero;
+ __le32 magic;
+- u8 human_readable[64];
++ u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
+ __le32 ver; /* major/minor/API/serial */
+ __le32 build;
+ __le64 ignore;
+diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
+index b1a3332..663a91a 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
++++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
+@@ -65,6 +65,8 @@
+ #include <linux/types.h>
+ #include <net/mac80211.h>
+
++#include "iwl-fw-file.h"
++
+ /**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+@@ -312,6 +314,7 @@ struct iwl_fw {
+ bool mvm_fw;
+
+ struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
++ u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
+ };
+
+ #endif /* __iwl_fw_h__ */
+diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
+index cc2f7de..d2fdd9f 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
+@@ -826,6 +826,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ {
+ struct iwl_fw_error_dump_file *dump_file;
+ struct iwl_fw_error_dump_data *dump_data;
++ struct iwl_fw_error_dump_info *dump_info;
+ u32 file_len;
+ u32 trans_len;
+
+@@ -834,10 +835,11 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ if (mvm->fw_error_dump)
+ return;
+
+- file_len = mvm->fw_error_sram_len +
++ file_len = sizeof(*dump_file) +
++ sizeof(*dump_data) * 3 +
++ mvm->fw_error_sram_len +
+ mvm->fw_error_rxf_len +
+- sizeof(*dump_file) +
+- sizeof(*dump_data) * 2;
++ sizeof(*dump_info);
+
+ trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
+ if (trans_len)
+@@ -852,6 +854,22 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
+ dump_file->file_len = cpu_to_le32(file_len);
+ dump_data = (void *)dump_file->data;
++
++ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO);
++ dump_data->len = cpu_to_le32(sizeof(*dump_info));
++ dump_info = (void *) dump_data->data;
++ dump_info->device_family =
++ mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
++ cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
++ cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
++ memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
++ sizeof(dump_info->fw_human_readable));
++ strncpy(dump_info->dev_human_readable, mvm->cfg->name,
++ sizeof(dump_info->dev_human_readable));
++ strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
++ sizeof(dump_info->bus_human_readable));
++
++ dump_data = iwl_mvm_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
+ dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
+ memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-don-t-collect-logs-in-the-interrupt-thread.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-don-t-collect-logs-in-the-interrupt-thread.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,159 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:24 +0200
+Subject: iwlwifi: mvm: don't collect logs in the interrupt thread
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/78dae98fab85f4cd2d38cfc3474dea6e87e7b53a
+Bug-Debian: https://bugs.debian.org/767088
+
+Instead of reading all the data in the context of the
+interrupt thread, collect the data in the restart flow
+before the actual restart takes place so that the device
+still has all the information.
+Remove iwl_mvm_fw_error_sram_dump and move its content to
+iwl_mvm_fw_error_dump.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 ---
+ drivers/net/wireless/iwlwifi/mvm/ops.c | 31 ++++++++++++-------------------
+ drivers/net/wireless/iwlwifi/mvm/utils.c | 22 ----------------------
+ 3 files changed, 12 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
+index fcc6c29..e084fc6 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
+@@ -586,8 +586,6 @@ struct iwl_mvm {
+ /* -1 for always, 0 for never, >0 for that many times */
+ s8 restart_fw;
+ void *fw_error_dump;
+- void *fw_error_sram;
+- u32 fw_error_sram_len;
+ u32 *fw_error_rxf;
+ u32 fw_error_rxf_len;
+
+@@ -721,7 +719,6 @@ u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
+ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
+-void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm);
+ void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm);
+ #endif
+ u8 first_antenna(u8 mask);
+diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
+index 2910f6d..94506ec 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
+@@ -549,7 +549,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
+
+ kfree(mvm->scan_cmd);
+ vfree(mvm->fw_error_dump);
+- kfree(mvm->fw_error_sram);
+ kfree(mvm->fw_error_rxf);
+ kfree(mvm->mcast_filter_cmd);
+ mvm->mcast_filter_cmd = NULL;
+@@ -827,6 +826,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ struct iwl_fw_error_dump_file *dump_file;
+ struct iwl_fw_error_dump_data *dump_data;
+ struct iwl_fw_error_dump_info *dump_info;
++ const struct fw_img *img;
++ u32 sram_len, sram_ofs;
+ u32 file_len;
+ u32 trans_len;
+
+@@ -835,9 +836,13 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ if (mvm->fw_error_dump)
+ return;
+
++ img = &mvm->fw->img[mvm->cur_ucode];
++ sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
++ sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
++
+ file_len = sizeof(*dump_file) +
+ sizeof(*dump_data) * 3 +
+- mvm->fw_error_sram_len +
++ sram_len +
+ mvm->fw_error_rxf_len +
+ sizeof(*dump_info);
+
+@@ -869,6 +874,8 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
+ sizeof(dump_info->bus_human_readable));
+
++ iwl_mvm_fw_error_rxf_dump(mvm);
++
+ dump_data = iwl_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
+ dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
+@@ -876,23 +883,14 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+
+ dump_data = iwl_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
+- dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
+-
+- /*
+- * No need for lock since at the stage the FW isn't loaded. So it
+- * can't assert - we are the only one who can possibly be accessing
+- * mvm->fw_error_sram right now.
+- */
+- memcpy(dump_data->data, mvm->fw_error_sram, mvm->fw_error_sram_len);
++ dump_data->len = cpu_to_le32(sram_len);
++ iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data,
++ sram_len);
+
+ kfree(mvm->fw_error_rxf);
+ mvm->fw_error_rxf = NULL;
+ mvm->fw_error_rxf_len = 0;
+
+- kfree(mvm->fw_error_sram);
+- mvm->fw_error_sram = NULL;
+- mvm->fw_error_sram_len = 0;
+-
+ if (trans_len) {
+ void *buf = iwl_fw_error_next_data(dump_data);
+ u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
+@@ -910,11 +908,6 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+
+ iwl_mvm_dump_nic_error_log(mvm);
+
+-#ifdef CONFIG_IWLWIFI_DEBUGFS
+- iwl_mvm_fw_error_sram_dump(mvm);
+- iwl_mvm_fw_error_rxf_dump(mvm);
+-#endif
+-
+ iwl_mvm_nic_restart(mvm);
+ }
+
+diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
+index aa9fc77..15db97c 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
++++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
+@@ -520,28 +520,6 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
+ }
+
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+-void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm)
+-{
+- const struct fw_img *img;
+- u32 ofs, sram_len;
+- void *sram;
+-
+- if (!mvm->ucode_loaded || mvm->fw_error_sram || mvm->fw_error_dump)
+- return;
+-
+- img = &mvm->fw->img[mvm->cur_ucode];
+- ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
+- sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
+-
+- sram = kzalloc(sram_len, GFP_ATOMIC);
+- if (!sram)
+- return;
+-
+- iwl_trans_read_mem_bytes(mvm->trans, ofs, sram, sram_len);
+- mvm->fw_error_sram = sram;
+- mvm->fw_error_sram_len = sram_len;
+-}
+-
+ void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm)
+ {
+ int i, reg_val;
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-kill-iwl_mvm_fw_error_rxf_dump.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-kill-iwl_mvm_fw_error_rxf_dump.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,315 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:25 +0200
+Subject: iwlwifi: mvm: kill iwl_mvm_fw_error_rxf_dump
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/655e6d6db21b0c0d411aef9d816816fb68b0496c
+Bug-Debian: https://bugs.debian.org/767088
+
+Its content can move to the caller.
+While at it, move iwl_mvm_fw_error_rxf_dump to caller.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/mvm/mac80211.c | 100 ++++++++++++++++++++++++++++
+ drivers/net/wireless/iwlwifi/mvm/mvm.h | 6 --
+ drivers/net/wireless/iwlwifi/mvm/ops.c | 83 -----------------------
+ drivers/net/wireless/iwlwifi/mvm/utils.c | 43 ------------
+ 4 files changed, 100 insertions(+), 132 deletions(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+index 98556d0..ed10e55 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+@@ -80,6 +80,8 @@
+ #include "fw-api-scan.h"
+ #include "iwl-phy-db.h"
+ #include "testmode.h"
++#include "iwl-fw-error-dump.h"
++#include "iwl-prph.h"
+
+ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
+ {
+@@ -637,6 +639,104 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
+ mvmvif->phy_ctxt = NULL;
+ }
+
++#ifdef CONFIG_IWLWIFI_DEBUGFS
++static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
++{
++ struct iwl_fw_error_dump_file *dump_file;
++ struct iwl_fw_error_dump_data *dump_data;
++ struct iwl_fw_error_dump_info *dump_info;
++ const struct fw_img *img;
++ u32 sram_len, sram_ofs;
++ u32 file_len, rxf_len;
++ unsigned long flags;
++ u32 trans_len;
++ int reg_val;
++
++ lockdep_assert_held(&mvm->mutex);
++
++ if (mvm->fw_error_dump)
++ return;
++
++ img = &mvm->fw->img[mvm->cur_ucode];
++ sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
++ sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
++
++ /* reading buffer size */
++ reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
++ rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
++
++ /* the register holds the value divided by 128 */
++ rxf_len = rxf_len << 7;
++
++ file_len = sizeof(*dump_file) +
++ sizeof(*dump_data) * 3 +
++ sram_len +
++ rxf_len +
++ sizeof(*dump_info);
++
++ trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
++ if (trans_len)
++ file_len += trans_len;
++
++ dump_file = vmalloc(file_len);
++ if (!dump_file)
++ return;
++
++ mvm->fw_error_dump = dump_file;
++
++ dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
++ dump_file->file_len = cpu_to_le32(file_len);
++ dump_data = (void *)dump_file->data;
++
++ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO);
++ dump_data->len = cpu_to_le32(sizeof(*dump_info));
++ dump_info = (void *) dump_data->data;
++ dump_info->device_family =
++ mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
++ cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
++ cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
++ memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
++ sizeof(dump_info->fw_human_readable));
++ strncpy(dump_info->dev_human_readable, mvm->cfg->name,
++ sizeof(dump_info->dev_human_readable));
++ strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
++ sizeof(dump_info->bus_human_readable));
++
++ dump_data = iwl_fw_error_next_data(dump_data);
++ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
++ dump_data->len = cpu_to_le32(rxf_len);
++
++ if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
++ u32 *rxf = (void *)dump_data->data;
++ int i;
++
++ for (i = 0; i < (rxf_len / sizeof(u32)); i++) {
++ iwl_trans_write_prph(mvm->trans,
++ RXF_LD_FENCE_OFFSET_ADDR,
++ i * sizeof(u32));
++ rxf[i] = iwl_trans_read_prph(mvm->trans,
++ RXF_FIFO_RD_FENCE_ADDR);
++ }
++ iwl_trans_release_nic_access(mvm->trans, &flags);
++ }
++
++ dump_data = iwl_fw_error_next_data(dump_data);
++ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
++ dump_data->len = cpu_to_le32(sram_len);
++ iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data,
++ sram_len);
++
++ if (trans_len) {
++ void *buf = iwl_fw_error_next_data(dump_data);
++ u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
++ trans_len);
++ dump_data = (void *)((u8 *)buf + real_trans_len);
++ dump_file->file_len =
++ cpu_to_le32(file_len - trans_len + real_trans_len);
++ }
++}
++#endif
++
+ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
+ {
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
+index e084fc6..e99b7f1 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
+@@ -586,8 +586,6 @@ struct iwl_mvm {
+ /* -1 for always, 0 for never, >0 for that many times */
+ s8 restart_fw;
+ void *fw_error_dump;
+- u32 *fw_error_rxf;
+- u32 fw_error_rxf_len;
+
+ #ifdef CONFIG_IWLWIFI_LEDS
+ struct led_classdev led;
+@@ -717,10 +715,6 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
+ struct ieee80211_tx_rate *r);
+ u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
+ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
+-#ifdef CONFIG_IWLWIFI_DEBUGFS
+-void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
+-void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm);
+-#endif
+ u8 first_antenna(u8 mask);
+ u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
+
+diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
+index 94506ec..172c1d4 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
+@@ -549,7 +549,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
+
+ kfree(mvm->scan_cmd);
+ vfree(mvm->fw_error_dump);
+- kfree(mvm->fw_error_rxf);
+ kfree(mvm->mcast_filter_cmd);
+ mvm->mcast_filter_cmd = NULL;
+
+@@ -820,88 +819,6 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
+ }
+ }
+
+-#ifdef CONFIG_IWLWIFI_DEBUGFS
+-void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+-{
+- struct iwl_fw_error_dump_file *dump_file;
+- struct iwl_fw_error_dump_data *dump_data;
+- struct iwl_fw_error_dump_info *dump_info;
+- const struct fw_img *img;
+- u32 sram_len, sram_ofs;
+- u32 file_len;
+- u32 trans_len;
+-
+- lockdep_assert_held(&mvm->mutex);
+-
+- if (mvm->fw_error_dump)
+- return;
+-
+- img = &mvm->fw->img[mvm->cur_ucode];
+- sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
+- sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
+-
+- file_len = sizeof(*dump_file) +
+- sizeof(*dump_data) * 3 +
+- sram_len +
+- mvm->fw_error_rxf_len +
+- sizeof(*dump_info);
+-
+- trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
+- if (trans_len)
+- file_len += trans_len;
+-
+- dump_file = vmalloc(file_len);
+- if (!dump_file)
+- return;
+-
+- mvm->fw_error_dump = dump_file;
+-
+- dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
+- dump_file->file_len = cpu_to_le32(file_len);
+- dump_data = (void *)dump_file->data;
+-
+- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO);
+- dump_data->len = cpu_to_le32(sizeof(*dump_info));
+- dump_info = (void *) dump_data->data;
+- dump_info->device_family =
+- mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
+- cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
+- cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
+- memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
+- sizeof(dump_info->fw_human_readable));
+- strncpy(dump_info->dev_human_readable, mvm->cfg->name,
+- sizeof(dump_info->dev_human_readable));
+- strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
+- sizeof(dump_info->bus_human_readable));
+-
+- iwl_mvm_fw_error_rxf_dump(mvm);
+-
+- dump_data = iwl_fw_error_next_data(dump_data);
+- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
+- dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
+- memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
+-
+- dump_data = iwl_fw_error_next_data(dump_data);
+- dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
+- dump_data->len = cpu_to_le32(sram_len);
+- iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data,
+- sram_len);
+-
+- kfree(mvm->fw_error_rxf);
+- mvm->fw_error_rxf = NULL;
+- mvm->fw_error_rxf_len = 0;
+-
+- if (trans_len) {
+- void *buf = iwl_fw_error_next_data(dump_data);
+- u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
+- trans_len);
+- dump_data = (void *)((u8 *)buf + real_trans_len);
+- dump_file->file_len =
+- cpu_to_le32(file_len - trans_len + real_trans_len);
+- }
+-}
+-#endif
+-
+ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
+ {
+ struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
+index 15db97c..ac249da 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
++++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
+@@ -519,49 +519,6 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
+ iwl_mvm_dump_umac_error_log(mvm);
+ }
+
+-#ifdef CONFIG_IWLWIFI_DEBUGFS
+-void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm)
+-{
+- int i, reg_val;
+- unsigned long flags;
+-
+- if (!mvm->ucode_loaded || mvm->fw_error_rxf || mvm->fw_error_dump)
+- return;
+-
+- /* reading buffer size */
+- reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
+- mvm->fw_error_rxf_len =
+- (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
+-
+- /* the register holds the value divided by 128 */
+- mvm->fw_error_rxf_len = mvm->fw_error_rxf_len << 7;
+-
+- if (!mvm->fw_error_rxf_len)
+- return;
+-
+- mvm->fw_error_rxf = kzalloc(mvm->fw_error_rxf_len, GFP_ATOMIC);
+- if (!mvm->fw_error_rxf) {
+- mvm->fw_error_rxf_len = 0;
+- return;
+- }
+-
+- if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
+- kfree(mvm->fw_error_rxf);
+- mvm->fw_error_rxf = NULL;
+- mvm->fw_error_rxf_len = 0;
+- return;
+- }
+-
+- for (i = 0; i < (mvm->fw_error_rxf_len / sizeof(u32)); i++) {
+- iwl_trans_write_prph(mvm->trans, RXF_LD_FENCE_OFFSET_ADDR,
+- i * sizeof(u32));
+- mvm->fw_error_rxf[i] =
+- iwl_trans_read_prph(mvm->trans, RXF_FIFO_RD_FENCE_ADDR);
+- }
+- iwl_trans_release_nic_access(mvm->trans, &flags);
+-}
+-#endif
+-
+ /**
+ * iwl_mvm_send_lq_cmd() - Send link quality command
+ * @init: This command is sent as part of station initialization right
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-update-layout-of-firmware-error-dump.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-update-layout-of-firmware-error-dump.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,28 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:26 +0200
+Subject: iwlwifi: mvm: update layout of firmware error dump
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/5bfe6f53283de44855ee45a102210abbfac995f9
+Bug-Debian: https://bugs.debian.org/767088
+
+The memory was not zeroed - fix that. Also update the
+iwl_fw_error_dump_info structure.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/mvm/mac80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+index ed10e55..83ab42a 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+@@ -678,7 +678,7 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ if (trans_len)
+ file_len += trans_len;
+
+- dump_file = vmalloc(file_len);
++ dump_file = vzalloc(file_len);
+ if (!dump_file)
+ return;
+
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-pcie-add-firmware-monitor-capabilities.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-pcie-add-firmware-monitor-capabilities.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,315 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:22 +0200
+Subject: iwlwifi: pcie: add firmware monitor capabilities
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/c2d202017da18ebd6567862bd9a50392970f048f
+Bug-Debian: https://bugs.debian.org/767088
+
+This allows to use the firmware monitor. This capability
+uses a lot of contiguous memory (up to 64MB), so make its
+usage module parameter dependent.
+
+The driver will try to allocate as much contiguous memory
+as possible downgrading its requirements until the
+allocation succeeds.
+
+Dump this data into the fw-error dump file when an error
+happens.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/iwl-drv.c | 4 +
+ drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 18 ++++
+ drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +
+ drivers/net/wireless/iwlwifi/iwl-prph.h | 6 ++
+ drivers/net/wireless/iwlwifi/pcie/internal.h | 7 ++
+ drivers/net/wireless/iwlwifi/pcie/trans.c | 125 ++++++++++++++++++++++-
+ 6 files changed, 158 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
+index 2967fce..32e334a 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
++++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
+@@ -1396,3 +1396,7 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
+ int, S_IRUGO);
+ MODULE_PARM_DESC(power_level,
+ "default power save level (range from 1 - 5, default: 1)");
++
++module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO);
++MODULE_PARM_DESC(fw_monitor,
++ "firmware monitor - to debug FW (default: false - needs lots of memory)");
+diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+index 3584a75..ced5ba9 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
++++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+@@ -76,6 +76,7 @@
+ * &struct iwl_fw_error_dump_txcmd packets
+ * @IWL_FW_ERROR_DUMP_DEV_FW_INFO: struct %iwl_fw_error_dump_info
+ * info on the device / firmware.
++ * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor
+ */
+ enum iwl_fw_error_dump_type {
+ IWL_FW_ERROR_DUMP_SRAM = 0,
+@@ -83,6 +84,7 @@ enum iwl_fw_error_dump_type {
+ IWL_FW_ERROR_DUMP_RXF = 2,
+ IWL_FW_ERROR_DUMP_TXCMD = 3,
+ IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4,
++ IWL_FW_ERROR_DUMP_FW_MONITOR = 5,
+
+ IWL_FW_ERROR_DUMP_MAX,
+ };
+@@ -145,6 +147,22 @@ struct iwl_fw_error_dump_info {
+ } __packed;
+
+ /**
++ * struct iwl_fw_error_fw_mon - FW monitor data
++ * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer
++ * @fw_mon_base_ptr: base pointer of the data
++ * @fw_mon_cycle_cnt: number of wrap arounds
++ * @reserved: for future use
++ * @data: captured data
++ */
++struct iwl_fw_error_fw_mon {
++ __le32 fw_mon_wr_ptr;
++ __le32 fw_mon_base_ptr;
++ __le32 fw_mon_cycle_cnt;
++ __le32 reserved[3];
++ u8 data[];
++} __packed;
++
++/**
+ * iwl_fw_error_next_data - advance fw error dump data pointer
+ * @data: previous data block
+ * Returns: next data block
+diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
+index d051857..f2d39cb 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
++++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
+@@ -103,6 +103,7 @@ enum iwl_disable_11n {
+ * @power_level: power level, default = 1
+ * @debug_level: levels are IWL_DL_*
+ * @ant_coupling: antenna coupling in dB, default = 0
++ * @fw_monitor: allow to use firmware monitor
+ */
+ struct iwl_mod_params {
+ int sw_crypto;
+@@ -120,6 +121,7 @@ struct iwl_mod_params {
+ int ant_coupling;
+ char *nvm_file;
+ bool uapsd_disable;
++ bool fw_monitor;
+ };
+
+ #endif /* #__iwl_modparams_h__ */
+diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
+index 4997e27..47033a3 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
++++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
+@@ -359,4 +359,10 @@ enum secure_load_status_reg {
+ #define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
+ #define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
+
++/* FW monitor */
++#define MON_BUFF_BASE_ADDR (0xa03c3c)
++#define MON_BUFF_END_ADDR (0xa03c40)
++#define MON_BUFF_WRPTR (0xa03c44)
++#define MON_BUFF_CYCLE_CNT (0xa03c48)
++
+ #endif /* __iwl_prph_h__ */
+diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
+index 6c22b23..78f72c3 100644
+--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
++++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
+@@ -260,6 +260,9 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
+ * @wd_timeout: queue watchdog timeout (jiffies)
+ * @reg_lock: protect hw register access
+ * @cmd_in_flight: true when we have a host command in flight
++ * @fw_mon_phys: physical address of the buffer for the firmware monitor
++ * @fw_mon_page: points to the first page of the buffer for the firmware monitor
++ * @fw_mon_size: size of the buffer for the firmware monitor
+ */
+ struct iwl_trans_pcie {
+ struct iwl_rxq rxq;
+@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
+ /*protect hw register */
+ spinlock_t reg_lock;
+ bool cmd_in_flight;
++
++ dma_addr_t fw_mon_phys;
++ struct page *fw_mon_page;
++ u32 fw_mon_size;
+ };
+
+ #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
+diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
+index 788085b..3ffac48 100644
+--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
++++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
+@@ -76,6 +76,68 @@
+ #include "iwl-fw-error-dump.h"
+ #include "internal.h"
+
++static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
++{
++ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
++
++ if (!trans_pcie->fw_mon_page)
++ return;
++
++ dma_unmap_page(trans->dev, trans_pcie->fw_mon_phys,
++ trans_pcie->fw_mon_size, DMA_FROM_DEVICE);
++ __free_pages(trans_pcie->fw_mon_page,
++ get_order(trans_pcie->fw_mon_size));
++ trans_pcie->fw_mon_page = NULL;
++ trans_pcie->fw_mon_phys = 0;
++ trans_pcie->fw_mon_size = 0;
++}
++
++static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
++{
++ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
++ struct page *page;
++ dma_addr_t phys;
++ u32 size;
++ u8 power;
++
++ if (trans_pcie->fw_mon_page) {
++ dma_sync_single_for_device(trans->dev, trans_pcie->fw_mon_phys,
++ trans_pcie->fw_mon_size,
++ DMA_FROM_DEVICE);
++ return;
++ }
++
++ phys = 0;
++ for (power = 26; power >= 11; power--) {
++ int order;
++
++ size = BIT(power);
++ order = get_order(size);
++ page = alloc_pages(__GFP_COMP | __GFP_NOWARN | __GFP_ZERO,
++ order);
++ if (!page)
++ continue;
++
++ phys = dma_map_page(trans->dev, page, 0, PAGE_SIZE << order,
++ DMA_FROM_DEVICE);
++ if (dma_mapping_error(trans->dev, phys)) {
++ __free_pages(page, order);
++ continue;
++ }
++ IWL_INFO(trans,
++ "Allocated 0x%08x bytes (order %d) for firmware monitor.\n",
++ size, order);
++ break;
++ }
++
++ if (!page)
++ return;
++
++ trans_pcie->fw_mon_page = page;
++ trans_pcie->fw_mon_phys = phys;
++ trans_pcie->fw_mon_size = size;
++}
++
+ static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg)
+ {
+ iwl_write32(trans, HEEP_CTRL_WRD_PCIEX_CTRL_REG,
+@@ -675,6 +737,7 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
+ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
+ const struct fw_img *image)
+ {
++ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ int ret = 0;
+ int first_ucode_section;
+
+@@ -733,6 +796,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
+ return ret;
+ }
+
++ /* supported for 7000 only for the moment */
++ if (iwlwifi_mod_params.fw_monitor &&
++ trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
++ iwl_pcie_alloc_fw_monitor(trans);
++
++ if (trans_pcie->fw_mon_size) {
++ iwl_write_prph(trans, MON_BUFF_BASE_ADDR,
++ trans_pcie->fw_mon_phys >> 4);
++ iwl_write_prph(trans, MON_BUFF_END_ADDR,
++ (trans_pcie->fw_mon_phys +
++ trans_pcie->fw_mon_size) >> 4);
++ }
++ }
++
+ /* release CPU reset */
+ if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
+ iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
+@@ -1126,6 +1203,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
+ if (trans_pcie->napi.poll)
+ netif_napi_del(&trans_pcie->napi);
+
++ iwl_pcie_free_fw_monitor(trans);
++
+ kfree(trans);
+ }
+
+@@ -1698,10 +1777,15 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
+ u32 len;
+ int i, ptr;
+
++ len = sizeof(*data) +
++ cmdq->q.n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE);
++
++ if (trans_pcie->fw_mon_page)
++ len += sizeof(*data) + sizeof(struct iwl_fw_error_fw_mon) +
++ trans_pcie->fw_mon_size;
++
+ if (!buf)
+- return sizeof(*data) +
+- cmdq->q.n_window * (sizeof(*txcmd) +
+- TFD_MAX_PAYLOAD_SIZE);
++ return len;
+
+ len = 0;
+ data = buf;
+@@ -1729,7 +1813,40 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
+ spin_unlock_bh(&cmdq->lock);
+
+ data->len = cpu_to_le32(len);
+- return sizeof(*data) + len;
++ len += sizeof(*data);
++
++ if (trans_pcie->fw_mon_page) {
++ struct iwl_fw_error_fw_mon *fw_mon_data;
++
++ data = iwl_fw_error_next_data(data);
++ data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
++ data->len = cpu_to_le32(trans_pcie->fw_mon_size +
++ sizeof(*fw_mon_data));
++ fw_mon_data = (void *)data->data;
++ fw_mon_data->fw_mon_wr_ptr =
++ cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR));
++ fw_mon_data->fw_mon_cycle_cnt =
++ cpu_to_le32(iwl_read_prph(trans, MON_BUFF_CYCLE_CNT));
++ fw_mon_data->fw_mon_base_ptr =
++ cpu_to_le32(iwl_read_prph(trans, MON_BUFF_BASE_ADDR));
++
++ /*
++ * The firmware is now asserted, it won't write anything to
++ * the buffer. CPU can take ownership to fetch the data.
++ * The buffer will be handed back to the device before the
++ * firmware will be restarted.
++ */
++ dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys,
++ trans_pcie->fw_mon_size,
++ DMA_FROM_DEVICE);
++ memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page),
++ trans_pcie->fw_mon_size);
++
++ len += sizeof(*data) + sizeof(*fw_mon_data) +
++ trans_pcie->fw_mon_size;
++ }
++
++ return len;
+ }
+ #else
+ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-remove-wrong-comment-about-alignment-in-iwl-fw-error-dump.h.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-remove-wrong-comment-about-alignment-in-iwl-fw-error-dump.h.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,30 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:23 +0200
+Subject: iwlwifi: remove wrong comment about alignment in iwl-fw-error-dump.h
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/d4849277f92a0bfa08a988545ea527fc8e0c9571
+Bug-Debian: https://bugs.debian.org/767088
+
+The chunks of data do not need to be multipliers of 4 nor
+4-bytes aligned.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+index ced5ba9..9fd860f 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
++++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+@@ -92,8 +92,8 @@ enum iwl_fw_error_dump_type {
+ /**
+ * struct iwl_fw_error_dump_data - data for one type
+ * @type: %enum iwl_fw_error_dump_type
+- * @len: the length starting from %data - must be a multiplier of 4.
+- * @data: the data itself padded to be a multiplier of 4.
++ * @len: the length starting from %data
++ * @data: the data itself
+ */
+ struct iwl_fw_error_dump_data {
+ __le32 type;
Added: dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-rename-iwl_mvm_fw_error_next_data.patch
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/iwlwifi-debug/iwlwifi-rename-iwl_mvm_fw_error_next_data.patch Tue Nov 4 00:06:12 2014 (r22029)
@@ -0,0 +1,62 @@
+From: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+Date: Tue, 28 Oct 2014 08:11:21 +0200
+Subject: iwlwifi: rename iwl_mvm_fw_error_next_data
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/linus/1fa1605648d15d42f350807279b6c6e8d33b6382
+Bug-Debian: https://bugs.debian.org/767088
+
+This is not related to mvm. Rename to iwl_fw_error_next_data.
+
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach at intel.com>
+---
+ drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h | 4 ++--
+ drivers/net/wireless/iwlwifi/mvm/ops.c | 6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+index aa0f85e..3584a75 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
++++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+@@ -145,12 +145,12 @@ struct iwl_fw_error_dump_info {
+ } __packed;
+
+ /**
+- * iwl_mvm_fw_error_next_data - advance fw error dump data pointer
++ * iwl_fw_error_next_data - advance fw error dump data pointer
+ * @data: previous data block
+ * Returns: next data block
+ */
+ static inline struct iwl_fw_error_dump_data *
+-iwl_mvm_fw_error_next_data(struct iwl_fw_error_dump_data *data)
++iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
+ {
+ return (void *)(data->data + le32_to_cpu(data->len));
+ }
+diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
+index d2fdd9f..2910f6d 100644
+--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
+@@ -869,12 +869,12 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
+ sizeof(dump_info->bus_human_readable));
+
+- dump_data = iwl_mvm_fw_error_next_data(dump_data);
++ dump_data = iwl_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
+ dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
+ memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
+
+- dump_data = iwl_mvm_fw_error_next_data(dump_data);
++ dump_data = iwl_fw_error_next_data(dump_data);
+ dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
+ dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
+
+@@ -894,7 +894,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
+ mvm->fw_error_sram_len = 0;
+
+ if (trans_len) {
+- void *buf = iwl_mvm_fw_error_next_data(dump_data);
++ void *buf = iwl_fw_error_next_data(dump_data);
+ u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
+ trans_len);
+ dump_data = (void *)((u8 *)buf + real_trans_len);
Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series Mon Nov 3 23:41:19 2014 (r22028)
+++ dists/sid/linux/debian/patches/series Tue Nov 4 00:06:12 2014 (r22029)
@@ -450,3 +450,10 @@
features/x86/apple-tb/0030-thunderbolt-Use-kcalloc.patch
features/x86/apple-tb/0031-thunderbolt-Clear-hops-before-overwriting.patch
bugfix/parisc/parisc-reduce-sigrtmin-from-37-to-32-to-behave-like-.patch
+features/all/iwlwifi-debug/iwlwifi-add-device-firmware-to-fw-error-dump-file.patch
+features/all/iwlwifi-debug/iwlwifi-rename-iwl_mvm_fw_error_next_data.patch
+features/all/iwlwifi-debug/iwlwifi-pcie-add-firmware-monitor-capabilities.patch
+features/all/iwlwifi-debug/iwlwifi-remove-wrong-comment-about-alignment-in-iwl-fw-error-dump.h.patch
+features/all/iwlwifi-debug/iwlwifi-mvm-don-t-collect-logs-in-the-interrupt-thread.patch
+features/all/iwlwifi-debug/iwlwifi-mvm-kill-iwl_mvm_fw_error_rxf_dump.patch
+features/all/iwlwifi-debug/iwlwifi-mvm-update-layout-of-firmware-error-dump.patch
More information about the Kernel-svn-changes
mailing list