diff options
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c')
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 110 | 
1 files changed, 110 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index b815ba38dbdb..b4c3a957c102 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -430,6 +430,13 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,  		else  			vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;  		break; +	case IWL_AMSDU_2K: +		if (cfg->mq_rx_supported) +			vht_cap->cap |= +				IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; +		else +			WARN(1, "RB size of 2K is not supported by this device\n"); +		break;  	case IWL_AMSDU_4K:  		vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;  		break; @@ -463,6 +470,101 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,  	vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;  } +static struct ieee80211_sband_iftype_data iwl_he_capa = { +	.types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP), +	.he_cap = { +		.has_he = true, +		.he_cap_elem = { +			.mac_cap_info[0] = +				IEEE80211_HE_MAC_CAP0_HTC_HE, +			.mac_cap_info[1] = +				IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US | +				IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_QOS_8, +			.mac_cap_info[2] = +				IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP | +				IEEE80211_HE_MAC_CAP2_ACK_EN, +			.mac_cap_info[3] = +				IEEE80211_HE_MAC_CAP3_GRP_ADDR_MULTI_STA_BA_DL_MU | +				IEEE80211_HE_MAC_CAP3_MAX_A_AMPDU_LEN_EXP_VHT_2, +			.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU, +			.phy_cap_info[0] = +				IEEE80211_HE_PHY_CAP0_DUAL_BAND | +				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G | +				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G | +				IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G, +			.phy_cap_info[1] = +				IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A | +				IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD | +				IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS, +			.phy_cap_info[2] = +				IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US | +				IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ | +				IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ, +			.phy_cap_info[3] = +				IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_BPSK | +				IEEE80211_HE_PHY_CAP3_DCM_MAX_TX_NSS_1 | +				IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_BPSK | +				IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1, +			.phy_cap_info[4] = +				IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE | +				IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_8 | +				IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_8, +			.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, +			.phy_cap_info[6] = +				IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT, +			.phy_cap_info[7] = +				IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR | +				IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI | +				IEEE80211_HE_PHY_CAP7_MAX_NC_7, +			.phy_cap_info[8] = +				IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI | +				IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G | +				IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU | +				IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU, +		}, +		/* +		 * Set default Tx/Rx HE MCS NSS Support field. Indicate support +		 * for up to 2 spatial streams and all MCS, without any special +		 * cases +		 */ +		.he_mcs_nss_supp = { +			.rx_mcs_80 = cpu_to_le16(0xfffa), +			.tx_mcs_80 = cpu_to_le16(0xfffa), +			.rx_mcs_160 = cpu_to_le16(0xfffa), +			.tx_mcs_160 = cpu_to_le16(0xfffa), +			.rx_mcs_80p80 = cpu_to_le16(0xffff), +			.tx_mcs_80p80 = cpu_to_le16(0xffff), +		}, +		/* +		 * Set default PPE thresholds, with PPET16 set to 0, PPET8 set +		 * to 7 +		 */ +		.ppe_thres = {0x61, 0x1c, 0xc7, 0x71}, +	}, +}; + +static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband, +				 u8 tx_chains, u8 rx_chains) +{ +	if (sband->band == NL80211_BAND_2GHZ || +	    sband->band == NL80211_BAND_5GHZ) +		sband->iftype_data = &iwl_he_capa; +	else +		return; + +	sband->n_iftype_data = 1; + +	/* If not 2x2, we need to indicate 1x1 in the Midamble RX Max NSTS */ +	if ((tx_chains & rx_chains) != ANT_AB) { +		iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[1] &= +			~IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_MAX_NSTS; +		iwl_he_capa.he_cap.he_cap_elem.phy_cap_info[2] &= +			~IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_MAX_NSTS; +	} +} +  static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,  			    struct iwl_nvm_data *data,  			    const __le16 *nvm_ch_flags, u8 tx_chains, @@ -483,6 +585,9 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,  	iwl_init_ht_hw_capab(cfg, 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(sband, tx_chains, rx_chains); +  	sband = &data->bands[NL80211_BAND_5GHZ];  	sband->band = NL80211_BAND_5GHZ;  	sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS]; @@ -495,6 +600,9 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,  		iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,  				      tx_chains, rx_chains); +	if (data->sku_cap_11ax_enable && !iwlwifi_mod_params.disable_11ax) +		iwl_init_he_hw_capab(sband, tx_chains, rx_chains); +  	if (n_channels != n_used)  		IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",  			    n_used, n_channels); @@ -1293,6 +1401,8 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,  		!!(mac_flags & NVM_MAC_SKU_FLAGS_802_11AC_ENABLED);  	nvm->sku_cap_11n_enable =  		!!(mac_flags & NVM_MAC_SKU_FLAGS_802_11N_ENABLED); +	nvm->sku_cap_11ax_enable = +		!!(mac_flags & NVM_MAC_SKU_FLAGS_802_11AX_ENABLED);  	nvm->sku_cap_band_24ghz_enable =  		!!(mac_flags & NVM_MAC_SKU_FLAGS_BAND_2_4_ENABLED);  	nvm->sku_cap_band_52ghz_enable =  |