aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahesh Palivela <maheshp@posedge.com>2012-07-23 23:33:10 -0400
committerJohannes Berg <johannes.berg@intel.com>2012-07-31 10:10:57 -0400
commitd545daba5357c1ca377a4fe917ccf4de3a3031e0 (patch)
treee5facfda9d7cf2d09a8b56bced8ae99d2f2aa895
parentbae35d92b6a1b6fd8c699415ab90aeeea2a56bc3 (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>
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/mlme.c40
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
364struct ieee80211_mgd_auth_data { 365struct 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
329static 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
329static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) 349static 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));