summaryrefslogtreecommitdiff
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2023-06-20 13:03:56 +0300
committerJohannes Berg <johannes.berg@intel.com>2023-06-21 15:02:15 +0300
commit3a9690d030d8572736e07b912deea5547dd94db3 (patch)
tree835f5649437e4cd7889f1e65a5cd74da96a4acdd /drivers/net/wireless
parent00e482010dfb5879fc9e8601d5819641fe4ae925 (diff)
downloadlinux-3a9690d030d8572736e07b912deea5547dd94db3.tar.xz
wifi: iwlwifi: limit EHT capabilities based on PCIe link speed
If a discrete NIC is connected to a PCIe link hat isn't at least Gen3 (8.0 GT/s), then we cannot sustain 320 MHz traffic, so remove that from EHT capabilities in that case. While at it, also move setting 320 MHz beamformee to the right place in the code so it's not set while not supporting 320 MHz. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230620125813.b77a1574a0a7.Id4120c161fb7df6dedc70d5f3e3829e9117b8cb1@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c15
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c9
3 files changed, 24 insertions, 4 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 39f13518ca5b..8c23f57f5c89 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -680,8 +680,7 @@ static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK,
.phy_cap_info[1] =
IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_80MHZ_MASK |
- IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK |
- IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK,
+ IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK,
.phy_cap_info[3] =
IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
@@ -890,6 +889,10 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
const struct iwl_fw *fw)
{
bool is_ap = iftype_data->types_mask & BIT(NL80211_IFTYPE_AP);
+ bool no_320;
+
+ no_320 = !trans->trans_cfg->integrated &&
+ trans->pcie_link_speed < PCI_EXP_LNKSTA_CLS_8_0GB;
if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be)
iftype_data->eht_cap.has_eht = false;
@@ -916,8 +919,12 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_MASK);
break;
case NL80211_BAND_6GHZ:
- iftype_data->eht_cap.eht_cap_elem.phy_cap_info[0] |=
- IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+ if (!no_320) {
+ iftype_data->eht_cap.eht_cap_elem.phy_cap_info[0] |=
+ IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
+ iftype_data->eht_cap.eht_cap_elem.phy_cap_info[1] |=
+ IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK;
+ }
fallthrough;
case NL80211_BAND_5GHZ:
iftype_data->he_cap.he_cap_elem.phy_cap_info[0] |=
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 1fa035decc03..d02943d0ea62 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -1067,6 +1067,8 @@ struct iwl_trans_txqs {
* @iwl_trans_txqs: transport tx queues data.
* @mbx_addr_0_step: step address data 0
* @mbx_addr_1_step: step address data 1
+ * @pcie_link_speed: current PCIe link speed (%PCI_EXP_LNKSTA_CLS_*),
+ * only valid for discrete (not integrated) NICs
*/
struct iwl_trans {
bool csme_own;
@@ -1129,6 +1131,8 @@ struct iwl_trans {
u32 mbx_addr_0_step;
u32 mbx_addr_1_step;
+ u8 pcie_link_speed;
+
/* pointer to trans specific struct */
/*Ensure that this pointer will always be aligned to sizeof pointer */
char trans_specific[] __aligned(sizeof(void *));
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index fcc0f3319bcd..18550c03f870 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -1760,6 +1760,15 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
trans_pcie->num_rx_bufs = RX_QUEUE_SIZE;
}
+ if (!iwl_trans->trans_cfg->integrated) {
+ u16 link_status;
+
+ pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &link_status);
+
+ iwl_trans->pcie_link_speed =
+ u16_get_bits(link_status, PCI_EXP_LNKSTA_CLS);
+ }
+
ret = iwl_trans_init(iwl_trans);
if (ret)
goto out_free_trans;