Commit 26d7cc0a authored by Ilan Peer's avatar Ilan Peer Committed by Gregory Greenman

wifi: iwlwifi: mvm: Advertise EHT capabilities

Add support for advertising EHT capabilities if supported by
device SKU and not disabled by module parameters.
Signed-off-by: default avatarIlan Peer <ilan.peer@intel.com>
Link: https://lore.kernel.org/r/20221122220713.6bc00d851794.I214005645f3da21d8f2458a70355deeca04a19e8@changeidSigned-off-by: default avatarGregory Greenman <gregory.greenman@intel.com>
parent eceb024e
...@@ -1971,3 +1971,6 @@ MODULE_PARM_DESC(remove_when_gone, ...@@ -1971,3 +1971,6 @@ MODULE_PARM_DESC(remove_when_gone,
module_param_named(disable_11ax, iwlwifi_mod_params.disable_11ax, bool, module_param_named(disable_11ax, iwlwifi_mod_params.disable_11ax, bool,
S_IRUGO); S_IRUGO);
MODULE_PARM_DESC(disable_11ax, "Disable HE capabilities (default: false)"); MODULE_PARM_DESC(disable_11ax, "Disable HE capabilities (default: false)");
module_param_named(disable_11be, iwlwifi_mod_params.disable_11be, bool, 0444);
MODULE_PARM_DESC(disable_11be, "Disable EHT capabilities (default: false)");
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/* /*
* Copyright (C) 2005-2014, 2018 Intel Corporation * Copyright (C) 2005-2014, 2018, 2020-2022 Intel Corporation
* Copyright (C) 2015 Intel Mobile Communications GmbH * Copyright (C) 2015 Intel Mobile Communications GmbH
*/ */
#ifndef __iwl_eeprom_parse_h__ #ifndef __iwl_eeprom_parse_h__
...@@ -31,6 +31,7 @@ struct iwl_nvm_data { ...@@ -31,6 +31,7 @@ struct iwl_nvm_data {
bool sku_cap_amt_enable; bool sku_cap_amt_enable;
bool sku_cap_ipan_enable; bool sku_cap_ipan_enable;
bool sku_cap_mimo_disabled; bool sku_cap_mimo_disabled;
bool sku_cap_11be_enable;
u16 radio_cfg_type; u16 radio_cfg_type;
u8 radio_cfg_step; u8 radio_cfg_step;
......
...@@ -62,6 +62,7 @@ enum iwl_uapsd_disable { ...@@ -62,6 +62,7 @@ enum iwl_uapsd_disable {
* @disable_11ac: disable VHT capabilities, default = false. * @disable_11ac: disable VHT capabilities, default = false.
* @remove_when_gone: remove an inaccessible device from the PCIe bus. * @remove_when_gone: remove an inaccessible device from the PCIe bus.
* @enable_ini: enable new FW debug infratructure (INI TLVs) * @enable_ini: enable new FW debug infratructure (INI TLVs)
* @disable_11be: disable EHT capabilities, default = false.
*/ */
struct iwl_mod_params { struct iwl_mod_params {
int swcrypto; int swcrypto;
......
...@@ -546,7 +546,7 @@ static const u8 iwl_vendor_caps[] = { ...@@ -546,7 +546,7 @@ static const u8 iwl_vendor_caps[] = {
0x00 0x00
}; };
static const struct ieee80211_sband_iftype_data iwl_he_capa[] = { static const struct ieee80211_sband_iftype_data iwl_he_eht_capa[] = {
{ {
.types_mask = BIT(NL80211_IFTYPE_STATION), .types_mask = BIT(NL80211_IFTYPE_STATION),
.he_cap = { .he_cap = {
...@@ -631,6 +631,78 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = { ...@@ -631,6 +631,78 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
*/ */
.ppe_thres = {0x61, 0x1c, 0xc7, 0x71}, .ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
}, },
.eht_cap = {
.has_eht = true,
.eht_cap_elem = {
.mac_cap_info[0] =
IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS |
IEEE80211_EHT_MAC_CAP0_OM_CONTROL |
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 |
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2,
.phy_cap_info[0] =
IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ |
IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI |
IEEE80211_EHT_PHY_CAP0_PARTIAL_BW_UL_MU_MIMO |
IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE |
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,
.phy_cap_info[3] =
IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK |
IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK |
IEEE80211_EHT_PHY_CAP3_TRIG_SU_BF_FDBK |
IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK |
IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK,
.phy_cap_info[4] =
IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO |
IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP |
IEEE80211_EHT_PHY_CAP4_EHT_MU_PPDU_4_EHT_LTF_08_GI,
.phy_cap_info[5] =
IEEE80211_EHT_PHY_CAP5_NON_TRIG_CQI_FEEDBACK |
IEEE80211_EHT_PHY_CAP5_TX_LESS_242_TONE_RU_SUPP |
IEEE80211_EHT_PHY_CAP5_RX_LESS_242_TONE_RU_SUPP |
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT,
.phy_cap_info[6] =
IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK |
IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP,
.phy_cap_info[8] =
IEEE80211_EHT_PHY_CAP8_RX_1024QAM_WIDER_BW_DL_OFDMA |
IEEE80211_EHT_PHY_CAP8_RX_4096QAM_WIDER_BW_DL_OFDMA,
},
/* For all MCS and bandwidth, set 2 NSS for both Tx and
* Rx - note we don't set the only_20mhz, but due to this
* being a union, it gets set correctly anyway.
*/
.eht_mcs_nss_supp = {
.bw._80 = {
.rx_tx_mcs9_max_nss = 0x22,
.rx_tx_mcs11_max_nss = 0x22,
.rx_tx_mcs13_max_nss = 0x22,
},
.bw._160 = {
.rx_tx_mcs9_max_nss = 0x22,
.rx_tx_mcs11_max_nss = 0x22,
.rx_tx_mcs13_max_nss = 0x22,
},
.bw._320 = {
.rx_tx_mcs9_max_nss = 0x22,
.rx_tx_mcs11_max_nss = 0x22,
.rx_tx_mcs13_max_nss = 0x22,
},
},
/*
* PPE thresholds for NSS = 2, and RU index bitmap set
* to 0xc.
*/
.eht_ppe_thres = {0xc1, 0x0e, 0xe0 }
},
}, },
{ {
.types_mask = BIT(NL80211_IFTYPE_AP), .types_mask = BIT(NL80211_IFTYPE_AP),
...@@ -687,6 +759,49 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = { ...@@ -687,6 +759,49 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
*/ */
.ppe_thres = {0x61, 0x1c, 0xc7, 0x71}, .ppe_thres = {0x61, 0x1c, 0xc7, 0x71},
}, },
.eht_cap = {
.has_eht = true,
.eht_cap_elem = {
.mac_cap_info[0] =
IEEE80211_EHT_MAC_CAP0_EPCS_PRIO_ACCESS |
IEEE80211_EHT_MAC_CAP0_OM_CONTROL |
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1 |
IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2,
.phy_cap_info[0] =
IEEE80211_EHT_PHY_CAP0_242_TONE_RU_GT20MHZ |
IEEE80211_EHT_PHY_CAP0_NDP_4_EHT_LFT_32_GI,
.phy_cap_info[5] =
IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT,
},
/* For all MCS and bandwidth, set 2 NSS for both Tx and
* Rx - note we don't set the only_20mhz, but due to this
* being a union, it gets set correctly anyway.
*/
.eht_mcs_nss_supp = {
.bw._80 = {
.rx_tx_mcs9_max_nss = 0x22,
.rx_tx_mcs11_max_nss = 0x22,
.rx_tx_mcs13_max_nss = 0x22,
},
.bw._160 = {
.rx_tx_mcs9_max_nss = 0x22,
.rx_tx_mcs11_max_nss = 0x22,
.rx_tx_mcs13_max_nss = 0x22,
},
.bw._320 = {
.rx_tx_mcs9_max_nss = 0x22,
.rx_tx_mcs11_max_nss = 0x22,
.rx_tx_mcs13_max_nss = 0x22,
},
},
/*
* PPE thresholds for NSS = 2, and RU index bitmap set
* to 0xc.
*/
.eht_ppe_thres = {0xc1, 0x0e, 0xe0 }
},
}, },
}; };
...@@ -738,6 +853,7 @@ static void iwl_init_he_6ghz_capa(struct iwl_trans *trans, ...@@ -738,6 +853,7 @@ static void iwl_init_he_6ghz_capa(struct iwl_trans *trans,
static void static void
iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
struct iwl_nvm_data *data,
struct ieee80211_supported_band *sband, struct ieee80211_supported_band *sband,
struct ieee80211_sband_iftype_data *iftype_data, struct ieee80211_sband_iftype_data *iftype_data,
u8 tx_chains, u8 rx_chains, u8 tx_chains, u8 rx_chains,
...@@ -745,6 +861,9 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, ...@@ -745,6 +861,9 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
{ {
bool is_ap = iftype_data->types_mask & BIT(NL80211_IFTYPE_AP); bool is_ap = iftype_data->types_mask & BIT(NL80211_IFTYPE_AP);
if (!data->sku_cap_11be_enable || iwlwifi_mod_params.disable_11be)
iftype_data->eht_cap.has_eht = false;
/* Advertise an A-MPDU exponent extension based on /* Advertise an A-MPDU exponent extension based on
* operating band * operating band
*/ */
...@@ -765,19 +884,44 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans, ...@@ -765,19 +884,44 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
iftype_data->he_cap.he_cap_elem.phy_cap_info[5] |= iftype_data->he_cap.he_cap_elem.phy_cap_info[5] |=
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 | IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_2 |
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2; IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_2;
if (!is_ap) if (!is_ap) {
iftype_data->he_cap.he_cap_elem.phy_cap_info[7] |= iftype_data->he_cap.he_cap_elem.phy_cap_info[7] |=
IEEE80211_HE_PHY_CAP7_MAX_NC_2; IEEE80211_HE_PHY_CAP7_MAX_NC_2;
} else if (!is_ap) {
/* If not 2x2, we need to indicate 1x1 in the if (iftype_data->eht_cap.has_eht) {
* Midamble RX Max NSTS - but not for AP mode /*
*/ * Set the number of sounding dimensions for each
iftype_data->he_cap.he_cap_elem.phy_cap_info[1] &= * bandwidth to 1 to indicate the maximal supported
~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS; * value of TXVECTOR parameter NUM_STS of 2
iftype_data->he_cap.he_cap_elem.phy_cap_info[2] &= */
~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS; iftype_data->eht_cap.eht_cap_elem.phy_cap_info[2] |= 0x49;
iftype_data->he_cap.he_cap_elem.phy_cap_info[7] |=
IEEE80211_HE_PHY_CAP7_MAX_NC_1; /*
* Set the MAX NC to 1 to indicate sounding feedback of
* 2 supported by the beamfomee.
*/
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[4] |= 0x10;
}
}
} else {
if (iftype_data->eht_cap.has_eht) {
struct ieee80211_eht_mcs_nss_supp *mcs_nss =
&iftype_data->eht_cap.eht_mcs_nss_supp;
memset(mcs_nss, 0x11, sizeof(*mcs_nss));
}
if (!is_ap) {
/* If not 2x2, we need to indicate 1x1 in the
* Midamble RX Max NSTS - but not for AP mode
*/
iftype_data->he_cap.he_cap_elem.phy_cap_info[1] &=
~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS;
iftype_data->he_cap.he_cap_elem.phy_cap_info[2] &=
~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS;
iftype_data->he_cap.he_cap_elem.phy_cap_info[7] |=
IEEE80211_HE_PHY_CAP7_MAX_NC_1;
}
} }
switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) { switch (CSR_HW_RFID_TYPE(trans->hw_rf_id)) {
...@@ -816,8 +960,8 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans, ...@@ -816,8 +960,8 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
if (WARN_ON(sband->iftype_data)) if (WARN_ON(sband->iftype_data))
return; return;
BUILD_BUG_ON(sizeof(data->iftd.low) != sizeof(iwl_he_capa)); BUILD_BUG_ON(sizeof(data->iftd.low) != sizeof(iwl_he_eht_capa));
BUILD_BUG_ON(sizeof(data->iftd.high) != sizeof(iwl_he_capa)); BUILD_BUG_ON(sizeof(data->iftd.high) != sizeof(iwl_he_eht_capa));
switch (sband->band) { switch (sband->band) {
case NL80211_BAND_2GHZ: case NL80211_BAND_2GHZ:
...@@ -832,13 +976,13 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans, ...@@ -832,13 +976,13 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
return; return;
} }
memcpy(iftype_data, iwl_he_capa, sizeof(iwl_he_capa)); memcpy(iftype_data, iwl_he_eht_capa, sizeof(iwl_he_eht_capa));
sband->iftype_data = iftype_data; sband->iftype_data = iftype_data;
sband->n_iftype_data = ARRAY_SIZE(iwl_he_capa); sband->n_iftype_data = ARRAY_SIZE(iwl_he_eht_capa);
for (i = 0; i < sband->n_iftype_data; i++) for (i = 0; i < sband->n_iftype_data; i++)
iwl_nvm_fixup_sband_iftd(trans, sband, &iftype_data[i], iwl_nvm_fixup_sband_iftd(trans, data, sband, &iftype_data[i],
tx_chains, rx_chains, fw); tx_chains, rx_chains, fw);
iwl_init_he_6ghz_capa(trans, data, sband, tx_chains, rx_chains); iwl_init_he_6ghz_capa(trans, data, sband, tx_chains, rx_chains);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment