Skip to content

Commit

Permalink
wifi: iwlwifi: mvm: Advertise EHT capabilities
Browse files Browse the repository at this point in the history
Add support for advertising EHT capabilities if supported by
device SKU and not disabled by module parameters.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Link: https://lore.kernel.org/r/20221122220713.6bc00d851794.I214005645f3da21d8f2458a70355deeca04a19e8@changeid
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
  • Loading branch information
Ilan Peer authored and Gregory Greenman committed Nov 28, 2022
1 parent eceb024 commit 26d7cc0
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 18 deletions.
3 changes: 3 additions & 0 deletions drivers/net/wireless/intel/iwlwifi/iwl-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1971,3 +1971,6 @@ MODULE_PARM_DESC(remove_when_gone,
module_param_named(disable_11ax, iwlwifi_mod_params.disable_11ax, bool,
S_IRUGO);
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)");
3 changes: 2 additions & 1 deletion drivers/net/wireless/intel/iwlwifi/iwl-eeprom-parse.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* 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
*/
#ifndef __iwl_eeprom_parse_h__
Expand Down Expand Up @@ -31,6 +31,7 @@ struct iwl_nvm_data {
bool sku_cap_amt_enable;
bool sku_cap_ipan_enable;
bool sku_cap_mimo_disabled;
bool sku_cap_11be_enable;

u16 radio_cfg_type;
u8 radio_cfg_step;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ enum iwl_uapsd_disable {
* @disable_11ac: disable VHT capabilities, default = false.
* @remove_when_gone: remove an inaccessible device from the PCIe bus.
* @enable_ini: enable new FW debug infratructure (INI TLVs)
* @disable_11be: disable EHT capabilities, default = false.
*/
struct iwl_mod_params {
int swcrypto;
Expand Down
178 changes: 161 additions & 17 deletions drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ static const u8 iwl_vendor_caps[] = {
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),
.he_cap = {
Expand Down Expand Up @@ -631,6 +631,78 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
*/
.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),
Expand Down Expand Up @@ -687,6 +759,49 @@ static const struct ieee80211_sband_iftype_data iwl_he_capa[] = {
*/
.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 }
},
},
};

Expand Down Expand Up @@ -738,13 +853,17 @@ static void iwl_init_he_6ghz_capa(struct iwl_trans *trans,

static void
iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
struct iwl_nvm_data *data,
struct ieee80211_supported_band *sband,
struct ieee80211_sband_iftype_data *iftype_data,
u8 tx_chains, u8 rx_chains,
const struct iwl_fw *fw)
{
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
* operating band
*/
Expand All @@ -765,19 +884,44 @@ iwl_nvm_fixup_sband_iftd(struct iwl_trans *trans,
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_ABOVE_80MHZ_2;
if (!is_ap)
if (!is_ap) {
iftype_data->he_cap.he_cap_elem.phy_cap_info[7] |=
IEEE80211_HE_PHY_CAP7_MAX_NC_2;
} else 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;

if (iftype_data->eht_cap.has_eht) {
/*
* Set the number of sounding dimensions for each
* bandwidth to 1 to indicate the maximal supported
* value of TXVECTOR parameter NUM_STS of 2
*/
iftype_data->eht_cap.eht_cap_elem.phy_cap_info[2] |= 0x49;

/*
* 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)) {
Expand Down Expand Up @@ -816,8 +960,8 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
if (WARN_ON(sband->iftype_data))
return;

BUILD_BUG_ON(sizeof(data->iftd.low) != sizeof(iwl_he_capa));
BUILD_BUG_ON(sizeof(data->iftd.high) != 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_eht_capa));

switch (sband->band) {
case NL80211_BAND_2GHZ:
Expand All @@ -832,13 +976,13 @@ static void iwl_init_he_hw_capab(struct iwl_trans *trans,
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->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++)
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);

iwl_init_he_6ghz_capa(trans, data, sband, tx_chains, rx_chains);
Expand Down

0 comments on commit 26d7cc0

Please sign in to comment.