2019-03-22 12:47:54

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 0/3] iwlwifi: fixes intended for 5.1 2019-03-22

From: Luca Coelho <[email protected]>

Hi,

This is the second patchset with fixes for 5.1.

The changes are:

* fix for a potential deadlock in the TX path;
* a fix for offloaded rate-control;
* support new PCI HW IDs which use a new FW;

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

Please review.

Cheers,
Luca.


Johannes Berg (2):
iwlwifi: mvm: avoid possible deadlock in TX path
iwlwifi: mvm: update offloaded rate control on changes

Luca Coelho (1):
iwlwifi: add support for quz firmwares

drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 18 ++++++++++++++++--
.../net/wireless/intel/iwlwifi/iwl-config.h | 1 +
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 +
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 7 +++++++
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 2 ++
.../net/wireless/intel/iwlwifi/pcie/trans.c | 4 ++++
6 files changed, 31 insertions(+), 2 deletions(-)

--
2.20.1



2019-03-22 12:47:54

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 1/3] iwlwifi: mvm: avoid possible deadlock in TX path

From: Johannes Berg <[email protected]>

iwl_mvm_tx_mpdu() may run from iwl_mvm_add_new_dqa_stream_wk(), where
soft-IRQs aren't disabled. In this case, it may hold the station lock
and be interrupted by a soft-IRQ that also wants to acquire said lock,
leading to a deadlock.

Fix it by disabling soft-IRQs in iwl_mvm_add_new_dqa_stream_wk().

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index db26f0041a81..98d123dd7177 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -1399,7 +1399,9 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk)

iwl_mvm_sta_alloc_queue(mvm, txq->sta, txq->ac, tid);
list_del_init(&mvmtxq->list);
+ local_bh_disable();
iwl_mvm_mac_itxq_xmit(mvm->hw, txq);
+ local_bh_enable();
}

mutex_unlock(&mvm->mutex);
--
2.20.1


2019-03-22 12:47:56

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 2/3] iwlwifi: mvm: update offloaded rate control on changes

From: Johannes Berg <[email protected]>

With offloaded rate control, if the station parameters (rates, NSS,
bandwidth) change (sta_rc_update method), call iwl_mvm_rs_rate_init()
to propagate those change to the firmware.

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

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index eeaeb8475666..6a3b11dd2edf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -3258,6 +3258,13 @@ static void iwl_mvm_sta_rc_update(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, u32 changed)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+ if (changed & (IEEE80211_RC_BW_CHANGED |
+ IEEE80211_RC_SUPP_RATES_CHANGED |
+ IEEE80211_RC_NSS_CHANGED))
+ iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
+ true);

if (vif->type == NL80211_IFTYPE_STATION &&
changed & IEEE80211_RC_NSS_CHANGED)
--
2.20.1


2019-03-22 12:47:56

by Luca Coelho

[permalink] [raw]
Subject: [PATCH 3/3] iwlwifi: add support for quz firmwares

From: Luca Coelho <[email protected]>

Add a new configuration with a new firmware name for quz devices.
And, since these devices have the same PCI device and subsystem IDs,
we need to add some code to switch from a normal qu firmware to the
quz firmware.

Signed-off-by: Luca Coelho <[email protected]>
---
drivers/net/wireless/intel/iwlwifi/cfg/22000.c | 18 ++++++++++++++++--
.../net/wireless/intel/iwlwifi/iwl-config.h | 1 +
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 1 +
.../net/wireless/intel/iwlwifi/pcie/trans.c | 4 ++++
4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index d5c29298ae3e..eb6defb6d0cd 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -82,6 +82,7 @@
#define IWL_22000_HR_A0_FW_PRE "iwlwifi-QuQnj-a0-hr-a0-"
#define IWL_22000_SU_Z0_FW_PRE "iwlwifi-su-z0-"
#define IWL_QU_B_JF_B_FW_PRE "iwlwifi-Qu-b0-jf-b0-"
+#define IWL_QUZ_A_HR_B_FW_PRE "iwlwifi-QuZ-a0-hr-b0-"
#define IWL_QNJ_B_JF_B_FW_PRE "iwlwifi-QuQnj-b0-jf-b0-"
#define IWL_CC_A_FW_PRE "iwlwifi-cc-a0-"
#define IWL_22000_SO_A_JF_B_FW_PRE "iwlwifi-so-a0-jf-b0-"
@@ -105,8 +106,8 @@
IWL_22000_HR_A0_FW_PRE __stringify(api) ".ucode"
#define IWL_22000_SU_Z0_MODULE_FIRMWARE(api) \
IWL_22000_SU_Z0_FW_PRE __stringify(api) ".ucode"
-#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
- IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
+#define IWL_QUZ_A_HR_B_MODULE_FIRMWARE(api) \
+ IWL_QUZ_A_HR_B_FW_PRE __stringify(api) ".ucode"
#define IWL_QU_B_JF_B_MODULE_FIRMWARE(api) \
IWL_QU_B_JF_B_FW_PRE __stringify(api) ".ucode"
#define IWL_QNJ_B_JF_B_MODULE_FIRMWARE(api) \
@@ -235,6 +236,18 @@ const struct iwl_cfg iwl_ax101_cfg_qu_hr = {
.max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
};

+const struct iwl_cfg iwl_ax101_cfg_quz_hr = {
+ .name = "Intel(R) Wi-Fi 6 AX101",
+ .fw_name_pre = IWL_QUZ_A_HR_B_FW_PRE,
+ IWL_DEVICE_22500,
+ /*
+ * This device doesn't support receiving BlockAck with a large bitmap
+ * so we need to restrict the size of transmitted aggregation to the
+ * HT size; mac80211 would otherwise pick the HE max (256) by default.
+ */
+ .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+};
+
const struct iwl_cfg iwl_ax200_cfg_cc = {
.name = "Intel(R) Wi-Fi 6 AX200 160MHz",
.fw_name_pre = IWL_CC_A_FW_PRE,
@@ -444,6 +457,7 @@ MODULE_FIRMWARE(IWL_22000_HR_B_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_HR_A0_QNJ_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SU_Z0_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QU_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL_QUZ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_QNJ_B_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_CC_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL_22000_SO_A_JF_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index c91b537fa7ff..93070848280a 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -549,6 +549,7 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
+extern const struct iwl_cfg iwl_ax101_cfg_quz_hr;
extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
extern const struct iwl_cfg iwl_ax200_cfg_cc;
extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index aea6d03e545a..e539bc94eff7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -327,6 +327,7 @@ enum {
#define CSR_HW_REV_TYPE_NONE (0x00001F0)
#define CSR_HW_REV_TYPE_QNJ (0x0000360)
#define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
+#define CSR_HW_REV_TYPE_QUZ (0x0000354)
#define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
#define CSR_HW_REV_TYPE_SO (0x0000370)
#define CSR_HW_REV_TYPE_TY (0x0000420)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 1d6f3053f233..79c1dc05f948 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3543,6 +3543,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
}
} else if (cfg == &iwl_ax101_cfg_qu_hr) {
if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
+ CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
+ trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
+ trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
+ } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
trans->cfg = &iwl_ax101_cfg_qu_hr;
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
--
2.20.1


2019-05-20 09:55:28

by Bjørn Mork

[permalink] [raw]
Subject: Re: [PATCH 3/3] iwlwifi: add support for quz firmwares

Luca Coelho <[email protected]> writes:

> --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
> @@ -549,6 +549,7 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
> extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
> extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
> extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
> +extern const struct iwl_cfg iwl_ax101_cfg_quz_hr;
> extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
> extern const struct iwl_cfg iwl_ax200_cfg_cc;
> extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
> diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> index aea6d03e545a..e539bc94eff7 100644
> --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> @@ -327,6 +327,7 @@ enum {
> #define CSR_HW_REV_TYPE_NONE (0x00001F0)
> #define CSR_HW_REV_TYPE_QNJ (0x0000360)
> #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
> +#define CSR_HW_REV_TYPE_QUZ (0x0000354)
> #define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
> #define CSR_HW_REV_TYPE_SO (0x0000370)
> #define CSR_HW_REV_TYPE_TY (0x0000420)
> diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> index 1d6f3053f233..79c1dc05f948 100644
> --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> @@ -3543,6 +3543,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
> }
> } else if (cfg == &iwl_ax101_cfg_qu_hr) {
> if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
> + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
> + trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
> + trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
> + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
> CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
> trans->cfg = &iwl_ax101_cfg_qu_hr;
> } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==

Did you intend to use CSR_HW_REV_TYPE_QUZ and iwl_cfg
iwl_ax101_cfg_quz_hr here, or am I misunderstanding something?

Must admit that I didn't actually read the code. Just happend to look
at this patch briefly while glancing through linux-wireless... Sorry if
I'just adding noise.


Bjørn

2019-07-02 08:33:54

by Luciano Coelho

[permalink] [raw]
Subject: Re: [PATCH 3/3] iwlwifi: add support for quz firmwares

On Mon, 2019-05-20 at 10:42 +0200, Bjørn Mork wrote:
> Luca Coelho <[email protected]> writes:
>
> > --- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
> > +++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
> > @@ -549,6 +549,7 @@ extern const struct iwl_cfg iwl22000_2ac_cfg_hr;
> > extern const struct iwl_cfg iwl22000_2ac_cfg_hr_cdb;
> > extern const struct iwl_cfg iwl22000_2ac_cfg_jf;
> > extern const struct iwl_cfg iwl_ax101_cfg_qu_hr;
> > +extern const struct iwl_cfg iwl_ax101_cfg_quz_hr;
> > extern const struct iwl_cfg iwl22000_2ax_cfg_hr;
> > extern const struct iwl_cfg iwl_ax200_cfg_cc;
> > extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
> > diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> > index aea6d03e545a..e539bc94eff7 100644
> > --- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> > +++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
> > @@ -327,6 +327,7 @@ enum {
> > #define CSR_HW_REV_TYPE_NONE (0x00001F0)
> > #define CSR_HW_REV_TYPE_QNJ (0x0000360)
> > #define CSR_HW_REV_TYPE_QNJ_B0 (0x0000364)
> > +#define CSR_HW_REV_TYPE_QUZ (0x0000354)
> > #define CSR_HW_REV_TYPE_HR_CDB (0x0000340)
> > #define CSR_HW_REV_TYPE_SO (0x0000370)
> > #define CSR_HW_REV_TYPE_TY (0x0000420)
> > diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> > index 1d6f3053f233..79c1dc05f948 100644
> > --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> > +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
> > @@ -3543,6 +3543,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
> > }
> > } else if (cfg == &iwl_ax101_cfg_qu_hr) {
> > if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
> > + CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
> > + trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
> > + trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
> > + } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
> > CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
> > trans->cfg = &iwl_ax101_cfg_qu_hr;
> > } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
>
> Did you intend to use CSR_HW_REV_TYPE_QUZ and iwl_cfg
> iwl_ax101_cfg_quz_hr here, or am I misunderstanding something?
>
> Must admit that I didn't actually read the code. Just happend to look
> at this patch briefly while glancing through linux-wireless... Sorry if
> I'just adding noise.

Sorry for the late reply! But yes, you are right, this was a merge
damage. I'll send a patch fixing it.

Thanks a lot for the attentive eyes!

--
Cheers,
Luca.