diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2008-04-21 18:42:00 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-07 15:02:16 -0400 |
commit | d1141dfb3ab5545491e3aa15b7f0d7330a186281 (patch) | |
tree | 8bd31ba38d1dabc1c0ce44ec1f4aa6969205dd6d /drivers/net/wireless/iwlwifi/iwl4965-base.c | |
parent | cc2a8ea82ef869532cb7764b9eac30338773fe88 (diff) |
iwlwifi: HT IE in probe request clean up
This patch cleans up the scan flow. This patch cleans up the insertion of
the HT IE in the probe request.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 182 |
1 files changed, 101 insertions, 81 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 028523af0104..4bfc670e8784 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -99,7 +99,7 @@ __le16 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr) | |||
99 | return NULL; | 99 | return NULL; |
100 | } | 100 | } |
101 | 101 | ||
102 | static const struct ieee80211_supported_band *iwl4965_get_hw_mode( | 102 | static const struct ieee80211_supported_band *iwl_get_hw_mode( |
103 | struct iwl_priv *priv, enum ieee80211_band band) | 103 | struct iwl_priv *priv, enum ieee80211_band band) |
104 | { | 104 | { |
105 | return priv->hw->wiphy->bands[band]; | 105 | return priv->hw->wiphy->bands[band]; |
@@ -1166,6 +1166,91 @@ static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, | |||
1166 | return ret_rates; | 1166 | return ret_rates; |
1167 | } | 1167 | } |
1168 | 1168 | ||
1169 | #ifdef CONFIG_IWL4965_HT | ||
1170 | static void iwl4965_ht_conf(struct iwl_priv *priv, | ||
1171 | struct ieee80211_bss_conf *bss_conf) | ||
1172 | { | ||
1173 | struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf; | ||
1174 | struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; | ||
1175 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | ||
1176 | |||
1177 | IWL_DEBUG_MAC80211("enter: \n"); | ||
1178 | |||
1179 | iwl_conf->is_ht = bss_conf->assoc_ht; | ||
1180 | |||
1181 | if (!iwl_conf->is_ht) | ||
1182 | return; | ||
1183 | |||
1184 | priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
1185 | |||
1186 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | ||
1187 | iwl_conf->sgf |= 0x1; | ||
1188 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | ||
1189 | iwl_conf->sgf |= 0x2; | ||
1190 | |||
1191 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); | ||
1192 | iwl_conf->max_amsdu_size = | ||
1193 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); | ||
1194 | |||
1195 | iwl_conf->supported_chan_width = | ||
1196 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); | ||
1197 | iwl_conf->extension_chan_offset = | ||
1198 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; | ||
1199 | /* If no above or below channel supplied disable FAT channel */ | ||
1200 | if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE && | ||
1201 | iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW) | ||
1202 | iwl_conf->supported_chan_width = 0; | ||
1203 | |||
1204 | iwl_conf->tx_mimo_ps_mode = | ||
1205 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
1206 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); | ||
1207 | |||
1208 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | ||
1209 | iwl_conf->tx_chan_width = | ||
1210 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); | ||
1211 | iwl_conf->ht_protection = | ||
1212 | ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; | ||
1213 | iwl_conf->non_GF_STA_present = | ||
1214 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); | ||
1215 | |||
1216 | IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); | ||
1217 | IWL_DEBUG_MAC80211("leave\n"); | ||
1218 | } | ||
1219 | |||
1220 | static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, | ||
1221 | u8 *pos, int *left) | ||
1222 | { | ||
1223 | struct ieee80211_ht_cap *ht_cap; | ||
1224 | |||
1225 | if (!sband || !sband->ht_info.ht_supported) | ||
1226 | return; | ||
1227 | |||
1228 | if (*left < sizeof(struct ieee80211_ht_cap)) | ||
1229 | return; | ||
1230 | |||
1231 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1232 | ht_cap = (struct ieee80211_ht_cap *) pos; | ||
1233 | |||
1234 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); | ||
1235 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
1236 | ht_cap->ampdu_params_info = | ||
1237 | (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
1238 | ((sband->ht_info.ampdu_density << 2) & | ||
1239 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
1240 | *left -= sizeof(struct ieee80211_ht_cap); | ||
1241 | } | ||
1242 | #else | ||
1243 | static inline void iwl4965_ht_conf(struct iwl_priv *priv, | ||
1244 | struct ieee80211_bss_conf *bss_conf) | ||
1245 | { | ||
1246 | } | ||
1247 | static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, | ||
1248 | u8 *pos, int *left) | ||
1249 | { | ||
1250 | } | ||
1251 | #endif | ||
1252 | |||
1253 | |||
1169 | /** | 1254 | /** |
1170 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request | 1255 | * iwl4965_fill_probe_req - fill in all required fields and IE for probe request |
1171 | */ | 1256 | */ |
@@ -1177,10 +1262,8 @@ static u16 iwl4965_fill_probe_req(struct iwl_priv *priv, | |||
1177 | int len = 0; | 1262 | int len = 0; |
1178 | u8 *pos = NULL; | 1263 | u8 *pos = NULL; |
1179 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; | 1264 | u16 active_rates, ret_rates, cck_rates, active_rate_basic; |
1180 | #ifdef CONFIG_IWL4965_HT | ||
1181 | const struct ieee80211_supported_band *sband = | 1265 | const struct ieee80211_supported_band *sband = |
1182 | iwl4965_get_hw_mode(priv, band); | 1266 | iwl_get_hw_mode(priv, band); |
1183 | #endif /* CONFIG_IWL4965_HT */ | ||
1184 | 1267 | ||
1185 | /* Make sure there is enough space for the probe request, | 1268 | /* Make sure there is enough space for the probe request, |
1186 | * two mandatory IEs and the data */ | 1269 | * two mandatory IEs and the data */ |
@@ -1263,24 +1346,19 @@ static u16 iwl4965_fill_probe_req(struct iwl_priv *priv, | |||
1263 | if (*pos > 0) | 1346 | if (*pos > 0) |
1264 | len += 2 + *pos; | 1347 | len += 2 + *pos; |
1265 | 1348 | ||
1266 | #ifdef CONFIG_IWL4965_HT | ||
1267 | if (sband && sband->ht_info.ht_supported) { | ||
1268 | struct ieee80211_ht_cap *ht_cap; | ||
1269 | pos += (*pos) + 1; | ||
1270 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1271 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1272 | ht_cap = (struct ieee80211_ht_cap *)pos; | ||
1273 | ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); | ||
1274 | memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); | ||
1275 | ht_cap->ampdu_params_info =(sband->ht_info.ampdu_factor & | ||
1276 | IEEE80211_HT_CAP_AMPDU_FACTOR) | | ||
1277 | ((sband->ht_info.ampdu_density << 2) & | ||
1278 | IEEE80211_HT_CAP_AMPDU_DENSITY); | ||
1279 | len += 2 + sizeof(struct ieee80211_ht_cap); | ||
1280 | } | ||
1281 | #endif /*CONFIG_IWL4965_HT */ | ||
1282 | |||
1283 | fill_end: | 1349 | fill_end: |
1350 | /* fill in HT IE */ | ||
1351 | left -= 2; | ||
1352 | if (left < 0) | ||
1353 | return 0; | ||
1354 | |||
1355 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1356 | *pos = 0; | ||
1357 | |||
1358 | iwl_ht_cap_to_ie(sband, pos, &left); | ||
1359 | |||
1360 | if (*pos > 0) | ||
1361 | len += 2 + *pos; | ||
1284 | return (u16)len; | 1362 | return (u16)len; |
1285 | } | 1363 | } |
1286 | 1364 | ||
@@ -2146,7 +2224,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv) | |||
2146 | struct ieee80211_rate *rate; | 2224 | struct ieee80211_rate *rate; |
2147 | int i; | 2225 | int i; |
2148 | 2226 | ||
2149 | hw = iwl4965_get_hw_mode(priv, priv->band); | 2227 | hw = iwl_get_hw_mode(priv, priv->band); |
2150 | if (!hw) { | 2228 | if (!hw) { |
2151 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); | 2229 | IWL_ERROR("Failed to set rate: unable to get hw mode\n"); |
2152 | return; | 2230 | return; |
@@ -4360,7 +4438,7 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | |||
4360 | u16 active_dwell = 0; | 4438 | u16 active_dwell = 0; |
4361 | int added, i; | 4439 | int added, i; |
4362 | 4440 | ||
4363 | sband = iwl4965_get_hw_mode(priv, band); | 4441 | sband = iwl_get_hw_mode(priv, band); |
4364 | if (!sband) | 4442 | if (!sband) |
4365 | return 0; | 4443 | return 0; |
4366 | 4444 | ||
@@ -6328,64 +6406,6 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, | |||
6328 | 6406 | ||
6329 | } | 6407 | } |
6330 | 6408 | ||
6331 | |||
6332 | #ifdef CONFIG_IWL4965_HT | ||
6333 | static void iwl4965_ht_conf(struct iwl_priv *priv, | ||
6334 | struct ieee80211_bss_conf *bss_conf) | ||
6335 | { | ||
6336 | struct ieee80211_ht_info *ht_conf = bss_conf->ht_conf; | ||
6337 | struct ieee80211_ht_bss_info *ht_bss_conf = bss_conf->ht_bss_conf; | ||
6338 | struct iwl_ht_info *iwl_conf = &priv->current_ht_config; | ||
6339 | |||
6340 | IWL_DEBUG_MAC80211("enter: \n"); | ||
6341 | |||
6342 | iwl_conf->is_ht = bss_conf->assoc_ht; | ||
6343 | |||
6344 | if (!iwl_conf->is_ht) | ||
6345 | return; | ||
6346 | |||
6347 | priv->ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
6348 | |||
6349 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20) | ||
6350 | iwl_conf->sgf |= 0x1; | ||
6351 | if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40) | ||
6352 | iwl_conf->sgf |= 0x2; | ||
6353 | |||
6354 | iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD); | ||
6355 | iwl_conf->max_amsdu_size = | ||
6356 | !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU); | ||
6357 | |||
6358 | iwl_conf->supported_chan_width = | ||
6359 | !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH); | ||
6360 | iwl_conf->extension_chan_offset = | ||
6361 | ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; | ||
6362 | /* If no above or below channel supplied disable FAT channel */ | ||
6363 | if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE && | ||
6364 | iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW) | ||
6365 | iwl_conf->supported_chan_width = 0; | ||
6366 | |||
6367 | iwl_conf->tx_mimo_ps_mode = | ||
6368 | (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); | ||
6369 | memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); | ||
6370 | |||
6371 | iwl_conf->control_channel = ht_bss_conf->primary_channel; | ||
6372 | iwl_conf->tx_chan_width = | ||
6373 | !!(ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_WIDTH); | ||
6374 | iwl_conf->ht_protection = | ||
6375 | ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_HT_PROTECTION; | ||
6376 | iwl_conf->non_GF_STA_present = | ||
6377 | !!(ht_bss_conf->bss_op_mode & IEEE80211_HT_IE_NON_GF_STA_PRSNT); | ||
6378 | |||
6379 | IWL_DEBUG_MAC80211("control channel %d\n", iwl_conf->control_channel); | ||
6380 | IWL_DEBUG_MAC80211("leave\n"); | ||
6381 | } | ||
6382 | #else | ||
6383 | static inline void iwl4965_ht_conf(struct iwl_priv *priv, | ||
6384 | struct ieee80211_bss_conf *bss_conf) | ||
6385 | { | ||
6386 | } | ||
6387 | #endif | ||
6388 | |||
6389 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) | 6409 | #define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6) |
6390 | static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, | 6410 | static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, |
6391 | struct ieee80211_vif *vif, | 6411 | struct ieee80211_vif *vif, |