2021-06-18 09:17:53

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 00/10] iwlwifi: updates intended for v5.14 2021-06-18

From: Luca Coelho <[email protected]>

Hi,

Here's the thjird set of patches intended for v5.14. It's the usual
development, new features, cleanups and bugfixes.

The changes are:

* Some fixes in IML (image loader) DMA handling;
* Fixes in WoWLAN;
* Some other small fixes, clean-ups and improvements.

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

Please review.

Cheers,
Luca.



Emmanuel Grumbach (2):
iwlwifi: mvm: support LONG_GROUP for WOWLAN_GET_STATUSES version
iwlwifi: mvm: introduce iwl_proto_offload_cmd_v4

Ilan Peer (1):
iwlwifi: mvm: Explicitly stop session protection before unbinding

Johannes Berg (4):
iwlwifi: pcie: free IML DMA memory allocation
iwlwifi: pcie: fix context info freeing
iwlwifi: mvm: fill phy_data.d1 for no-data RX
iwlwifi: pcie: free some DMA memory earlier

Luca Coelho (1):
iwlwifi: fix NUM_IWL_UCODE_TLV_* definitions to avoid sparse errors

Naftali Goldstein (2):
iwlwifi: mvm: don't request mac80211 to disable/enable sta's queues
iwlwifi: support ver 6 of WOWLAN_CONFIGURATION and ver 10 of
WOWLAN_GET_STATUSES

.../net/wireless/intel/iwlwifi/fw/api/d3.h | 28 +++++++++---
drivers/net/wireless/intel/iwlwifi/fw/file.h | 14 +++---
.../intel/iwlwifi/iwl-context-info-gen3.h | 4 +-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 44 ++++++++++++-------
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 -
.../wireless/intel/iwlwifi/mvm/offloading.c | 26 ++++++++---
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 10 ++---
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 8 +++-
.../wireless/intel/iwlwifi/mvm/time-event.c | 41 ++++++++++++-----
.../intel/iwlwifi/pcie/ctxt-info-gen3.c | 28 ++++++++----
.../wireless/intel/iwlwifi/pcie/internal.h | 3 ++
.../wireless/intel/iwlwifi/pcie/trans-gen2.c | 7 ++-
12 files changed, 148 insertions(+), 66 deletions(-)

--
2.32.0


2021-06-18 09:17:53

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 02/10] iwlwifi: mvm: don't request mac80211 to disable/enable sta's queues

From: Naftali Goldstein <[email protected]>

When operating in AP mode with NICs supporting the AP_LINK_PS hw flag,
mac80211 doesn't need to start/stop queueing tx for connected stations
because the FW already handles that.

Signed-off-by: Naftali Goldstein <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index f618368eda83..9c45a64c5009 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -3794,8 +3794,12 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,

mvm_sta->disable_tx = disable;

- /* Tell mac80211 to start/stop queuing tx for this station */
- ieee80211_sta_block_awake(mvm->hw, sta, disable);
+ /*
+ * If sta PS state is handled by mac80211, tell it to start/stop
+ * queuing tx for this station.
+ */
+ if (!ieee80211_hw_check(mvm->hw, AP_LINK_PS))
+ ieee80211_sta_block_awake(mvm->hw, sta, disable);

iwl_mvm_sta_modify_disable_tx(mvm, mvm_sta, disable);

--
2.32.0

2021-06-18 09:18:07

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 05/10] iwlwifi: pcie: free IML DMA memory allocation

From: Johannes Berg <[email protected]>

In the case of gen3 devices with image loader (IML) support,
we were leaking the IML DMA allocation and never freeing it.
Fix that.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c | 15 ++++++++++-----
.../net/wireless/intel/iwlwifi/pcie/internal.h | 3 +++
2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
index 49560e508b5e..c7b9ca264429 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -79,7 +79,6 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
struct iwl_prph_scratch *prph_scratch;
struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl;
struct iwl_prph_info *prph_info;
- void *iml_img;
u32 control_flags = 0;
int ret;
int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
@@ -190,14 +189,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
trans_pcie->prph_scratch = prph_scratch;

/* Allocate IML */
- iml_img = dma_alloc_coherent(trans->dev, trans->iml_len,
- &trans_pcie->iml_dma_addr, GFP_KERNEL);
- if (!iml_img) {
+ trans_pcie->iml = dma_alloc_coherent(trans->dev, trans->iml_len,
+ &trans_pcie->iml_dma_addr,
+ GFP_KERNEL);
+ if (!trans_pcie->iml) {
ret = -ENOMEM;
goto err_free_ctxt_info;
}

- memcpy(iml_img, trans->iml, trans->iml_len);
+ memcpy(trans_pcie->iml, trans->iml, trans->iml_len);

iwl_enable_fw_load_int_ctx_info(trans);

@@ -244,6 +244,11 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
trans_pcie->ctxt_info_dma_addr = 0;
trans_pcie->ctxt_info_gen3 = NULL;

+ dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml,
+ trans_pcie->iml_dma_addr);
+ trans_pcie->iml_dma_addr = 0;
+ trans_pcie->iml = NULL;
+
iwl_pcie_ctxt_info_free_fw_img(trans);

dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch),
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 292b972a25db..69289e9f8d7e 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -271,6 +271,8 @@ struct cont_rec {
* Context information addresses will be taken from here.
* This is driver's local copy for keeping track of size and
* count for allocating and freeing the memory.
+ * @iml: image loader image virtual address
+ * @iml_dma_addr: image loader image DMA address
* @trans: pointer to the generic transport area
* @scd_base_addr: scheduler sram base address in SRAM
* @kw: keep warm address
@@ -322,6 +324,7 @@ struct iwl_trans_pcie {
};
struct iwl_prph_info *prph_info;
struct iwl_prph_scratch *prph_scratch;
+ void *iml;
dma_addr_t ctxt_info_dma_addr;
dma_addr_t prph_info_dma_addr;
dma_addr_t prph_scratch_dma_addr;
--
2.32.0

2021-06-18 09:18:07

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 04/10] iwlwifi: mvm: support LONG_GROUP for WOWLAN_GET_STATUSES version

From: Emmanuel Grumbach <[email protected]>

It's been a while that the firmware uses LONG_GROUP by default
and not LEGACY_GROUP.
Until now the firmware wrongly advertise the WOWLAN_GET_STATUS
command's version with LEGACY_GROUP, but it is now being fixed.
In order to support both firmwares, first try to get the version
number of the command with the LONG_GROUP and if the firmware
didn't advertise the command version with LONG_GROUP, try to get
the command version with LEGACY_GROUP.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index e86f0e949b86..6617fe5a7ece 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1614,8 +1614,11 @@ struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm)
len = iwl_rx_packet_payload_len(cmd.resp_pkt);

/* default to 7 (when we have IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL) */
- notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
- WOWLAN_GET_STATUSES, 7);
+ notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
+ WOWLAN_GET_STATUSES, 0);
+ if (!notif_ver)
+ notif_ver = iwl_fw_lookup_notif_ver(mvm->fw, LEGACY_GROUP,
+ WOWLAN_GET_STATUSES, 7);

if (!fw_has_api(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_API_WOWLAN_KEY_MATERIAL)) {
--
2.32.0

2021-06-18 09:18:07

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 07/10] iwlwifi: mvm: fill phy_data.d1 for no-data RX

From: Johannes Berg <[email protected]>

We don't fill in phy_data.d1 in no-data RX, and thus we
pretend some data is actually filled in radiotap when it
isn't or has default (zero) values.

Fill in phy_data.d1 appropriately, and while at it also
move the info_type initialization into the initializer.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 8e26422ca326..c0babb8d5b5c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
*/
@@ -2001,8 +2001,10 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
struct sk_buff *skb;
u8 channel, energy_a, energy_b;
struct iwl_mvm_rx_phy_data phy_data = {
+ .info_type = le32_get_bits(desc->phy_info[1],
+ IWL_RX_PHY_DATA1_INFO_TYPE_MASK),
.d0 = desc->phy_info[0],
- .info_type = IWL_RX_PHY_INFO_TYPE_NONE,
+ .d1 = desc->phy_info[1],
};

if (unlikely(iwl_rx_packet_payload_len(pkt) < sizeof(*desc)))
@@ -2015,10 +2017,6 @@ void iwl_mvm_rx_monitor_no_data(struct iwl_mvm *mvm, struct napi_struct *napi,
energy_b = (rssi & RX_NO_DATA_CHAIN_B_MSK) >> RX_NO_DATA_CHAIN_B_POS;
channel = (rssi & RX_NO_DATA_CHANNEL_MSK) >> RX_NO_DATA_CHANNEL_POS;

- phy_data.info_type =
- le32_get_bits(desc->phy_info[1],
- IWL_RX_PHY_DATA1_INFO_TYPE_MASK);
-
/* Dont use dev_alloc_skb(), we'll have enough headroom once
* ieee80211_hdr pulled.
*/
--
2.32.0

2021-06-18 09:18:08

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 08/10] iwlwifi: pcie: free some DMA memory earlier

From: Johannes Berg <[email protected]>

In gen3, after firmware is alive, we no longer need the
firmware and image loader images, only the context info
itself and PRPH info/scratch need to remain.

Call iwl_pcie_ctxt_info_gen3_free() appropriately in the
alive callback (iwl_trans_pcie_gen2_fw_alive()) with a new
argument indicating whether it can free everything or only
partially.

The context info and PRPH scratch are also not needed after
PNVM load, but we don't have a good hook for freeing after
that, so keep them for now.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../intel/iwlwifi/iwl-context-info-gen3.h | 4 ++--
.../intel/iwlwifi/pcie/ctxt-info-gen3.c | 23 ++++++++++++-------
.../wireless/intel/iwlwifi/pcie/trans-gen2.c | 6 +++--
3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
index 2be605cc6fbf..518a1bc79584 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-context-info-gen3.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2018, 2020 Intel Corporation
+ * Copyright (C) 2018, 2020-2021 Intel Corporation
*/
#ifndef __iwl_context_info_file_gen3_h__
#define __iwl_context_info_file_gen3_h__
@@ -245,7 +245,7 @@ struct iwl_context_info_gen3 {

int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
const struct fw_img *fw);
-void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans);
+void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive);

int iwl_trans_pcie_ctx_info_gen3_set_pnvm(struct iwl_trans *trans,
const void *data, u32 len);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
index c7b9ca264429..c69a1541e678 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c
@@ -231,32 +231,39 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,

}

-void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
+void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans, bool alive)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

+ if (trans_pcie->iml) {
+ dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml,
+ trans_pcie->iml_dma_addr);
+ trans_pcie->iml_dma_addr = 0;
+ trans_pcie->iml = NULL;
+ }
+
+ iwl_pcie_ctxt_info_free_fw_img(trans);
+
+ if (alive)
+ return;
+
if (!trans_pcie->ctxt_info_gen3)
return;

+ /* ctxt_info_gen3 and prph_scratch are still needed for PNVM load */
dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3),
trans_pcie->ctxt_info_gen3,
trans_pcie->ctxt_info_dma_addr);
trans_pcie->ctxt_info_dma_addr = 0;
trans_pcie->ctxt_info_gen3 = NULL;

- dma_free_coherent(trans->dev, trans->iml_len, trans_pcie->iml,
- trans_pcie->iml_dma_addr);
- trans_pcie->iml_dma_addr = 0;
- trans_pcie->iml = NULL;
-
- iwl_pcie_ctxt_info_free_fw_img(trans);
-
dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch),
trans_pcie->prph_scratch,
trans_pcie->prph_scratch_dma_addr);
trans_pcie->prph_scratch_dma_addr = 0;
trans_pcie->prph_scratch = NULL;

+ /* this is needed for the entire lifetime */
dma_free_coherent(trans->dev, PAGE_SIZE, trans_pcie->prph_info,
trans_pcie->prph_info_dma_addr);
trans_pcie->prph_info_dma_addr = 0;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index 93b957866beb..a34009357227 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -149,7 +149,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)

iwl_pcie_ctxt_info_free_paging(trans);
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
- iwl_pcie_ctxt_info_gen3_free(trans);
+ iwl_pcie_ctxt_info_gen3_free(trans, false);
else
iwl_pcie_ctxt_info_free(trans);

@@ -323,7 +323,9 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
/* now that we got alive we can free the fw image & the context info.
* paging memory cannot be freed included since FW will still use it
*/
- if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
+ if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
+ iwl_pcie_ctxt_info_gen3_free(trans, true);
+ else
iwl_pcie_ctxt_info_free(trans);

/*
--
2.32.0

2021-06-18 09:18:10

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 09/10] iwlwifi: fix NUM_IWL_UCODE_TLV_* definitions to avoid sparse errors

From: Luca Coelho <[email protected]>

We were assigning these macros manually when sparse is running, but
with newer versions of sparse, it started causing other warnings. Fix
it by making it a macro when sparse is running.

Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/fw/file.h | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index d189e5de478b..ef1a24504c8b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -277,10 +277,11 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_BAND_IN_RX_DATA = (__force iwl_ucode_tlv_api_t)59,


- NUM_IWL_UCODE_TLV_API
#ifdef __CHECKER__
- /* sparse says it cannot increment the previous enum member */
- = 128
+ /* sparse says it cannot increment the previous enum member */
+#define NUM_IWL_UCODE_TLV_API 128
+#else
+ NUM_IWL_UCODE_TLV_API
#endif
};

@@ -447,10 +448,11 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_BIGTK_SUPPORT = (__force iwl_ucode_tlv_capa_t)100,
IWL_UCODE_TLV_CAPA_RFIM_SUPPORT = (__force iwl_ucode_tlv_capa_t)102,

- NUM_IWL_UCODE_TLV_CAPA
#ifdef __CHECKER__
- /* sparse says it cannot increment the previous enum member */
- = 128
+ /* sparse says it cannot increment the previous enum member */
+#define NUM_IWL_UCODE_TLV_CAPA 128
+#else
+ NUM_IWL_UCODE_TLV_CAPA
#endif
};

--
2.32.0

2021-06-18 09:20:30

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 06/10] iwlwifi: pcie: fix context info freeing

From: Johannes Berg <[email protected]>

After firmware alive, iwl_trans_pcie_gen2_fw_alive() is called
to free the context info. However, on gen3 that will then free
the context info with the wrong size.

Since we free this allocation later, let it stick around until
the device is stopped for now, freeing some of it earlier is a
separate change.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index 56162c4500d7..93b957866beb 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -323,7 +323,8 @@ void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr)
/* now that we got alive we can free the fw image & the context info.
* paging memory cannot be freed included since FW will still use it
*/
- iwl_pcie_ctxt_info_free(trans);
+ if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
+ iwl_pcie_ctxt_info_free(trans);

/*
* Re-enable all the interrupts, including the RF-Kill one, now that
--
2.32.0

2021-06-18 09:20:30

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 01/10] iwlwifi: mvm: Explicitly stop session protection before unbinding

From: Ilan Peer <[email protected]>

In case of unbinding, the FW would remove the session protection time
events without sending a notification, so explicitly cancel the
session protection, so future requests for mgd_prepare_tx() would not
assume that the session protection is running.

Signed-off-by: Ilan Peer <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 -
.../wireless/intel/iwlwifi/mvm/time-event.c | 41 ++++++++++++++-----
2 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 80dd4506f205..4c9c64210646 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -4261,7 +4261,6 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
struct ieee80211_vif *disabled_vif = NULL;

lockdep_assert_held(&mvm->mutex);
-
iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);

switch (vif->type) {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
index f19081a6f046..d3307a11fcac 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
@@ -31,6 +31,13 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
return;

list_del(&te_data->list);
+
+ /*
+ * the list is only used for AUX ROC events so make sure it is always
+ * initialized
+ */
+ INIT_LIST_HEAD(&te_data->list);
+
te_data->running = false;
te_data->uid = 0;
te_data->id = TE_MAX;
@@ -609,14 +616,15 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
}

static void iwl_mvm_cancel_session_protection(struct iwl_mvm *mvm,
- struct iwl_mvm_vif *mvmvif)
+ struct iwl_mvm_vif *mvmvif,
+ u32 id)
{
struct iwl_mvm_session_prot_cmd cmd = {
.id_and_color =
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
mvmvif->color)),
.action = cpu_to_le32(FW_CTXT_ACTION_REMOVE),
- .conf_id = cpu_to_le32(mvmvif->time_event_data.id),
+ .conf_id = cpu_to_le32(id),
};
int ret;

@@ -634,6 +642,12 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
{
u32 id;
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif);
+ enum nl80211_iftype iftype;
+
+ if (!te_data->vif)
+ return false;
+
+ iftype = te_data->vif->type;

/*
* It is possible that by the time we got to this point the time
@@ -658,8 +672,8 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) {
/* Session protection is still ongoing. Cancel it */
- iwl_mvm_cancel_session_protection(mvm, mvmvif);
- if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
+ iwl_mvm_cancel_session_protection(mvm, mvmvif, id);
+ if (iftype == NL80211_IFTYPE_P2P_DEVICE) {
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
iwl_mvm_roc_finished(mvm);
}
@@ -740,11 +754,6 @@ void iwl_mvm_remove_time_event(struct iwl_mvm *mvm,
IWL_ERR(mvm, "Couldn't remove the time event\n");
}

-/*
- * When the firmware supports the session protection API,
- * this is not needed since it'll automatically remove the
- * session protection after association + beacon reception.
- */
void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
struct ieee80211_vif *vif)
{
@@ -758,7 +767,15 @@ void iwl_mvm_stop_session_protection(struct iwl_mvm *mvm,
id = te_data->id;
spin_unlock_bh(&mvm->time_event_lock);

- if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
+ if (fw_has_capa(&mvm->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) {
+ if (id != SESSION_PROTECT_CONF_ASSOC) {
+ IWL_DEBUG_TE(mvm,
+ "don't remove session protection id=%u\n",
+ id);
+ return;
+ }
+ } else if (id != TE_BSS_STA_AGGRESSIVE_ASSOC) {
IWL_DEBUG_TE(mvm,
"don't remove TE with id=%u (not session protection)\n",
id);
@@ -985,7 +1002,8 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
mvmvif = iwl_mvm_vif_from_mac80211(vif);

if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
- iwl_mvm_cancel_session_protection(mvm, mvmvif);
+ iwl_mvm_cancel_session_protection(mvm, mvmvif,
+ mvmvif->time_event_data.id);
set_bit(IWL_MVM_STATUS_NEED_FLUSH_P2P, &mvm->status);
} else {
iwl_mvm_remove_aux_roc_te(mvm, mvmvif,
@@ -1145,6 +1163,7 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,

iwl_mvm_te_clear_data(mvm, te_data);
te_data->duration = le32_to_cpu(cmd.duration_tu);
+ te_data->vif = vif;
spin_unlock_bh(&mvm->time_event_lock);

IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
--
2.32.0

2021-06-18 09:20:30

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 10/10] iwlwifi: mvm: introduce iwl_proto_offload_cmd_v4

From: Emmanuel Grumbach <[email protected]>

We need to pass the station id to tell the firmware
on which station we want to configure the protocol
offload.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/fw/api/d3.h | 16 ++++++++++++
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 11 +++++---
.../wireless/intel/iwlwifi/mvm/offloading.c | 26 ++++++++++++++-----
3 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 5373182c1364..a9e8f30ef91d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -159,6 +159,22 @@ struct iwl_proto_offload_cmd_v3_large {
struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L];
} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */

+/**
+ * struct iwl_proto_offload_cmd_v4 - ARP/NS offload configuration
+ * @sta_id: station id
+ * @common: common/IPv4 configuration
+ * @num_valid_ipv6_addrs: number of valid IPv6 addresses
+ * @targ_addrs: target IPv6 addresses
+ * @ns_config: NS offload configurations
+ */
+struct iwl_proto_offload_cmd_v4 {
+ __le32 sta_id;
+ struct iwl_proto_offload_cmd_common common;
+ __le32 num_valid_ipv6_addrs;
+ struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L];
+ struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L];
+} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_4 */
+
/*
* WOWLAN_PATTERNS
*/
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 6617fe5a7ece..7b13c4fc1b58 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1693,10 +1693,13 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm)
{
int ret;

- /* only for tracing for now */
- ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0, 0, NULL);
- if (ret)
- IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
+ if (!mvm->net_detect) {
+ /* only for tracing for now */
+ int ret = iwl_mvm_send_cmd_pdu(mvm, OFFLOADS_QUERY_CMD, 0,
+ 0, NULL);
+ if (ret)
+ IWL_ERR(mvm, "failed to query offload statistics (%d)\n", ret);
+ }

return iwl_mvm_send_wowlan_get_status(mvm);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c b/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c
index 1cc90e61367b..41880517e8bb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/offloading.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014 Intel Corporation
+ * Copyright (C) 2012-2014, 2021 Intel Corporation
* Copyright (C) 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015 Intel Deutschland GmbH
*/
@@ -36,7 +36,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
struct iwl_proto_offload_cmd_v1 v1;
struct iwl_proto_offload_cmd_v2 v2;
struct iwl_proto_offload_cmd_v3_small v3s;
- struct iwl_proto_offload_cmd_v3_large v3l;
+ struct iwl_proto_offload_cmd_v4 v4;
} cmd = {};
struct iwl_host_cmd hcmd = {
.id = PROT_OFFLOAD_CONFIG_CMD,
@@ -47,6 +47,9 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
struct iwl_proto_offload_cmd_common *common;
u32 enabled = 0, size;
u32 capa_flags = mvm->fw->ucode_capa.flags;
+ int ver = iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+ PROT_OFFLOAD_CONFIG_CMD, 0);
+
#if IS_ENABLED(CONFIG_IPV6)
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int i;
@@ -72,9 +75,9 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
addrs = cmd.v3s.targ_addrs;
n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S;
} else {
- nsc = cmd.v3l.ns_config;
+ nsc = cmd.v4.ns_config;
n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L;
- addrs = cmd.v3l.targ_addrs;
+ addrs = cmd.v4.targ_addrs;
n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
}

@@ -116,7 +119,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
cmd.v3s.num_valid_ipv6_addrs =
cpu_to_le32(i - num_skipped);
else
- cmd.v3l.num_valid_ipv6_addrs =
+ cmd.v4.num_valid_ipv6_addrs =
cpu_to_le32(i - num_skipped);
} else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
bool found = false;
@@ -171,8 +174,17 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
common = &cmd.v3s.common;
size = sizeof(cmd.v3s);
} else if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
- common = &cmd.v3l.common;
- size = sizeof(cmd.v3l);
+ common = &cmd.v4.common;
+ size = sizeof(cmd.v4);
+ if (ver < 4) {
+ /*
+ * This basically uses iwl_proto_offload_cmd_v3_large
+ * which doesn't have the sta_id parameter before the
+ * common part.
+ */
+ size -= sizeof(cmd.v4.sta_id);
+ hcmd.data[0] = common;
+ }
} else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
common = &cmd.v2.common;
size = sizeof(cmd.v2);
--
2.32.0

2021-06-18 09:20:30

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 03/10] iwlwifi: support ver 6 of WOWLAN_CONFIGURATION and ver 10 of WOWLAN_GET_STATUSES

From: Naftali Goldstein <[email protected]>

These two version updates deprecate the need to set/get the nonqos sequence
counter during suspend/resume flow respectively; NICs supporting this
version maintain this counter internally and don't lose it during the
suspend/resume flow.

Note that this means that for such NICs the NON_QOS_TX_COUNTER_CMD is no
longer ever sent.

Signed-off-by: Naftali Goldstein <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/fw/api/d3.h | 12 +++++----
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 26 ++++++++++++-------
2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 6488c0f8b471..5373182c1364 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -339,9 +339,10 @@ enum iwl_wowlan_flags {
};

/**
- * struct iwl_wowlan_config_cmd - WoWLAN configuration
+ * struct iwl_wowlan_config_cmd - WoWLAN configuration (versions 5 and 6)
* @wakeup_filter: filter from &enum iwl_wowlan_wakeup_filters
- * @non_qos_seq: non-QoS sequence counter to use next
+ * @non_qos_seq: non-QoS sequence counter to use next.
+ * Reserved if the struct has version >= 6.
* @qos_seq: QoS sequence counters to use next
* @wowlan_ba_teardown_tids: bitmap of BA sessions to tear down
* @is_11n_connection: indicates HT connection
@@ -604,12 +605,13 @@ struct iwl_wowlan_status_v7 {
} __packed; /* WOWLAN_STATUSES_API_S_VER_7 */

/**
- * struct iwl_wowlan_status_v9 - WoWLAN status (version 9)
+ * struct iwl_wowlan_status_v9 - WoWLAN status (versions 9 and 10)
* @gtk: GTK data
* @igtk: IGTK data
* @replay_ctr: GTK rekey replay counter
* @pattern_number: number of the matched pattern
- * @non_qos_seq_ctr: non-QoS sequence counter to use next
+ * @non_qos_seq_ctr: non-QoS sequence counter to use next.
+ * Reserved if the struct has version >= 10.
* @qos_seq_ctr: QoS sequence counters to use next
* @wakeup_reasons: wakeup reasons, see &enum iwl_wowlan_wakeup_reason
* @num_of_gtk_rekeys: number of GTK rekeys
@@ -638,7 +640,7 @@ struct iwl_wowlan_status_v9 {
u8 tid_tear_down;
u8 reserved[3];
u8 wake_packet[]; /* can be truncated from _length to _bufsize */
-} __packed; /* WOWLAN_STATUSES_API_S_VER_9 */
+} __packed; /* WOWLAN_STATUSES_RSP_API_S_VER_9 */

/**
* struct iwl_wowlan_status - WoWLAN status
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 2e28cf299ef4..e86f0e949b86 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -636,7 +636,6 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, struct iwl_mvm_vif *mvmvif,
struct ieee80211_sta *ap_sta)
{
- int ret;
struct iwl_mvm_sta *mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);

/* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
@@ -646,12 +645,16 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;

- /* Query the last used seqno and set it */
- ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
- if (ret < 0)
- return ret;
+ if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+ WOWLAN_CONFIGURATION, 0) < 6) {
+ /* Query the last used seqno and set it */
+ int ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
+
+ if (ret < 0)
+ return ret;

- wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
+ wowlan_config_cmd->non_qos_seq = cpu_to_le16(ret);
+ }

iwl_mvm_set_wowlan_qos_seq(mvm_ap_sta, wowlan_config_cmd);

@@ -1534,9 +1537,12 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
}

out:
- mvmvif->seqno_valid = true;
- /* +0x10 because the set API expects next-to-use, not last-used */
- mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
+ if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP,
+ WOWLAN_GET_STATUSES, 0) < 10) {
+ mvmvif->seqno_valid = true;
+ /* +0x10 because the set API expects next-to-use, not last-used */
+ mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10;
+ }

return true;
}
@@ -1654,7 +1660,7 @@ struct iwl_wowlan_status *iwl_mvm_send_wowlan_get_status(struct iwl_mvm *mvm)

status->gtk[0] = v7->gtk[0];
status->igtk[0] = v7->igtk[0];
- } else if (notif_ver == 9) {
+ } else if (notif_ver == 9 || notif_ver == 10) {
struct iwl_wowlan_status_v9 *v9 = (void *)cmd.resp_pkt->data;

status = iwl_mvm_parse_wowlan_status_common_v9(mvm,
--
2.32.0

2021-06-22 12:25:04

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH 01/10] iwlwifi: mvm: Explicitly stop session protection before unbinding

Luca Coelho <[email protected]> wrote:

> From: Ilan Peer <[email protected]>
>
> In case of unbinding, the FW would remove the session protection time
> events without sending a notification, so explicitly cancel the
> session protection, so future requests for mgd_prepare_tx() would not
> assume that the session protection is running.
>
> Signed-off-by: Ilan Peer <[email protected]>
> Signed-off-by: Luca Coelho <[email protected]>

10 patches applied to iwlwifi-next.git, thanks.

36ec9b2d888b iwlwifi: mvm: Explicitly stop session protection before unbinding
429fdaf8225c iwlwifi: mvm: don't request mac80211 to disable/enable sta's queues
995567a6e716 iwlwifi: support ver 6 of WOWLAN_CONFIGURATION and ver 10 of WOWLAN_GET_STATUSES
74036b4eee86 iwlwifi: mvm: support LONG_GROUP for WOWLAN_GET_STATUSES version
9a3daf10de54 iwlwifi: pcie: free IML DMA memory allocation
50e5cd79b42b iwlwifi: pcie: fix context info freeing
f34f4bf5e572 iwlwifi: mvm: fill phy_data.d1 for no-data RX
bd2a0cc7707b iwlwifi: pcie: free some DMA memory earlier
a28c4e3dc256 iwlwifi: fix NUM_IWL_UCODE_TLV_* definitions to avoid sparse errors
48effacf61ed iwlwifi: mvm: introduce iwl_proto_offload_cmd_v4