diff options
author | Mahesh Palivela <maheshp@posedge.com> | 2012-07-23 23:33:10 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-31 10:10:57 -0400 |
commit | d545daba5357c1ca377a4fe917ccf4de3a3031e0 (patch) | |
tree | e5facfda9d7cf2d09a8b56bced8ae99d2f2aa895 /net/mac80211 | |
parent | bae35d92b6a1b6fd8c699415ab90aeeea2a56bc3 (diff) |
mac80211: VHT (11ac) association
Insert VHT IEs into association frames to allow
mac80211 to connect as a VHT client.
Signed-off-by: Mahesh Palivela <maheshp@posedge.com>
[clarify commit message]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 40 |
2 files changed, 39 insertions, 2 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index bb61f7718c4c..3e2f03b1b50e 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -359,6 +359,7 @@ enum ieee80211_sta_flags { | |||
359 | IEEE80211_STA_NULLFUNC_ACKED = BIT(8), | 359 | IEEE80211_STA_NULLFUNC_ACKED = BIT(8), |
360 | IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9), | 360 | IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9), |
361 | IEEE80211_STA_DISABLE_40MHZ = BIT(10), | 361 | IEEE80211_STA_DISABLE_40MHZ = BIT(10), |
362 | IEEE80211_STA_DISABLE_VHT = BIT(11), | ||
362 | }; | 363 | }; |
363 | 364 | ||
364 | struct ieee80211_mgd_auth_data { | 365 | struct ieee80211_mgd_auth_data { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cef0c9e79aba..725258c20746 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -326,6 +326,26 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, | |||
326 | ieee80211_ie_build_ht_cap(pos, &ht_cap, cap); | 326 | ieee80211_ie_build_ht_cap(pos, &ht_cap, cap); |
327 | } | 327 | } |
328 | 328 | ||
329 | static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, | ||
330 | struct sk_buff *skb, | ||
331 | struct ieee80211_supported_band *sband) | ||
332 | { | ||
333 | u8 *pos; | ||
334 | u32 cap; | ||
335 | struct ieee80211_sta_vht_cap vht_cap; | ||
336 | |||
337 | BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap)); | ||
338 | |||
339 | memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap)); | ||
340 | |||
341 | /* determine capability flags */ | ||
342 | cap = vht_cap.cap; | ||
343 | |||
344 | /* reserve and fill IE */ | ||
345 | pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2); | ||
346 | ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); | ||
347 | } | ||
348 | |||
329 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | 349 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) |
330 | { | 350 | { |
331 | struct ieee80211_local *local = sdata->local; | 351 | struct ieee80211_local *local = sdata->local; |
@@ -371,6 +391,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
371 | 4 + /* power capability */ | 391 | 4 + /* power capability */ |
372 | 2 + 2 * sband->n_channels + /* supported channels */ | 392 | 2 + 2 * sband->n_channels + /* supported channels */ |
373 | 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ | 393 | 2 + sizeof(struct ieee80211_ht_cap) + /* HT */ |
394 | 2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */ | ||
374 | assoc_data->ie_len + /* extra IEs */ | 395 | assoc_data->ie_len + /* extra IEs */ |
375 | 9, /* WMM */ | 396 | 9, /* WMM */ |
376 | GFP_KERNEL); | 397 | GFP_KERNEL); |
@@ -503,6 +524,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
503 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, | 524 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, |
504 | sband, local->oper_channel, ifmgd->ap_smps); | 525 | sband, local->oper_channel, ifmgd->ap_smps); |
505 | 526 | ||
527 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) | ||
528 | ieee80211_add_vht_ie(sdata, skb, sband); | ||
529 | |||
506 | /* if present, add any custom non-vendor IEs that go after HT */ | 530 | /* if present, add any custom non-vendor IEs that go after HT */ |
507 | if (assoc_data->ie_len && assoc_data->ie) { | 531 | if (assoc_data->ie_len && assoc_data->ie) { |
508 | noffset = ieee80211_ie_split_vendor(assoc_data->ie, | 532 | noffset = ieee80211_ie_split_vendor(assoc_data->ie, |
@@ -3301,6 +3325,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3301 | 3325 | ||
3302 | ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; | 3326 | ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; |
3303 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | 3327 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; |
3328 | ifmgd->flags &= ~IEEE80211_STA_DISABLE_VHT; | ||
3304 | 3329 | ||
3305 | ifmgd->beacon_crc_valid = false; | 3330 | ifmgd->beacon_crc_valid = false; |
3306 | 3331 | ||
@@ -3316,13 +3341,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3316 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | 3341 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || |
3317 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { | 3342 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { |
3318 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3343 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3344 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
3319 | netdev_info(sdata->dev, | 3345 | netdev_info(sdata->dev, |
3320 | "disabling HT due to WEP/TKIP use\n"); | 3346 | "disabling HT/VHT due to WEP/TKIP use\n"); |
3321 | } | 3347 | } |
3322 | } | 3348 | } |
3323 | 3349 | ||
3324 | if (req->flags & ASSOC_REQ_DISABLE_HT) | 3350 | if (req->flags & ASSOC_REQ_DISABLE_HT) { |
3325 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3351 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3352 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
3353 | } | ||
3326 | 3354 | ||
3327 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ | 3355 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ |
3328 | sband = local->hw.wiphy->bands[req->bss->channel->band]; | 3356 | sband = local->hw.wiphy->bands[req->bss->channel->band]; |
@@ -3333,6 +3361,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3333 | "disabling HT as WMM/QoS is not supported\n"); | 3361 | "disabling HT as WMM/QoS is not supported\n"); |
3334 | } | 3362 | } |
3335 | 3363 | ||
3364 | /* disable VHT if we don't support it or the AP doesn't use WMM */ | ||
3365 | if (!sband->vht_cap.vht_supported || | ||
3366 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { | ||
3367 | ifmgd->flags |= IEEE80211_STA_DISABLE_VHT; | ||
3368 | netdev_info(sdata->dev, | ||
3369 | "disabling VHT as WMM/QoS is not supported\n"); | ||
3370 | } | ||
3371 | |||
3336 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); | 3372 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); |
3337 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, | 3373 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, |
3338 | sizeof(ifmgd->ht_capa_mask)); | 3374 | sizeof(ifmgd->ht_capa_mask)); |