2018-04-22 08:27:57

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 00/12] iwlwifi: updates intended for v4.18 2018-04-22

From: Luca Coelho <[email protected]>

Hi,

Here's the second batch of patches intended for 4.18. Normal
development work this time. The patches include these changes:

* Some preparations for new hardware;
* A workaround to rescan the bus for the rare situation when older
devices become irresponsive,
* Hardening of the firmware loading code to avoid issues with
corrupted files;
* A few clean-ups and bugfixes.

As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.

Please review.

Cheers,
Luca.


Eliad Peller (2):
iwlwifi: pcie: allow sending pre-built A-MSDUs
iwlwifi: mvm: set wakeup filters for wowlan "any" configuration

Golan Ben Ami (2):
iwlwifi: allow different csr flags for different device families
iwlwifi: support new csr addresses for hw address

Golan Ben-Ami (1):
iwlwifi: introduce Image Loader (IML) - new firmware image

Johannes Berg (1):
iwlwifi: mvm: move skb padding reservation earlier

Luca Coelho (5):
iwlwifi: cfg: remove unnecessary cfg data in non-dvm devices
iwlwifi: fw: harden page loading code
iwlwifi: fw: combine loading of last page block into main copy loop
iwlwifi: pcie: remove non-responsive device
iwlwifi: make bitfield a u32 instead of u16

Sara Sharon (1):
iwlwifi: mvm: remove check for non low latency TIDs

drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 8 +-
drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 13 +-
.../net/wireless/intel/iwlwifi/cfg/22000.c | 10 +-
drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 8 +-
drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 19 ++-
drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 12 +-
drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 10 +-
drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 6 +-
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 +
drivers/net/wireless/intel/iwlwifi/fw/img.h | 6 +
.../net/wireless/intel/iwlwifi/fw/paging.c | 78 ++++++----
.../net/wireless/intel/iwlwifi/iwl-config.h | 87 ++++++++++-
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 28 +---
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 14 ++
.../wireless/intel/iwlwifi/iwl-eeprom-read.c | 8 +-
.../wireless/intel/iwlwifi/iwl-modparams.h | 2 +
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 14 +-
.../net/wireless/intel/iwlwifi/iwl-trans.h | 5 +
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 15 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 +
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 20 +--
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 1 -
.../net/wireless/intel/iwlwifi/mvm/utils.c | 8 +-
.../wireless/intel/iwlwifi/pcie/internal.h | 5 +
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 +-
.../wireless/intel/iwlwifi/pcie/trans-gen2.c | 15 +-
.../net/wireless/intel/iwlwifi/pcie/trans.c | 139 ++++++++++++++----
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 24 ++-
28 files changed, 400 insertions(+), 164 deletions(-)

--
2.17.0


2018-04-25 08:01:08

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 09/12] iwlwifi: pcie: remove non-responsive device

Luca Coelho <[email protected]> writes:

> On Tue, 2018-04-24 at 12:44 +0300, Kalle Valo wrote:
>> Luca Coelho <[email protected]> writes:
>>
>> > From: Luca Coelho <[email protected]>
>> >
>> > If we fail to to grab NIC access because the device is not
>> > responding
>> > (i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from the
>> > PCI
>> > bus, to avoid any further damage, and to let the user space rescan.
>> >
>> > Signed-off-by: Luca Coelho <[email protected]>
>> > Signed-off-by: Rajat Jain <[email protected]>
>>
>> The commit log doesn't mention anything about the module parameter
>> nor
>> about the kobject uevent.
>
> Good point. The uevent and the module parameter were added in later
> patches and I squashed them all into this one, but forgot to update the
> commit message. I'll fix it.

Good, thanks.

>> > +static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
>> > +{
>> > + struct iwl_trans_pcie_removal *removal =
>> > + container_of(wk, struct iwl_trans_pcie_removal,
>> > work);
>> > + struct pci_dev *pdev = removal->pdev;
>> > + char *prop[] = {"EVENT=INACCESSIBLE", NULL};
>> > +
>> > + dev_err(&pdev->dev, "Device gone - attempting removal\n");
>> > + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
>> > + pci_lock_rescan_remove();
>> > + pci_dev_put(pdev);
>> > + pci_stop_and_remove_bus_device(pdev);
>> > + pci_unlock_rescan_remove();
>> > +
>> > + kfree(removal);
>> > + module_put(THIS_MODULE);
>> > +}
>>
>> So is the uevent some standard thing or what? At least grepping
>> INACCESSIBLE for didn't tell me anything.
>
> No, this is not standard. We didn't find any appropriate standard
> message for this case, so we created a new one. Also, we didn't want
> to interfere with components that may react to standard messages.
>
> This is disabled by default and the idea is to change this in the
> future to allow the driver to remove and rescan the device
> automatically. So we will have 3 options in the module parameter: do
> nothing; auto-rescan or; send uevent.

Ok, I assume you will explain this in the commit log.

In my opinion the driver should not be sending custom events like this
and instead pci_stop_and_remove_bus_device() should do it, but maybe
that's just me?

--
Kalle Valo

2018-04-22 08:27:59

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 04/12] iwlwifi: pcie: allow sending pre-built A-MSDUs

From: Eliad Peller <[email protected]>

In case of A-MSDUs, the trans layer is taking care of building
the subframes (out of the given skb), according to the given gso_size.

However, in some testing flows, we want to build the whole A-MSDU
frame in a different place (e.g. userspace), and ask the driver
to send it as-is.

In case of gso_size==0, simply treat the frame as normal-frame,
although the A-MSDU flag is set.

Signed-off-by: Eliad Peller <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 1cbb8f470afd..473fe7ccb07c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -2397,7 +2397,13 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
goto out_err;
iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false);

- if (amsdu) {
+ /*
+ * If gso_size wasn't set, don't give the frame "amsdu treatment"
+ * (adding subframes, etc.).
+ * This can happen in some testing flows when the amsdu was already
+ * pre-built, and we just need to send the resulting skb.
+ */
+ if (amsdu && skb_shinfo(skb)->gso_size) {
if (unlikely(iwl_fill_data_tbs_amsdu(trans, skb, txq, hdr_len,
out_meta, dev_cmd,
tb1_len)))
--
2.17.0

2018-04-22 08:28:01

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 06/12] iwlwifi: mvm: move skb padding reservation earlier

From: Johannes Berg <[email protected]>

Future changes will require moving the HE radiotap data into
the SKB head, but this means we need to have the alignment
reservation done before that. To prepare, move the alignment
reservation earlier here.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 34791628cfb3..bb63e75a9b7f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -151,17 +151,9 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);

if (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD) {
+ len -= 2;
pad_len = 2;
-
- /*
- * If the device inserted padding it means that (it thought)
- * the 802.11 header wasn't a multiple of 4 bytes long. In
- * this case, reserve two bytes at the start of the SKB to
- * align the payload properly in case we end up copying it.
- */
- skb_reserve(skb, pad_len);
}
- len -= pad_len;

/* If frame is small enough to fit in skb->head, pull it completely.
* If not, only pull ieee80211_hdr (including crypto if present, and
@@ -866,6 +858,16 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
return;
}

+ if (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD) {
+ /*
+ * If the device inserted padding it means that (it thought)
+ * the 802.11 header wasn't a multiple of 4 bytes long. In
+ * this case, reserve two bytes at the start of the SKB to
+ * align the payload properly in case we end up copying it.
+ */
+ skb_reserve(skb, 2);
+ }
+
rx_status = IEEE80211_SKB_RXCB(skb);

if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, desc,
--
2.17.0

2018-04-22 08:27:57

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 01/12] iwlwifi: allow different csr flags for different device families

From: Golan Ben Ami <[email protected]>

Different device families may have different flag values
for passing a message to the fw (i.e. SW_RESET).
In order to keep the code readable, and avoid conditioning
upon the family, store a value for each flag, which indicates
the bit that needs to be enabled.

Signed-off-by: Golan Ben Ami <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/cfg/1000.c | 8 ++-
drivers/net/wireless/intel/iwlwifi/cfg/2000.c | 13 ++--
.../net/wireless/intel/iwlwifi/cfg/22000.c | 7 ++
drivers/net/wireless/intel/iwlwifi/cfg/5000.c | 8 ++-
drivers/net/wireless/intel/iwlwifi/cfg/6000.c | 19 ++++--
drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 5 +-
drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 5 +-
drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 3 +-
.../net/wireless/intel/iwlwifi/iwl-config.h | 65 +++++++++++++++++++
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 28 +-------
.../wireless/intel/iwlwifi/iwl-eeprom-read.c | 8 ++-
.../net/wireless/intel/iwlwifi/mvm/utils.c | 8 ++-
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 +-
.../wireless/intel/iwlwifi/pcie/trans-gen2.c | 15 +++--
.../net/wireless/intel/iwlwifi/pcie/trans.c | 65 +++++++++++--------
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 16 +++--
16 files changed, 184 insertions(+), 92 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
index b2573b1d1506..591687984962 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/1000.c
@@ -1,6 +1,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -27,7 +28,6 @@
#include <linux/module.h>
#include <linux/stringify.h>
#include "iwl-config.h"
-#include "iwl-csr.h"
#include "iwl-agn-hw.h"

/* Highest firmware API version supported */
@@ -91,7 +91,8 @@ static const struct iwl_eeprom_params iwl1000_eeprom_params = {
.base_params = &iwl1000_base_params, \
.eeprom_params = &iwl1000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl1000_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
@@ -117,7 +118,8 @@ const struct iwl_cfg iwl1000_bg_cfg = {
.eeprom_params = &iwl1000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl100_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 100 BGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
index 1b32ad413b9e..a63ca8820568 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/2000.c
@@ -1,6 +1,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -115,7 +116,8 @@ static const struct iwl_eeprom_params iwl20x0_eeprom_params = {
.base_params = &iwl2000_base_params, \
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1


const struct iwl_cfg iwl2000_2bgn_cfg = {
@@ -142,7 +144,8 @@ const struct iwl_cfg iwl2000_2bgn_d_cfg = {
.base_params = &iwl2030_base_params, \
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl2030_2bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 2230 BGN",
@@ -163,7 +166,8 @@ const struct iwl_cfg iwl2030_2bgn_cfg = {
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl105_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 105 BGN",
@@ -190,7 +194,8 @@ const struct iwl_cfg iwl105_bgn_d_cfg = {
.eeprom_params = &iwl20x0_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
.rx_with_siso_diversity = true, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl135_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N 135 BGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index f2b6e0e8d787..afc78a1e1cfc 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -143,6 +143,7 @@ const struct iwl_cfg iwl22000_2ac_cfg_hr = {
.name = "Intel(R) Dual Band Wireless AC 22000",
.fw_name_pre = IWL_22000_HR_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
@@ -153,6 +154,7 @@ const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb = {
.name = "Intel(R) Dual Band Wireless AC 22000",
.fw_name_pre = IWL_22000_HR_CDB_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
@@ -164,6 +166,7 @@ const struct iwl_cfg iwl22000_2ac_cfg_jf = {
.name = "Intel(R) Dual Band Wireless AC 22000",
.fw_name_pre = IWL_22000_JF_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
@@ -174,6 +177,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_hr = {
.name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_22000_HR_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
@@ -184,6 +188,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_f0 = {
.name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_22000_HR_F0_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
@@ -194,6 +199,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_jf_b0 = {
.name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_22000_JF_B0_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
@@ -204,6 +210,7 @@ const struct iwl_cfg iwl22000_2ax_cfg_qnj_hr_a0 = {
.name = "Intel(R) Dual Band Wireless AX 22000",
.fw_name_pre = IWL_22000_HR_A0_FW_PRE,
IWL_DEVICE_22000,
+ .csr = &iwl_csr_v1,
.ht_params = &iwl_22000_ht_params,
.nvm_ver = IWL_22000_NVM_VERSION,
.nvm_calib_ver = IWL_22000_TX_POWER_VERSION,
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
index 4aa8f0a05c8a..a224f1be1ec2 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c
@@ -1,6 +1,7 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -28,7 +29,6 @@
#include <linux/stringify.h>
#include "iwl-config.h"
#include "iwl-agn-hw.h"
-#include "iwl-csr.h"

/* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 5
@@ -89,7 +89,8 @@ static const struct iwl_eeprom_params iwl5000_eeprom_params = {
.base_params = &iwl5000_base_params, \
.eeprom_params = &iwl5000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl5300_agn_cfg = {
.name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
@@ -153,7 +154,8 @@ const struct iwl_cfg iwl5350_agn_cfg = {
.eeprom_params = &iwl5000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.internal_wimax_coex = true, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl5150_agn_cfg = {
.name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
index 39335b7b0c16..51cec0bb75fc 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
@@ -1,6 +1,7 @@
/******************************************************************************
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
@@ -135,7 +136,8 @@ static const struct iwl_eeprom_params iwl6000_eeprom_params = {
.base_params = &iwl6000_g2_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl6005_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6205 AGN",
@@ -189,7 +191,8 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = {
.base_params = &iwl6000_g2_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl6030_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6230 AGN",
@@ -225,7 +228,8 @@ const struct iwl_cfg iwl6030_2bg_cfg = {
.base_params = &iwl6000_g2_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_RF_STATE, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl6035_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6235 AGN",
@@ -280,7 +284,8 @@ const struct iwl_cfg iwl130_bg_cfg = {
.base_params = &iwl6000_base_params, \
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl6000i_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
@@ -313,7 +318,8 @@ const struct iwl_cfg iwl6000i_2bg_cfg = {
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.internal_wimax_coex = true, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl6050_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
@@ -339,7 +345,8 @@ const struct iwl_cfg iwl6050_2abg_cfg = {
.eeprom_params = &iwl6000_eeprom_params, \
.led_mode = IWL_LED_BLINK, \
.internal_wimax_coex = true, \
- .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K
+ .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl6150_bgn_cfg = {
.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index ce741beec1fc..8e9684e8e603 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -167,7 +169,8 @@ static const struct iwl_ht_params iwl7000_ht_params = {
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
.non_shared_ant = ANT_A, \
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
- .dccm_offset = IWL7000_DCCM_OFFSET
+ .dccm_offset = IWL7000_DCCM_OFFSET, \
+ .csr = &iwl_csr_v1

#define IWL_DEVICE_7000 \
IWL_DEVICE_7000_COMMON, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
index 3f4d9bac9f73..e8299b2ab6bd 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
@@ -8,6 +8,7 @@
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -34,6 +35,7 @@
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -158,7 +160,8 @@ static const struct iwl_tt_params iwl8000_tt_params = {
.apmg_not_supported = true, \
.nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true, \
- .min_umac_error_event_table = 0x800000
+ .min_umac_error_event_table = 0x800000, \
+ .csr = &iwl_csr_v1

#define IWL_DEVICE_8000 \
IWL_DEVICE_8000_COMMON, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index e1c869a1f8cc..fe376fce3444 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -156,7 +156,8 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.rf_id = true, \
.nvm_type = IWL_NVM_EXT, \
.dbgc_supported = true, \
- .min_umac_error_event_table = 0x800000
+ .min_umac_error_event_table = 0x800000, \
+ .csr = &iwl_csr_v1

const struct iwl_cfg iwl9160_2ac_cfg = {
.name = "Intel(R) Dual Band Wireless AC 9160",
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 14e69e7a2287..7f0b7cea8b9b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -7,6 +7,7 @@
*
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright (C) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,6 +71,7 @@
#include <linux/netdevice.h>
#include <linux/ieee80211.h>
#include <linux/nl80211.h>
+#include "iwl-csr.h"

enum iwl_device_family {
IWL_DEVICE_FAMILY_UNDEFINED,
@@ -284,6 +287,44 @@ struct iwl_pwr_tx_backoff {
u32 backoff;
};

+/**
+ * struct iwl_csr_params
+ *
+ * @flag_sw_reset: reset the device
+ * @flag_mac_clock_ready:
+ * Indicates MAC (ucode processor, etc.) is powered up and can run.
+ * Internal resources are accessible.
+ * NOTE: This does not indicate that the processor is actually running.
+ * NOTE: This does not indicate that device has completed
+ * init or post-power-down restore of internal SRAM memory.
+ * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
+ * SRAM is restored and uCode is in normal operation mode.
+ * This note is relevant only for pre 5xxx devices.
+ * NOTE: After device reset, this bit remains "0" until host sets
+ * INIT_DONE
+ * @flag_init_done: Host sets this to put device into fully operational
+ * D0 power mode. Host resets this after SW_RESET to put device into
+ * low power mode.
+ * @flag_mac_access_req: Host sets this to request and maintain MAC wakeup,
+ * to allow host access to device-internal resources. Host must wait for
+ * mac_clock_ready (and !GOING_TO_SLEEP) before accessing non-CSR device
+ * registers.
+ * @flag_val_mac_access_en: mac access is enabled
+ * @flag_master_dis: disable master
+ * @flag_stop_master: stop master
+ * @addr_sw_reset: address for resetting the device
+ */
+struct iwl_csr_params {
+ u8 flag_sw_reset;
+ u8 flag_mac_clock_ready;
+ u8 flag_init_done;
+ u8 flag_mac_access_req;
+ u8 flag_val_mac_access_en;
+ u8 flag_master_dis;
+ u8 flag_stop_master;
+ u8 addr_sw_reset;
+};
+
/**
* struct iwl_cfg
* @name: Official name of the device
@@ -316,6 +357,7 @@ struct iwl_pwr_tx_backoff {
* @mac_addr_from_csr: read HW address from CSR registers
* @features: hw features, any combination of feature_whitelist
* @pwr_tx_backoffs: translation table between power limits and backoffs
+ * @csr: csr flags and addresses that are different across devices
* @max_rx_agg_size: max RX aggregation size of the ADDBA request/response
* @max_tx_agg_size: max TX aggregation size of the ADDBA request/response
* @max_ht_ampdu_factor: the exponent of the max length of A-MPDU that the
@@ -354,6 +396,7 @@ struct iwl_cfg {
const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
const char *default_nvm_file_C_step;
const struct iwl_tt_params *thermal_params;
+ const struct iwl_csr_params *csr;
enum iwl_device_family device_family;
enum iwl_led_mode led_mode;
enum iwl_nvm_type nvm_type;
@@ -400,6 +443,28 @@ struct iwl_cfg {
u32 extra_phy_cfg_flags;
};

+static const struct iwl_csr_params iwl_csr_v1 = {
+ .flag_mac_clock_ready = 0,
+ .flag_val_mac_access_en = 0,
+ .flag_init_done = 2,
+ .flag_mac_access_req = 3,
+ .flag_sw_reset = 7,
+ .flag_master_dis = 8,
+ .flag_stop_master = 9,
+ .addr_sw_reset = (CSR_BASE + 0x020)
+};
+
+static const struct iwl_csr_params iwl_csr_v2 = {
+ .flag_init_done = 6,
+ .flag_mac_clock_ready = 20,
+ .flag_val_mac_access_en = 20,
+ .flag_mac_access_req = 21,
+ .flag_master_dis = 28,
+ .flag_stop_master = 29,
+ .flag_sw_reset = 31,
+ .addr_sw_reset = (CSR_BASE + 0x024)
+};
+
/*
* This list declares the config structures for all devices.
*/
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index 4f0d070eda54..ba971d3946e2 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -8,6 +8,7 @@
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -34,6 +35,7 @@
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -257,7 +259,6 @@
/* RESET */
#define CSR_RESET_REG_FLAG_NEVO_RESET (0x00000001)
#define CSR_RESET_REG_FLAG_FORCE_NMI (0x00000002)
-#define CSR_RESET_REG_FLAG_SW_RESET (0x00000080)
#define CSR_RESET_REG_FLAG_MASTER_DISABLED (0x00000100)
#define CSR_RESET_REG_FLAG_STOP_MASTER (0x00000200)
#define CSR_RESET_LINK_PWR_MGMT_DISABLED (0x80000000)
@@ -280,35 +281,10 @@
* 4: GOING_TO_SLEEP
* Indicates MAC is entering a power-saving sleep power-down.
* Not a good time to access device-internal resources.
- * 3: MAC_ACCESS_REQ
- * Host sets this to request and maintain MAC wakeup, to allow host
- * access to device-internal resources. Host must wait for
- * MAC_CLOCK_READY (and !GOING_TO_SLEEP) before accessing non-CSR
- * device registers.
- * 2: INIT_DONE
- * Host sets this to put device into fully operational D0 power mode.
- * Host resets this after SW_RESET to put device into low power mode.
- * 0: MAC_CLOCK_READY
- * Indicates MAC (ucode processor, etc.) is powered up and can run.
- * Internal resources are accessible.
- * NOTE: This does not indicate that the processor is actually running.
- * NOTE: This does not indicate that device has completed
- * init or post-power-down restore of internal SRAM memory.
- * Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
- * SRAM is restored and uCode is in normal operation mode.
- * Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
- * do not need to save/restore it.
- * NOTE: After device reset, this bit remains "0" until host sets
- * INIT_DONE
*/
-#define CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY (0x00000001)
-#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
-#define CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ (0x00000008)
#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
#define CSR_GP_CNTRL_REG_FLAG_XTAL_ON (0x00000400)

-#define CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN (0x00000001)
-
#define CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE (0x07000000)
#define CSR_GP_CNTRL_REG_FLAG_RFKILL_WAKE_L1A_EN (0x04000000)
#define CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW (0x08000000)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
index f2cea1c7befc..ac965c34a2f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-read.c
@@ -6,6 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -31,6 +32,7 @@
* BSD LICENSE
*
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -199,12 +201,12 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
/* Enable 40MHz radio clock */
iwl_write32(trans, CSR_GP_CNTRL,
iwl_read32(trans, CSR_GP_CNTRL) |
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ BIT(trans->cfg->csr->flag_init_done));

/* wait for clock to be ready */
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
25000);
if (ret < 0) {
IWL_ERR(trans, "Time out access OTP\n");
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index 0497c7a44def..b002a7afb5f5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -520,15 +522,15 @@ static void iwl_mvm_dump_lmac_error_log(struct iwl_mvm *mvm, u32 base)

/* set INIT_DONE flag */
iwl_set_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ BIT(trans->cfg->csr->flag_init_done));

/* and wait for clock stabilization */
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
udelay(2);

err = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
25000);
if (err < 0) {
IWL_DEBUG_INFO(trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index f25ce3a1ea50..f772d70a65e4 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -3,6 +3,7 @@
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -201,7 +202,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup, GP1 = 0x%x\n",
reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
rxq->need_update = true;
return;
}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index cb4012541f45..b8e8dac2895d 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -6,6 +6,7 @@
* GPL LICENSE SUMMARY
*
* Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -19,6 +20,7 @@
* BSD LICENSE
*
* Copyright(c) 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -92,7 +94,8 @@ static int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
* Set "initialization complete" bit to move adapter from
* D0U* --> D0A* (powered-up active) state.
*/
- iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ BIT(trans->cfg->csr->flag_init_done));

/*
* Wait for clock stabilization; once stabilized, access to
@@ -100,8 +103,9 @@ static int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
* and accesses to uCode SRAM.
*/
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ 25000);
if (ret < 0) {
IWL_DEBUG_INFO(trans, "Failed to init the card\n");
return ret;
@@ -143,7 +147,8 @@ static void iwl_pcie_gen2_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
* Clear "initialization complete" bit to move adapter from
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
- iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_clear_bit(trans, CSR_GP_CNTRL,
+ BIT(trans->cfg->csr->flag_init_done));
}

void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)
@@ -187,7 +192,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans, bool low_power)

/* Make sure (redundant) we've released our request to stay awake */
iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));

/* Stop the device, and put it in low power state */
iwl_pcie_gen2_apm_stop(trans, false);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index f8a0234d332c..623476603cd4 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -8,6 +8,7 @@
* Copyright(c) 2007 - 2015 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
* Copyright(c) 2005 - 2015 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -179,7 +181,8 @@ static void iwl_trans_pcie_dump_regs(struct iwl_trans *trans)
static void iwl_trans_pcie_sw_reset(struct iwl_trans *trans)
{
/* Reset entire device - do controller reset (results in SHRD_HW_RST) */
- iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset,
+ BIT(trans->cfg->csr->flag_sw_reset));
usleep_range(5000, 6000);
}

@@ -372,7 +375,8 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
* Set "initialization complete" bit to move adapter from
* D0U* --> D0A* (powered-up active) state.
*/
- iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ BIT(trans->cfg->csr->flag_init_done));

/*
* Wait for clock stabilization; once stabilized, access to
@@ -380,8 +384,9 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
* and accesses to uCode SRAM.
*/
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ 25000);
if (ret < 0) {
IWL_ERR(trans, "Failed to init the card\n");
return ret;
@@ -459,15 +464,16 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
* Set "initialization complete" bit to move adapter from
* D0U* --> D0A* (powered-up active) state.
*/
- iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ BIT(trans->cfg->csr->flag_init_done));

/*
* Wait for clock stabilization; once stabilized, access to
* device-internal resources is possible.
*/
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
25000);
if (WARN_ON(ret < 0)) {
IWL_ERR(trans, "Access time out - failed to enable LP XTAL\n");
@@ -519,7 +525,7 @@ static void iwl_pcie_apm_lp_xtal_enable(struct iwl_trans *trans)
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ BIT(trans->cfg->csr->flag_init_done));

/* Activates XTAL resources monitor */
__iwl_trans_pcie_set_bit(trans, CSR_MONITOR_CFG_REG,
@@ -541,11 +547,12 @@ void iwl_pcie_apm_stop_master(struct iwl_trans *trans)
int ret;

/* stop device's busmaster DMA activity */
- iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+ iwl_set_bit(trans, trans->cfg->csr->addr_sw_reset,
+ BIT(trans->cfg->csr->flag_stop_master));

- ret = iwl_poll_bit(trans, CSR_RESET,
- CSR_RESET_REG_FLAG_MASTER_DISABLED,
- CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
+ ret = iwl_poll_bit(trans, trans->cfg->csr->addr_sw_reset,
+ BIT(trans->cfg->csr->flag_master_dis),
+ BIT(trans->cfg->csr->flag_master_dis), 100);
if (ret < 0)
IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n");

@@ -594,7 +601,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ BIT(trans->cfg->csr->flag_init_done));
}

static int iwl_pcie_nic_init(struct iwl_trans *trans)
@@ -1267,7 +1274,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)

/* Make sure (redundant) we've released our request to stay awake */
iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));

/* Stop the device, and put it in low power state */
iwl_pcie_apm_stop(trans, false);
@@ -1497,9 +1504,9 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
iwl_pcie_synchronize_irqs(trans);

iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ BIT(trans->cfg->csr->flag_init_done));

iwl_pcie_enable_rx_wake(trans, false);

@@ -1543,15 +1550,17 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
iwl_pcie_reset_ict(trans);
iwl_enable_interrupts(trans);

- iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
- iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ BIT(trans->cfg->csr->flag_mac_access_req));
+ iwl_set_bit(trans, CSR_GP_CNTRL,
+ BIT(trans->cfg->csr->flag_init_done));

if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
udelay(2);

ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
25000);
if (ret < 0) {
IWL_ERR(trans, "Failed to resume the device (mac ready)\n");
@@ -1562,7 +1571,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,

if (!reset) {
iwl_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
} else {
iwl_trans_pcie_tx_reset(trans);

@@ -1939,7 +1948,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,

/* this bit wakes up the NIC */
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_8000)
udelay(2);

@@ -1964,8 +1973,8 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
* and do not save/restore SRAM when power cycling.
*/
ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+ BIT(trans->cfg->csr->flag_val_mac_access_en),
+ (BIT(trans->cfg->csr->flag_mac_clock_ready) |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (unlikely(ret < 0)) {
iwl_trans_pcie_dump_regs(trans);
@@ -2003,7 +2012,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
goto out;

__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
/*
* Above we read the CSR_GP_CNTRL register, which will flush
* any previous writes, but we need the write that clears the
@@ -3232,12 +3241,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* id located at the AUX bus MISC address space.
*/
iwl_set_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ BIT(trans->cfg->csr->flag_init_done));
udelay(2);

ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
- CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
+ BIT(trans->cfg->csr->flag_mac_clock_ready),
25000);
if (ret < 0) {
IWL_DEBUG_INFO(trans, "Failed to wake up the nic\n");
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index cf468b9f5a82..1cbb8f470afd 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -3,6 +3,7 @@
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* Portions of this file are derived from the ipw3945 project, as well
* as portions of the ieee80211 subsystem header files.
@@ -273,7 +274,7 @@ static void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans,
IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup, GP1 = 0x%x\n",
txq_id, reg);
iwl_set_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
txq->need_update = true;
return;
}
@@ -611,7 +612,7 @@ static void iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)

trans_pcie->cmd_hold_nic_awake = false;
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(trans->cfg->csr->flag_mac_access_req));
}

/*
@@ -1171,6 +1172,7 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
const struct iwl_host_cmd *cmd)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ const struct iwl_cfg *cfg = trans->cfg;
int ret;

lockdep_assert_held(&trans_pcie->reg_lock);
@@ -1188,19 +1190,19 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
* returned. This needs to be done only on NICs that have
* apmg_wake_up_wa set.
*/
- if (trans->cfg->base_params->apmg_wake_up_wa &&
+ if (cfg->base_params->apmg_wake_up_wa &&
!trans_pcie->cmd_hold_nic_awake) {
__iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(cfg->csr->flag_mac_access_req));

ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+ BIT(cfg->csr->flag_val_mac_access_en),
+ (BIT(cfg->csr->flag_mac_clock_ready) |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
15000);
if (ret < 0) {
__iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
- CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ BIT(cfg->csr->flag_mac_access_req));
IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
return -EIO;
}
--
2.17.0

2018-04-24 09:44:40

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 09/12] iwlwifi: pcie: remove non-responsive device

Luca Coelho <[email protected]> writes:

> From: Luca Coelho <[email protected]>
>
> If we fail to to grab NIC access because the device is not responding
> (i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from the PCI
> bus, to avoid any further damage, and to let the user space rescan.
>
> Signed-off-by: Luca Coelho <[email protected]>
> Signed-off-by: Rajat Jain <[email protected]>

The commit log doesn't mention anything about the module parameter nor
about the kobject uevent.

> +static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
> +{
> + struct iwl_trans_pcie_removal *removal =
> + container_of(wk, struct iwl_trans_pcie_removal, work);
> + struct pci_dev *pdev = removal->pdev;
> + char *prop[] = {"EVENT=INACCESSIBLE", NULL};
> +
> + dev_err(&pdev->dev, "Device gone - attempting removal\n");
> + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
> + pci_lock_rescan_remove();
> + pci_dev_put(pdev);
> + pci_stop_and_remove_bus_device(pdev);
> + pci_unlock_rescan_remove();
> +
> + kfree(removal);
> + module_put(THIS_MODULE);
> +}

So is the uevent some standard thing or what? At least grepping
INACCESSIBLE for didn't tell me anything.

--
Kalle Valo

2018-04-22 08:28:00

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 05/12] iwlwifi: support new csr addresses for hw address

From: Golan Ben Ami <[email protected]>

In future devices we use different csr addresses for hw addresses.
Update csr addresses to support new and legacy devices.

Signed-off-by: Golan Ben Ami <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/iwl-config.h | 20 +++++++++++++++++--
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 14 +++++++++----
2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 7752794d0437..cfd14e5ea59c 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -313,6 +313,10 @@ struct iwl_pwr_tx_backoff {
* @flag_master_dis: disable master
* @flag_stop_master: stop master
* @addr_sw_reset: address for resetting the device
+ * @mac_addr0_otp: first part of MAC address from OTP
+ * @mac_addr1_otp: second part of MAC address from OTP
+ * @mac_addr0_strap: first part of MAC address from strap
+ * @mac_addr1_strap: second part of MAC address from strap
*/
struct iwl_csr_params {
u8 flag_sw_reset;
@@ -323,6 +327,10 @@ struct iwl_csr_params {
u8 flag_master_dis;
u8 flag_stop_master;
u8 addr_sw_reset;
+ u32 mac_addr0_otp;
+ u32 mac_addr1_otp;
+ u32 mac_addr0_strap;
+ u32 mac_addr1_strap;
};

/**
@@ -451,7 +459,11 @@ static const struct iwl_csr_params iwl_csr_v1 = {
.flag_sw_reset = 7,
.flag_master_dis = 8,
.flag_stop_master = 9,
- .addr_sw_reset = (CSR_BASE + 0x020)
+ .addr_sw_reset = (CSR_BASE + 0x020),
+ .mac_addr0_otp = 0x380,
+ .mac_addr1_otp = 0x384,
+ .mac_addr0_strap = 0x388,
+ .mac_addr1_strap = 0x38C
};

static const struct iwl_csr_params iwl_csr_v2 = {
@@ -462,7 +474,11 @@ static const struct iwl_csr_params iwl_csr_v2 = {
.flag_master_dis = 28,
.flag_stop_master = 29,
.flag_sw_reset = 31,
- .addr_sw_reset = (CSR_BASE + 0x024)
+ .addr_sw_reset = (CSR_BASE + 0x024),
+ .mac_addr0_otp = 0x30,
+ .mac_addr1_otp = 0x34,
+ .mac_addr0_strap = 0x38,
+ .mac_addr1_strap = 0x3C
};

/*
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 6d33c14579d9..aa83db5744df 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -579,8 +579,12 @@ static void iwl_flip_hw_address(__le32 mac_addr0, __le32 mac_addr1, u8 *dest)
static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
struct iwl_nvm_data *data)
{
- __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
- __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
+ __le32 mac_addr0 =
+ cpu_to_le32(iwl_read32(trans,
+ trans->cfg->csr->mac_addr0_strap));
+ __le32 mac_addr1 =
+ cpu_to_le32(iwl_read32(trans,
+ trans->cfg->csr->mac_addr1_strap));

iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
/*
@@ -590,8 +594,10 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
if (is_valid_ether_addr(data->hw_addr))
return;

- mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
- mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
+ mac_addr0 = cpu_to_le32(iwl_read32(trans,
+ trans->cfg->csr->mac_addr0_otp));
+ mac_addr1 = cpu_to_le32(iwl_read32(trans,
+ trans->cfg->csr->mac_addr1_otp));

iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
}
--
2.17.0

2018-04-26 07:55:29

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH v2 12/12] iwlwifi: pcie: remove non-responsive device

Ooops, I obviously meant "PATCH v2 09/12" in the subject.

--
Luca.


On Thu, 2018-04-26 at 10:53 +0300, Luca Coelho wrote:
> From: Luca Coelho <[email protected]>
>
> If we fail to to grab NIC access because the device is not responding
> (i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from the
> PCI
> bus, to avoid any further damage, and to let the user space rescan.
>
> In order to inform the userspace that a rescan is needed, we send a
> kobject uevent with "INACCESSIBLE".
>
> This functionality is disabled by default, but can be enabled via a
> new module parameter called "remove_when_gone". In the future we may
> change this module parameter to include 3 modes instead: do nothing;
> auto-rescan or; send uevent.
>
> Signed-off-by: Luca Coelho <[email protected]>
> Signed-off-by: Rajat Jain <[email protected]>
> ---
> drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 6 ++
> .../wireless/intel/iwlwifi/iwl-modparams.h | 2 +
> .../wireless/intel/iwlwifi/pcie/internal.h | 5 ++
> .../net/wireless/intel/iwlwifi/pcie/trans.c | 74
> ++++++++++++++++++-
> 4 files changed, 84 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
> b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
> index 4f451a6f20b9..c59ce4f8a5ed 100644
> --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
> @@ -1850,3 +1850,9 @@ MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3
> entry when idle (ms)");
>
> module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac,
> bool, 0444);
> MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default:
> false)");
> +
> +module_param_named(remove_when_gone,
> + iwlwifi_mod_params.remove_when_gone, bool,
> + 0444);
> +MODULE_PARM_DESC(remove_when_gone,
> + "Remove dev from PCIe bus if it is deemed
> inaccessible (default: false)");
> diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
> b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
> index a41c46e63eb1..a7dd8a8cddf9 100644
> --- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
> @@ -122,6 +122,7 @@ enum iwl_uapsd_disable {
> * @lar_disable: disable LAR (regulatory), default = 0
> * @fw_monitor: allow to use firmware monitor
> * @disable_11ac: disable VHT capabilities, default = false.
> + * @remove_when_gone: remove an inaccessible device from the PCIe
> bus.
> */
> struct iwl_mod_params {
> int swcrypto;
> @@ -143,6 +144,7 @@ struct iwl_mod_params {
> bool lar_disable;
> bool fw_monitor;
> bool disable_11ac;
> + bool remove_when_gone;
> };
>
> #endif /* #__iwl_modparams_h__ */
> diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
> b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
> index cda66340d357..45ea32796cda 100644
> --- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
> +++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
> @@ -383,6 +383,8 @@ struct iwl_self_init_dram {
> * @hw_init_mask: initial unmasked hw causes
> * @fh_mask: current unmasked fh causes
> * @hw_mask: current unmasked hw causes
> + * @in_rescan: true if we have triggered a device rescan
> + * @scheduled_for_removal: true if we have scheduled a device
> removal
> */
> struct iwl_trans_pcie {
> struct iwl_rxq *rxq;
> @@ -464,6 +466,9 @@ struct iwl_trans_pcie {
> u32 fh_mask;
> u32 hw_mask;
> cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
> + u16 tx_cmd_queue_size;
> + bool in_rescan;
> + bool scheduled_for_removal;
> };
>
> static inline struct iwl_trans_pcie *
> diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> index 623476603cd4..6e9a9ecfb11c 100644
> --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> @@ -75,6 +75,7 @@
> #include <linux/gfp.h>
> #include <linux/vmalloc.h>
> #include <linux/pm_runtime.h>
> +#include <linux/module.h>
>
> #include "iwl-drv.h"
> #include "iwl-trans.h"
> @@ -1935,6 +1936,29 @@ static void iwl_trans_pcie_set_pmi(struct
> iwl_trans *trans, bool state)
> clear_bit(STATUS_TPOWER_PMI, &trans->status);
> }
>
> +struct iwl_trans_pcie_removal {
> + struct pci_dev *pdev;
> + struct work_struct work;
> +};
> +
> +static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
> +{
> + struct iwl_trans_pcie_removal *removal =
> + container_of(wk, struct iwl_trans_pcie_removal,
> work);
> + struct pci_dev *pdev = removal->pdev;
> + char *prop[] = {"EVENT=INACCESSIBLE", NULL};
> +
> + dev_err(&pdev->dev, "Device gone - attempting removal\n");
> + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
> + pci_lock_rescan_remove();
> + pci_dev_put(pdev);
> + pci_stop_and_remove_bus_device(pdev);
> + pci_unlock_rescan_remove();
> +
> + kfree(removal);
> + module_put(THIS_MODULE);
> +}
> +
> static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
> unsigned long *flags)
> {
> @@ -1977,11 +2001,55 @@ static bool
> iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
> (BIT(trans->cfg->csr-
> >flag_mac_clock_ready) |
> CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP),
> 15000);
> if (unlikely(ret < 0)) {
> - iwl_trans_pcie_dump_regs(trans);
> - iwl_write32(trans, CSR_RESET,
> CSR_RESET_REG_FLAG_FORCE_NMI);
> + u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
> +
> WARN_ONCE(1,
> "Timeout waiting for hardware access
> (CSR_GP_CNTRL 0x%08x)\n",
> - iwl_read32(trans, CSR_GP_CNTRL));
> + cntrl);
> +
> + iwl_trans_pcie_dump_regs(trans);
> +
> + if (iwlwifi_mod_params.remove_when_gone && cntrl ==
> ~0U) {
> + struct iwl_trans_pcie_removal *removal;
> +
> + if (trans_pcie->scheduled_for_removal)
> + goto err;
> +
> + IWL_ERR(trans, "Device gone - scheduling
> removal!\n");
> +
> + /*
> + * get a module reference to avoid doing
> this
> + * while unloading anyway and to avoid
> + * scheduling a work with code that's being
> + * removed.
> + */
> + if (!try_module_get(THIS_MODULE)) {
> + IWL_ERR(trans,
> + "Module is being unloaded -
> abort\n");
> + goto err;
> + }
> +
> + removal = kzalloc(sizeof(*removal),
> GFP_ATOMIC);
> + if (!removal) {
> + module_put(THIS_MODULE);
> + goto err;
> + }
> + /*
> + * we don't need to clear this flag, because
> + * the trans will be freed and reallocated.
> + */
> + trans_pcie->scheduled_for_removal = true;
> +
> + removal->pdev = to_pci_dev(trans->dev);
> + INIT_WORK(&removal->work,
> iwl_trans_pcie_removal_wk);
> + pci_dev_get(removal->pdev);
> + schedule_work(&removal->work);
> + } else {
> + iwl_write32(trans, CSR_RESET,
> + CSR_RESET_REG_FLAG_FORCE_NMI);
> + }
> +
> +err:
> spin_unlock_irqrestore(&trans_pcie->reg_lock,
> *flags);
> return false;
> }

2018-04-24 09:45:44

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 12/12] iwlwifi: mvm: set wakeup filters for wowlan "any" configuration

Luca Coelho <[email protected]> writes:

> From: Eliad Peller <[email protected]>
>
> In can of "any" wowlan trigger is configured, no valid wakeup filter
> was configured.

"In case"?

--
Kalle Valo

2018-04-26 07:53:52

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 12/12] iwlwifi: pcie: remove non-responsive device

From: Luca Coelho <[email protected]>

If we fail to to grab NIC access because the device is not responding
(i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from the PCI
bus, to avoid any further damage, and to let the user space rescan.

In order to inform the userspace that a rescan is needed, we send a
kobject uevent with "INACCESSIBLE".

This functionality is disabled by default, but can be enabled via a
new module parameter called "remove_when_gone". In the future we may
change this module parameter to include 3 modes instead: do nothing;
auto-rescan or; send uevent.

Signed-off-by: Luca Coelho <[email protected]>
Signed-off-by: Rajat Jain <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 6 ++
.../wireless/intel/iwlwifi/iwl-modparams.h | 2 +
.../wireless/intel/iwlwifi/pcie/internal.h | 5 ++
.../net/wireless/intel/iwlwifi/pcie/trans.c | 74 ++++++++++++++++++-
4 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 4f451a6f20b9..c59ce4f8a5ed 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1850,3 +1850,9 @@ MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");

module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444);
MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)");
+
+module_param_named(remove_when_gone,
+ iwlwifi_mod_params.remove_when_gone, bool,
+ 0444);
+MODULE_PARM_DESC(remove_when_gone,
+ "Remove dev from PCIe bus if it is deemed inaccessible (default: false)");
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
index a41c46e63eb1..a7dd8a8cddf9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
@@ -122,6 +122,7 @@ enum iwl_uapsd_disable {
* @lar_disable: disable LAR (regulatory), default = 0
* @fw_monitor: allow to use firmware monitor
* @disable_11ac: disable VHT capabilities, default = false.
+ * @remove_when_gone: remove an inaccessible device from the PCIe bus.
*/
struct iwl_mod_params {
int swcrypto;
@@ -143,6 +144,7 @@ struct iwl_mod_params {
bool lar_disable;
bool fw_monitor;
bool disable_11ac;
+ bool remove_when_gone;
};

#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index cda66340d357..45ea32796cda 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -383,6 +383,8 @@ struct iwl_self_init_dram {
* @hw_init_mask: initial unmasked hw causes
* @fh_mask: current unmasked fh causes
* @hw_mask: current unmasked hw causes
+ * @in_rescan: true if we have triggered a device rescan
+ * @scheduled_for_removal: true if we have scheduled a device removal
*/
struct iwl_trans_pcie {
struct iwl_rxq *rxq;
@@ -464,6 +466,9 @@ struct iwl_trans_pcie {
u32 fh_mask;
u32 hw_mask;
cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
+ u16 tx_cmd_queue_size;
+ bool in_rescan;
+ bool scheduled_for_removal;
};

static inline struct iwl_trans_pcie *
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 623476603cd4..6e9a9ecfb11c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -75,6 +75,7 @@
#include <linux/gfp.h>
#include <linux/vmalloc.h>
#include <linux/pm_runtime.h>
+#include <linux/module.h>

#include "iwl-drv.h"
#include "iwl-trans.h"
@@ -1935,6 +1936,29 @@ static void iwl_trans_pcie_set_pmi(struct iwl_trans *trans, bool state)
clear_bit(STATUS_TPOWER_PMI, &trans->status);
}

+struct iwl_trans_pcie_removal {
+ struct pci_dev *pdev;
+ struct work_struct work;
+};
+
+static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
+{
+ struct iwl_trans_pcie_removal *removal =
+ container_of(wk, struct iwl_trans_pcie_removal, work);
+ struct pci_dev *pdev = removal->pdev;
+ char *prop[] = {"EVENT=INACCESSIBLE", NULL};
+
+ dev_err(&pdev->dev, "Device gone - attempting removal\n");
+ kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
+ pci_lock_rescan_remove();
+ pci_dev_put(pdev);
+ pci_stop_and_remove_bus_device(pdev);
+ pci_unlock_rescan_remove();
+
+ kfree(removal);
+ module_put(THIS_MODULE);
+}
+
static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
unsigned long *flags)
{
@@ -1977,11 +2001,55 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
(BIT(trans->cfg->csr->flag_mac_clock_ready) |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (unlikely(ret < 0)) {
- iwl_trans_pcie_dump_regs(trans);
- iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+ u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
+
WARN_ONCE(1,
"Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
- iwl_read32(trans, CSR_GP_CNTRL));
+ cntrl);
+
+ iwl_trans_pcie_dump_regs(trans);
+
+ if (iwlwifi_mod_params.remove_when_gone && cntrl == ~0U) {
+ struct iwl_trans_pcie_removal *removal;
+
+ if (trans_pcie->scheduled_for_removal)
+ goto err;
+
+ IWL_ERR(trans, "Device gone - scheduling removal!\n");
+
+ /*
+ * get a module reference to avoid doing this
+ * while unloading anyway and to avoid
+ * scheduling a work with code that's being
+ * removed.
+ */
+ if (!try_module_get(THIS_MODULE)) {
+ IWL_ERR(trans,
+ "Module is being unloaded - abort\n");
+ goto err;
+ }
+
+ removal = kzalloc(sizeof(*removal), GFP_ATOMIC);
+ if (!removal) {
+ module_put(THIS_MODULE);
+ goto err;
+ }
+ /*
+ * we don't need to clear this flag, because
+ * the trans will be freed and reallocated.
+ */
+ trans_pcie->scheduled_for_removal = true;
+
+ removal->pdev = to_pci_dev(trans->dev);
+ INIT_WORK(&removal->work, iwl_trans_pcie_removal_wk);
+ pci_dev_get(removal->pdev);
+ schedule_work(&removal->work);
+ } else {
+ iwl_write32(trans, CSR_RESET,
+ CSR_RESET_REG_FLAG_FORCE_NMI);
+ }
+
+err:
spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
return false;
}
--
2.17.0

2018-04-24 10:56:16

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 09/12] iwlwifi: pcie: remove non-responsive device

On Tue, 2018-04-24 at 12:44 +0300, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > From: Luca Coelho <[email protected]>
> >
> > If we fail to to grab NIC access because the device is not
> > responding
> > (i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from the
> > PCI
> > bus, to avoid any further damage, and to let the user space rescan.
> >
> > Signed-off-by: Luca Coelho <[email protected]>
> > Signed-off-by: Rajat Jain <[email protected]>
>
> The commit log doesn't mention anything about the module parameter
> nor
> about the kobject uevent.

Good point. The uevent and the module parameter were added in later
patches and I squashed them all into this one, but forgot to update the
commit message. I'll fix it.


> > +static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
> > +{
> > + struct iwl_trans_pcie_removal *removal =
> > + container_of(wk, struct iwl_trans_pcie_removal,
> > work);
> > + struct pci_dev *pdev = removal->pdev;
> > + char *prop[] = {"EVENT=INACCESSIBLE", NULL};
> > +
> > + dev_err(&pdev->dev, "Device gone - attempting removal\n");
> > + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
> > + pci_lock_rescan_remove();
> > + pci_dev_put(pdev);
> > + pci_stop_and_remove_bus_device(pdev);
> > + pci_unlock_rescan_remove();
> > +
> > + kfree(removal);
> > + module_put(THIS_MODULE);
> > +}
>
> So is the uevent some standard thing or what? At least grepping
> INACCESSIBLE for didn't tell me anything.

No, this is not standard. We didn't find any appropriate standard
message for this case, so we created a new one. Also, we didn't want
to interfere with components that may react to standard messages.

This is disabled by default and the idea is to change this in the
future to allow the driver to remove and rescan the device
automatically. So we will have 3 options in the module parameter: do
nothing; auto-rescan or; send uevent.

--
Cheers,
Luca.

2018-04-22 08:28:03

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 07/12] iwlwifi: fw: harden page loading code

From: Luca Coelho <[email protected]>

The page loading code trusts the data provided in the firmware images
a bit too much and may cause a buffer overflow or copy unknown data if
the block sizes don't match what we expect.

To prevent potential problems, harden the code by checking if the
sizes we are copying are what we expect.

Cc: [email protected]
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/fw/paging.c | 49 ++++++++++++++++---
1 file changed, 41 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
index 1fec8e3a6b35..6afcfd1f0eec 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -163,7 +165,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt,
static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
const struct fw_img *image)
{
- int sec_idx, idx;
+ int sec_idx, idx, ret;
u32 offset = 0;

/*
@@ -190,17 +192,23 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
*/
if (sec_idx >= image->num_sec - 1) {
IWL_ERR(fwrt, "Paging: Missing CSS and/or paging sections\n");
- iwl_free_fw_paging(fwrt);
- return -EINVAL;
+ ret = -EINVAL;
+ goto err;
}

/* copy the CSS block to the dram */
IWL_DEBUG_FW(fwrt, "Paging: load paging CSS to FW, sec = %d\n",
sec_idx);

+ if (image->sec[sec_idx].len > fwrt->fw_paging_db[0].fw_paging_size) {
+ IWL_ERR(fwrt, "CSS block is larger than paging size\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
memcpy(page_address(fwrt->fw_paging_db[0].fw_paging_block),
image->sec[sec_idx].data,
- fwrt->fw_paging_db[0].fw_paging_size);
+ image->sec[sec_idx].len);
dma_sync_single_for_device(fwrt->trans->dev,
fwrt->fw_paging_db[0].fw_paging_phys,
fwrt->fw_paging_db[0].fw_paging_size,
@@ -221,6 +229,14 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
for (idx = 1; idx < fwrt->num_of_paging_blk; idx++) {
struct iwl_fw_paging *block = &fwrt->fw_paging_db[idx];

+ if (block->fw_paging_size > image->sec[sec_idx].len - offset) {
+ IWL_ERR(fwrt,
+ "Paging: paging size is larger than remaining data in block %d\n",
+ idx);
+ ret = -EINVAL;
+ goto err;
+ }
+
memcpy(page_address(block->fw_paging_block),
image->sec[sec_idx].data + offset,
block->fw_paging_size);
@@ -231,19 +247,32 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,

IWL_DEBUG_FW(fwrt,
"Paging: copied %d paging bytes to block %d\n",
- fwrt->fw_paging_db[idx].fw_paging_size,
- idx);
+ block->fw_paging_size, idx);

- offset += fwrt->fw_paging_db[idx].fw_paging_size;
+ offset += block->fw_paging_size;
+
+ if (offset > image->sec[sec_idx].len) {
+ IWL_ERR(fwrt,
+ "Paging: offset goes over section size\n");
+ ret = -EINVAL;
+ goto err;
+ }
}

/* copy the last paging block */
if (fwrt->num_of_pages_in_last_blk > 0) {
struct iwl_fw_paging *block = &fwrt->fw_paging_db[idx];

+ if (image->sec[sec_idx].len - offset > block->fw_paging_size) {
+ IWL_ERR(fwrt,
+ "Paging: last block is larger than paging size\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
memcpy(page_address(block->fw_paging_block),
image->sec[sec_idx].data + offset,
- FW_PAGING_SIZE * fwrt->num_of_pages_in_last_blk);
+ image->sec[sec_idx].len - offset);
dma_sync_single_for_device(fwrt->trans->dev,
block->fw_paging_phys,
block->fw_paging_size,
@@ -255,6 +284,10 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
}

return 0;
+
+err:
+ iwl_free_fw_paging(fwrt);
+ return ret;
}

static int iwl_save_fw_paging(struct iwl_fw_runtime *fwrt,
--
2.17.0

2018-04-22 08:28:03

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 09/12] iwlwifi: pcie: remove non-responsive device

From: Luca Coelho <[email protected]>

If we fail to to grab NIC access because the device is not responding
(i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from the PCI
bus, to avoid any further damage, and to let the user space rescan.

Signed-off-by: Luca Coelho <[email protected]>
Signed-off-by: Rajat Jain <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 6 ++
.../wireless/intel/iwlwifi/iwl-modparams.h | 2 +
.../wireless/intel/iwlwifi/pcie/internal.h | 5 ++
.../net/wireless/intel/iwlwifi/pcie/trans.c | 74 ++++++++++++++++++-
4 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index 4f451a6f20b9..c59ce4f8a5ed 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1850,3 +1850,9 @@ MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");

module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool, 0444);
MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities (default: false)");
+
+module_param_named(remove_when_gone,
+ iwlwifi_mod_params.remove_when_gone, bool,
+ 0444);
+MODULE_PARM_DESC(remove_when_gone,
+ "Remove dev from PCIe bus if it is deemed inaccessible (default: false)");
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
index a41c46e63eb1..a7dd8a8cddf9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
@@ -122,6 +122,7 @@ enum iwl_uapsd_disable {
* @lar_disable: disable LAR (regulatory), default = 0
* @fw_monitor: allow to use firmware monitor
* @disable_11ac: disable VHT capabilities, default = false.
+ * @remove_when_gone: remove an inaccessible device from the PCIe bus.
*/
struct iwl_mod_params {
int swcrypto;
@@ -143,6 +144,7 @@ struct iwl_mod_params {
bool lar_disable;
bool fw_monitor;
bool disable_11ac;
+ bool remove_when_gone;
};

#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index cda66340d357..45ea32796cda 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -383,6 +383,8 @@ struct iwl_self_init_dram {
* @hw_init_mask: initial unmasked hw causes
* @fh_mask: current unmasked fh causes
* @hw_mask: current unmasked hw causes
+ * @in_rescan: true if we have triggered a device rescan
+ * @scheduled_for_removal: true if we have scheduled a device removal
*/
struct iwl_trans_pcie {
struct iwl_rxq *rxq;
@@ -464,6 +466,9 @@ struct iwl_trans_pcie {
u32 fh_mask;
u32 hw_mask;
cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
+ u16 tx_cmd_queue_size;
+ bool in_rescan;
+ bool scheduled_for_removal;
};

static inline struct iwl_trans_pcie *
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 623476603cd4..6e9a9ecfb11c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -75,6 +75,7 @@
#include <linux/gfp.h>
#include <linux/vmalloc.h>
#include <linux/pm_runtime.h>
+#include <linux/module.h>

#include "iwl-drv.h"
#include "iwl-trans.h"
@@ -1935,6 +1936,29 @@ static void iwl_trans_pcie_set_pmi(struct iwl_trans *trans, bool state)
clear_bit(STATUS_TPOWER_PMI, &trans->status);
}

+struct iwl_trans_pcie_removal {
+ struct pci_dev *pdev;
+ struct work_struct work;
+};
+
+static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
+{
+ struct iwl_trans_pcie_removal *removal =
+ container_of(wk, struct iwl_trans_pcie_removal, work);
+ struct pci_dev *pdev = removal->pdev;
+ char *prop[] = {"EVENT=INACCESSIBLE", NULL};
+
+ dev_err(&pdev->dev, "Device gone - attempting removal\n");
+ kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE, prop);
+ pci_lock_rescan_remove();
+ pci_dev_put(pdev);
+ pci_stop_and_remove_bus_device(pdev);
+ pci_unlock_rescan_remove();
+
+ kfree(removal);
+ module_put(THIS_MODULE);
+}
+
static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
unsigned long *flags)
{
@@ -1977,11 +2001,55 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
(BIT(trans->cfg->csr->flag_mac_clock_ready) |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
if (unlikely(ret < 0)) {
- iwl_trans_pcie_dump_regs(trans);
- iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+ u32 cntrl = iwl_read32(trans, CSR_GP_CNTRL);
+
WARN_ONCE(1,
"Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
- iwl_read32(trans, CSR_GP_CNTRL));
+ cntrl);
+
+ iwl_trans_pcie_dump_regs(trans);
+
+ if (iwlwifi_mod_params.remove_when_gone && cntrl == ~0U) {
+ struct iwl_trans_pcie_removal *removal;
+
+ if (trans_pcie->scheduled_for_removal)
+ goto err;
+
+ IWL_ERR(trans, "Device gone - scheduling removal!\n");
+
+ /*
+ * get a module reference to avoid doing this
+ * while unloading anyway and to avoid
+ * scheduling a work with code that's being
+ * removed.
+ */
+ if (!try_module_get(THIS_MODULE)) {
+ IWL_ERR(trans,
+ "Module is being unloaded - abort\n");
+ goto err;
+ }
+
+ removal = kzalloc(sizeof(*removal), GFP_ATOMIC);
+ if (!removal) {
+ module_put(THIS_MODULE);
+ goto err;
+ }
+ /*
+ * we don't need to clear this flag, because
+ * the trans will be freed and reallocated.
+ */
+ trans_pcie->scheduled_for_removal = true;
+
+ removal->pdev = to_pci_dev(trans->dev);
+ INIT_WORK(&removal->work, iwl_trans_pcie_removal_wk);
+ pci_dev_get(removal->pdev);
+ schedule_work(&removal->work);
+ } else {
+ iwl_write32(trans, CSR_RESET,
+ CSR_RESET_REG_FLAG_FORCE_NMI);
+ }
+
+err:
spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
return false;
}
--
2.17.0

2018-04-22 08:28:19

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 10/12] iwlwifi: make bitfield a u32 instead of u16

From: Luca Coelho <[email protected]>

The bitfield we use in struct iwl_cfg contains 17 bits, but we declare
it as u16. The compiler doesn't seem to have any problems with that
(it probably automatically makes it u32), but it's cleaner to use a
type that is long enough for all the flags.

Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index cfd14e5ea59c..c503b26793f6 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -420,7 +420,7 @@ struct iwl_cfg {
u32 soc_latency;
u16 nvm_ver;
u16 nvm_calib_ver;
- u16 rx_with_siso_diversity:1,
+ u32 rx_with_siso_diversity:1,
bt_shared_single_ant:1,
internal_wimax_coex:1,
host_interrupt_operation_mode:1,
--
2.17.0

2018-04-24 10:57:00

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 12/12] iwlwifi: mvm: set wakeup filters for wowlan "any" configuration

On Tue, 2018-04-24 at 12:45 +0300, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > From: Eliad Peller <[email protected]>
> >
> > In can of "any" wowlan trigger is configured, no valid wakeup
> > filter
> > was configured.
>
> "In case"?

Yeah, I'll fix it and resend.

--
Luca.

2018-04-22 08:28:02

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 08/12] iwlwifi: fw: combine loading of last page block into main copy loop

From: Luca Coelho <[email protected]>

Now that we check and copy only the actual size of the page block,
there is no need to treat the last block separately. Remove the
mostly duplicate code and make the main copy loop handle also the last
block.

Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/fw/paging.c | 69 +++++++------------
1 file changed, 26 insertions(+), 43 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
index 6afcfd1f0eec..9b8dd7fe7112 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
@@ -221,25 +221,39 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,
sec_idx++;

/*
- * copy the paging blocks to the dram
- * loop index start from 1 since that CSS block already copied to dram
- * and CSS index is 0.
- * loop stop at num_of_paging_blk since that last block is not full.
+ * Copy the paging blocks to the dram. The loop index starts
+ * from 1 since the CSS block (index 0) was already copied to
+ * dram. We use num_of_paging_blk + 1 to account for that.
*/
- for (idx = 1; idx < fwrt->num_of_paging_blk; idx++) {
+ for (idx = 1; idx < fwrt->num_of_paging_blk + 1; idx++) {
struct iwl_fw_paging *block = &fwrt->fw_paging_db[idx];
-
- if (block->fw_paging_size > image->sec[sec_idx].len - offset) {
+ int remaining = image->sec[sec_idx].len - offset;
+ int len = block->fw_paging_size;
+
+ /*
+ * For the last block, we copy all that is remaining,
+ * for all other blocks, we copy fw_paging_size at a
+ * time. */
+ if (idx == fwrt->num_of_paging_blk) {
+ len = remaining;
+ if (remaining !=
+ fwrt->num_of_pages_in_last_blk * FW_PAGING_SIZE) {
+ IWL_ERR(fwrt,
+ "Paging: last block contains more data than expected %d\n",
+ remaining);
+ ret = -EINVAL;
+ goto err;
+ }
+ } else if (block->fw_paging_size > remaining) {
IWL_ERR(fwrt,
- "Paging: paging size is larger than remaining data in block %d\n",
- idx);
+ "Paging: not enough data in other in block %d (%d)\n",
+ idx, remaining);
ret = -EINVAL;
goto err;
}

memcpy(page_address(block->fw_paging_block),
- image->sec[sec_idx].data + offset,
- block->fw_paging_size);
+ image->sec[sec_idx].data + offset, len);
dma_sync_single_for_device(fwrt->trans->dev,
block->fw_paging_phys,
block->fw_paging_size,
@@ -247,40 +261,9 @@ static int iwl_fill_paging_mem(struct iwl_fw_runtime *fwrt,

IWL_DEBUG_FW(fwrt,
"Paging: copied %d paging bytes to block %d\n",
- block->fw_paging_size, idx);
+ len, idx);

offset += block->fw_paging_size;
-
- if (offset > image->sec[sec_idx].len) {
- IWL_ERR(fwrt,
- "Paging: offset goes over section size\n");
- ret = -EINVAL;
- goto err;
- }
- }
-
- /* copy the last paging block */
- if (fwrt->num_of_pages_in_last_blk > 0) {
- struct iwl_fw_paging *block = &fwrt->fw_paging_db[idx];
-
- if (image->sec[sec_idx].len - offset > block->fw_paging_size) {
- IWL_ERR(fwrt,
- "Paging: last block is larger than paging size\n");
- ret = -EINVAL;
- goto err;
- }
-
- memcpy(page_address(block->fw_paging_block),
- image->sec[sec_idx].data + offset,
- image->sec[sec_idx].len - offset);
- dma_sync_single_for_device(fwrt->trans->dev,
- block->fw_paging_phys,
- block->fw_paging_size,
- DMA_BIDIRECTIONAL);
-
- IWL_DEBUG_FW(fwrt,
- "Paging: copied %d pages in the last block %d\n",
- fwrt->num_of_pages_in_last_blk, idx);
}

return 0;
--
2.17.0

2018-04-26 07:53:03

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 12/12] iwlwifi: mvm: set wakeup filters for wowlan "any" configuration

From: Eliad Peller <[email protected]>

In case of "any" wowlan trigger is configured, no valid wakeup filter
was configured.

Moreover, the fw assumes there's no connection when there are no configured
wakeup filters.
This leads to the station info not being updated on D3 command, causing
rate_n_flags to be 0 when the offloading code sends tx frame (triggering
SYSASSERT_102C due to invalid antenna param)

Note: "any" trigger is currently assumed to only be used when entering
d0i3 (which has a different flow). However, we still reach this code
when using d3_test.

Signed-off-by: Eliad Peller <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 80a9a7cb83be..3fcf489f3120 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -18,11 +19,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
@@ -35,6 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -693,6 +690,14 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
IWL_WOWLAN_WAKEUP_LINK_CHANGE);
}

+ if (wowlan->any) {
+ wowlan_config_cmd->wakeup_filter |=
+ cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
+ IWL_WOWLAN_WAKEUP_LINK_CHANGE |
+ IWL_WOWLAN_WAKEUP_RX_FRAME |
+ IWL_WOWLAN_WAKEUP_BCN_FILTERING);
+ }
+
return 0;
}

--
2.17.0

2018-04-22 08:28:38

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 11/12] iwlwifi: mvm: remove check for non low latency TIDs

From: Sara Sharon <[email protected]>

Firmware will only send non low-latency TIDs in the
bitmap, so the check is now redundant.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index d0916f2552e2..df4c60496f72 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -803,7 +803,6 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);

if (iwl_mvm_vif_low_latency(iwl_mvm_vif_from_mac80211(mvmsta->vif)) ||
- tid_to_mac80211_ac[tid] < IEEE80211_AC_BE ||
!(mvmsta->amsdu_enabled & BIT(tid)))
return iwl_mvm_tx_tso_segment(skb, 1, netdev_flags, mpdus_skb);

--
2.17.0

2018-04-22 08:27:59

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 03/12] iwlwifi: cfg: remove unnecessary cfg data in non-dvm devices

From: Luca Coelho <[email protected]>

The max_data_size and max_inst_size values are only needed for DVM
devices. Remove the assignment to those fields in 7000 and newer
families so we can also remove the otherwise unnecessary inclusion of
iwl-agn.h headers.

Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 3 ---
drivers/net/wireless/intel/iwlwifi/cfg/7000.c | 11 ++++-------
drivers/net/wireless/intel/iwlwifi/cfg/8000.c | 9 +++------
drivers/net/wireless/intel/iwlwifi/cfg/9000.c | 3 ---
drivers/net/wireless/intel/iwlwifi/iwl-config.h | 4 ++--
5 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index afc78a1e1cfc..d4ba66aecdc9 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -54,7 +54,6 @@
#include <linux/module.h>
#include <linux/stringify.h>
#include "iwl-config.h"
-#include "iwl-agn-hw.h"

/* Highest firmware API version supported */
#define IWL_22000_UCODE_API_MAX 38
@@ -115,8 +114,6 @@ static const struct iwl_ht_params iwl_22000_ht_params = {
.ucode_api_max = IWL_22000_UCODE_API_MAX, \
.ucode_api_min = IWL_22000_UCODE_API_MIN, \
.device_family = IWL_DEVICE_FAMILY_22000, \
- .max_inst_size = IWL60_RTC_INST_SIZE, \
- .max_data_size = IWL60_RTC_DATA_SIZE, \
.base_params = &iwl_22000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_22000, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
index 8e9684e8e603..69bfa827e82a 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/7000.c
@@ -7,8 +7,8 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
- * Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,8 +35,8 @@
*
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
- * Copyright(c) 2015 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -70,7 +70,6 @@
#include <linux/module.h>
#include <linux/stringify.h>
#include "iwl-config.h"
-#include "iwl-agn-hw.h"

/* Highest firmware API version supported */
#define IWL7260_UCODE_API_MAX 17
@@ -162,8 +161,6 @@ static const struct iwl_ht_params iwl7000_ht_params = {

#define IWL_DEVICE_7000_COMMON \
.device_family = IWL_DEVICE_FAMILY_7000, \
- .max_inst_size = IWL60_RTC_INST_SIZE, \
- .max_data_size = IWL60_RTC_DATA_SIZE, \
.base_params = &iwl7000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
index e8299b2ab6bd..7262e973e0d6 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/8000.c
@@ -7,8 +7,8 @@
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016 Intel Deutschland GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,7 +35,7 @@
*
* Copyright(c) 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2014 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2018 Intel Corporation
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -69,7 +69,6 @@
#include <linux/module.h>
#include <linux/stringify.h>
#include "iwl-config.h"
-#include "iwl-agn-hw.h"

/* Highest firmware API version supported */
#define IWL8000_UCODE_API_MAX 36
@@ -142,8 +141,6 @@ static const struct iwl_tt_params iwl8000_tt_params = {

#define IWL_DEVICE_8000_COMMON \
.device_family = IWL_DEVICE_FAMILY_8000, \
- .max_inst_size = IWL60_RTC_INST_SIZE, \
- .max_data_size = IWL60_RTC_DATA_SIZE, \
.base_params = &iwl8000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
index fe376fce3444..9706624911f8 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/9000.c
@@ -54,7 +54,6 @@
#include <linux/module.h>
#include <linux/stringify.h>
#include "iwl-config.h"
-#include "iwl-agn-hw.h"
#include "fw/file.h"

/* Highest firmware API version supported */
@@ -135,8 +134,6 @@ static const struct iwl_tt_params iwl9000_tt_params = {
.ucode_api_max = IWL9000_UCODE_API_MAX, \
.ucode_api_min = IWL9000_UCODE_API_MIN, \
.device_family = IWL_DEVICE_FAMILY_9000, \
- .max_inst_size = IWL60_RTC_INST_SIZE, \
- .max_data_size = IWL60_RTC_DATA_SIZE, \
.base_params = &iwl9000_base_params, \
.led_mode = IWL_LED_RF_STATE, \
.nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_9000, \
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index 7f0b7cea8b9b..7752794d0437 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -337,8 +337,8 @@ struct iwl_csr_params {
* next step. Supported only in integrated solutions.
* @ucode_api_max: Highest version of uCode API supported by driver.
* @ucode_api_min: Lowest version of uCode API supported by driver.
- * @max_inst_size: The maximal length of the fw inst section
- * @max_data_size: The maximal length of the fw data section
+ * @max_inst_size: The maximal length of the fw inst section (only DVM)
+ * @max_data_size: The maximal length of the fw data section (only DVM)
* @valid_tx_ant: valid transmit antenna
* @valid_rx_ant: valid receive antenna
* @non_shared_ant: the antenna that is for WiFi only
--
2.17.0

2018-04-22 08:28:42

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 12/12] iwlwifi: mvm: set wakeup filters for wowlan "any" configuration

From: Eliad Peller <[email protected]>

In can of "any" wowlan trigger is configured, no valid wakeup filter
was configured.

Moreover, the fw assumes there's no connection when there are no configured
wakeup filters.
This leads to the station info not being updated on D3 command, causing
rate_n_flags to be 0 when the offloading code sends tx frame (triggering
SYSASSERT_102C due to invalid antenna param)

Note: "any" trigger is currently assumed to only be used when entering
d0i3 (which has a different flow). However, we still reach this code
when using d3_test.

Signed-off-by: Eliad Peller <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 80a9a7cb83be..3fcf489f3120 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -8,6 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -18,11 +19,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
*
@@ -35,6 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -693,6 +690,14 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
IWL_WOWLAN_WAKEUP_LINK_CHANGE);
}

+ if (wowlan->any) {
+ wowlan_config_cmd->wakeup_filter |=
+ cpu_to_le32(IWL_WOWLAN_WAKEUP_BEACON_MISS |
+ IWL_WOWLAN_WAKEUP_LINK_CHANGE |
+ IWL_WOWLAN_WAKEUP_RX_FRAME |
+ IWL_WOWLAN_WAKEUP_BCN_FILTERING);
+ }
+
return 0;
}

--
2.17.0

2018-04-26 07:46:29

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 09/12] iwlwifi: pcie: remove non-responsive device

On Wed, 2018-04-25 at 11:01 +0300, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > On Tue, 2018-04-24 at 12:44 +0300, Kalle Valo wrote:
> > > Luca Coelho <[email protected]> writes:
> > >
> > > > From: Luca Coelho <[email protected]>
> > > >
> > > > If we fail to to grab NIC access because the device is not
> > > > responding
> > > > (i.e. CSR_GP_CNTRL returns 0xFFFFFFFF), remove the device from
> > > > the
> > > > PCI
> > > > bus, to avoid any further damage, and to let the user space
> > > > rescan.
> > > >
> > > > Signed-off-by: Luca Coelho <[email protected]>
> > > > Signed-off-by: Rajat Jain <[email protected]>
> > >
> > > The commit log doesn't mention anything about the module
> > > parameter
> > > nor
> > > about the kobject uevent.
> >
> > Good point. The uevent and the module parameter were added in
> > later
> > patches and I squashed them all into this one, but forgot to update
> > the
> > commit message. I'll fix it.
>
> Good, thanks.
>
> > > > +static void iwl_trans_pcie_removal_wk(struct work_struct *wk)
> > > > +{
> > > > + struct iwl_trans_pcie_removal *removal =
> > > > + container_of(wk, struct
> > > > iwl_trans_pcie_removal,
> > > > work);
> > > > + struct pci_dev *pdev = removal->pdev;
> > > > + char *prop[] = {"EVENT=INACCESSIBLE", NULL};
> > > > +
> > > > + dev_err(&pdev->dev, "Device gone - attempting
> > > > removal\n");
> > > > + kobject_uevent_env(&pdev->dev.kobj, KOBJ_CHANGE,
> > > > prop);
> > > > + pci_lock_rescan_remove();
> > > > + pci_dev_put(pdev);
> > > > + pci_stop_and_remove_bus_device(pdev);
> > > > + pci_unlock_rescan_remove();
> > > > +
> > > > + kfree(removal);
> > > > + module_put(THIS_MODULE);
> > > > +}
> > >
> > > So is the uevent some standard thing or what? At least grepping
> > > INACCESSIBLE for didn't tell me anything.
> >
> > No, this is not standard. We didn't find any appropriate standard
> > message for this case, so we created a new one. Also, we didn't
> > want
> > to interfere with components that may react to standard messages.
> >
> > This is disabled by default and the idea is to change this in the
> > future to allow the driver to remove and rescan the device
> > automatically. So we will have 3 options in the module parameter:
> > do
> > nothing; auto-rescan or; send uevent.
>
> Ok, I assume you will explain this in the commit log.

Yes, I'll improve the commit message.


> In my opinion the driver should not be sending custom events like
> this
> and instead pci_stop_and_remove_bus_device() should do it, but maybe
> that's just me?

pci_stop_and_remove_bus_device() will already trigger some events, like
"REMOVED" or something like that. But the semantics is a little bit
different. If the device was removed, you don't usually want to rescan
the bus, because the device will not be there anymore. In our case,
the device *is* there, but got stuck and we want to rescan to get it
back.

--
Cheers,
Luca.

2018-04-22 08:27:58

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 02/12] iwlwifi: introduce Image Loader (IML) - new firmware image

From: Golan Ben-Ami <[email protected]>

In future devices a new image will be introduced - IML. The IML, image
loader, is loaded by the ROM, and as part of the new self-init flow,
loads the rest of the firmware images to the device.

Store the image, so the ROM can load it to the device.

Signed-off-by: Golan Ben Ami <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 +++
drivers/net/wireless/intel/iwlwifi/fw/img.h | 6 ++++++
drivers/net/wireless/intel/iwlwifi/iwl-drv.c | 8 ++++++++
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 5 +++++
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 3 +++
5 files changed, 25 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 9b2805e1e3b1..9d939cbaf6c6 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -8,6 +8,7 @@
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -143,6 +145,7 @@ enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
IWL_UCODE_TLV_FW_GSCAN_CAPA = 50,
IWL_UCODE_TLV_FW_MEM_SEG = 51,
+ IWL_UCODE_TLV_IML = 52,
};

struct iwl_ucode_tlv {
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
index b23ffe12ad84..f4912382b6af 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
@@ -8,6 +8,7 @@
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -35,6 +36,7 @@
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2018 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -241,6 +243,8 @@ enum iwl_fw_type {
* @ucode_ver: ucode version from the ucode file
* @fw_version: firmware version string
* @img: ucode image like ucode_rt, ucode_init, ucode_wowlan.
+ * @iml_len: length of the image loader image
+ * @iml: image loader fw image
* @ucode_capa: capabilities parsed from the ucode file.
* @enhance_sensitivity_table: device can do enhanced sensitivity.
* @init_evtlog_ptr: event log offset for init ucode.
@@ -267,6 +271,8 @@ struct iwl_fw {

/* ucode images */
struct fw_img img[IWL_UCODE_TYPE_MAX];
+ size_t iml_len;
+ u8 *iml;

struct iwl_ucode_capabilities ucode_capa;
bool enhance_sensitivity_table;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index aa2d5c14e202..4f451a6f20b9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -179,6 +179,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
kfree(drv->fw.dbg_trigger_tlv[i]);
kfree(drv->fw.dbg_mem_tlv);
+ kfree(drv->fw.iml);

for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
iwl_free_fw_img(drv, drv->fw.img + i);
@@ -1126,6 +1127,13 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
pieces->n_dbg_mem_tlv++;
break;
}
+ case IWL_UCODE_TLV_IML: {
+ drv->fw.iml_len = tlv_len;
+ drv->fw.iml = kmemdup(tlv_data, tlv_len, GFP_KERNEL);
+ if (!drv->fw.iml)
+ return -ENOMEM;
+ break;
+ }
default:
IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
break;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index a92832711683..1b9c627ee34d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -691,6 +691,8 @@ enum iwl_plat_pm_mode {
* @wide_cmd_header: true when ucode supports wide command header format
* @num_rx_queues: number of RX queues allocated by the transport;
* the transport must set this before calling iwl_drv_start()
+ * @iml_len: the length of the image loader
+ * @iml: a pointer to the image loader itself
* @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
* The user should use iwl_trans_{alloc,free}_tx_cmd.
* @rx_mpdu_cmd: MPDU RX command ID, must be assigned by opmode before
@@ -735,6 +737,9 @@ struct iwl_trans {

u8 num_rx_queues;

+ size_t iml_len;
+ u8 *iml;
+
/* The following fields are internal only */
struct kmem_cache *dev_cmd_pool;
char dev_cmd_pool_name[50];
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index de46e6258a5c..ff1e518096c5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -739,6 +739,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
sizeof(trans->dbg_conf_tlv));
trans->dbg_trigger_tlv = mvm->fw->dbg_trigger_tlv;

+ trans->iml = mvm->fw->iml;
+ trans->iml_len = mvm->fw->iml_len;
+
/* set up notification wait support */
iwl_notification_wait_init(&mvm->notif_wait);

--
2.17.0

2018-05-31 09:17:50

by Luca Coelho

[permalink] [raw]
Subject: Re: iwlwifi: regression due to: allow different csr flags for different device families

On Thu, 2018-05-31 at 11:44 +0300, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > On Sun, 2018-05-27 at 14:08 +0200, Alexander Wetzel wrote:
> > > > From: Golan Ben Ami <[email protected]>
> > > >
> > > > Different device families may have different flag values
> > > > for passing a message to the fw (i.e. SW_RESET).
> > > > In order to keep the code readable, and avoid conditioning
> > > > upon the family, store a value for each flag, which indicates
> > > > the bit that needs to be enabled.
> > > >
> > > > Signed-off-by: Golan Ben Ami <[email protected]>
> > > > Signed-off-by: Luca Coelho <[email protected]>
> > >
> > > This patch generates a Null pointer exception for my Ultimate-N
> > > 6300
> > > card when loading the driver, making the card unusable.
> > > (Bisecting linked it to commit
> > > a8cbb46f831d2c101feccdd0e0daf3627b8c1dca.)
> > >
> > > Sine the commit could not be simply reverted I applied this
> > > commit to
> > > my
> > > distribution kernel - basically 4.16.12 - and can confirm it is
> > > indeed
> > > causing the issue.
> >
> > It seems that I forgot to reply to this, even though we looked into
> > it
> > and provided a fix[1]. This fix will hopefully be included in 4.17
> > final.
> >
> > Thanks a lot for reporting and bisecting!
> >
> > [1] https://patchwork.kernel.org/patch/10437773/
>
> Something is not right, commit 0513c083d1f4 is in wireless-drivers-
> next
> so it will be in 4.18. Are we mixing commits or releases or did I
> pull
> it to wrong tree?
>
> 0513c083d1f4 iwlwifi: add csr configuration for 6300 devices

No, you are right, it was my mistake (I mixed this up with the 16 CPUs
which you picked up for 4.17). The fix for this regression should go
only to 4.18, since the original patch is not even in 4.17-rc*.

Sorry for the confusion.

So, rephrasing my buggy phrase from the previous email:

"This fix will hopefully be included in 4.18-rc1 and probably earlier
in wireless-testing".

--
Cheers,
Luca.

2018-05-31 06:30:53

by Luca Coelho

[permalink] [raw]
Subject: Re: iwlwifi: regression due to: allow different csr flags for different device families

On Sun, 2018-05-27 at 14:08 +0200, Alexander Wetzel wrote:
> > From: Golan Ben Ami <[email protected]>
> >
> > Different device families may have different flag values
> > for passing a message to the fw (i.e. SW_RESET).
> > In order to keep the code readable, and avoid conditioning
> > upon the family, store a value for each flag, which indicates
> > the bit that needs to be enabled.
> >
> > Signed-off-by: Golan Ben Ami <[email protected]>
> > Signed-off-by: Luca Coelho <[email protected]>
>
> This patch generates a Null pointer exception for my Ultimate-N 6300
> card when loading the driver, making the card unusable.
> (Bisecting linked it to commit
> a8cbb46f831d2c101feccdd0e0daf3627b8c1dca.)
>
> Sine the commit could not be simply reverted I applied this commit to
> my
> distribution kernel - basically 4.16.12 - and can confirm it is
> indeed
> causing the issue.

It seems that I forgot to reply to this, even though we looked into it
and provided a fix[1]. This fix will hopefully be included in 4.17
final.

Thanks a lot for reporting and bisecting!

[1] https://patchwork.kernel.org/patch/10437773/

--
Cheers,
Luca.

2018-05-31 08:44:51

by Kalle Valo

[permalink] [raw]
Subject: Re: iwlwifi: regression due to: allow different csr flags for different device families

Luca Coelho <[email protected]> writes:

> On Sun, 2018-05-27 at 14:08 +0200, Alexander Wetzel wrote:
>> > From: Golan Ben Ami <[email protected]>
>> >
>> > Different device families may have different flag values
>> > for passing a message to the fw (i.e. SW_RESET).
>> > In order to keep the code readable, and avoid conditioning
>> > upon the family, store a value for each flag, which indicates
>> > the bit that needs to be enabled.
>> >
>> > Signed-off-by: Golan Ben Ami <[email protected]>
>> > Signed-off-by: Luca Coelho <[email protected]>
>>
>> This patch generates a Null pointer exception for my Ultimate-N 6300
>> card when loading the driver, making the card unusable.
>> (Bisecting linked it to commit
>> a8cbb46f831d2c101feccdd0e0daf3627b8c1dca.)
>>
>> Sine the commit could not be simply reverted I applied this commit to
>> my
>> distribution kernel - basically 4.16.12 - and can confirm it is
>> indeed
>> causing the issue.
>
> It seems that I forgot to reply to this, even though we looked into it
> and provided a fix[1]. This fix will hopefully be included in 4.17
> final.
>
> Thanks a lot for reporting and bisecting!
>
> [1] https://patchwork.kernel.org/patch/10437773/

Something is not right, commit 0513c083d1f4 is in wireless-drivers-next
so it will be in 4.18. Are we mixing commits or releases or did I pull
it to wrong tree?

0513c083d1f4 iwlwifi: add csr configuration for 6300 devices

--
Kalle Valo

2018-05-27 13:27:11

by Alexander Wetzel

[permalink] [raw]
Subject: iwlwifi: regression due to: allow different csr flags for different device families

> From: Golan Ben Ami <[email protected]>
>
> Different device families may have different flag values
> for passing a message to the fw (i.e. SW_RESET).
> In order to keep the code readable, and avoid conditioning
> upon the family, store a value for each flag, which indicates
> the bit that needs to be enabled.
>
> Signed-off-by: Golan Ben Ami <[email protected]>
> Signed-off-by: Luca Coelho <[email protected]>

This patch generates a Null pointer exception for my Ultimate-N 6300
card when loading the driver, making the card unusable.
(Bisecting linked it to commit
a8cbb46f831d2c101feccdd0e0daf3627b8c1dca.)

Sine the commit could not be simply reverted I applied this commit to my
distribution kernel - basically 4.16.12 - and can confirm it is indeed
causing the issue.

I've a trace from loading the module with the current 4.17.0-rc6-wt+,
but that's not very interesting:

modprobe-32134 [006] 705.747029: iwlwifi_info:
CONFIG_IWLWIFI_DEBUG enabled
modprobe-32134 [006] 705.747037: iwlwifi_info:
CONFIG_IWLWIFI_DEBUGFS enabled
modprobe-32134 [006] 705.747038: iwlwifi_info:
CONFIG_IWLWIFI_DEVICE_TRACING enabled
modprobe-32134 [006] 705.747039: iwlwifi_dbg: ***
LOAD DRIVER ***
modprobe-32134 [006] 705.747039: iwlwifi_dbg: BT
channel inhibition is On
modprobe-32134 [006] 705.747041: iwlwifi_info:
Detected Intel(R) Centrino(R) Ultimate-N 6300 AGN, REV=0x74
modprobe-32134 [006] 705.747042: iwlwifi_dbg:
iwl_trans_prepare_card_hw enter
modprobe-32134 [006] 705.747093: iwlwifi_dbg:
hardware ready


Here how the error looks in dmesg when loading the module (matches to
the trace above):

[ 705.772297] iwlwifi 0000:03:00.0: CONFIG_IWLWIFI_DEBUG enabled
[ 705.772307] iwlwifi 0000:03:00.0: CONFIG_IWLWIFI_DEBUGFS enabled
[ 705.772309] iwlwifi 0000:03:00.0: CONFIG_IWLWIFI_DEVICE_TRACING enabled
[ 705.772312] iwlwifi 0000:03:00.0: Detected Intel(R) Centrino(R)
Ultimate-N 6300 AGN, REV=0x74
[ 705.772369] BUG: unable to handle kernel NULL pointer dereference at
0000000000000000
[ 705.772371] PGD 0 P4D 0
[ 705.772374] Oops: 0000 [#1] SMP PTI
[ 705.772376] Modules linked in: iwldvm(+) ctr ccm arc4 rt2800usb
rt2x00usb rt2800lib crc_ccitt rt2x00lib iptable_mangle ipt_MASQUERADE
nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4
nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4
xt_tcpudp tun bridge stp llc ip6table_filter ip6_tables iptable_filter
ip_tables x_tables btusb btrtl btbcm btintel bluetooth
snd_hda_codec_realtek snd_hda_codec_generic x86_pkg_temp_thermal
coretemp ext4 mbcache jbd2 mac80211 iwlwifi snd_hda_intel kvm_intel kvm
sdhci_pci snd_hda_codec cqhci irqbypass joydev e1000e xhci_pci
thinkpad_acpi input_leds snd_hda_core sdhci cfg80211 firewire_ohci
nouveau thermal nvram snd_hwdep ehci_pci xhci_hcd mmc_core snd_pcm
ehci_hcd rfkill firewire_core ptp snd_timer led_class battery ac rtc_cmos
[ 705.772415] usbcore snd pps_core ttm i2c_i801 usb_common
[ 705.772421] CPU: 6 PID: 32134 Comm: modprobe Not tainted
4.17.0-rc6-wt #13
[ 705.772423] Hardware name: LENOVO 2438CTO/2438CTO, BIOS G5ETA7WW
(2.67 ) 05/16/2017
[ 705.772429] RIP: 0010:iwl_trans_pcie_sw_reset+0x12/0x40 [iwlwifi]
[ 705.772430] RSP: 0018:ffffc90003187bb8 EFLAGS: 00010246
[ 705.772431] RAX: 0000000000000000 RBX: ffff880617820018 RCX:
0000000000000000
[ 705.772432] RDX: 0000000000000001 RSI: 0000000000000246 RDI:
ffff880617820018
[ 705.772433] RBP: 0000000000000000 R08: 0000000000000008 R09:
ffff880625bcc000
[ 705.772434] R10: 00000000000004c1 R11: ffff880625ba4c00 R12:
ffff880617827d30
[ 705.772435] R13: 0000000000000001 R14: ffff880617820220 R15:
ffffc90003187c00
[ 705.772437] FS: 00007f55a3e08740(0000) GS:ffff88063e380000(0000)
knlGS:0000000000000000
[ 705.772438] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 705.772439] CR2: 0000000000000000 CR3: 000000054522a002 CR4:
00000000001606e0
[ 705.772440] Call Trace:
[ 705.772446] iwl_trans_pcie_start_hw+0x3f/0x1a0 [iwlwifi]
[ 705.772453] iwl_op_mode_dvm_start+0x259/0xb70 [iwldvm]
[ 705.772458] _iwl_op_mode_start.isra.8+0x47/0xa0 [iwlwifi]
[ 705.772461] ? _cond_resched+0x15/0x40
[ 705.772465] iwl_opmode_register+0x6f/0xe0 [iwlwifi]
[ 705.772467] ? 0xffffffffa08d6000
[ 705.772472] iwl_init+0x34/0x1000 [iwldvm]
[ 705.772476] do_one_initcall+0x4f/0x1d0
[ 705.772478] ? _cond_resched+0x15/0x40
[ 705.772480] do_init_module+0x5b/0x1fb
[ 705.772483] load_module+0x23a7/0x28c0
[ 705.772486] ? __se_sys_finit_module+0x87/0xa0
[ 705.772488] __se_sys_finit_module+0x87/0xa0
[ 705.772490] do_syscall_64+0x4f/0x100
[ 705.772494] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 705.772496] RIP: 0033:0x7f55a3746749
[ 705.772497] RSP: 002b:00007ffdc02fd8e8 EFLAGS: 00000206 ORIG_RAX:
0000000000000139
[ 705.772499] RAX: ffffffffffffffda RBX: 000055c87462abe0 RCX:
00007f55a3746749
[ 705.772500] RDX: 0000000000000000 RSI: 000055c87390d65e RDI:
0000000000000003
[ 705.772501] RBP: 000055c87390d65e R08: 0000000000000000 R09:
0000000000000000
[ 705.772502] R10: 0000000000000003 R11: 0000000000000206 R12:
0000000000000000
[ 705.772503] R13: 000055c87462ae10 R14: 0000000000040000 R15:
0000000000000000
[ 705.772505] Code: c7 c1 80 4a d7 a0 e8 3e 39 ff ff 89 e8 5b 5d c3 66
0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8b 47 10 ba 01 00 00 00 48 8b
40 50 <0f> b6 08 0f b6 70 07 48 8b 07 48 d3 e2 89 d1 48 8b 80 f8 00 00
[ 705.772538] RIP: iwl_trans_pcie_sw_reset+0x12/0x40 [iwlwifi] RSP:
ffffc90003187bb8
[ 705.772540] CR2: 0000000000000000
[ 705.772542] ---[ end trace 4337b74fce7e90bc ]---