[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