iwlwifi: Backport firmware monitor from 3.17 (Closes: #767088)
svn path=/dists/sid/linux/; revision=22029
This commit is contained in:
parent
6692d97e08
commit
78038d0e59
|
@ -158,6 +158,7 @@ linux (3.16.7-1) UNRELEASED; urgency=medium
|
|||
* [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
|
||||
|
|
175
debian/patches/features/all/iwlwifi-debug/iwlwifi-add-device-firmware-to-fw-error-dump-file.patch
vendored
Normal file
175
debian/patches/features/all/iwlwifi-debug/iwlwifi-add-device-firmware-to-fw-error-dump-file.patch
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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);
|
|
@ -0,0 +1,159 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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;
|
315
debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-kill-iwl_mvm_fw_error_rxf_dump.patch
vendored
Normal file
315
debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-kill-iwl_mvm_fw_error_rxf_dump.patch
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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
|
28
debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-update-layout-of-firmware-error-dump.patch
vendored
Normal file
28
debian/patches/features/all/iwlwifi-debug/iwlwifi-mvm-update-layout-of-firmware-error-dump.patch
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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;
|
||||
|
315
debian/patches/features/all/iwlwifi-debug/iwlwifi-pcie-add-firmware-monitor-capabilities.patch
vendored
Normal file
315
debian/patches/features/all/iwlwifi-debug/iwlwifi-pcie-add-firmware-monitor-capabilities.patch
vendored
Normal file
|
@ -0,0 +1,315 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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,
|
|
@ -0,0 +1,30 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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;
|
62
debian/patches/features/all/iwlwifi-debug/iwlwifi-rename-iwl_mvm_fw_error_next_data.patch
vendored
Normal file
62
debian/patches/features/all/iwlwifi-debug/iwlwifi-rename-iwl_mvm_fw_error_next_data.patch
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
From: Emmanuel Grumbach <emmanuel.grumbach@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@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);
|
|
@ -450,3 +450,10 @@ features/x86/apple-tb/0029-thunderbolt-Correct-the-size-argument-to-devm_kzallo.
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue