iwlwifi: mvm: advertise VHT capabilities
authorEytan Lifshitz <eytan.lifshitz@intel.com>
Wed, 20 Feb 2013 09:01:13 +0000 (11:01 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 Mar 2013 15:47:52 +0000 (16:47 +0100)
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>
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c

index 2ab4bd67ba92ae93f71bbd723d44a3e9a7a227d4..1ae6f2c1558d1b617ec9a92fb19e9dcfdca8c8ff 100644 (file)
@@ -149,6 +149,8 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
  * @NVM_CHANNEL_DFS: dynamic freq selection candidate
  * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
  * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
+ * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
+ * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
  */
 enum iwl_nvm_channel_flags {
        NVM_CHANNEL_VALID = BIT(0),
@@ -158,6 +160,8 @@ enum iwl_nvm_channel_flags {
        NVM_CHANNEL_DFS = BIT(7),
        NVM_CHANNEL_WIDE = BIT(8),
        NVM_CHANNEL_40MHZ = BIT(9),
+       NVM_CHANNEL_80MHZ = BIT(10),
+       NVM_CHANNEL_160MHZ = BIT(11),
 };
 
 #define CHECK_AND_PRINT_I(x)   \
@@ -210,6 +214,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
                        else
                                channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
                }
+               if (!(ch_flags & NVM_CHANNEL_80MHZ))
+                       channel->flags |= IEEE80211_CHAN_NO_80MHZ;
+               if (!(ch_flags & NVM_CHANNEL_160MHZ))
+                       channel->flags |= IEEE80211_CHAN_NO_160MHZ;
 
                if (!(ch_flags & NVM_CHANNEL_IBSS))
                        channel->flags |= IEEE80211_CHAN_NO_IBSS;
@@ -245,6 +253,43 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
        return n_channels;
 }
 
+static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
+                                 struct iwl_nvm_data *data,
+                                 struct ieee80211_sta_vht_cap *vht_cap)
+{
+       /* For now, assume new devices with NVM are VHT capable */
+
+       vht_cap->vht_supported = true;
+
+       vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
+                      IEEE80211_VHT_CAP_RXSTBC_1 |
+                      IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+                      7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
+
+       if (iwlwifi_mod_params.amsdu_size_8K)
+               vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
+
+       vht_cap->vht_mcs.rx_mcs_map =
+               cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
+                           IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
+                           IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
+                           IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
+                           IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
+                           IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
+                           IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
+                           IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
+
+       if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
+               vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
+                               IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
+               /* this works because NOT_SUPPORTED == 3 */
+               vht_cap->vht_mcs.rx_mcs_map |=
+                       cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
+       }
+
+       vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
+}
+
 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
                            struct iwl_nvm_data *data, const __le16 *nvm_sw)
 {
@@ -268,6 +313,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
        n_used += iwl_init_sband_channels(data, sband, n_channels,
                                          IEEE80211_BAND_5GHZ);
        iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
+       iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
 
        if (n_channels != n_used)
                IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",