aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorEytan Lifshitz <eytan.lifshitz@intel.com>2013-02-20 04:01:13 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 10:47:52 -0500
commit33158fefc88e58fa17a46fdd90ba5231c3c8c89a (patch)
tree64aaa9465532427bdbbee55be9c68df1d9f43460 /drivers/net/wireless/iwlwifi
parent5bc5aaad407ccc49262d9fd3456d6ab332286395 (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.c46
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 */
153enum iwl_nvm_channel_flags { 155enum 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
256static 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
248static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 293static 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",