2018-08-21 09:55:53

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 00/15] iwlwifi: updates intended for v4.20 2018-08-21

From: Luca Coelho <[email protected]>

Hi,

Here's the second set of patches intended for v4.20. It's the usual
developments, with some small new feauters, cleanups and bugfixes.

The changes are:

* Some improvements in the PCI recovery mechanism;
* Support for a few FW API changes;
* Miscellaneous bugfixes;
* Other clean-ups and small improvements;

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

I have a lot of pending patches in our internal tree, so I'll probably
send another patchset before sending the pull-request.

Please review.

Cheers,
Luca.


Avraham Stern (1):
iwlwifi: mvm: Send LQ command as async when necessary

Ayala Beker (1):
iwlwifi: mvm: skip EBS in low latency mode while fragmented scan isn't
supported

Emmanuel Grumbach (1):
iwlwifi: improve the flow when a NIC is disconnected

Erel Geron (1):
iwlwifi: mvm: support Coex Schema 2

Golan Ben Ami (3):
iwlwifi: remove FSF's address from the license notice
iwlwifi: pcie: store the default rxq number
iwlwifi: pcie: make gen2 of apm_init non-static

Haim Dreyfuss (1):
iwlwifi: mvm: support new reduce tx power FW API.

Johannes Berg (2):
iwlwifi: remove dump_regs() from transport ops
iwlwifi: don't WARN on trying to dump dead firmware

Matt Chen (1):
iwlwifi: pcie: avoid unnecessary work if NIC is disconnected

Mordechay Goodstein (1):
iwlwifi: add 80211 hdr offset to trace data

Sara Sharon (3):
iwlwifi: mvm: fix BAR seq ctrl reporting
iwlwifi: mvm: avoid sending too many BARs
iwlwifi: pcie: set interrupt coalescing also for gen2

.../net/wireless/intel/iwlwifi/fw/api/coex.h | 3 ++
.../wireless/intel/iwlwifi/fw/api/commands.h | 3 +-
.../net/wireless/intel/iwlwifi/fw/api/power.h | 30 ++++++++++++++++--
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 7 ++---
drivers/net/wireless/intel/iwlwifi/fw/file.h | 7 +++++
.../intel/iwlwifi/iwl-devtrace-data.h | 10 ++----
.../intel/iwlwifi/iwl-devtrace-iwlwifi.h | 14 +++++----
.../net/wireless/intel/iwlwifi/iwl-devtrace.h | 22 +++++++------
.../net/wireless/intel/iwlwifi/iwl-op-mode.h | 6 ++--
.../net/wireless/intel/iwlwifi/iwl-trans.h | 11 -------
drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 9 ++++--
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 23 +++++++++-----
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 31 +++++++++++++------
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 ++++-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 ++--
drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 18 +++++------
drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 11 ++++++-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 17 +++++++---
.../net/wireless/intel/iwlwifi/mvm/utils.c | 7 ++---
.../wireless/intel/iwlwifi/pcie/internal.h | 6 ++--
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 5 ++-
.../wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +-
.../net/wireless/intel/iwlwifi/pcie/trans.c | 13 +++++---
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 10 +++++-
25 files changed, 186 insertions(+), 94 deletions(-)

--
2.18.0


2018-08-21 09:56:10

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 15/15] iwlwifi: pcie: set interrupt coalescing also for gen2

From: Sara Sharon <[email protected]>

We offloaded all the RX configuration of init to firmware. However,
the configuration of interrupt coalescing was left hanging - it wasn't
offloaded nor was it written by host.

This write to the CSR is allowed in gen2, so the host can do it.
Without it we have various issues with RX fullness.

Signed-off-by: Sara Sharon <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 8075466aa4c4..7d9a4e5d4926 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1107,6 +1107,9 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)

int iwl_pcie_gen2_rx_init(struct iwl_trans *trans)
{
+ /* Set interrupt coalescing timer to default (2048 usecs) */
+ iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
+
/*
* We don't configure the RFH.
* Restock will be done at alive, after firmware configured the RFH.
--
2.18.0

2018-08-21 09:55:53

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 01/15] iwlwifi: remove dump_regs() from transport ops

From: Johannes Berg <[email protected]>

This is used only within PCIe, and there's no reason to go through
the transport methods for a function call within PCIe itself.
Remove the dump_regs() method and call the function directly.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 11 -----------
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 1 +
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +--
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 2 +-
4 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 0b8cf7f3af93..dbac9ac80ce9 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -539,9 +539,6 @@ struct iwl_trans_rxq_dma_data {
* @dump_data: return a vmalloc'ed buffer with debug data, maybe containing last
* TX'ed commands and similar. The buffer will be vfree'd by the caller.
* Note that the transport must fill in the proper file headers.
- * @dump_regs: dump using IWL_ERR configuration space and memory mapped
- * registers of the device to diagnose failure, e.g., when HW becomes
- * inaccessible.
*/
struct iwl_trans_ops {

@@ -612,8 +609,6 @@ struct iwl_trans_ops {
struct iwl_trans_dump_data *(*dump_data)(struct iwl_trans *trans,
const struct iwl_fw_dbg_trigger_tlv
*trigger);
-
- void (*dump_regs)(struct iwl_trans *trans);
};

/**
@@ -898,12 +893,6 @@ iwl_trans_dump_data(struct iwl_trans *trans,
return trans->ops->dump_data(trans, trigger);
}

-static inline void iwl_trans_dump_regs(struct iwl_trans *trans)
-{
- if (trans->ops->dump_regs)
- trans->ops->dump_regs(trans);
-}
-
static inline struct iwl_device_cmd *
iwl_trans_alloc_tx_cmd(struct iwl_trans *trans)
{
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index cb43b194dc05..74442189d639 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -988,6 +988,7 @@ static inline void __iwl_trans_pcie_set_bit(struct iwl_trans *trans,
}

void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state);
+void iwl_trans_pcie_dump_regs(struct iwl_trans *trans);

#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 7d319b6863fe..7cc438f31154 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -92,7 +92,7 @@
#define IWL_FW_MEM_EXTENDED_START 0x40000
#define IWL_FW_MEM_EXTENDED_END 0x57FFF

-static void iwl_trans_pcie_dump_regs(struct iwl_trans *trans)
+void iwl_trans_pcie_dump_regs(struct iwl_trans *trans)
{
#define PCI_DUMP_SIZE 64
#define PREFIX_LEN 32
@@ -3175,7 +3175,6 @@ static void iwl_trans_pcie_resume(struct iwl_trans *trans)
.ref = iwl_trans_pcie_ref, \
.unref = iwl_trans_pcie_unref, \
.dump_data = iwl_trans_pcie_dump_data, \
- .dump_regs = iwl_trans_pcie_dump_regs, \
.d3_suspend = iwl_trans_pcie_d3_suspend, \
.d3_resume = iwl_trans_pcie_d3_resume

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index da8e0e7c7844..debff193016e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1912,7 +1912,7 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,
}

if (test_bit(STATUS_FW_ERROR, &trans->status)) {
- iwl_trans_dump_regs(trans);
+ iwl_trans_pcie_dump_regs(trans);
IWL_ERR(trans, "FW error in SYNC CMD %s\n",
iwl_get_cmd_string(trans, cmd->id));
dump_stack();
--
2.18.0

2018-08-22 15:23:18

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 07/15] iwlwifi: add 80211 hdr offset to trace data

On Wed, 2018-08-22 at 14:45 +0300, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > From: Mordechay Goodstein <[email protected]>
> >
> > Every rx mpdu cmd is built from cmd_hdr | 80211_hdr. The problem
> > is
> > that the size of cmd_hdr changes with API changes and we don't know
> > where the 80211_hdr starts.
> >
> > By adding the size of cmd_hdr dynamically, we can ensure that we
> > always
> > know how to parse mpdu frames, without dependending on the API
> > changes.
> >
> > Signed-off-by: Mordechay Goodstein <[email protected]>
> > Signed-off-by: Luca Coelho <[email protected]>
>
> [...]
>
> > --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
> > +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
> > @@ -2,6 +2,7 @@
> > *
> > * Copyright(c) 2009 - 2014 Intel Corporation. All rights
> > reserved.
> > * 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
> > @@ -12,10 +13,6 @@
> > * 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 LICENSE.
> > *
>
> Ok, you have more of these removals in this patch so I guess it's
> intentional. But IMHO it would be nicer to remove these all in one go
> instead of sprinkle around in different patches.

IMHO it's too much fuzz for mostly useless warning removal... We need
to update the copyright when this hits, so we just do it at the same
time.

But you're the boss, I can submit a patch to remove just that, all at
once.

--
Luca.

2018-08-21 09:55:57

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 08/15] iwlwifi: don't WARN on trying to dump dead firmware

From: Johannes Berg <[email protected]>

There's no point in warning here, the user will just get an
error back to the debugfs file write, and warning just makes
it seem like there's an internal consistency problem when in
reality the user just happened to hit this at a bad time.
Remove the warning.

Fixes: f45f979dc208 ("iwlwifi: mvm: disable dbg data collect when fw isn't alive")
Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 70173ad11050..9c1d13e6bad3 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -1041,7 +1041,7 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
* If the loading of the FW completed successfully, the next step is to
* get the SMEM config data. Thus, if fwrt->smem_cfg.num_lmacs is non
* zero, the FW was already loaded successully. If the state is "NO_FW"
- * in such a case - WARN and exit, since FW may be dead. Otherwise, we
+ * in such a case - exit, since FW may be dead. Otherwise, we
* can try to collect the data, since FW might just not be fully
* loaded (no "ALIVE" yet), and the debug data is accessible.
*
@@ -1049,9 +1049,8 @@ int iwl_fw_dbg_collect_desc(struct iwl_fw_runtime *fwrt,
* config. In such a case, due to HW access problems, we might
* collect garbage.
*/
- if (WARN((fwrt->trans->state == IWL_TRANS_NO_FW) &&
- fwrt->smem_cfg.num_lmacs,
- "Can't collect dbg data when FW isn't alive\n"))
+ if (fwrt->trans->state == IWL_TRANS_NO_FW &&
+ fwrt->smem_cfg.num_lmacs)
return -EIO;

if (test_and_set_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status))
--
2.18.0

2018-08-23 15:19:51

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 07/15] iwlwifi: add 80211 hdr offset to trace data

On Thu, 2018-08-23 at 14:13 +0300, Kalle Valo wrote:
> Luca Coelho <[email protected]> writes:
>
> > > > - * 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 LICENSE.
> > > > *
> > >
> > > Ok, you have more of these removals in this patch so I guess it's
> > > intentional. But IMHO it would be nicer to remove these all in
> > > one go
> > > instead of sprinkle around in different patches.
> >
> > IMHO it's too much fuzz for mostly useless warning removal... We
> > need
> > to update the copyright when this hits, so we just do it at the
> > same
> > time.
> >
> > But you're the boss, I can submit a patch to remove just that, all
> > at
> > once.
>
> Yeah, please do that. It shouldn't take more than few minutes anyway.
>
> The thing is that then you are reviewing a big patchset and all of
> sudden see a license text changes without no mention in the commit
> log,
> it takes extra time to check it. Sure, with one patch it doens't
> matter
> but then you are going through 20+ patches (or even more) it makes a
> difference. So it's a lot easier for me to change all license text in
> one go.

Okay. I'll send one patch on top of all these ones I sent already,
okay?

--
Luca.

2018-08-21 09:56:29

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 14/15] iwlwifi: mvm: Send LQ command as async when necessary

From: Avraham Stern <[email protected]>

The parameter that indicated whether the LQ command should be sent
as sync or async was removed, causing the LQ command to be sent as
sync from interrupt context (e.g. from the RX path). This resulted
in a kernel warning: "scheduling while atomic" and failing to send
the LQ command, which ultimately leads to a queue hang.

Fix it by adding back the required parameter to send the command as
sync only when it is allowed.

Fixes: d94c5a820d10 ("iwlwifi: mvm: open BA session only when sta is authorized")
Signed-off-by: Avraham Stern <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++--
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/rs.c | 18 ++++++++----------
drivers/net/wireless/intel/iwlwifi/mvm/rs.h | 2 +-
drivers/net/wireless/intel/iwlwifi/mvm/utils.c | 7 +++----
5 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index c0c3ff6a0e6a..c95c1f3c1fb4 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -2949,7 +2949,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
}

- iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
+ iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+ false);
ret = iwl_mvm_update_sta(mvm, vif, sta);
} else if (old_state == IEEE80211_STA_ASSOC &&
new_state == IEEE80211_STA_AUTHORIZED) {
@@ -2965,7 +2966,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
/* enable beacon filtering */
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));

- iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
+ iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+ true);

ret = 0;
} else if (old_state == IEEE80211_STA_AUTHORIZED &&
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 762abfc42b62..98189f2f1e65 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1708,7 +1708,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
#endif /* CONFIG_IWLWIFI_DEBUGFS */

/* rate scaling */
-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
+int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync);
void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg);
int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);
void rs_update_last_rssi(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 30cfd7d50bc9..d3e389a99a8a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -1276,7 +1276,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
(unsigned long)(lq_sta->last_tx +
(IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
- iwl_mvm_rs_rate_init(mvm, sta, info->band);
+ iwl_mvm_rs_rate_init(mvm, sta, info->band, true);
return;
}
lq_sta->last_tx = jiffies;
@@ -2859,9 +2859,8 @@ void rs_update_last_rssi(struct iwl_mvm *mvm,
static void rs_initialize_lq(struct iwl_mvm *mvm,
struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta,
- enum nl80211_band band)
+ enum nl80211_band band, bool update)
{
- struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
struct iwl_scale_tbl_info *tbl;
struct rs_rate *rate;
u8 active_tbl = 0;
@@ -2890,8 +2889,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
rs_set_expected_tpt_table(lq_sta, tbl);
rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
/* TODO restore station should remember the lq cmd */
- iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq,
- mvmsta->sta_state < IEEE80211_STA_AUTHORIZED);
+ iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, !update);
}

static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
@@ -3144,7 +3142,7 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
* Called after adding a new station to initialize rate scaling
*/
static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
- enum nl80211_band band)
+ enum nl80211_band band, bool update)
{
int i, j;
struct ieee80211_hw *hw = mvm->hw;
@@ -3224,7 +3222,7 @@ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
#ifdef CONFIG_IWLWIFI_DEBUGFS
iwl_mvm_reset_frame_stats(mvm);
#endif
- rs_initialize_lq(mvm, sta, lq_sta, band);
+ rs_initialize_lq(mvm, sta, lq_sta, band, update);
}

static void rs_drv_rate_update(void *mvm_r,
@@ -3244,7 +3242,7 @@ static void rs_drv_rate_update(void *mvm_r,
for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
ieee80211_stop_tx_ba_session(sta, tid);

- iwl_mvm_rs_rate_init(mvm, sta, sband->band);
+ iwl_mvm_rs_rate_init(mvm, sta, sband->band, true);
}

#ifdef CONFIG_MAC80211_DEBUGFS
@@ -4098,12 +4096,12 @@ static const struct rate_control_ops rs_mvm_ops_drv = {
};

void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
- enum nl80211_band band)
+ enum nl80211_band band, bool update)
{
if (iwl_mvm_has_tlc_offload(mvm))
rs_fw_rate_init(mvm, sta, band);
else
- rs_drv_rate_init(mvm, sta, band);
+ rs_drv_rate_init(mvm, sta, band, update);
}

int iwl_mvm_rate_control_register(void)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
index d2cf484e2b73..8e7f993e2911 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
@@ -420,7 +420,7 @@ struct iwl_lq_sta {

/* Initialize station's rate scaling information after adding station */
void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
- enum nl80211_band band);
+ enum nl80211_band band, bool init);

/* Notify RS about Tx status */
void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
index b002a7afb5f5..6a5349401aa9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
@@ -900,20 +900,19 @@ int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,

/**
* iwl_mvm_send_lq_cmd() - Send link quality command
- * @init: This command is sent as part of station initialization right
- * after station has been added.
+ * @sync: This command can be sent synchronously.
*
* The link quality command is sent as the last step of station creation.
* This is the special case in which init is set and we call a callback in
* this case to clear the state indicating that station creation is in
* progress.
*/
-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
+int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync)
{
struct iwl_host_cmd cmd = {
.id = LQ_CMD,
.len = { sizeof(struct iwl_lq_cmd), },
- .flags = init ? 0 : CMD_ASYNC,
+ .flags = sync ? 0 : CMD_ASYNC,
.data = { lq, },
};

--
2.18.0

2018-08-21 09:56:25

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 12/15] iwlwifi: mvm: fix BAR seq ctrl reporting

From: Sara Sharon <[email protected]>

There is a bug in FW where the sequence control may be
incorrect, and the driver overrides it with the value
of the ieee80211 header.

However, in BAR there is no sequence control in the header,
which result with arbitrary sequence.

This access to an unknown location is bad and it makes the
logs very confusing - so fix it.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 796f010204d5..31a81a4c6e78 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1480,6 +1480,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
while (!skb_queue_empty(&skbs)) {
struct sk_buff *skb = __skb_dequeue(&skbs);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct ieee80211_hdr *hdr = (void *)skb->data;
bool flushed = false;

skb_freed++;
@@ -1524,11 +1525,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
info->flags &= ~IEEE80211_TX_CTL_AMPDU;

- /* W/A FW bug: seq_ctl is wrong when the status isn't success */
- if (status != TX_STATUS_SUCCESS) {
- struct ieee80211_hdr *hdr = (void *)skb->data;
+ /* W/A FW bug: seq_ctl is wrong upon failure / BAR frame */
+ if (ieee80211_is_back_req(hdr->frame_control))
+ seq_ctl = 0;
+ else if (status != TX_STATUS_SUCCESS)
seq_ctl = le16_to_cpu(hdr->seq_ctrl);
- }

if (unlikely(!seq_ctl)) {
struct ieee80211_hdr *hdr = (void *)skb->data;
--
2.18.0

2018-08-21 09:55:56

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 06/15] iwlwifi: pcie: make gen2 of apm_init non-static

From: Golan Ben Ami <[email protected]>

This will allow using the same init in future generations.

Signed-off-by: Golan Ben Ami <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 1 +
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index c03de2bc5739..8fdef4a26db4 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -1009,6 +1009,7 @@ void iwl_pcie_enable_rx_wake(struct iwl_trans *trans, bool enable);
void iwl_pcie_rx_allocator_work(struct work_struct *data);

/* common functions that are used by gen2 transport */
+int iwl_pcie_gen2_apm_init(struct iwl_trans *trans);
void iwl_pcie_apm_config(struct iwl_trans *trans);
int iwl_pcie_prepare_card_hw(struct iwl_trans *trans);
void iwl_pcie_synchronize_irqs(struct iwl_trans *trans);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index 3e5c732a89db..9b2a248e88b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -61,7 +61,7 @@
* (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop())
* NOTE: This does not load uCode nor start the embedded processor
*/
-static int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
+int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
{
int ret = 0;

--
2.18.0

2018-08-21 09:55:59

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 09/15] iwlwifi: pcie: avoid unnecessary work if NIC is disconnected

From: Matt Chen <[email protected]>

When the NIC is disconnected from PCI bus, we are not
able to access it anymore. Check the status to avoid
some unnecessary work so can improve the performance.
It will help to make PCI bus rescan to bring back the
device much faster.

The real test is able to improve 7 seconds.

[w/o patch] It takes around 9 seconds
..
2018-04-20T01:22:39.691929-07:00 WARNING kernel:
[ 66.335881] Timeout waiting for hardware access (CSR_GP_CNTRL 0xffffffff)
..
2018-04-20T01:22:48.101094-07:00 INFO kernel:
[ 74.747364] iwlwifi 0000:01:00.0: loaded firmware version 29.610311.0 op_mode iwlmvm

[w/a patch] It takes about 2 seconds.
..
2018-04-20T01:18:16.454087-07:00 WARNING kernel:
[ 75.966860] Timeout waiting for hardware access (CSR_GP_CNTRL 0xffffffff)
..
2018-04-20T01:18:18.602717-07:00 INFO kernel:
[ 78.116132] iwlwifi 0000:01:00.0: loaded firmware version 29.610311.0 op_mode iwlmvm
..

Fixes: 49564a806fc5 ("iwlwifi: pcie: remove non-responsive device")
Signed-off-by: Matt Chen <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 4 ++++
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 10 ++++++++++
2 files changed, 14 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 631f0015102b..cf7d1acc8e7a 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2266,6 +2266,10 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx)
unsigned long now = jiffies;
u8 wr_ptr;

+ /* Make sure the NIC is still alive in the bus */
+ if (trans_pcie->scheduled_for_removal)
+ return -EIO;
+
if (!test_bit(txq_idx, trans_pcie->queue_used))
return -EINVAL;

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index debff193016e..d5aba9ebd84a 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1188,6 +1188,10 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,

lockdep_assert_held(&trans_pcie->reg_lock);

+ /* Make sure the NIC is still alive in the bus */
+ if (trans_pcie->scheduled_for_removal)
+ return -EIO;
+
if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
!trans_pcie->ref_cmd_in_flight) {
trans_pcie->ref_cmd_in_flight = true;
@@ -1957,6 +1961,12 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,

int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+ /* Make sure the NIC is still alive in the bus */
+ if (trans_pcie->scheduled_for_removal)
+ return -EIO;
+
if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
test_bit(STATUS_RFKILL_OPMODE, &trans->status)) {
IWL_DEBUG_RF_KILL(trans, "Dropping CMD 0x%x: RF KILL\n",
--
2.18.0

2018-08-21 09:56:14

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 11/15] iwlwifi: improve the flow when a NIC is disconnected

From: Emmanuel Grumbach <[email protected]>

When the NIC is disconnected, we just can't do anything
besides seeking for help from the bus driver. Dumping the
device's memory is not necessary and just bloats the logs
with unusable data. Moreover, asking mac80211 to restart
the hardware is also useless. Bypass all this.

Also, use the STATUS_TRANS_DEAD status bit instead of a
bool inside the transport layer. The advantage of this is
that now, the transport and the op_mode can know what is the
situation and bypass the useless recovery steps mentioned
above.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 6 ++++--
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 --
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 ++++----
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 10 ++++------
4 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index d275832dbb14..da1aafb71298 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -1254,7 +1254,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
schedule_work(&reprobe->work);
} else if (mvm->fwrt.cur_fw_img == IWL_UCODE_REGULAR &&
- mvm->hw_registered) {
+ mvm->hw_registered &&
+ !test_bit(STATUS_TRANS_DEAD, &mvm->trans->status)) {
/* don't let the transport/FW power down */
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);

@@ -1269,7 +1270,8 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);

- iwl_mvm_dump_nic_error_log(mvm);
+ if (!test_bit(STATUS_TRANS_DEAD, &mvm->trans->status))
+ iwl_mvm_dump_nic_error_log(mvm);

iwl_mvm_nic_restart(mvm, true);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 8fdef4a26db4..1089e6b216aa 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -480,7 +480,6 @@ struct iwl_self_init_dram {
* @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;
@@ -573,7 +572,6 @@ struct iwl_trans_pcie {
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 cf7d1acc8e7a..2a20999d4c15 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2013,7 +2013,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
if (iwlwifi_mod_params.remove_when_gone && cntrl == ~0U) {
struct iwl_trans_pcie_removal *removal;

- if (trans_pcie->scheduled_for_removal)
+ if (test_bit(STATUS_TRANS_DEAD, &trans->status))
goto err;

IWL_ERR(trans, "Device gone - scheduling removal!\n");
@@ -2039,7 +2039,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
* we don't need to clear this flag, because
* the trans will be freed and reallocated.
*/
- trans_pcie->scheduled_for_removal = true;
+ set_bit(STATUS_TRANS_DEAD, &trans->status);

removal->pdev = to_pci_dev(trans->dev);
INIT_WORK(&removal->work, iwl_trans_pcie_removal_wk);
@@ -2267,8 +2267,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, int txq_idx)
u8 wr_ptr;

/* Make sure the NIC is still alive in the bus */
- if (trans_pcie->scheduled_for_removal)
- return -EIO;
+ if (test_bit(STATUS_TRANS_DEAD, &trans->status))
+ return -ENODEV;

if (!test_bit(txq_idx, trans_pcie->queue_used))
return -EINVAL;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index d5aba9ebd84a..b89e976ecfcd 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1189,8 +1189,8 @@ static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
lockdep_assert_held(&trans_pcie->reg_lock);

/* Make sure the NIC is still alive in the bus */
- if (trans_pcie->scheduled_for_removal)
- return -EIO;
+ if (test_bit(STATUS_TRANS_DEAD, &trans->status))
+ return -ENODEV;

if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
!trans_pcie->ref_cmd_in_flight) {
@@ -1961,11 +1961,9 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans,

int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
{
- struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
-
/* Make sure the NIC is still alive in the bus */
- if (trans_pcie->scheduled_for_removal)
- return -EIO;
+ if (test_bit(STATUS_TRANS_DEAD, &trans->status))
+ return -ENODEV;

if (!(cmd->flags & CMD_SEND_IN_RFKILL) &&
test_bit(STATUS_RFKILL_OPMODE, &trans->status)) {
--
2.18.0

2018-08-22 15:10:00

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 07/15] iwlwifi: add 80211 hdr offset to trace data

Luca Coelho <[email protected]> writes:

> From: Mordechay Goodstein <[email protected]>
>
> Every rx mpdu cmd is built from cmd_hdr | 80211_hdr. The problem is
> that the size of cmd_hdr changes with API changes and we don't know
> where the 80211_hdr starts.
>
> By adding the size of cmd_hdr dynamically, we can ensure that we always
> know how to parse mpdu frames, without dependending on the API changes.
>
> Signed-off-by: Mordechay Goodstein <[email protected]>
> Signed-off-by: Luca Coelho <[email protected]>

[...]

> --- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
> @@ -2,6 +2,7 @@
> *
> * Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
> * 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
> @@ -12,10 +13,6 @@
> * 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 LICENSE.
> *

Ok, you have more of these removals in this patch so I guess it's
intentional. But IMHO it would be nicer to remove these all in one go
instead of sprinkle around in different patches.

--
Kalle Valo

2018-08-23 15:54:21

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 07/15] iwlwifi: add 80211 hdr offset to trace data

Luca Coelho <[email protected]> writes:

> On Thu, 2018-08-23 at 14:13 +0300, Kalle Valo wrote:
>> Luca Coelho <[email protected]> writes:
>>
>> > > > - * 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 LICENSE.
>> > > > *
>> > >
>> > > Ok, you have more of these removals in this patch so I guess it's
>> > > intentional. But IMHO it would be nicer to remove these all in
>> > > one go
>> > > instead of sprinkle around in different patches.
>> >
>> > IMHO it's too much fuzz for mostly useless warning removal... We
>> > need
>> > to update the copyright when this hits, so we just do it at the
>> > same
>> > time.
>> >
>> > But you're the boss, I can submit a patch to remove just that, all
>> > at
>> > once.
>>
>> Yeah, please do that. It shouldn't take more than few minutes anyway.
>>
>> The thing is that then you are reviewing a big patchset and all of
>> sudden see a license text changes without no mention in the commit
>> log,
>> it takes extra time to check it. Sure, with one patch it doens't
>> matter
>> but then you are going through 20+ patches (or even more) it makes a
>> difference. So it's a lot easier for me to change all license text in
>> one go.
>
> Okay. I'll send one patch on top of all these ones I sent already,
> okay?

Yeah, no need to change existing patches. So sounds good, thanks!

--
Kalle Valo

2018-08-21 09:55:55

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 04/15] iwlwifi: mvm: support new reduce tx power FW API.

From: Haim Dreyfuss <[email protected]>

Update reduce tx power command API to be compatible with new FW API.

Signed-off-by: Haim Dreyfuss <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../wireless/intel/iwlwifi/fw/api/commands.h | 3 +-
.../net/wireless/intel/iwlwifi/fw/api/power.h | 30 +++++++++++++++++--
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 ++
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 23 +++++++++-----
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 25 +++++++++++-----
5 files changed, 66 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 6dad748e5cdc..8b4922bbe139 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -436,7 +436,8 @@ enum iwl_legacy_cmds {

/**
* @REDUCE_TX_POWER_CMD:
- * &struct iwl_dev_tx_power_cmd_v3 or &struct iwl_dev_tx_power_cmd
+ * &struct iwl_dev_tx_power_cmd_v3 or &struct iwl_dev_tx_power_cmd_v4
+ * or &struct iwl_dev_tx_power_cmd
*/
REDUCE_TX_POWER_CMD = 0x9f,

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
index a3c77e01863b..286a22da232d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/power.h
@@ -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
@@ -30,6 +31,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
@@ -316,7 +318,9 @@ enum iwl_dev_tx_power_cmd_mode {
IWL_TX_POWER_MODE_SET_DEVICE = 1,
IWL_TX_POWER_MODE_SET_CHAINS = 2,
IWL_TX_POWER_MODE_SET_ACK = 3,
-}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_4 */;
+ IWL_TX_POWER_MODE_SET_SAR_TIMER = 4,
+ IWL_TX_POWER_MODE_SET_SAR_TIMER_DEFAULT_TABLE = 5,
+}; /* TX_POWER_REDUCED_FLAGS_TYPE_API_E_VER_5 */;

#define IWL_NUM_CHAIN_LIMITS 2
#define IWL_NUM_SUB_BANDS 5
@@ -350,13 +354,35 @@ struct iwl_dev_tx_power_cmd_v3 {
* reduction.
* @reserved: reserved (padding)
*/
-struct iwl_dev_tx_power_cmd {
+struct iwl_dev_tx_power_cmd_v4 {
/* v4 is just an extension of v3 - keep this here */
struct iwl_dev_tx_power_cmd_v3 v3;
u8 enable_ack_reduction;
u8 reserved[3];
} __packed; /* TX_REDUCED_POWER_API_S_VER_4 */

+/**
+ * struct iwl_dev_tx_power_cmd - TX power reduction command
+ * @v3: version 3 of the command, embedded here for easier software handling
+ * @enable_ack_reduction: enable or disable close range ack TX power
+ * reduction.
+ * @per_chain_restriction_changed: is per_chain_restriction has changed
+ * from last command. used if set_mode is
+ * IWL_TX_POWER_MODE_SET_SAR_TIMER.
+ * note: if not changed, the command is used for keep alive only.
+ * @reserved: reserved (padding)
+ * @timer_period: timer in milliseconds. if expires FW will change to default
+ * BIOS values. relevant if setMode is IWL_TX_POWER_MODE_SET_SAR_TIMER
+ */
+struct iwl_dev_tx_power_cmd {
+ /* v5 is just an extension of v3 - keep this here */
+ struct iwl_dev_tx_power_cmd_v3 v3;
+ u8 enable_ack_reduction;
+ u8 per_chain_restriction_changed;
+ u8 reserved[2];
+ __le32 timer_period;
+} __packed; /* TX_REDUCED_POWER_API_S_VER_5 */
+
#define IWL_NUM_GEO_PROFILES 3

/**
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index c7e296a5dda9..fce52ee4caec 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -259,6 +259,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8
* of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_8
* @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS
+ * @IWL_UCODE_TLV_API_REDUCE_TX_POWER: This ucode supports v5 of
+ * the REDUCE_TX_POWER_CMD.
*
* @NUM_IWL_UCODE_TLV_API: number of bits used
*/
@@ -282,6 +284,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41,
IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42,
IWL_UCODE_TLV_API_FRAG_EBS = (__force iwl_ucode_tlv_api_t)44,
+ IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45,

NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 6bb1a99a197a..878dc29c2010 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -773,19 +773,28 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)

int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
{
- struct iwl_dev_tx_power_cmd cmd = {
- .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
- };
+ union {
+ struct iwl_dev_tx_power_cmd v5;
+ struct iwl_dev_tx_power_cmd_v4 v4;
+ } cmd;
int i, j, idx;
int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b };
- int len = sizeof(cmd);
+ int len;

BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS < 2);
BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS !=
ACPI_SAR_TABLE_SIZE);

- if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
- len = sizeof(cmd.v3);
+ cmd.v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS);
+
+ if (fw_has_api(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_API_REDUCE_TX_POWER))
+ len = sizeof(cmd.v5);
+ else if (fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
+ len = sizeof(cmd.v4);
+ else
+ len = sizeof(cmd.v4.v3);

for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) {
struct iwl_mvm_sar_profile *prof;
@@ -812,7 +821,7 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
IWL_DEBUG_RADIO(mvm, " Chain[%d]:\n", i);
for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) {
idx = (i * ACPI_SAR_NUM_SUB_BANDS) + j;
- cmd.v3.per_chain_restriction[i][j] =
+ cmd.v5.v3.per_chain_restriction[i][j] =
cpu_to_le16(prof->table[idx]);
IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n",
j, prof->table[idx]);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 66a4ca090412..c0c3ff6a0e6a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1309,19 +1309,28 @@ static struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm)
static int iwl_mvm_set_tx_power(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
s16 tx_power)
{
- struct iwl_dev_tx_power_cmd cmd = {
- .v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
- .v3.mac_context_id =
+ int len;
+ union {
+ struct iwl_dev_tx_power_cmd v5;
+ struct iwl_dev_tx_power_cmd_v4 v4;
+ } cmd = {
+ .v5.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_MAC),
+ .v5.v3.mac_context_id =
cpu_to_le32(iwl_mvm_vif_from_mac80211(vif)->id),
- .v3.pwr_restriction = cpu_to_le16(8 * tx_power),
+ .v5.v3.pwr_restriction = cpu_to_le16(8 * tx_power),
};
- int len = sizeof(cmd);

if (tx_power == IWL_DEFAULT_MAX_TX_POWER)
- cmd.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);
+ cmd.v5.v3.pwr_restriction = cpu_to_le16(IWL_DEV_MAX_TX_POWER);

- if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
- len = sizeof(cmd.v3);
+ if (fw_has_api(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_API_REDUCE_TX_POWER))
+ len = sizeof(cmd.v5);
+ else if (fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
+ len = sizeof(cmd.v4);
+ else
+ len = sizeof(cmd.v4.v3);

return iwl_mvm_send_cmd_pdu(mvm, REDUCE_TX_POWER_CMD, 0, len, &cmd);
}
--
2.18.0

2018-08-23 14:43:07

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 07/15] iwlwifi: add 80211 hdr offset to trace data

Luca Coelho <[email protected]> writes:

>> > - * 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 LICENSE.
>> > *
>>
>> Ok, you have more of these removals in this patch so I guess it's
>> intentional. But IMHO it would be nicer to remove these all in one go
>> instead of sprinkle around in different patches.
>
> IMHO it's too much fuzz for mostly useless warning removal... We need
> to update the copyright when this hits, so we just do it at the same
> time.
>
> But you're the boss, I can submit a patch to remove just that, all at
> once.

Yeah, please do that. It shouldn't take more than few minutes anyway.

The thing is that then you are reviewing a big patchset and all of
sudden see a license text changes without no mention in the commit log,
it takes extra time to check it. Sure, with one patch it doens't matter
but then you are going through 20+ patches (or even more) it makes a
difference. So it's a lot easier for me to change all license text in
one go.

--
Kalle Valo

2018-08-21 09:56:21

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 13/15] iwlwifi: mvm: avoid sending too many BARs

From: Sara Sharon <[email protected]>

When we receive TX response, we may release a few packets
due to a hole that was closed in the transmission window.

However, if that frame failed, we will mark all the released
frames as failed and will send multiple BARs.

This affects statistics badly, and cause unnecessary frames
transmission.

Instead, mark all the following packets as success, with the
desired result of sending a bar for the failed frame only.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 31a81a4c6e78..b33b8357a8f7 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -1510,6 +1510,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
break;
}

+ /*
+ * If we are freeing multiple frames, mark all the frames
+ * but the first one as acked, since they were acknowledged
+ * before
+ * */
+ if (skb_freed > 1)
+ info->flags |= IEEE80211_TX_STAT_ACK;
+
iwl_mvm_tx_status_check_trigger(mvm, status);

info->status.rates[0].count = tx_resp->failure_frame + 1;
--
2.18.0

2018-08-21 09:56:17

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 10/15] iwlwifi: mvm: support Coex Schema 2

From: Erel Geron <[email protected]>

The new coex schema requires moving to SISO only when BT AG is 4.
Adjust the SISO criteria according to the coex schema version reported
by firmware.

Signed-off-by: Erel Geron <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/api/coex.h | 3 +++
drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 ++
drivers/net/wireless/intel/iwlwifi/mvm/coex.c | 9 +++++++--
3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
index 87c1ddea75ae..68060085010f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/coex.h
@@ -8,6 +8,7 @@
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* 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
@@ -30,6 +31,7 @@
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
* 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
@@ -203,6 +205,7 @@ enum iwl_bt_activity_grading {
BT_ON_NO_CONNECTION = 1,
BT_LOW_TRAFFIC = 2,
BT_HIGH_TRAFFIC = 3,
+ BT_VERY_HIGH_TRAFFIC = 4,

BT_MAX_AG,
}; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index fce52ee4caec..7638d0bb1e11 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -331,6 +331,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_capa_t;
* @IWL_UCODE_TLV_CAPA_STA_PM_NOTIF: firmware will send STA PM notification
* @IWL_UCODE_TLV_CAPA_TLC_OFFLOAD: firmware implements rate scaling algorithm
* @IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA: firmware implements quota related
+ * @IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2: firmware implements Coex Schema 2
* @IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE: extended DTS measurement
* @IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS: supports short PM timeouts
* @IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT: supports bt-coex Multi-priority LUT
@@ -388,6 +389,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_D0I3_END_FIRST = (__force iwl_ucode_tlv_capa_t)41,
IWL_UCODE_TLV_CAPA_TLC_OFFLOAD = (__force iwl_ucode_tlv_capa_t)43,
IWL_UCODE_TLV_CAPA_DYNAMIC_QUOTA = (__force iwl_ucode_tlv_capa_t)44,
+ IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2 = (__force iwl_ucode_tlv_capa_t)45,
IWL_UCODE_TLV_CAPA_EXTENDED_DTS_MEASURE = (__force iwl_ucode_tlv_capa_t)64,
IWL_UCODE_TLV_CAPA_SHORT_PM_TIMEOUTS = (__force iwl_ucode_tlv_capa_t)65,
IWL_UCODE_TLV_CAPA_BT_MPLUT_SUPPORT = (__force iwl_ucode_tlv_capa_t)67,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
index 016e03a5034f..9707f455086b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/coex.c
@@ -331,7 +331,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
struct ieee80211_chanctx_conf *chanctx_conf;
/* default smps_mode is AUTOMATIC - only used for client modes */
enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
- u32 bt_activity_grading;
+ u32 bt_activity_grading, min_ag_for_static_smps;
int ave_rssi;

lockdep_assert_held(&mvm->mutex);
@@ -363,8 +363,13 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
return;
}

+ if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_COEX_SCHEMA_2))
+ min_ag_for_static_smps = BT_VERY_HIGH_TRAFFIC;
+ else
+ min_ag_for_static_smps = BT_HIGH_TRAFFIC;
+
bt_activity_grading = le32_to_cpu(data->notif->bt_activity_grading);
- if (bt_activity_grading >= BT_HIGH_TRAFFIC)
+ if (bt_activity_grading >= min_ag_for_static_smps)
smps_mode = IEEE80211_SMPS_STATIC;
else if (bt_activity_grading >= BT_LOW_TRAFFIC)
smps_mode = IEEE80211_SMPS_DYNAMIC;
--
2.18.0

2018-08-21 09:55:54

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 03/15] iwlwifi: mvm: skip EBS in low latency mode while fragmented scan isn't supported

From: Ayala Beker <[email protected]>

While associated in low latency mode, or when traffic load is high,
don't enable EBS in scan request if fragmented EBS is not supported
by the FW.

Signed-off-by: Ayala Beker <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/file.h | 2 ++
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 5 +++++
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 11 ++++++++++-
3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index c116dc3fbffe..c7e296a5dda9 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -258,6 +258,7 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* deprecated.
* @IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2: This ucode supports version 8
* of scan request: SCAN_REQUEST_CMD_UMAC_API_S_VER_8
+ * @IWL_UCODE_TLV_API_FRAG_EBS: This ucode supports fragmented EBS
*
* @NUM_IWL_UCODE_TLV_API: number of bits used
*/
@@ -280,6 +281,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38,
IWL_UCODE_TLV_API_DEPRECATE_TTAK = (__force iwl_ucode_tlv_api_t)41,
IWL_UCODE_TLV_API_ADAPTIVE_DWELL_V2 = (__force iwl_ucode_tlv_api_t)42,
+ IWL_UCODE_TLV_API_FRAG_EBS = (__force iwl_ucode_tlv_api_t)44,

NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 09d94aaa7d1e..762abfc42b62 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1245,6 +1245,11 @@ static inline bool iwl_mvm_is_oce_supported(struct iwl_mvm *mvm)
return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_OCE);
}

+static inline bool iwl_mvm_is_frag_ebs_supported(struct iwl_mvm *mvm)
+{
+ return fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_FRAG_EBS);
+}
+
static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
{
/* For now we only use this mode to differentiate between
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 11ecdf63b732..8a89989f59fd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -836,16 +836,25 @@ static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
const struct iwl_ucode_capabilities *capa = &mvm->fw->ucode_capa;
+ bool low_latency;
+
+ if (iwl_mvm_is_cdb_supported(mvm))
+ low_latency = iwl_mvm_low_latency_band(mvm, NL80211_BAND_5GHZ);
+ else
+ low_latency = iwl_mvm_low_latency(mvm);

/* We can only use EBS if:
* 1. the feature is supported;
* 2. the last EBS was successful;
* 3. if only single scan, the single scan EBS API is supported;
* 4. it's not a p2p find operation.
+ * 5. we are not in low latency mode,
+ * or if fragmented ebs is supported by the FW
*/
return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS &&
- vif->type != NL80211_IFTYPE_P2P_DEVICE);
+ vif->type != NL80211_IFTYPE_P2P_DEVICE &&
+ (!low_latency || iwl_mvm_is_frag_ebs_supported(mvm)));
}

static inline bool iwl_mvm_is_regular_scan(struct iwl_mvm_scan_params *params)
--
2.18.0

2018-08-21 09:55:53

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 02/15] iwlwifi: remove FSF's address from the license notice

From: Golan Ben Ami <[email protected]>

The Free Software Foundation's address shouldn't be in the license
notice anymore, and some of our check scripts complain about it
(via checkpatch.pl). Remove the address to silence it.

Signed-off-by: Golan Ben Ami <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
index b49eda8150bb..cbbdede2e01b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-op-mode.h
@@ -8,6 +8,7 @@
* Copyright(c) 2007 - 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
@@ -19,9 +20,7 @@
* 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
+ * along with this program.
*
* The full GNU General Public License is included in this distribution
* in the file called COPYING.
@@ -35,6 +34,7 @@
* Copyright(c) 2005 - 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
--
2.18.0

2018-08-21 09:55:55

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 05/15] iwlwifi: pcie: store the default rxq number

From: Golan Ben Ami <[email protected]>

Store the default rxq number in a variable, so we won't need
to use the actual number in the code.

Signed-off-by: Golan Ben Ami <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/internal.h | 2 ++
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 2 +-
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 ++
3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 74442189d639..c03de2bc5739 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -456,6 +456,7 @@ struct iwl_self_init_dram {
* @ucode_write_complete: indicates that the ucode has been copied.
* @ucode_write_waitq: wait queue for uCode load
* @cmd_queue - command queue number
+ * @def_rx_queue - default rx queue number
* @rx_buf_size: Rx buffer size
* @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
* @scd_set_active: should the transport configure the SCD for HCMD queue
@@ -536,6 +537,7 @@ struct iwl_trans_pcie {
u8 page_offs, dev_cmd_offs;

u8 cmd_queue;
+ u8 def_rx_queue;
u8 cmd_fifo;
unsigned int cmd_q_wdg_timeout;
u8 n_no_reclaim_cmds;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index acae8f967912..8075466aa4c4 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -1271,7 +1271,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
index = SEQ_TO_INDEX(sequence);
cmd_index = iwl_pcie_get_cmd_index(txq, index);

- if (rxq->id == 0)
+ if (rxq->id == trans_pcie->def_rx_queue)
iwl_op_mode_rx(trans->op_mode, &rxq->napi,
&rxcb);
else
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 7cc438f31154..631f0015102b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3276,6 +3276,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
PCIE_LINK_STATE_CLKPM);
}

+ trans_pcie->def_rx_queue = 0;
+
if (cfg->use_tfh) {
addr_size = 64;
trans_pcie->max_tbs = IWL_TFH_NUM_TBS;
--
2.18.0

2018-08-21 09:55:57

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 07/15] iwlwifi: add 80211 hdr offset to trace data

From: Mordechay Goodstein <[email protected]>

Every rx mpdu cmd is built from cmd_hdr | 80211_hdr. The problem is
that the size of cmd_hdr changes with API changes and we don't know
where the 80211_hdr starts.

By adding the size of cmd_hdr dynamically, we can ensure that we always
know how to parse mpdu frames, without dependending on the API changes.

Signed-off-by: Mordechay Goodstein <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../intel/iwlwifi/iwl-devtrace-data.h | 10 +++------
.../intel/iwlwifi/iwl-devtrace-iwlwifi.h | 14 +++++++-----
.../net/wireless/intel/iwlwifi/iwl-devtrace.h | 22 +++++++++++--------
3 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
index a80e4202cd03..2cc6c019d0e1 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-data.h
@@ -2,6 +2,7 @@
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* 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
@@ -12,10 +13,6 @@
* 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 LICENSE.
*
@@ -76,12 +73,11 @@ TRACE_EVENT(iwlwifi_dev_rx_data,
TP_ARGS(dev, trans, rxbuf, len),
TP_STRUCT__entry(
DEV_ENTRY
-
__dynamic_array(u8, data,
- len - iwl_rx_trace_len(trans, rxbuf, len))
+ len - iwl_rx_trace_len(trans, rxbuf, len, NULL))
),
TP_fast_assign(
- size_t offs = iwl_rx_trace_len(trans, rxbuf, len);
+ size_t offs = iwl_rx_trace_len(trans, rxbuf, len, NULL);
DEV_ASSIGN;
if (offs < len)
memcpy(__get_dynamic_array(data),
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
index 27e3e4e96aa2..82cfbfa0795d 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
@@ -3,6 +3,7 @@
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 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
@@ -13,10 +14,6 @@
* 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 LICENSE.
*
@@ -75,13 +72,18 @@ TRACE_EVENT(iwlwifi_dev_rx,
TP_STRUCT__entry(
DEV_ENTRY
__field(u16, cmd)
- __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, pkt, len))
+ __field(u8, hdr_offset)
+ __dynamic_array(u8, rxbuf,
+ iwl_rx_trace_len(trans, pkt, len, NULL))
),
TP_fast_assign(
+ size_t hdr_offset = 0;
+
DEV_ASSIGN;
__entry->cmd = WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd);
memcpy(__get_dynamic_array(rxbuf), pkt,
- iwl_rx_trace_len(trans, pkt, len));
+ iwl_rx_trace_len(trans, pkt, len, &hdr_offset));
+ __entry->hdr_offset = hdr_offset;
),
TP_printk("[%s] RX cmd %#.2x",
__get_str(dev), __entry->cmd)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
index f5c1127253cb..fc649b2bc017 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace.h
@@ -1,7 +1,8 @@
/******************************************************************************
*
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
- * Copyright(C) 2016 Intel Deutschland 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
@@ -12,10 +13,6 @@
* 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 LICENSE.
*
@@ -60,16 +57,23 @@ static inline bool iwl_trace_data(struct sk_buff *skb)
}

static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
- void *rxbuf, size_t len)
+ void *rxbuf, size_t len,
+ size_t *out_hdr_offset)
{
struct iwl_cmd_header *cmd = (void *)((u8 *)rxbuf + sizeof(__le32));
- struct ieee80211_hdr *hdr;
+ struct ieee80211_hdr *hdr = NULL;
+ size_t hdr_offset;

if (cmd->cmd != trans->rx_mpdu_cmd)
return len;

- hdr = (void *)((u8 *)cmd + sizeof(struct iwl_cmd_header) +
- trans->rx_mpdu_cmd_hdr_size);
+ hdr_offset = sizeof(struct iwl_cmd_header) +
+ trans->rx_mpdu_cmd_hdr_size;
+
+ if (out_hdr_offset)
+ *out_hdr_offset = hdr_offset;
+
+ hdr = (void *)((u8 *)cmd + hdr_offset);
if (!ieee80211_is_data(hdr->frame_control))
return len;
/* maybe try to identify EAPOL frames? */
--
2.18.0

2018-09-06 12:56:58

by Tee Hao Wei

[permalink] [raw]
Subject: Re: [PATCH 14/15] iwlwifi: mvm: Send LQ command as async when necessary

Hi,

On 21/8/18 2:36 PM, Luca Coelho wrote:
> From: Avraham Stern <[email protected]>
>
> The parameter that indicated whether the LQ command should be sent
> as sync or async was removed, causing the LQ command to be sent as
> sync from interrupt context (e.g. from the RX path). This resulted
> in a kernel warning: "scheduling while atomic" and failing to send
> the LQ command, which ultimately leads to a queue hang.
>
> Fix it by adding back the required parameter to send the command as
> sync only when it is allowed.
>
> Fixes: d94c5a820d10 ("iwlwifi: mvm: open BA session only when sta is authorized")
> Signed-off-by: Avraham Stern <[email protected]>
> Signed-off-by: Luca Coelho <[email protected]>

I'm not sure whether you guys normally send fixes to stable, but this
really should go to stable. I run into this bug as often as a few times
an hour and sometimes it leads to IRQs from other devices being dropped
(e.g. touchpad, in turn causing the driver to timeout and quit, and the
touchpad dies).

Thanks.

--
Hao Wei

2018-09-06 13:18:56

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 14/15] iwlwifi: mvm: Send LQ command as async when necessary

On Thu, 2018-09-06 at 16:22 +0800, Hao Wei Tee wrote:
> Hi,

Hi Hao Wei,


> On 21/8/18 2:36 PM, Luca Coelho wrote:
> > From: Avraham Stern <[email protected]>
> >
> > The parameter that indicated whether the LQ command should be sent
> > as sync or async was removed, causing the LQ command to be sent as
> > sync from interrupt context (e.g. from the RX path). This resulted
> > in a kernel warning: "scheduling while atomic" and failing to send
> > the LQ command, which ultimately leads to a queue hang.
> >
> > Fix it by adding back the required parameter to send the command as
> > sync only when it is allowed.
> >
> > Fixes: d94c5a820d10 ("iwlwifi: mvm: open BA session only when sta is authorized")
> > Signed-off-by: Avraham Stern <[email protected]>
> > Signed-off-by: Luca Coelho <[email protected]>
>
> I'm not sure whether you guys normally send fixes to stable, but this
> really should go to stable. I run into this bug as often as a few times
> an hour and sometimes it leads to IRQs from other devices being dropped
> (e.g. touchpad, in turn causing the driver to timeout and quit, and the
> touchpad dies).

We do send things for stable and the "Fixes" tag included in this patch
will cause it to be automatically considered for the stable releases
that contain the commit it points to. So we should be fine here.

If you notice that, for some reason, this doesn't end up applied in the
specific stable kernel you need it on, please let us know and we'll
check it out. Also note that anyone can suggest any patch to stable
releases, there's a process[1] in place for that.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/stable-kernel-rules.rst

Thanks for your contribution!

--
Cheers,
Luca.