diff options
author | Eytan Lifshitz <eytan.lifshitz@intel.com> | 2013-02-20 04:01:13 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-03-06 10:47:52 -0500 |
commit | 33158fefc88e58fa17a46fdd90ba5231c3c8c89a (patch) | |
tree | 64aaa9465532427bdbbee55be9c68df1d9f43460 /drivers/net/wireless/iwlwifi | |
parent | 5bc5aaad407ccc49262d9fd3456d6ab332286395 (diff) |
iwlwifi: mvm: advertise VHT capabilities
Update the NVM parsing functions to add VHT capabilities;
they are only added for 5 GHz, of course. This assumes
that all devices with NVM reading (rather than EEPROM)
that support 5 GHz have VHT, which is true right now.
Signed-off-by: Eytan Lifshitz <eytan.lifshitz@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 2ab4bd67ba92..1ae6f2c1558d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -149,6 +149,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = { | |||
149 | * @NVM_CHANNEL_DFS: dynamic freq selection candidate | 149 | * @NVM_CHANNEL_DFS: dynamic freq selection candidate |
150 | * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) | 150 | * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) |
151 | * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) | 151 | * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) |
152 | * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) | ||
153 | * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?) | ||
152 | */ | 154 | */ |
153 | enum iwl_nvm_channel_flags { | 155 | enum iwl_nvm_channel_flags { |
154 | NVM_CHANNEL_VALID = BIT(0), | 156 | NVM_CHANNEL_VALID = BIT(0), |
@@ -158,6 +160,8 @@ enum iwl_nvm_channel_flags { | |||
158 | NVM_CHANNEL_DFS = BIT(7), | 160 | NVM_CHANNEL_DFS = BIT(7), |
159 | NVM_CHANNEL_WIDE = BIT(8), | 161 | NVM_CHANNEL_WIDE = BIT(8), |
160 | NVM_CHANNEL_40MHZ = BIT(9), | 162 | NVM_CHANNEL_40MHZ = BIT(9), |
163 | NVM_CHANNEL_80MHZ = BIT(10), | ||
164 | NVM_CHANNEL_160MHZ = BIT(11), | ||
161 | }; | 165 | }; |
162 | 166 | ||
163 | #define CHECK_AND_PRINT_I(x) \ | 167 | #define CHECK_AND_PRINT_I(x) \ |
@@ -210,6 +214,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
210 | else | 214 | else |
211 | channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; | 215 | channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS; |
212 | } | 216 | } |
217 | if (!(ch_flags & NVM_CHANNEL_80MHZ)) | ||
218 | channel->flags |= IEEE80211_CHAN_NO_80MHZ; | ||
219 | if (!(ch_flags & NVM_CHANNEL_160MHZ)) | ||
220 | channel->flags |= IEEE80211_CHAN_NO_160MHZ; | ||
213 | 221 | ||
214 | if (!(ch_flags & NVM_CHANNEL_IBSS)) | 222 | if (!(ch_flags & NVM_CHANNEL_IBSS)) |
215 | channel->flags |= IEEE80211_CHAN_NO_IBSS; | 223 | channel->flags |= IEEE80211_CHAN_NO_IBSS; |
@@ -245,6 +253,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, | |||
245 | return n_channels; | 253 | return n_channels; |
246 | } | 254 | } |
247 | 255 | ||
256 | static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, | ||
257 | struct iwl_nvm_data *data, | ||
258 | struct ieee80211_sta_vht_cap *vht_cap) | ||
259 | { | ||
260 | /* For now, assume new devices with NVM are VHT capable */ | ||
261 | |||
262 | vht_cap->vht_supported = true; | ||
263 | |||
264 | vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 | | ||
265 | IEEE80211_VHT_CAP_RXSTBC_1 | | ||
266 | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | | ||
267 | 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; | ||
268 | |||
269 | if (iwlwifi_mod_params.amsdu_size_8K) | ||
270 | vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; | ||
271 | |||
272 | vht_cap->vht_mcs.rx_mcs_map = | ||
273 | cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | | ||
274 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | | ||
275 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 | | ||
276 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 | | ||
277 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 | | ||
278 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 | | ||
279 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 | | ||
280 | IEEE80211_VHT_MCS_NOT_SUPPORTED << 14); | ||
281 | |||
282 | if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) { | ||
283 | vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN | | ||
284 | IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN; | ||
285 | /* this works because NOT_SUPPORTED == 3 */ | ||
286 | vht_cap->vht_mcs.rx_mcs_map |= | ||
287 | cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2); | ||
288 | } | ||
289 | |||
290 | vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map; | ||
291 | } | ||
292 | |||
248 | static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | 293 | static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, |
249 | struct iwl_nvm_data *data, const __le16 *nvm_sw) | 294 | struct iwl_nvm_data *data, const __le16 *nvm_sw) |
250 | { | 295 | { |
@@ -268,6 +313,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, | |||
268 | n_used += iwl_init_sband_channels(data, sband, n_channels, | 313 | n_used += iwl_init_sband_channels(data, sband, n_channels, |
269 | IEEE80211_BAND_5GHZ); | 314 | IEEE80211_BAND_5GHZ); |
270 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); | 315 | iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ); |
316 | iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap); | ||
271 | 317 | ||
272 | if (n_channels != n_used) | 318 | if (n_channels != n_used) |
273 | IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", | 319 | IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n", |