2021-02-10 12:00:31

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 00/12] iwlwifi: updates intended for v5.12 2021-02-07

From: Luca Coelho <[email protected]>

Hi,

In v2:

* Rebased on top of "iwlwifi: add new cards for So and Qu family",
which wasn't taken to v5.11.


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

The changes are:

* Add some device IDs that got lost in a rebase;
* A bunch of fixes in the PPAG code;
* 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: enhance a print in CSA flows
iwlwifi: pcie: NULLify pointers after free

Johannes Berg (2):
iwlwifi: pcie: don't disable interrupts for reg_lock
iwlwifi: mvm: remove useless iwl_mvm_resume_d3() function

Luca Coelho (6):
iwlwifi: pcie: add a few missing entries for So with Hr
iwlwifi: acpi: fix PPAG table sizes
iwlwifi: mvm: fix the type we use in the PPAG table validity checks
iwlwifi: mvm: store PPAG enabled/disabled flag properly
iwlwifi: mvm: send stored PPAG command instead of local
iwlwifi: mvm: assign SAR table revision to the command later

Matti Gottlieb (1):
iwlwifi: pcie: Change Ma device ID

Mordechay Goodstein (1):
iwlwifi: when HW has rate offload don't look at control field

drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 4 +-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 7 +--
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 45 ++++++++++++-------
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 22 +++++----
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 10 ++++-
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 ++
.../net/wireless/intel/iwlwifi/pcie/trans.c | 19 ++++----
.../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 5 +--
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 22 ++++-----
10 files changed, 80 insertions(+), 60 deletions(-)

--
2.30.0


2021-02-10 12:00:56

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 01/12] iwlwifi: pcie: add a few missing entries for So with Hr

From: Luca Coelho <[email protected]>

Some devices were missing from the So with Hr section.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index c17234c0c945..edd1a0fe19c3 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -596,9 +596,16 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
/* So with HR */
IWL_DEV_INFO(0x2725, 0x0090, iwlax211_2ax_cfg_so_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x0020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0x2020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0x0024, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x0310, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x0510, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x2725, 0x0A10, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0xE020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0xE024, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0x4020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0x6020, iwlax210_2ax_cfg_ty_gf_a0, NULL),
+ IWL_DEV_INFO(0x2725, 0x6024, iwlax210_2ax_cfg_ty_gf_a0, NULL),
IWL_DEV_INFO(0x7A70, 0x0090, iwlax211_2ax_cfg_so_gf_a0_long, NULL),
IWL_DEV_INFO(0x7A70, 0x0098, iwlax211_2ax_cfg_so_gf_a0_long, NULL),
IWL_DEV_INFO(0x7A70, 0x00B0, iwlax411_2ax_cfg_so_gf4_a0_long, NULL),
@@ -617,6 +624,7 @@ static const struct iwl_dev_info iwl_dev_info_table[] = {
IWL_DEV_INFO(0x2726, 0x0090, iwlax211_cfg_snj_gf_a0, NULL),
IWL_DEV_INFO(0x2726, 0x0098, iwlax211_cfg_snj_gf_a0, NULL),
IWL_DEV_INFO(0x2726, 0x00B0, iwlax411_2ax_cfg_sosnj_gf4_a0, NULL),
+ IWL_DEV_INFO(0x2726, 0x00B4, iwlax411_2ax_cfg_sosnj_gf4_a0, NULL),
IWL_DEV_INFO(0x2726, 0x0510, iwlax211_cfg_snj_gf_a0, NULL),
IWL_DEV_INFO(0x2726, 0x1651, iwl_cfg_snj_hr_b0, iwl_ax201_killer_1650s_name),
IWL_DEV_INFO(0x2726, 0x1652, iwl_cfg_snj_hr_b0, iwl_ax201_killer_1650i_name),
--
2.30.0

2021-02-10 12:01:11

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 04/12] iwlwifi: mvm: fix the type we use in the PPAG table validity checks

From: Luca Coelho <[email protected]>

The value we receive from ACPI is a long long unsigned integer but the
values should be treated as signed char. When comparing the received
value with ACPI_PPAG_MIN_LB/HB, we were doing an unsigned comparison,
so the negative value would actually be treated as a very high number.

To solve this issue, assign the value to our table of s8's before
making the comparison, so the value is already converted when we do
so.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 6a6567a7372b..3bfb80dd17cf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -965,16 +965,23 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
union acpi_object *ent;

ent = &wifi_pkg->package.elements[idx++];
- if (ent->type != ACPI_TYPE_INTEGER ||
- (j == 0 && ent->integer.value > ACPI_PPAG_MAX_LB) ||
- (j == 0 && ent->integer.value < ACPI_PPAG_MIN_LB) ||
- (j != 0 && ent->integer.value > ACPI_PPAG_MAX_HB) ||
- (j != 0 && ent->integer.value < ACPI_PPAG_MIN_HB)) {
- ppag_table.v1.enabled = cpu_to_le32(0);
+ if (ent->type != ACPI_TYPE_INTEGER) {
ret = -EINVAL;
goto out_free;
}
+
gain[i * num_sub_bands + j] = ent->integer.value;
+
+ if ((j == 0 &&
+ (gain[i * num_sub_bands + j] > ACPI_PPAG_MAX_LB ||
+ gain[i * num_sub_bands + j] < ACPI_PPAG_MIN_LB)) ||
+ (j != 0 &&
+ (gain[i * num_sub_bands + j] > ACPI_PPAG_MAX_HB ||
+ gain[i * num_sub_bands + j] < ACPI_PPAG_MIN_HB))) {
+ ppag_table.v1.enabled = cpu_to_le32(0);
+ ret = -EINVAL;
+ goto out_free;
+ }
}
}
ret = 0;
--
2.30.0

2021-02-10 12:01:20

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 07/12] iwlwifi: mvm: enhance a print in CSA flows

From: Emmanuel Grumbach <[email protected]>

Add the count and the mode to the modify CSA flow.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index aecf91df7f11..6704ad0895cb 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -4674,7 +4674,8 @@ static void iwl_mvm_channel_switch_rx_beacon(struct ieee80211_hw *hw,
if (mvmvif->csa_failed)
goto out_unlock;

- IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d\n", mvmvif->id);
+ IWL_DEBUG_MAC80211(mvm, "Modify CSA on mac %d count = %d mode = %d\n",
+ mvmvif->id, chsw->count, chsw->block_tx);
WARN_ON(iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(MAC_CONF_GROUP,
CHANNEL_SWITCH_TIME_EVENT_CMD),
--
2.30.0

2021-02-10 12:01:38

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 08/12] iwlwifi: mvm: remove useless iwl_mvm_resume_d3() function

From: Johannes Berg <[email protected]>

This is called exactly once, a few lines down, so there's
no point in having the extra function.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index acb3062f9eac..7c51c781cfaf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -2164,17 +2164,12 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
return 1;
}

-static int iwl_mvm_resume_d3(struct iwl_mvm *mvm)
-{
- return __iwl_mvm_resume(mvm, false);
-}
-
int iwl_mvm_resume(struct ieee80211_hw *hw)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
int ret;

- ret = iwl_mvm_resume_d3(mvm);
+ ret = __iwl_mvm_resume(mvm, false);

iwl_mvm_resume_tcm(mvm);

--
2.30.0

2021-02-10 12:01:42

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 09/12] iwlwifi: mvm: assign SAR table revision to the command later

From: Luca Coelho <[email protected]>

The call to iwl_sar_geo_init() was moved to the end of the
iwl_mvm_sar_geo_init() function, after the table revision is assigned
to the FW command. But the revision is only known after
iwl_sar_geo_init() is called, so we were always assigning zero to it.

Fix that by moving the assignment code after the iwl_sar_geo_init()
function is called.

Signed-off-by: Luca Coelho <[email protected]>
Fixes: 45acebf8d6a6 ("iwlwifi: fix sar geo table initialization")
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 8675a78ff9e9..76c460852398 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -862,12 +862,10 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
if (cmd_ver == 3) {
len = sizeof(cmd.v3);
n_bands = ARRAY_SIZE(cmd.v3.table[0]);
- cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
} else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
IWL_UCODE_TLV_API_SAR_TABLE_VER)) {
len = sizeof(cmd.v2);
n_bands = ARRAY_SIZE(cmd.v2.table[0]);
- cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
} else {
len = sizeof(cmd.v1);
n_bands = ARRAY_SIZE(cmd.v1.table[0]);
@@ -887,6 +885,16 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
if (ret)
return 0;

+ /*
+ * Set the revision on versions that contain it.
+ * This must be done after calling iwl_sar_geo_init().
+ */
+ if (cmd_ver == 3)
+ cmd.v3.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
+ else if (fw_has_api(&mvm->fwrt.fw->ucode_capa,
+ IWL_UCODE_TLV_API_SAR_TABLE_VER))
+ cmd.v2.table_revision = cpu_to_le32(mvm->fwrt.geo_rev);
+
return iwl_mvm_send_cmd_pdu(mvm,
WIDE_ID(PHY_OPS_GROUP, GEO_TX_POWER_LIMIT),
0, len, &cmd);
--
2.30.0

2021-02-10 12:02:09

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 05/12] iwlwifi: mvm: store PPAG enabled/disabled flag properly

From: Luca Coelho <[email protected]>

When reading the PPAG table from ACPI, we should store everything in
our fwrt structure, so it can be accessed later. But we had a local
ppag_table variable in the function and were erroneously storing the
enabled/disabled flag in it instead of storing it in the fwrt. Fix
this by removing the local variable and storing everything directly in
fwrt.

Signed-off-by: Luca Coelho <[email protected]>
Fixes: f2134f66f40e ("iwlwifi: acpi: support ppag table command v2")
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 3bfb80dd17cf..57471ab2f5ef 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -895,7 +895,6 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
{
union acpi_object *wifi_pkg, *data, *enabled;
- union iwl_ppag_table_cmd ppag_table;
int i, j, ret, tbl_rev, num_sub_bands;
int idx = 2;
s8 *gain;
@@ -949,8 +948,8 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
goto out_free;
}

- ppag_table.v1.enabled = cpu_to_le32(enabled->integer.value);
- if (!ppag_table.v1.enabled) {
+ mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(enabled->integer.value);
+ if (!mvm->fwrt.ppag_table.v1.enabled) {
ret = 0;
goto out_free;
}
@@ -978,7 +977,7 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
(j != 0 &&
(gain[i * num_sub_bands + j] > ACPI_PPAG_MAX_HB ||
gain[i * num_sub_bands + j] < ACPI_PPAG_MIN_HB))) {
- ppag_table.v1.enabled = cpu_to_le32(0);
+ mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(0);
ret = -EINVAL;
goto out_free;
}
--
2.30.0

2021-02-10 12:03:23

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 03/12] iwlwifi: acpi: fix PPAG table sizes

From: Luca Coelho <[email protected]>

We were erroneously adding 3 extra values to the table size
calculation, when we should actually add only a 2 (one for the domain
type and one for the enabled/disabled flag). Fix this for both
revisions we support.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 1cce30d1ef55..62665dfee3cb 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -54,9 +54,9 @@
#define ACPI_WGDS_TABLE_SIZE 3

#define ACPI_PPAG_WIFI_DATA_SIZE ((IWL_NUM_CHAIN_LIMITS * \
- IWL_NUM_SUB_BANDS) + 3)
+ IWL_NUM_SUB_BANDS) + 2)
#define ACPI_PPAG_WIFI_DATA_SIZE_V2 ((IWL_NUM_CHAIN_LIMITS * \
- IWL_NUM_SUB_BANDS_V2) + 3)
+ IWL_NUM_SUB_BANDS_V2) + 2)

/* PPAG gain value bounds in 1/8 dBm */
#define ACPI_PPAG_MIN_LB -16
--
2.30.0

2021-02-10 12:03:24

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 02/12] iwlwifi: pcie: don't disable interrupts for reg_lock

From: Johannes Berg <[email protected]>

The only thing we do touching the device in hard interrupt context
is, at most, writing an interrupt ACK register, which isn't racing
in with anything protected by the reg_lock.

Thus, avoid disabling interrupts here for potentially long periods
of time, particularly long periods have been observed with dumping
of firmware memory (leading to lockup warnings on some devices.)

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
.../net/wireless/intel/iwlwifi/pcie/trans.c | 11 +++++-----
.../net/wireless/intel/iwlwifi/pcie/tx-gen2.c | 5 ++---
drivers/net/wireless/intel/iwlwifi/pcie/tx.c | 22 ++++++++-----------
3 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 16f5757b1260..a73f2c54d446 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1972,7 +1972,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
int ret;
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);

- spin_lock_irqsave(&trans_pcie->reg_lock, *flags);
+ spin_lock_bh(&trans_pcie->reg_lock);

if (trans_pcie->cmd_hold_nic_awake)
goto out;
@@ -2057,7 +2057,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
}

err:
- spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
+ spin_unlock_bh(&trans_pcie->reg_lock);
return false;
}

@@ -2095,7 +2095,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
* scheduled on different CPUs (after we drop reg_lock).
*/
out:
- spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
+ spin_unlock_bh(&trans_pcie->reg_lock);
}

static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
@@ -2296,11 +2296,10 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
u32 mask, u32 value)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- unsigned long flags;

- spin_lock_irqsave(&trans_pcie->reg_lock, flags);
+ spin_lock_bh(&trans_pcie->reg_lock);
__iwl_trans_pcie_set_bits_mask(trans, reg, mask, value);
- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
+ spin_unlock_bh(&trans_pcie->reg_lock);
}

static const char *get_csr_string(int cmd)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
index 1099df7bc26f..4456abb9a074 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
@@ -31,7 +31,6 @@ int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id];
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
- unsigned long flags;
void *dup_buf = NULL;
dma_addr_t phys_addr;
int i, cmd_pos, idx;
@@ -244,11 +243,11 @@ int iwl_pcie_gen2_enqueue_hcmd(struct iwl_trans *trans,
if (txq->read_ptr == txq->write_ptr && txq->wd_timeout)
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);

- spin_lock_irqsave(&trans_pcie->reg_lock, flags);
+ spin_lock(&trans_pcie->reg_lock);
/* Increment and update queue's write index */
txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr);
iwl_txq_inc_wr_ptr(trans, txq);
- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
+ spin_unlock(&trans_pcie->reg_lock);

out:
spin_unlock_bh(&txq->lock);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 2e9d4113a9f1..e8acbfbf3ddc 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -223,12 +223,10 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
txq->read_ptr = iwl_txq_inc_wrap(trans, txq->read_ptr);

if (txq->read_ptr == txq->write_ptr) {
- unsigned long flags;
-
- spin_lock_irqsave(&trans_pcie->reg_lock, flags);
+ spin_lock(&trans_pcie->reg_lock);
if (txq_id == trans->txqs.cmd.q_id)
iwl_pcie_clear_cmd_in_flight(trans);
- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
+ spin_unlock(&trans_pcie->reg_lock);
}
}

@@ -679,7 +677,6 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_txq *txq = trans->txqs.txq[txq_id];
- unsigned long flags;
int nfreed = 0;
u16 r;

@@ -710,9 +707,10 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
}

if (txq->read_ptr == txq->write_ptr) {
- spin_lock_irqsave(&trans_pcie->reg_lock, flags);
+ /* BHs are also disabled due to txq->lock */
+ spin_lock(&trans_pcie->reg_lock);
iwl_pcie_clear_cmd_in_flight(trans);
- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
+ spin_unlock(&trans_pcie->reg_lock);
}

iwl_txq_progress(txq);
@@ -921,7 +919,6 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
struct iwl_txq *txq = trans->txqs.txq[trans->txqs.cmd.q_id];
struct iwl_device_cmd *out_cmd;
struct iwl_cmd_meta *out_meta;
- unsigned long flags;
void *dup_buf = NULL;
dma_addr_t phys_addr;
int idx;
@@ -1164,20 +1161,19 @@ int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
if (txq->read_ptr == txq->write_ptr && txq->wd_timeout)
mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);

- spin_lock_irqsave(&trans_pcie->reg_lock, flags);
+ spin_lock(&trans_pcie->reg_lock);
ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
if (ret < 0) {
idx = ret;
- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
- goto out;
+ goto unlock_reg;
}

/* Increment and update queue's write index */
txq->write_ptr = iwl_txq_inc_wrap(trans, txq->write_ptr);
iwl_pcie_txq_inc_wr_ptr(trans, txq);

- spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
-
+ unlock_reg:
+ spin_unlock(&trans_pcie->reg_lock);
out:
spin_unlock_bh(&txq->lock);
free_dup_buf:
--
2.30.0

2021-02-10 12:03:28

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 06/12] iwlwifi: mvm: send stored PPAG command instead of local

From: Luca Coelho <[email protected]>

Some change conflicts apparently cause a confusion between a local
variable being used to send the PPAG command and the introduction of a
union for this command. Most parts of the local command were never
copied from the stored data, so the FW was getting garbage in the
tables instead of getting valid values.

Fix this by completely removing the local and using only the union
that we have stored in fwrt.

Signed-off-by: Luca Coelho <[email protected]>
Fixes: f2134f66f40e ("iwlwifi: acpi: support ppag table command v2")
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 57471ab2f5ef..8675a78ff9e9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -993,7 +993,6 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
{
u8 cmd_ver;
int i, j, ret, num_sub_bands, cmd_size;
- union iwl_ppag_table_cmd ppag_table;
s8 *gain;

if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_PPAG)) {
@@ -1006,15 +1005,13 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
return 0;
}

- ppag_table.v1.enabled = mvm->fwrt.ppag_table.v1.enabled;
-
cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_OPS_GROUP,
PER_PLATFORM_ANT_GAIN_CMD,
IWL_FW_CMD_VER_UNKNOWN);
if (cmd_ver == 1) {
num_sub_bands = IWL_NUM_SUB_BANDS;
gain = mvm->fwrt.ppag_table.v1.gain[0];
- cmd_size = sizeof(ppag_table.v1);
+ cmd_size = sizeof(mvm->fwrt.ppag_table.v1);
if (mvm->fwrt.ppag_ver == 2) {
IWL_DEBUG_RADIO(mvm,
"PPAG table is v2 but FW supports v1, sending truncated table\n");
@@ -1022,7 +1019,7 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
} else if (cmd_ver == 2) {
num_sub_bands = IWL_NUM_SUB_BANDS_V2;
gain = mvm->fwrt.ppag_table.v2.gain[0];
- cmd_size = sizeof(ppag_table.v2);
+ cmd_size = sizeof(mvm->fwrt.ppag_table.v2);
if (mvm->fwrt.ppag_ver == 1) {
IWL_DEBUG_RADIO(mvm,
"PPAG table is v1 but FW supports v2, sending padded table\n");
@@ -1042,7 +1039,7 @@ int iwl_mvm_ppag_send_cmd(struct iwl_mvm *mvm)
IWL_DEBUG_RADIO(mvm, "Sending PER_PLATFORM_ANT_GAIN_CMD\n");
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
PER_PLATFORM_ANT_GAIN_CMD),
- 0, cmd_size, &ppag_table);
+ 0, cmd_size, &mvm->fwrt.ppag_table);
if (ret < 0)
IWL_ERR(mvm, "failed to send PER_PLATFORM_ANT_GAIN_CMD (%d)\n",
ret);
--
2.30.0

2021-02-10 12:07:48

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 11/12] iwlwifi: when HW has rate offload don't look at control field

From: Mordechay Goodstein <[email protected]>

Control field is set by mac80211 only if case rate is not offloaded to
hw.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 871e9daf56f8..1ad621d13ad3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -265,20 +265,24 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
struct ieee80211_tx_info *info,
struct ieee80211_sta *sta, __le16 fc)
{
- int rate_idx;
+ int rate_idx = -1;
u8 rate_plcp;
u32 rate_flags = 0;
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);

- /* HT rate doesn't make sense for a non data frame */
- WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS &&
- !ieee80211_is_data(fc),
- "Got a HT rate (flags:0x%x/mcs:%d/fc:0x%x/state:%d) for a non data frame\n",
- info->control.rates[0].flags,
- info->control.rates[0].idx,
- le16_to_cpu(fc), mvmsta->sta_state);
+ /* info->control is only relevant for non HW rate control */
+ if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
+ /* HT rate doesn't make sense for a non data frame */
+ WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS &&
+ !ieee80211_is_data(fc),
+ "Got a HT rate (flags:0x%x/mcs:%d/fc:0x%x/state:%d) for a non data frame\n",
+ info->control.rates[0].flags,
+ info->control.rates[0].idx,
+ le16_to_cpu(fc), mvmsta->sta_state);
+
+ rate_idx = info->control.rates[0].idx;
+ }

- rate_idx = info->control.rates[0].idx;
/* if the rate isn't a well known legacy rate, take the lowest one */
if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY)
rate_idx = rate_lowest_index(
--
2.30.0

2021-02-10 12:08:21

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 10/12] iwlwifi: pcie: NULLify pointers after free

From: Emmanuel Grumbach <[email protected]>

Remember that those pointers have been freed by setting them
to NULL. Otherwise, we'd keep rxq pointing to random memory
which would prevent us from trying to re-allocate the Rx
resources if we call rx_alloc again.

Also, propagate the allocation failure to the caller of
iwl_pcie_nic_init so that we won't go further in the
start flow.

Signed-off-by: Emmanuel Grumbach <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 3 +++
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 8 ++++++--
2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 407809c7e958..664481ca58c9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -834,8 +834,11 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans)
trans_pcie->base_rb_stts_dma = 0;
}
kfree(trans_pcie->rx_pool);
+ trans_pcie->rx_pool = NULL;
kfree(trans_pcie->global_table);
+ trans_pcie->global_table = NULL;
kfree(trans_pcie->rxq);
+ trans_pcie->rxq = NULL;

return ret;
}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index a73f2c54d446..c0d2221a18a9 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -523,11 +523,15 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans)
iwl_op_mode_nic_config(trans->op_mode);

/* Allocate the RX queue, or reset if it is already allocated */
- iwl_pcie_rx_init(trans);
+ ret = iwl_pcie_rx_init(trans);
+ if (ret)
+ return ret;

/* Allocate or reset and init all Tx and Command queues */
- if (iwl_pcie_tx_init(trans))
+ if (iwl_pcie_tx_init(trans)) {
+ iwl_pcie_rx_free(trans);
return -ENOMEM;
+ }

if (trans->trans_cfg->base_params->shadow_reg_enable) {
/* enable shadow regs in HW */
--
2.30.0

2021-02-10 12:08:32

by Luca Coelho

[permalink] [raw]
Subject: [PATCH v2 12/12] iwlwifi: pcie: Change Ma device ID

From: Matti Gottlieb <[email protected]>

The Ma device ID needs to be 0x7E40 instead of 0x7E80.

Signed-off-by: Matti Gottlieb <[email protected]>
Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index edd1a0fe19c3..3e149141fec5 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -488,7 +488,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {

/* Ma devices */
{IWL_PCI_DEVICE(0x2729, PCI_ANY_ID, iwl_ma_trans_cfg)},
- {IWL_PCI_DEVICE(0x7E80, PCI_ANY_ID, iwl_ma_trans_cfg)},
+ {IWL_PCI_DEVICE(0x7E40, PCI_ANY_ID, iwl_ma_trans_cfg)},

#endif /* CONFIG_IWLMVM */

--
2.30.0

2021-02-10 12:43:56

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH v2 01/12] iwlwifi: pcie: add a few missing entries for So with Hr

Luca Coelho <[email protected]> wrote:

> From: Luca Coelho <[email protected]>
>
> Some devices were missing from the So with Hr section.
>
> Signed-off-by: Luca Coelho <[email protected]>

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

806832c9651b iwlwifi: pcie: add a few missing entries for So with Hr
874020f8adce iwlwifi: pcie: don't disable interrupts for reg_lock
f9a78edb2881 iwlwifi: acpi: fix PPAG table sizes
5a6842455c11 iwlwifi: mvm: fix the type we use in the PPAG table validity checks
551d793f6536 iwlwifi: mvm: store PPAG enabled/disabled flag properly
659844d39182 iwlwifi: mvm: send stored PPAG command instead of local
b06b598664da iwlwifi: mvm: enhance a print in CSA flows
34b79fcf1e39 iwlwifi: mvm: remove useless iwl_mvm_resume_d3() function
28db1862067c iwlwifi: mvm: assign SAR table revision to the command later
9cf671d60fdb iwlwifi: pcie: NULLify pointers after free
004272bc8d9d iwlwifi: when HW has rate offload don't look at control field
1c094e5e2b02 iwlwifi: pcie: Change Ma device ID

2021-09-07 11:36:35

by Kai-Heng Feng

[permalink] [raw]
Subject: Re: [PATCH v2 05/12] iwlwifi: mvm: store PPAG enabled/disabled flag properly

Hi Luca,

On Wed, Feb 10, 2021 at 8:00 PM Luca Coelho <[email protected]> wrote:
>
> From: Luca Coelho <[email protected]>
>
> When reading the PPAG table from ACPI, we should store everything in
> our fwrt structure, so it can be accessed later. But we had a local
> ppag_table variable in the function and were erroneously storing the
> enabled/disabled flag in it instead of storing it in the fwrt. Fix
> this by removing the local variable and storing everything directly in
> fwrt.

This patch enables PPAG, but it breaks one of HP laptop with Intel 9560.

dmesg with iwlwifi.debug=0x80 attached in the bug report:
https://bugzilla.kernel.org/show_bug.cgi?id=214343

>
> Signed-off-by: Luca Coelho <[email protected]>
> Fixes: f2134f66f40e ("iwlwifi: acpi: support ppag table command v2")
> Signed-off-by: Luca Coelho <[email protected]>
> ---
> drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> index 3bfb80dd17cf..57471ab2f5ef 100644
> --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
> @@ -895,7 +895,6 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
> static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
> {
> union acpi_object *wifi_pkg, *data, *enabled;
> - union iwl_ppag_table_cmd ppag_table;
> int i, j, ret, tbl_rev, num_sub_bands;
> int idx = 2;
> s8 *gain;
> @@ -949,8 +948,8 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
> goto out_free;
> }
>
> - ppag_table.v1.enabled = cpu_to_le32(enabled->integer.value);
> - if (!ppag_table.v1.enabled) {
> + mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(enabled->integer.value);
> + if (!mvm->fwrt.ppag_table.v1.enabled) {
> ret = 0;
> goto out_free;
> }
> @@ -978,7 +977,7 @@ static int iwl_mvm_get_ppag_table(struct iwl_mvm *mvm)
> (j != 0 &&
> (gain[i * num_sub_bands + j] > ACPI_PPAG_MAX_HB ||
> gain[i * num_sub_bands + j] < ACPI_PPAG_MIN_HB))) {
> - ppag_table.v1.enabled = cpu_to_le32(0);
> + mvm->fwrt.ppag_table.v1.enabled = cpu_to_le32(0);
> ret = -EINVAL;
> goto out_free;
> }
> --
> 2.30.0
>

2021-09-07 12:09:12

by Luca Coelho

[permalink] [raw]
Subject: Re: [PATCH v2 05/12] iwlwifi: mvm: store PPAG enabled/disabled flag properly

On Tue, 2021-09-07 at 19:30 +0800, Kai-Heng Feng wrote:
> Hi Luca,
>
> On Wed, Feb 10, 2021 at 8:00 PM Luca Coelho <[email protected]> wrote:
> >
> > From: Luca Coelho <[email protected]>
> >
> > When reading the PPAG table from ACPI, we should store everything in
> > our fwrt structure, so it can be accessed later. But we had a local
> > ppag_table variable in the function and were erroneously storing the
> > enabled/disabled flag in it instead of storing it in the fwrt. Fix
> > this by removing the local variable and storing everything directly in
> > fwrt.
>
> This patch enables PPAG, but it breaks one of HP laptop with Intel 9560.
>
> dmesg with iwlwifi.debug=0x80 attached in the bug report:
> https://bugzilla.kernel.org/show_bug.cgi?id=214343

Thanks for the report. There seems to be an incompatibility between
the command the driver is sending to the FW and the version the FW
supports.

The commit you mentioned just enables sending this commands, which was
mistakenly not sent before.

Let's continue this discussion in bugzilla. I'll add more information
there as I figure it out.

--
Cheers,
Luca.