* [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21
@ 2023-09-21 8:57 gregory.greenman
2023-09-21 8:57 ` [PATCH 01/12] wifi: iwlwifi: mvm: support set_antenna() gregory.greenman
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Gregory Greenman
From: Gregory Greenman <gregory.greenman@intel.com>
Hi,
This patch set includes iwlwifi patches intended for v6.7.
The main changes are:
* driver implementation of set_antenna() API
* a few MLO fixes
* small regulatory feature (China 2022 regulatory)
* error recovery improvements
* support new CRF (Companion RF) type
* fixes and cleanups
Thanks,
Gregory
Anjaneyulu (1):
wifi: iwlwifi: implement enable/disable for China 2022 regulatory
Emmanuel Grumbach (1):
wifi: iwlwifi: mvm: support set_antenna()
Johannes Berg (8):
wifi: iwlwifi: mvm: iterate active links for STA queues
wifi: iwlwifi: mvm: handle link-STA allocation in restart
wifi: iwlwifi: pcie: (re-)assign BAR0 on driver bind
wifi: iwlwifi: fail NIC access fast on dead NIC
wifi: iwlwifi: mvm: make pldr_sync AX210 specific
wifi: iwlwifi: mvm: refactor TX rate handling
wifi: iwlwifi: mvm: support injection antenna control
wifi: iwlwifi: mvm: check for iwl_mvm_mld_update_sta() errors
Mukesh Sisodiya (1):
wifi: iwlwifi: add mapping of a periphery register crf for WH RF
Yedidya Benshimol (1):
wifi: iwlwifi: mvm: add support for new wowlan_info_notif
drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 18 ++
drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 5 +
.../net/wireless/intel/iwlwifi/fw/api/d3.h | 46 ++++-
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 6 +-
.../wireless/intel/iwlwifi/fw/api/offload.h | 6 +-
.../net/wireless/intel/iwlwifi/fw/debugfs.c | 8 +-
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 +-
.../wireless/intel/iwlwifi/iwl-eeprom-parse.c | 5 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 76 ++++++--
.../wireless/intel/iwlwifi/iwl-nvm-parse.h | 19 +-
drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 1 +
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 165 +++++++++++++++---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 15 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 25 +++
.../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 1 +
.../net/wireless/intel/iwlwifi/mvm/mld-sta.c | 23 ++-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 29 ++-
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 12 +-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +-
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 7 +-
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 90 ++++++----
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +
.../net/wireless/intel/iwlwifi/pcie/trans.c | 12 ++
23 files changed, 468 insertions(+), 112 deletions(-)
--
2.38.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 01/12] wifi: iwlwifi: mvm: support set_antenna()
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
@ 2023-09-21 8:57 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 02/12] wifi: iwlwifi: mvm: iterate active links for STA queues gregory.greenman
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:57 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Emmanuel Grumbach, Ben Greear, Gregory Greenman
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
set_antenna() is supported only when the device is not started in
mac80211 which translates to the firmware not being loaded in iwlwifi.
The tricky part is that iwlwifi populates the sband data during its boot
and doesn't touch this data afterwards, but if the antenna settings
forbid MIMO, we need to update the sband data.
Rework the nvm parsing code to allow to get an existing nvm_data and
modify the sband with additional constraints (tx / rx chains masks).
Suggested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
.../wireless/intel/iwlwifi/iwl-eeprom-parse.c | 5 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 76 ++++++++++++++++---
.../wireless/intel/iwlwifi/iwl-nvm-parse.h | 19 +++--
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 3 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 25 ++++++
.../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 1 +
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 29 +++++--
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c | 12 ++-
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 5 +-
9 files changed, 148 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
index d7a7835b935c..5aab64c63a13 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2005-2014, 2018-2020 Intel Corporation
+ * Copyright (C) 2005-2014, 2018-2021, 2023 Intel Corporation
* Copyright (C) 2015 Intel Mobile Communications GmbH
*/
#include <linux/types.h>
@@ -721,6 +721,9 @@ void iwl_init_ht_hw_capab(struct iwl_trans *trans,
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_4;
ht_info->mcs.rx_mask[0] = 0xFF;
+ ht_info->mcs.rx_mask[1] = 0x00;
+ ht_info->mcs.rx_mask[2] = 0x00;
+
if (rx_chains >= 2)
ht_info->mcs.rx_mask[1] = 0xFF;
if (rx_chains >= 3)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index cff1f97536e3..512af3605a2c 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -962,6 +962,9 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
}
}
} else {
+ struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp =
+ &iftype_data->he_cap.he_mcs_nss_supp;
+
if (iftype_data->eht_cap.has_eht) {
struct ieee80211_eht_mcs_nss_supp *mcs_nss =
&iftype_data->eht_cap.eht_mcs_nss_supp;
@@ -980,6 +983,19 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
iftype_data->he_cap.he_cap_elem.phy_cap_info[7] |=
IEEE80211_HE_PHY_CAP7_MAX_NC_1;
}
+
+ he_mcs_nss_supp->rx_mcs_80 |=
+ cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
+ he_mcs_nss_supp->tx_mcs_80 |=
+ cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
+ he_mcs_nss_supp->rx_mcs_160 |=
+ cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
+ he_mcs_nss_supp->tx_mcs_160 |=
+ cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
+ he_mcs_nss_supp->rx_mcs_80p80 |=
+ cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
+ he_mcs_nss_supp->tx_mcs_80p80 |=
+ cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << 2);
}
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210 && !is_ap)
@@ -1052,10 +1068,6 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
struct ieee80211_sband_iftype_data *iftype_data;
int i;
- /* should only initialize once */
- if (WARN_ON(sband->iftype_data))
- return;
-
BUILD_BUG_ON(sizeof(data->iftd.low) != sizeof(iwl_he_eht_capa));
BUILD_BUG_ON(sizeof(data->iftd.high) != sizeof(iwl_he_eht_capa));
BUILD_BUG_ON(sizeof(data->iftd.uhb) != sizeof(iwl_he_eht_capa));
@@ -1087,6 +1099,37 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
iwl_init_he_6ghz_capa(trans, data, sband, tx_chains, rx_chains);
}
+void iwl_reinit_cab(struct iwl_trans *trans, struct iwl_nvm_data *data,
+ u8 tx_chains, u8 rx_chains, const struct iwl_fw *fw)
+{
+ struct ieee80211_supported_band *sband;
+
+ sband = &data->bands[NL80211_BAND_2GHZ];
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_2GHZ,
+ tx_chains, rx_chains);
+
+ if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
+ iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains,
+ fw);
+
+ sband = &data->bands[NL80211_BAND_5GHZ];
+ iwl_init_ht_hw_capab(trans, data, &sband->ht_cap, NL80211_BAND_5GHZ,
+ tx_chains, rx_chains);
+ if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
+ iwl_init_vht_hw_capab(trans, data, &sband->vht_cap,
+ tx_chains, rx_chains);
+
+ if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
+ iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains,
+ fw);
+
+ sband = &data->bands[NL80211_BAND_6GHZ];
+ if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax)
+ iwl_init_he_hw_capab(trans, data, sband, tx_chains, rx_chains,
+ fw);
+}
+IWL_EXPORT_SYMBOL(iwl_reinit_cab);
+
static void iwl_init_sbands(struct iwl_trans *trans,
struct iwl_nvm_data *data,
const void *nvm_ch_flags, u8 tx_chains,
@@ -1365,7 +1408,7 @@ iwl_nvm_no_wide_in_5ghz(struct iwl_trans *trans, const struct iwl_cfg *cfg,
struct iwl_nvm_data *
iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const struct iwl_mei_nvm *mei_nvm,
- const struct iwl_fw *fw)
+ const struct iwl_fw *fw, u8 tx_ant, u8 rx_ant)
{
struct iwl_nvm_data *data;
u32 sbands_flags = 0;
@@ -1392,6 +1435,10 @@ iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
tx_chains &= data->valid_tx_ant;
if (data->valid_rx_ant)
rx_chains &= data->valid_rx_ant;
+ if (tx_ant)
+ tx_chains &= tx_ant;
+ if (rx_ant)
+ rx_chains &= rx_ant;
data->sku_cap_mimo_disabled = false;
data->sku_cap_band_24ghz_enable = true;
@@ -1957,7 +2004,8 @@ int iwl_read_external_nvm(struct iwl_trans *trans,
IWL_EXPORT_SYMBOL(iwl_read_external_nvm);
struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
- const struct iwl_fw *fw)
+ const struct iwl_fw *fw,
+ u8 set_tx_ant, u8 set_rx_ant)
{
struct iwl_nvm_get_info cmd = {};
struct iwl_nvm_data *nvm;
@@ -1971,6 +2019,9 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
bool empty_otp;
u32 mac_flags;
u32 sbands_flags = 0;
+ u8 tx_ant;
+ u8 rx_ant;
+
/*
* All the values in iwl_nvm_get_info_rsp v4 are the same as
* in v3, except for the channel profile part of the
@@ -2058,10 +2109,15 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
channel_profile = v4 ? (void *)rsp->regulatory.channel_profile :
(void *)rsp_v3->regulatory.channel_profile;
- iwl_init_sbands(trans, nvm,
- channel_profile,
- nvm->valid_tx_ant & fw->valid_tx_ant,
- nvm->valid_rx_ant & fw->valid_rx_ant,
+ tx_ant = nvm->valid_tx_ant & fw->valid_tx_ant;
+ rx_ant = nvm->valid_rx_ant & fw->valid_rx_ant;
+
+ if (set_tx_ant)
+ tx_ant &= set_tx_ant;
+ if (set_rx_ant)
+ rx_ant &= set_rx_ant;
+
+ iwl_init_sbands(trans, nvm, channel_profile, tx_ant, rx_ant,
sbands_flags, v4, fw);
iwl_free_resp(&hcmd);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
index c79f72d54482..651ed25b683b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2005-2015, 2018-2022 Intel Corporation
+ * Copyright (C) 2005-2015, 2018-2023 Intel Corporation
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
#ifndef __iwl_nvm_parse_h__
@@ -21,7 +21,7 @@ enum iwl_nvm_sbands_flags {
IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ = BIT(1),
};
-/**
+/*
* iwl_parse_nvm_data - parse NVM data and return values
*
* This function parses all NVM values we need and then
@@ -73,21 +73,28 @@ int iwl_read_external_nvm(struct iwl_trans *trans,
void iwl_nvm_fixups(u32 hw_id, unsigned int section, u8 *data,
unsigned int len);
-/**
+/*
* iwl_get_nvm - retrieve NVM data from firmware
*
* Allocates a new iwl_nvm_data structure, fills it with
* NVM data, and returns it to caller.
*/
struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
- const struct iwl_fw *fw);
+ const struct iwl_fw *fw,
+ u8 set_tx_ant, u8 set_rx_ant);
-/**
+/*
* iwl_parse_mei_nvm_data - parse the mei_nvm_data and get an iwl_nvm_data
*/
struct iwl_nvm_data *
iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
const struct iwl_mei_nvm *mei_nvm,
- const struct iwl_fw *fw);
+ const struct iwl_fw *fw, u8 set_tx_ant, u8 set_rx_ant);
+
+/*
+ * iwl_reinit_cab - to be called when the tx_chains or rx_chains are modified
+ */
+void iwl_reinit_cab(struct iwl_trans *trans, struct iwl_nvm_data *data,
+ u8 tx_chains, u8 rx_chains, const struct iwl_fw *fw);
#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 567b02754a43..6e5c0f81e041 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -681,7 +681,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)
/* Read the NVM only at driver load time, no need to do this twice */
if (!IWL_MVM_PARSE_NVM && !mvm->nvm_data) {
- mvm->nvm_data = iwl_get_nvm(mvm->trans, mvm->fw);
+ mvm->nvm_data = iwl_get_nvm(mvm->trans, mvm->fw,
+ mvm->set_tx_ant, mvm->set_rx_ant);
if (IS_ERR(mvm->nvm_data)) {
ret = PTR_ERR(mvm->nvm_data);
mvm->nvm_data = NULL;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index ba3109d0eb2b..6fc5b3f22746 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -279,6 +279,30 @@ int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
return 0;
}
+int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+ /* This has been tested on those devices only */
+ if (mvm->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_9000 &&
+ mvm->trans->trans_cfg->device_family != IWL_DEVICE_FAMILY_22000)
+ return -ENOTSUPP;
+
+ if (!mvm->nvm_data)
+ return -EBUSY;
+
+ /* mac80211 ensures the device is not started,
+ * so the firmware cannot be running
+ */
+
+ mvm->set_tx_ant = tx_ant;
+ mvm->set_rx_ant = rx_ant;
+
+ iwl_reinit_cab(mvm->trans, mvm->nvm_data, tx_ant, rx_ant, mvm->fw);
+
+ return 0;
+}
+
int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
{
struct ieee80211_hw *hw = mvm->hw;
@@ -6202,6 +6226,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
.wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
.ampdu_action = iwl_mvm_mac_ampdu_action,
.get_antenna = iwl_mvm_op_get_antenna,
+ .set_antenna = iwl_mvm_op_set_antenna,
.start = iwl_mvm_mac_start,
.reconfig_complete = iwl_mvm_mac_reconfig_complete,
.stop = iwl_mvm_mac_stop,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
index 9615bfff7f7d..5449deb3c2d6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
@@ -1121,6 +1121,7 @@ const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
.wake_tx_queue = iwl_mvm_mac_wake_tx_queue,
.ampdu_action = iwl_mvm_mac_ampdu_action,
.get_antenna = iwl_mvm_op_get_antenna,
+ .set_antenna = iwl_mvm_op_set_antenna,
.start = iwl_mvm_mac_start,
.reconfig_complete = iwl_mvm_mac_reconfig_complete,
.stop = iwl_mvm_mac_stop,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index f0f9a1665443..8c1f6aa2bc70 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -980,6 +980,9 @@ struct iwl_mvm {
u8 scan_last_antenna_idx; /* to toggle TX between antennas */
u8 mgmt_last_antenna_idx;
+ u8 set_tx_ant;
+ u8 set_rx_ant;
+
/* last smart fifo state that was successfully sent to firmware */
enum iwl_sf_state sf_state;
@@ -1715,16 +1718,29 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
static inline u8 iwl_mvm_get_valid_tx_ant(struct iwl_mvm *mvm)
{
- return mvm->nvm_data && mvm->nvm_data->valid_tx_ant ?
- mvm->fw->valid_tx_ant & mvm->nvm_data->valid_tx_ant :
- mvm->fw->valid_tx_ant;
+ u8 tx_ant = mvm->fw->valid_tx_ant;
+
+ if (mvm->nvm_data && mvm->nvm_data->valid_tx_ant)
+ tx_ant &= mvm->nvm_data->valid_tx_ant;
+
+ if (mvm->set_tx_ant)
+ tx_ant &= mvm->set_tx_ant;
+
+ return tx_ant;
}
static inline u8 iwl_mvm_get_valid_rx_ant(struct iwl_mvm *mvm)
{
- return mvm->nvm_data && mvm->nvm_data->valid_rx_ant ?
- mvm->fw->valid_rx_ant & mvm->nvm_data->valid_rx_ant :
- mvm->fw->valid_rx_ant;
+ u8 rx_ant = mvm->fw->valid_tx_ant;
+
+ if (mvm->nvm_data && mvm->nvm_data->valid_rx_ant)
+ rx_ant &= mvm->nvm_data->valid_tx_ant;
+
+ if (mvm->set_rx_ant)
+ rx_ant &= mvm->set_tx_ant;
+
+ return rx_ant;
+
}
static inline void iwl_mvm_toggle_tx_ant(struct iwl_mvm *mvm, u8 *ant)
@@ -2625,6 +2641,7 @@ int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_ampdu_params *params);
int iwl_mvm_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
+int iwl_mvm_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
int iwl_mvm_mac_start(struct ieee80211_hw *hw);
void iwl_mvm_mac_reconfig_complete(struct ieee80211_hw *hw,
enum ieee80211_reconfig_type reconfig_type);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
index f67ab8ee18c2..17a1e5717dde 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
- * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2019, 2021-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -220,6 +220,8 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
struct iwl_nvm_section *sections = mvm->nvm_sections;
const __be16 *hw;
const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku;
+ u8 tx_ant = mvm->fw->valid_tx_ant;
+ u8 rx_ant = mvm->fw->valid_rx_ant;
int regulatory_type;
/* Checking for required sections */
@@ -270,9 +272,15 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
(const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY_SDP].data :
(const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
+ if (mvm->set_tx_ant)
+ tx_ant &= mvm->set_tx_ant;
+
+ if (mvm->set_rx_ant)
+ rx_ant &= mvm->set_rx_ant;
+
return iwl_parse_nvm_data(mvm->trans, mvm->cfg, mvm->fw, hw, sw, calib,
regulatory, mac_override, phy_sku,
- mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant);
+ tx_ant, rx_ant);
}
/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index 1c21a313f8f1..465090f67aaf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -751,7 +751,10 @@ static int iwl_mvm_start_get_nvm(struct iwl_mvm *mvm)
*/
mvm->nvm_data =
iwl_parse_mei_nvm_data(trans, trans->cfg,
- mvm->mei_nvm_data, mvm->fw);
+ mvm->mei_nvm_data,
+ mvm->fw,
+ mvm->set_tx_ant,
+ mvm->set_rx_ant);
return 0;
}
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 02/12] wifi: iwlwifi: mvm: iterate active links for STA queues
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
2023-09-21 8:57 ` [PATCH 01/12] wifi: iwlwifi: mvm: support set_antenna() gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 03/12] wifi: iwlwifi: mvm: handle link-STA allocation in restart gregory.greenman
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
During HW restart in eSR, links allocated in a station and links
active in the interface may differ. Use for_each_sta_active_link
to capture this.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 51ca99bd5117..61d564735d57 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -865,11 +865,11 @@ int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
if (sta) {
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+ struct ieee80211_link_sta *link_sta;
unsigned int link_id;
- for (link_id = 0;
- link_id < ARRAY_SIZE(mvmsta->link);
- link_id++) {
+ rcu_read_lock();
+ for_each_sta_active_link(mvmsta->vif, sta, link_sta, link_id) {
struct iwl_mvm_link_sta *link =
rcu_dereference_protected(mvmsta->link[link_id],
lockdep_is_held(&mvm->mutex));
@@ -879,6 +879,7 @@ int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
sta_mask |= BIT(link->sta_id);
}
+ rcu_read_unlock();
} else {
sta_mask |= BIT(sta_id);
}
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 03/12] wifi: iwlwifi: mvm: handle link-STA allocation in restart
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
2023-09-21 8:57 ` [PATCH 01/12] wifi: iwlwifi: mvm: support set_antenna() gregory.greenman
2023-09-21 8:58 ` [PATCH 02/12] wifi: iwlwifi: mvm: iterate active links for STA queues gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 04/12] wifi: iwlwifi: implement enable/disable for China 2022 regulatory gregory.greenman
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
During HW restart, STA link changes happen while the link-sta is
already allocated (had been prior to the restart). Adjust the
allocation and checks to handle that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
.../net/wireless/intel/iwlwifi/mvm/mld-sta.c | 21 ++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
index 524852cf5cd2..4e9d19eb31f1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
@@ -1104,15 +1104,26 @@ int iwl_mvm_mld_update_sta_links(struct iwl_mvm *mvm,
link_sta_dereference_protected(sta, link_id);
mvm_vif_link = mvm_vif->link[link_id];
- if (WARN_ON(!mvm_vif_link || !link_conf || !link_sta ||
- mvm_sta->link[link_id])) {
+ if (WARN_ON(!mvm_vif_link || !link_conf || !link_sta)) {
ret = -EINVAL;
goto err;
}
- ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta, link_id);
- if (WARN_ON(ret))
- goto err;
+ if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
+ if (WARN_ON(!mvm_sta->link[link_id])) {
+ ret = -EINVAL;
+ goto err;
+ }
+ } else {
+ if (WARN_ON(mvm_sta->link[link_id])) {
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = iwl_mvm_mld_alloc_sta_link(mvm, vif, sta,
+ link_id);
+ if (WARN_ON(ret))
+ goto err;
+ }
link_sta->agg.max_rc_amsdu_len = 1;
ieee80211_sta_recalc_aggregates(sta);
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 04/12] wifi: iwlwifi: implement enable/disable for China 2022 regulatory
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (2 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 03/12] wifi: iwlwifi: mvm: handle link-STA allocation in restart gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 05/12] wifi: iwlwifi: pcie: (re-)assign BAR0 on driver bind gregory.greenman
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Anjaneyulu, Gregory Greenman
From: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
China 2022 regulations are enabled by default. Disable only when
disabled in BIOS or the firmware don't support this capability. If the
firmware has this capability, read BIOS configuration data in
function 4 using ACPI API and send GRP_REGULATORY_LARI_CONFIG_CHANGE_CMD
to the firmware. Any error while reading BIOS data results in enablement
of china 2022 regulations.
Signed-off-by: Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/fw/acpi.c | 18 ++++++++++++++++++
drivers/net/wireless/intel/iwlwifi/fw/acpi.h | 5 +++++
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 6 ++++--
.../net/wireless/intel/iwlwifi/fw/debugfs.c | 8 +++++++-
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 ++-
5 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index b26f90e52256..e83ce797a68b 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -1011,6 +1011,7 @@ __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
{
int ret;
u8 value;
+ u32 val;
__le32 config_bitmap = 0;
/*
@@ -1039,6 +1040,23 @@ __le32 iwl_acpi_get_lari_config_bitmap(struct iwl_fw_runtime *fwrt)
cpu_to_le32(LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK);
}
+ if (fw_has_capa(&fwrt->fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT)) {
+ /*
+ ** Evaluate func 'DSM_FUNC_REGULATORY_CONFIG'
+ */
+ ret = iwl_acpi_get_dsm_u32(fwrt->dev, 0,
+ DSM_FUNC_REGULATORY_CONFIG,
+ &iwl_guid, &val);
+ /*
+ * China 2022 enable if the BIOS object does not exist or
+ * if it is enabled in BIOS.
+ */
+ if (ret < 0 || val & DSM_MASK_CHINA_22_REG)
+ config_bitmap |=
+ cpu_to_le32(LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK);
+ }
+
return config_bitmap;
}
IWL_EXPORT_SYMBOL(iwl_acpi_get_lari_config_bitmap);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index c36c62d6414d..d129fc66d8bb 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -134,6 +134,7 @@ enum iwl_dsm_funcs_rev_0 {
DSM_FUNC_DISABLE_SRD = 1,
DSM_FUNC_ENABLE_INDONESIA_5G2 = 2,
DSM_FUNC_ENABLE_6E = 3,
+ DSM_FUNC_REGULATORY_CONFIG = 4,
DSM_FUNC_11AX_ENABLEMENT = 6,
DSM_FUNC_ENABLE_UNII4_CHAN = 7,
DSM_FUNC_ACTIVATE_CHANNEL = 8,
@@ -164,6 +165,10 @@ enum iwl_dsm_values_rfi {
DSM_VALUE_RFI_MAX
};
+enum iwl_dsm_masks_reg {
+ DSM_MASK_CHINA_22_REG = BIT(2)
+};
+
#ifdef CONFIG_ACPI
struct iwl_fw_runtime;
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index 28bfabb399b2..c4577219c501 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2012-2014, 2018-2022 Intel Corporation
+ * Copyright (C) 2012-2014, 2018-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -480,18 +480,20 @@ union iwl_tas_config_cmd {
struct iwl_tas_config_cmd_v4 v4;
};
/**
- * enum iwl_lari_configs - bit masks for the various LARI config operations
+ * enum iwl_lari_config_masks - bit masks for the various LARI config operations
* @LARI_CONFIG_DISABLE_11AC_UKRAINE_MSK: disable 11ac in ukraine
* @LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK: ETSI 5.8GHz SRD passive scan
* @LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK: ETSI 5.8GHz SRD disabled
* @LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK: enable 5.15/5.35GHz bands in
* Indonesia
+ * @LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK: enable 2022 china regulatory
*/
enum iwl_lari_config_masks {
LARI_CONFIG_DISABLE_11AC_UKRAINE_MSK = BIT(0),
LARI_CONFIG_CHANGE_ETSI_TO_PASSIVE_MSK = BIT(1),
LARI_CONFIG_CHANGE_ETSI_TO_DISABLED_MSK = BIT(2),
LARI_CONFIG_ENABLE_5G2_IN_INDONESIA_MSK = BIT(3),
+ LARI_CONFIG_ENABLE_CHINA_22_REG_SUPPORT_MSK = BIT(7),
};
#define IWL_11AX_UKRAINE_MASK 3
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
index 3cdbc6ac7ae5..b8d4a4d571e7 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.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-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -342,6 +342,12 @@ static int iwl_dbgfs_fw_info_seq_show(struct seq_file *seq, void *v)
" %d: %d\n",
IWL_UCODE_TLV_CAPA_PPAG_CHINA_BIOS_SUPPORT,
has_capa);
+ has_capa = fw_has_capa(&fw->ucode_capa,
+ IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT) ? 1 : 0;
+ seq_printf(seq,
+ " %d: %d\n",
+ IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT,
+ has_capa);
seq_puts(seq, "fw_api_ver:\n");
}
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 41841524f983..7e0894ea1005 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
- * Copyright (C) 2008-2014, 2018-2021 Intel Corporation
+ * Copyright (C) 2008-2014, 2018-2023 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
*/
@@ -472,6 +472,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_OFFLOAD_BTM_SUPPORT = (__force iwl_ucode_tlv_capa_t)113,
IWL_UCODE_TLV_CAPA_STA_EXP_MFP_SUPPORT = (__force iwl_ucode_tlv_capa_t)114,
IWL_UCODE_TLV_CAPA_SNIFF_VALIDATE_SUPPORT = (__force iwl_ucode_tlv_capa_t)116,
+ IWL_UCODE_TLV_CAPA_CHINA_22_REG_SUPPORT = (__force iwl_ucode_tlv_capa_t)117,
NUM_IWL_UCODE_TLV_CAPA
/*
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 05/12] wifi: iwlwifi: pcie: (re-)assign BAR0 on driver bind
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (3 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 04/12] wifi: iwlwifi: implement enable/disable for China 2022 regulatory gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 06/12] wifi: iwlwifi: mvm: add support for new wowlan_info_notif gregory.greenman
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
There's a race with runtime PM getting enabled by userspace:
- we rescan the PCI bus
- this creates the new PCI device including its sysfs
representation
- udev sees the new device, and the (OS-specific?) scripting
enables runtime PM by writing to power/control; this can
happen _before_ the next step - this will runtime-suspend
the device which saves the config space, including the BAR0
that wasn't assigned yet
- the bus rescan assigns resources to the devices and writes
them to the config space of the device
(but not the runtime-pm saved copy)
- the driver binds and this disallows runtime PM, so the device
is resumed, restoring the (incomplete!) config space
- the driver cannot work due to BAR0 not being configured
Fixing the actual race is hard and deep in the PCI layer,
though probably should be done for upstream as well; perhaps
runtime PM should only be allowed after resource assignment,
or some other TBD way.
Work around this in the driver for now by simply (re-)assigning
BAR0 when the driver initializes, if it's unset.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 849ea1851508..5020ae4493c6 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -3610,10 +3610,19 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
int ret, addr_size;
const struct iwl_trans_ops *ops = &trans_ops_pcie_gen2;
void __iomem * const *table;
+ u32 bar0;
if (!cfg_trans->gen2)
ops = &trans_ops_pcie;
+ /* reassign our BAR 0 if invalid due to possible runtime PM races */
+ pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &bar0);
+ if (bar0 == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ ret = pci_assign_resource(pdev, 0);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+
ret = pcim_enable_device(pdev);
if (ret)
return ERR_PTR(ret);
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 06/12] wifi: iwlwifi: mvm: add support for new wowlan_info_notif
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (4 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 05/12] wifi: iwlwifi: pcie: (re-)assign BAR0 on driver bind gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 07/12] wifi: iwlwifi: fail NIC access fast on dead NIC gregory.greenman
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Yedidya Benshimol, Gregory Greenman
From: Yedidya Benshimol <yedidya.ben.shimol@intel.com>
This new version of wolan_info_notif supports the handling
of bigtk during d3, this patch holds parsing of the new
notif version, adding new keys and updating ipn of
existing keys during the resume flow.
Signed-off-by: Yedidya Benshimol <yedidya.ben.shimol@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
.../net/wireless/intel/iwlwifi/fw/api/d3.h | 46 ++++-
.../wireless/intel/iwlwifi/fw/api/offload.h | 6 +-
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 165 +++++++++++++++---
3 files changed, 184 insertions(+), 33 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
index 72d461c47323..ea99d41040d2 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/d3.h
@@ -397,6 +397,8 @@ struct iwl_wowlan_config_cmd {
#define WOWLAN_GTK_KEYS_NUM 2
#define WOWLAN_IGTK_KEYS_NUM 2
#define WOWLAN_IGTK_MIN_INDEX 4
+#define WOWLAN_BIGTK_KEYS_NUM 2
+#define WOWLAN_BIGTK_MIN_INDEX 6
/*
* WOWLAN_TSC_RSC_PARAMS
@@ -621,9 +623,10 @@ struct iwl_wowlan_gtk_status_v3 {
* @ipn: the IGTK packet number (replay counter)
* @key_len: IGTK length, if set to 0, the key is not available
* @key_flags: information about the key:
- * bits[0]: key index assigned by the AP (0: index 4, 1: index 5)
- * bits[1:5]: IGTK index of the key in the internal DB
- * bit[6]: Set iff this is the currently used IGTK
+ * bits[0]: key index assigned by the AP (0: index 4, 1: index 5)
+ * (0: index 6, 1: index 7 with bigtk)
+ * bits[1:5]: IGTK index of the key in the internal DB
+ * bit[6]: Set iff this is the currently used IGTK
*/
struct iwl_wowlan_igtk_status {
u8 key[WOWLAN_KEY_MAX_SIZE];
@@ -807,10 +810,44 @@ struct iwl_wowlan_info_notif_v1 {
u8 reserved2[2];
} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_1 */
+/**
+ * struct iwl_wowlan_info_notif_v2 - WoWLAN information notification
+ * @gtk: GTK data
+ * @igtk: IGTK data
+ * @replay_ctr: GTK rekey replay counter
+ * @pattern_number: number of the matched patterns
+ * @reserved1: reserved
+ * @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
+ * @transmitted_ndps: number of transmitted neighbor discovery packets
+ * @received_beacons: number of received beacons
+ * @tid_tear_down: bit mask of tids whose BA sessions were closed
+ * in suspend state
+ * @station_id: station id
+ * @reserved2: reserved
+ */
+struct iwl_wowlan_info_notif_v2 {
+ struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
+ struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
+ __le64 replay_ctr;
+ __le16 pattern_number;
+ __le16 reserved1;
+ __le16 qos_seq_ctr[8];
+ __le32 wakeup_reasons;
+ __le32 num_of_gtk_rekeys;
+ __le32 transmitted_ndps;
+ __le32 received_beacons;
+ u8 tid_tear_down;
+ u8 station_id;
+ u8 reserved2[2];
+} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_2 */
+
/**
* struct iwl_wowlan_info_notif - WoWLAN information notification
* @gtk: GTK data
* @igtk: IGTK data
+ * @bigtk: BIGTK data
* @replay_ctr: GTK rekey replay counter
* @pattern_number: number of the matched patterns
* @reserved1: reserved
@@ -827,6 +864,7 @@ struct iwl_wowlan_info_notif_v1 {
struct iwl_wowlan_info_notif {
struct iwl_wowlan_gtk_status_v3 gtk[WOWLAN_GTK_KEYS_NUM];
struct iwl_wowlan_igtk_status igtk[WOWLAN_IGTK_KEYS_NUM];
+ struct iwl_wowlan_igtk_status bigtk[WOWLAN_BIGTK_KEYS_NUM];
__le64 replay_ctr;
__le16 pattern_number;
__le16 reserved1;
@@ -838,7 +876,7 @@ struct iwl_wowlan_info_notif {
u8 tid_tear_down;
u8 station_id;
u8 reserved2[2];
-} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_2 */
+} __packed; /* WOWLAN_INFO_NTFY_API_S_VER_3 */
/**
* struct iwl_wowlan_wake_pkt_notif - WoWLAN wake packet notification
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
index 898bf351f6e4..2d2b9c8c36ea 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/offload.h
@@ -3,7 +3,7 @@
* Copyright (C) 2012-2014 Intel Corporation
* Copyright (C) 2013-2015 Intel Mobile Communications GmbH
* Copyright (C) 2016-2017 Intel Deutschland GmbH
- * Copyright (C) 2021-2022 Intel Corporation
+ * Copyright (C) 2021-2023 Intel Corporation
*/
#ifndef __iwl_fw_api_offload_h__
#define __iwl_fw_api_offload_h__
@@ -18,7 +18,9 @@ enum iwl_prot_offload_subcmd_ids {
WOWLAN_WAKE_PKT_NOTIFICATION = 0xFC,
/**
- * @WOWLAN_INFO_NOTIFICATION: Notification in &struct iwl_wowlan_info_notif
+ * @WOWLAN_INFO_NOTIFICATION: Notification in
+ * &struct iwl_wowlan_info_notif_v1, &struct iwl_wowlan_info_notif_v2,
+ * or iwl_wowlan_info_notif
*/
WOWLAN_INFO_NOTIFICATION = 0xFD,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index f6488b4bbe68..ffb1fdd7ee32 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -1438,6 +1438,7 @@ struct iwl_wowlan_status_data {
} ptk;
struct iwl_multicast_key_data igtk;
+ struct iwl_multicast_key_data bigtk[WOWLAN_BIGTK_KEYS_NUM];
u8 *wake_packet;
};
@@ -1781,8 +1782,8 @@ static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key,
struct iwl_mvm_d3_gtk_iter_data {
struct iwl_mvm *mvm;
struct iwl_wowlan_status_data *status;
- u32 gtk_cipher, igtk_cipher;
- bool unhandled_cipher, igtk_support;
+ u32 gtk_cipher, igtk_cipher, bigtk_cipher;
+ bool unhandled_cipher, igtk_support, bigtk_support;
int num_keys;
};
@@ -1817,6 +1818,9 @@ static void iwl_mvm_d3_find_last_keys(struct ieee80211_hw *hw,
if (data->igtk_support &&
(key->keyidx == 4 || key->keyidx == 5)) {
data->igtk_cipher = key->cipher;
+ } else if (data->bigtk_support &&
+ (key->keyidx == 6 || key->keyidx == 7)) {
+ data->bigtk_cipher = key->cipher;
} else {
data->unhandled_cipher = true;
return;
@@ -1848,6 +1852,24 @@ iwl_mvm_d3_set_igtk_bigtk_ipn(const struct iwl_multicast_key_data *key,
}
}
+static void
+iwl_mvm_d3_update_igtk_bigtk(struct iwl_wowlan_status_data *status,
+ struct ieee80211_key_conf *key,
+ struct iwl_multicast_key_data *key_data)
+{
+ if (status->num_of_gtk_rekeys && key_data->len) {
+ /* remove rekeyed key */
+ ieee80211_remove_key(key);
+ } else {
+ struct ieee80211_key_seq seq;
+
+ iwl_mvm_d3_set_igtk_bigtk_ipn(key_data,
+ &seq,
+ key->cipher);
+ ieee80211_set_key_rx_seq(key, 0, &seq);
+ }
+}
+
static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -1900,17 +1922,14 @@ static void iwl_mvm_d3_update_keys(struct ieee80211_hw *hw,
case WLAN_CIPHER_SUITE_BIP_CMAC_256:
case WLAN_CIPHER_SUITE_AES_CMAC:
if (key->keyidx == 4 || key->keyidx == 5) {
- /* remove rekeyed key */
- if (status->num_of_gtk_rekeys) {
- ieee80211_remove_key(key);
- } else {
- struct ieee80211_key_seq seq;
+ iwl_mvm_d3_update_igtk_bigtk(status, key,
+ &status->igtk);
+ }
+ if (key->keyidx == 6 || key->keyidx == 7) {
+ u8 idx = key->keyidx == status->bigtk[1].id;
- iwl_mvm_d3_set_igtk_bigtk_ipn(&status->igtk,
- &seq,
- key->cipher);
- ieee80211_set_key_rx_seq(key, 0, &seq);
- }
+ iwl_mvm_d3_update_igtk_bigtk(status, key,
+ &status->bigtk[idx]);
}
}
}
@@ -2042,6 +2061,8 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
.mvm = mvm,
.status = status,
};
+ int i;
+
u32 disconnection_reasons =
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON |
IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH;
@@ -2058,6 +2079,11 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
0))
gtkdata.igtk_support = true;
+ if (iwl_fw_lookup_notif_ver(mvm->fw, PROT_OFFLOAD_GROUP,
+ WOWLAN_INFO_NOTIFICATION,
+ 0) >= 3)
+ gtkdata.bigtk_support = true;
+
/* find last GTK that we used initially, if any */
ieee80211_iter_keys(mvm->hw, vif,
iwl_mvm_d3_find_last_keys, >kdata);
@@ -2088,6 +2114,13 @@ static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm,
&status->igtk))
return false;
+ for (i = 0; i < ARRAY_SIZE(status->bigtk); i++) {
+ if (!iwl_mvm_d3_igtk_bigtk_rekey_add(status, vif,
+ gtkdata.bigtk_cipher,
+ &status->bigtk[i]))
+ return false;
+ }
+
ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid,
(void *)&replay_ctr, GFP_KERNEL);
}
@@ -2172,6 +2205,37 @@ static void iwl_mvm_convert_igtk(struct iwl_wowlan_status_data *status,
memcpy(status->igtk.ipn, data->ipn, sizeof(data->ipn));
}
+static void iwl_mvm_convert_bigtk(struct iwl_wowlan_status_data *status,
+ const struct iwl_wowlan_igtk_status *data)
+{
+ int data_idx, status_idx = 0;
+
+ BUILD_BUG_ON(ARRAY_SIZE(status->bigtk) < WOWLAN_BIGTK_KEYS_NUM);
+
+ for (data_idx = 0; data_idx < WOWLAN_BIGTK_KEYS_NUM; data_idx++) {
+ if (!data[data_idx].key_len)
+ continue;
+
+ status->bigtk[status_idx].len = data[data_idx].key_len;
+ status->bigtk[status_idx].flags = data[data_idx].key_flags;
+ status->bigtk[status_idx].id =
+ u32_get_bits(data[data_idx].key_flags,
+ IWL_WOWLAN_IGTK_BIGTK_IDX_MASK)
+ + WOWLAN_BIGTK_MIN_INDEX;
+
+ BUILD_BUG_ON(sizeof(status->bigtk[status_idx].key) <
+ sizeof(data[data_idx].key));
+ BUILD_BUG_ON(sizeof(status->bigtk[status_idx].ipn) <
+ sizeof(data[data_idx].ipn));
+
+ memcpy(status->bigtk[status_idx].key, data[data_idx].key,
+ sizeof(data[data_idx].key));
+ memcpy(status->bigtk[status_idx].ipn, data[data_idx].ipn,
+ sizeof(data[data_idx].ipn));
+ status_idx++;
+ }
+}
+
static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm,
struct iwl_wowlan_info_notif *data,
struct iwl_wowlan_status_data *status,
@@ -2194,7 +2258,42 @@ static void iwl_mvm_parse_wowlan_info_notif(struct iwl_mvm *mvm,
iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc);
iwl_mvm_convert_gtk_v3(status, data->gtk);
iwl_mvm_convert_igtk(status, &data->igtk[0]);
+ iwl_mvm_convert_bigtk(status, data->bigtk);
+ status->replay_ctr = le64_to_cpu(data->replay_ctr);
+ status->pattern_number = le16_to_cpu(data->pattern_number);
+ for (i = 0; i < IWL_MAX_TID_COUNT; i++)
+ status->qos_seq_ctr[i] =
+ le16_to_cpu(data->qos_seq_ctr[i]);
+ status->wakeup_reasons = le32_to_cpu(data->wakeup_reasons);
+ status->num_of_gtk_rekeys =
+ le32_to_cpu(data->num_of_gtk_rekeys);
+ status->received_beacons = le32_to_cpu(data->received_beacons);
+ status->tid_tear_down = data->tid_tear_down;
+}
+
+static void
+iwl_mvm_parse_wowlan_info_notif_v2(struct iwl_mvm *mvm,
+ struct iwl_wowlan_info_notif_v2 *data,
+ struct iwl_wowlan_status_data *status,
+ u32 len)
+{
+ u32 i;
+
+ if (!data) {
+ IWL_ERR(mvm, "iwl_wowlan_info_notif data is NULL\n");
+ status = NULL;
+ return;
+ }
+
+ if (len < sizeof(*data)) {
+ IWL_ERR(mvm, "Invalid WoWLAN info notification!\n");
+ status = NULL;
+ return;
+ }
+ iwl_mvm_convert_key_counters_v5(status, &data->gtk[0].sc);
+ iwl_mvm_convert_gtk_v3(status, data->gtk);
+ iwl_mvm_convert_igtk(status, &data->igtk[0]);
status->replay_ctr = le64_to_cpu(data->replay_ctr);
status->pattern_number = le16_to_cpu(data->pattern_number);
for (i = 0; i < IWL_MAX_TID_COUNT; i++)
@@ -2866,7 +2965,7 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
struct iwl_mvm *mvm =
container_of(notif_wait, struct iwl_mvm, notif_wait);
struct iwl_d3_data *d3_data = data;
- u32 len;
+ u32 len = iwl_rx_packet_payload_len(pkt);
int ret;
int wowlan_info_ver = iwl_fw_lookup_notif_ver(mvm->fw,
PROT_OFFLOAD_GROUP,
@@ -2876,7 +2975,6 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
switch (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd)) {
case WIDE_ID(PROT_OFFLOAD_GROUP, WOWLAN_INFO_NOTIFICATION): {
- struct iwl_wowlan_info_notif *notif;
if (d3_data->notif_received & IWL_D3_NOTIF_WOWLAN_INFO) {
/* We might get two notifications due to dual bss */
@@ -2886,26 +2984,39 @@ static bool iwl_mvm_wait_d3_notif(struct iwl_notif_wait_data *notif_wait,
}
if (wowlan_info_ver < 2) {
- struct iwl_wowlan_info_notif_v1 *notif_v1 = (void *)pkt->data;
+ struct iwl_wowlan_info_notif_v1 *notif_v1 =
+ (void *)pkt->data;
+ struct iwl_wowlan_info_notif_v2 *notif_v2;
- notif = kmemdup(notif_v1, sizeof(*notif), GFP_ATOMIC);
- if (!notif)
+ notif_v2 = kmemdup(notif_v1, sizeof(*notif_v2), GFP_ATOMIC);
+
+ if (!notif_v2)
return false;
- notif->tid_tear_down = notif_v1->tid_tear_down;
- notif->station_id = notif_v1->station_id;
- memset_after(notif, 0, station_id);
+ notif_v2->tid_tear_down = notif_v1->tid_tear_down;
+ notif_v2->station_id = notif_v1->station_id;
+ memset_after(notif_v2, 0, station_id);
+ iwl_mvm_parse_wowlan_info_notif_v2(mvm, notif_v2,
+ d3_data->status,
+ len);
+ kfree(notif_v2);
+
+ } else if (wowlan_info_ver == 2) {
+ struct iwl_wowlan_info_notif_v2 *notif_v2 =
+ (void *)pkt->data;
+
+ iwl_mvm_parse_wowlan_info_notif_v2(mvm, notif_v2,
+ d3_data->status,
+ len);
} else {
- notif = (void *)pkt->data;
+ struct iwl_wowlan_info_notif *notif =
+ (void *)pkt->data;
+
+ iwl_mvm_parse_wowlan_info_notif(mvm, notif,
+ d3_data->status, len);
}
d3_data->notif_received |= IWL_D3_NOTIF_WOWLAN_INFO;
- len = iwl_rx_packet_payload_len(pkt);
- iwl_mvm_parse_wowlan_info_notif(mvm, notif, d3_data->status,
- len);
-
- if (wowlan_info_ver < 2)
- kfree(notif);
if (d3_data->status &&
d3_data->status->wakeup_reasons & IWL_WOWLAN_WAKEUP_REASON_HAS_WAKEUP_PKT)
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 07/12] wifi: iwlwifi: fail NIC access fast on dead NIC
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (5 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 06/12] wifi: iwlwifi: mvm: add support for new wowlan_info_notif gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 08/12] wifi: iwlwifi: mvm: make pldr_sync AX210 specific gregory.greenman
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
If the NIC is already dead, as detected by the transport then
there's no point to try to grab the NIC access and time out,
we can just fail fast. This may speed up recovery.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 5020ae4493c6..385e152f04fe 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -2177,6 +2177,9 @@ bool __iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans)
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP;
u32 poll = CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN;
+ if (test_bit(STATUS_TRANS_DEAD, &trans->status))
+ return false;
+
spin_lock(&trans_pcie->reg_lock);
if (trans_pcie->cmd_hold_nic_awake)
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 08/12] wifi: iwlwifi: mvm: make pldr_sync AX210 specific
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (6 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 07/12] wifi: iwlwifi: fail NIC access fast on dead NIC gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 09/12] wifi: iwlwifi: mvm: refactor TX rate handling gregory.greenman
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
The register here is device specific, so we need to gate
the reading/checking to apply only on AX210 family.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/fw.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 6e5c0f81e041..5c719636c9bd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -593,11 +593,13 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm)
mvm->rfkill_safe_init_done = false;
- sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG);
- /* if needed, we'll reset this on our way out later */
- mvm->pldr_sync = !(sb_cfg & SB_CFG_RESIDES_IN_OTP_MASK);
- if (mvm->pldr_sync && iwl_mei_pldr_req())
- return -EBUSY;
+ if (mvm->trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
+ sb_cfg = iwl_read_umac_prph(mvm->trans, SB_MODIFY_CFG_FLAG);
+ /* if needed, we'll reset this on our way out later */
+ mvm->pldr_sync = !(sb_cfg & SB_CFG_RESIDES_IN_OTP_MASK);
+ if (mvm->pldr_sync && iwl_mei_pldr_req())
+ return -EBUSY;
+ }
iwl_init_notification_wait(&mvm->notif_wait,
&init_wait,
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 09/12] wifi: iwlwifi: mvm: refactor TX rate handling
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (7 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 08/12] wifi: iwlwifi: mvm: make pldr_sync AX210 specific gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 10/12] wifi: iwlwifi: mvm: support injection antenna control gregory.greenman
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
Refactor the injection and other frame TX rate handling
to always return the injection rate directly, by factoring
the legay rate portion out into a new function called in
the two relevant places (injection and non-injection).
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 78 ++++++++++++---------
1 file changed, 45 insertions(+), 33 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 6e2e52936761..c398e04b597c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -262,6 +262,38 @@ static u32 iwl_mvm_get_tx_ant(struct iwl_mvm *mvm,
return BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
}
+static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm,
+ struct ieee80211_tx_info *info,
+ int rate_idx)
+{
+ u32 rate_flags = 0;
+ u8 rate_plcp;
+ bool is_cck;
+
+ /* 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 = iwl_mvm_mac_ctxt_get_lowest_rate(mvm,
+ info,
+ info->control.vif);
+
+ /* Get PLCP rate for tx_cmd->rate_n_flags */
+ rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx);
+ is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) &&
+ (rate_idx <= IWL_LAST_CCK_RATE);
+
+ /* Set CCK or OFDM flag */
+ if (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) > 8) {
+ if (!is_cck)
+ rate_flags |= RATE_MCS_LEGACY_OFDM_MSK;
+ else
+ rate_flags |= RATE_MCS_CCK_MSK;
+ } else if (is_cck) {
+ rate_flags |= RATE_MCS_CCK_MSK_V1;
+ }
+
+ return (u32)rate_plcp | rate_flags;
+}
+
static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
struct ieee80211_tx_info *info)
{
@@ -288,6 +320,9 @@ static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
result |= u32_encode_bits(2, RATE_MCS_CHAN_WIDTH_MSK_V1);
else if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
result |= u32_encode_bits(3, RATE_MCS_CHAN_WIDTH_MSK_V1);
+
+ if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6)
+ result = iwl_new_rate_from_v1(result);
} else if (rate->flags & IEEE80211_TX_RC_MCS) {
result = RATE_MCS_HT_MSK_V1;
result |= u32_encode_bits(rate->idx,
@@ -301,12 +336,15 @@ static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
result |= RATE_MCS_LDPC_MSK_V1;
if (u32_get_bits(info->flags, IEEE80211_TX_CTL_STBC))
result |= RATE_MCS_STBC_MSK;
+
+ if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6)
+ result = iwl_new_rate_from_v1(result);
} else {
- return 0;
+ int rate_idx = info->control.rates[0].idx;
+
+ result = iwl_mvm_convert_rate_idx(mvm, info, rate_idx);
}
- if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TX_CMD, 0) > 6)
- return iwl_new_rate_from_v1(result);
return result;
}
@@ -315,17 +353,11 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
struct ieee80211_sta *sta, __le16 fc)
{
int rate_idx = -1;
- u8 rate_plcp;
- u32 rate_flags = 0;
- bool is_cck;
- if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT)) {
- u32 result = iwl_mvm_get_inject_tx_rate(mvm, info);
+ if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT))
+ return iwl_mvm_get_inject_tx_rate(mvm, info);
- if (result)
- return result;
- rate_idx = info->control.rates[0].idx;
- } else if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
+ if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
/* info->control is only relevant for non HW rate control */
/* HT rate doesn't make sense for a non data frame */
@@ -350,27 +382,7 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
}
- /* 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 = iwl_mvm_mac_ctxt_get_lowest_rate(mvm,
- info,
- info->control.vif);
-
- /* Get PLCP rate for tx_cmd->rate_n_flags */
- rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(mvm->fw, rate_idx);
- is_cck = (rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE);
-
- /* Set CCK or OFDM flag */
- if (iwl_fw_lookup_cmd_ver(mvm->fw, TX_CMD, 0) > 8) {
- if (!is_cck)
- rate_flags |= RATE_MCS_LEGACY_OFDM_MSK;
- else
- rate_flags |= RATE_MCS_CCK_MSK;
- } else if (is_cck) {
- rate_flags |= RATE_MCS_CCK_MSK_V1;
- }
-
- return (u32)rate_plcp | rate_flags;
+ return iwl_mvm_convert_rate_idx(mvm, info, rate_idx);
}
static u32 iwl_mvm_get_tx_rate_n_flags(struct iwl_mvm *mvm,
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/12] wifi: iwlwifi: mvm: support injection antenna control
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (8 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 09/12] wifi: iwlwifi: mvm: refactor TX rate handling gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 11/12] wifi: iwlwifi: mvm: check for iwl_mvm_mld_update_sta() errors gregory.greenman
2023-09-21 8:58 ` [PATCH 12/12] wifi: iwlwifi: add mapping of a periphery register crf for WH RF gregory.greenman
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
Pull up the injection rate control one layer, and let it
control the antenna settings as well. Since mac80211 has
already checked that enough antennas are configured, and
we only have two bits, it's enough to just copy the data
over.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index c398e04b597c..ec18e348553d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -295,7 +295,9 @@ static u32 iwl_mvm_convert_rate_idx(struct iwl_mvm *mvm,
}
static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
- struct ieee80211_tx_info *info)
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ __le16 fc)
{
struct ieee80211_tx_rate *rate = &info->control.rates[0];
u32 result;
@@ -345,6 +347,12 @@ static u32 iwl_mvm_get_inject_tx_rate(struct iwl_mvm *mvm,
result = iwl_mvm_convert_rate_idx(mvm, info, rate_idx);
}
+ if (info->control.antennas)
+ result |= u32_encode_bits(info->control.antennas,
+ RATE_MCS_ANT_AB_MSK);
+ else
+ result |= iwl_mvm_get_tx_ant(mvm, info, sta, fc);
+
return result;
}
@@ -354,9 +362,6 @@ static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm,
{
int rate_idx = -1;
- if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT))
- return iwl_mvm_get_inject_tx_rate(mvm, info);
-
if (!ieee80211_hw_check(mvm->hw, HAS_RATE_CONTROL)) {
/* info->control is only relevant for non HW rate control */
@@ -389,6 +394,9 @@ static u32 iwl_mvm_get_tx_rate_n_flags(struct iwl_mvm *mvm,
struct ieee80211_tx_info *info,
struct ieee80211_sta *sta, __le16 fc)
{
+ if (unlikely(info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT))
+ return iwl_mvm_get_inject_tx_rate(mvm, info, sta, fc);
+
return iwl_mvm_get_tx_rate(mvm, info, sta, fc) |
iwl_mvm_get_tx_ant(mvm, info, sta, fc);
}
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 11/12] wifi: iwlwifi: mvm: check for iwl_mvm_mld_update_sta() errors
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (9 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 10/12] wifi: iwlwifi: mvm: support injection antenna control gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
2023-09-21 8:58 ` [PATCH 12/12] wifi: iwlwifi: add mapping of a periphery register crf for WH RF gregory.greenman
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Johannes Berg, Gregory Greenman
From: Johannes Berg <johannes.berg@intel.com>
The return value of this function is assigned, but then unused.
Check for errors here.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
index 4e9d19eb31f1..1464aad039e1 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
@@ -697,6 +697,8 @@ int iwl_mvm_mld_add_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
/* at this stage sta link pointers are already allocated */
ret = iwl_mvm_mld_update_sta(mvm, vif, sta);
+ if (ret)
+ goto err;
for_each_sta_active_link(vif, sta, link_sta, link_id) {
struct ieee80211_bss_conf *link_conf =
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 12/12] wifi: iwlwifi: add mapping of a periphery register crf for WH RF
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
` (10 preceding siblings ...)
2023-09-21 8:58 ` [PATCH 11/12] wifi: iwlwifi: mvm: check for iwl_mvm_mld_update_sta() errors gregory.greenman
@ 2023-09-21 8:58 ` gregory.greenman
11 siblings, 0 replies; 13+ messages in thread
From: gregory.greenman @ 2023-09-21 8:58 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Mukesh Sisodiya, Gregory Greenman
From: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
Add the support for prph register RF details and map it
to get the RF ID of NIC.
Signed-off-by: Mukesh Sisodiya <mukesh.sisodiya@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 1 +
drivers/net/wireless/intel/iwlwifi/pcie/drv.c | 3 +++
2 files changed, 4 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 6dd381ff0f9e..6fad5b65a836 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -452,6 +452,7 @@ enum {
#define REG_CRF_ID_TYPE_FM 0x910
#define REG_CRF_ID_TYPE_FMI 0x930
#define REG_CRF_ID_TYPE_FMR 0x900
+#define REG_CRF_ID_TYPE_WHP 0xA10
#define HPM_DEBUG 0xA03440
#define PERSISTENCE_BIT BIT(12)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index bc83d2ba55c6..e8687683ff29 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1196,6 +1196,9 @@ static int map_crf_id(struct iwl_trans *iwl_trans)
case REG_CRF_ID_TYPE_FMR:
iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_FM << 12);
break;
+ case REG_CRF_ID_TYPE_WHP:
+ iwl_trans->hw_rf_id = (IWL_CFG_RF_TYPE_WH << 12);
+ break;
default:
ret = -EIO;
IWL_ERR(iwl_trans,
--
2.38.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2023-09-21 21:23 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-21 8:57 [PATCH 00/12] wifi: iwlwifi: updates - 2023-09-21 gregory.greenman
2023-09-21 8:57 ` [PATCH 01/12] wifi: iwlwifi: mvm: support set_antenna() gregory.greenman
2023-09-21 8:58 ` [PATCH 02/12] wifi: iwlwifi: mvm: iterate active links for STA queues gregory.greenman
2023-09-21 8:58 ` [PATCH 03/12] wifi: iwlwifi: mvm: handle link-STA allocation in restart gregory.greenman
2023-09-21 8:58 ` [PATCH 04/12] wifi: iwlwifi: implement enable/disable for China 2022 regulatory gregory.greenman
2023-09-21 8:58 ` [PATCH 05/12] wifi: iwlwifi: pcie: (re-)assign BAR0 on driver bind gregory.greenman
2023-09-21 8:58 ` [PATCH 06/12] wifi: iwlwifi: mvm: add support for new wowlan_info_notif gregory.greenman
2023-09-21 8:58 ` [PATCH 07/12] wifi: iwlwifi: fail NIC access fast on dead NIC gregory.greenman
2023-09-21 8:58 ` [PATCH 08/12] wifi: iwlwifi: mvm: make pldr_sync AX210 specific gregory.greenman
2023-09-21 8:58 ` [PATCH 09/12] wifi: iwlwifi: mvm: refactor TX rate handling gregory.greenman
2023-09-21 8:58 ` [PATCH 10/12] wifi: iwlwifi: mvm: support injection antenna control gregory.greenman
2023-09-21 8:58 ` [PATCH 11/12] wifi: iwlwifi: mvm: check for iwl_mvm_mld_update_sta() errors gregory.greenman
2023-09-21 8:58 ` [PATCH 12/12] wifi: iwlwifi: add mapping of a periphery register crf for WH RF gregory.greenman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).