diff options
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 126 |
1 files changed, 106 insertions, 20 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 51e256c5fb7..7683cb83fe4 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -812,23 +812,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
812 | offset = noffset; | 812 | offset = noffset; |
813 | } | 813 | } |
814 | 814 | ||
815 | if (sband->ht_cap.ht_supported) { | 815 | if (sband->ht_cap.ht_supported) |
816 | u16 cap = sband->ht_cap.cap; | 816 | pos = ieee80211_ie_build_ht_cap(pos, sband, sband->ht_cap.cap); |
817 | __le16 tmp; | ||
818 | |||
819 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
820 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
821 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
822 | tmp = cpu_to_le16(cap); | ||
823 | memcpy(pos, &tmp, sizeof(u16)); | ||
824 | pos += sizeof(u16); | ||
825 | *pos++ = sband->ht_cap.ampdu_factor | | ||
826 | (sband->ht_cap.ampdu_density << | ||
827 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
828 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
829 | pos += sizeof(sband->ht_cap.mcs); | ||
830 | pos += 2 + 4 + 1; /* ext info, BF cap, antsel */ | ||
831 | } | ||
832 | 817 | ||
833 | /* | 818 | /* |
834 | * If adding more here, adjust code in main.c | 819 | * If adding more here, adjust code in main.c |
@@ -1022,7 +1007,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1022 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1007 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
1023 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | 1008 | sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1024 | ieee80211_sdata_running(sdata)) | 1009 | ieee80211_sdata_running(sdata)) |
1025 | res = drv_add_interface(local, &sdata->vif); | 1010 | res = drv_add_interface(local, sdata); |
1026 | } | 1011 | } |
1027 | 1012 | ||
1028 | /* add STAs back */ | 1013 | /* add STAs back */ |
@@ -1073,7 +1058,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1073 | BSS_CHANGED_BEACON_INT | | 1058 | BSS_CHANGED_BEACON_INT | |
1074 | BSS_CHANGED_BSSID | | 1059 | BSS_CHANGED_BSSID | |
1075 | BSS_CHANGED_CQM | | 1060 | BSS_CHANGED_CQM | |
1076 | BSS_CHANGED_QOS; | 1061 | BSS_CHANGED_QOS | |
1062 | BSS_CHANGED_IDLE; | ||
1077 | 1063 | ||
1078 | switch (sdata->vif.type) { | 1064 | switch (sdata->vif.type) { |
1079 | case NL80211_IFTYPE_STATION: | 1065 | case NL80211_IFTYPE_STATION: |
@@ -1086,7 +1072,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1086 | changed |= BSS_CHANGED_IBSS; | 1072 | changed |= BSS_CHANGED_IBSS; |
1087 | /* fall through */ | 1073 | /* fall through */ |
1088 | case NL80211_IFTYPE_AP: | 1074 | case NL80211_IFTYPE_AP: |
1089 | changed |= BSS_CHANGED_SSID; | 1075 | changed |= BSS_CHANGED_SSID | |
1076 | BSS_CHANGED_AP_PROBE_RESP; | ||
1090 | /* fall through */ | 1077 | /* fall through */ |
1091 | case NL80211_IFTYPE_MESH_POINT: | 1078 | case NL80211_IFTYPE_MESH_POINT: |
1092 | changed |= BSS_CHANGED_BEACON | | 1079 | changed |= BSS_CHANGED_BEACON | |
@@ -1108,6 +1095,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1108 | } | 1095 | } |
1109 | } | 1096 | } |
1110 | 1097 | ||
1098 | ieee80211_recalc_ps(local, -1); | ||
1099 | |||
1111 | /* | 1100 | /* |
1112 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1101 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
1113 | * sessions can be established after a resume. | 1102 | * sessions can be established after a resume. |
@@ -1363,6 +1352,103 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif) | |||
1363 | } | 1352 | } |
1364 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); | 1353 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); |
1365 | 1354 | ||
1355 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, | ||
1356 | u16 cap) | ||
1357 | { | ||
1358 | __le16 tmp; | ||
1359 | |||
1360 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1361 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1362 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
1363 | |||
1364 | /* capability flags */ | ||
1365 | tmp = cpu_to_le16(cap); | ||
1366 | memcpy(pos, &tmp, sizeof(u16)); | ||
1367 | pos += sizeof(u16); | ||
1368 | |||
1369 | /* AMPDU parameters */ | ||
1370 | *pos++ = sband->ht_cap.ampdu_factor | | ||
1371 | (sband->ht_cap.ampdu_density << | ||
1372 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
1373 | |||
1374 | /* MCS set */ | ||
1375 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
1376 | pos += sizeof(sband->ht_cap.mcs); | ||
1377 | |||
1378 | /* extended capabilities */ | ||
1379 | pos += sizeof(__le16); | ||
1380 | |||
1381 | /* BF capabilities */ | ||
1382 | pos += sizeof(__le32); | ||
1383 | |||
1384 | /* antenna selection */ | ||
1385 | pos += sizeof(u8); | ||
1386 | |||
1387 | return pos; | ||
1388 | } | ||
1389 | |||
1390 | u8 *ieee80211_ie_build_ht_info(u8 *pos, | ||
1391 | struct ieee80211_sta_ht_cap *ht_cap, | ||
1392 | struct ieee80211_channel *channel, | ||
1393 | enum nl80211_channel_type channel_type) | ||
1394 | { | ||
1395 | struct ieee80211_ht_info *ht_info; | ||
1396 | /* Build HT Information */ | ||
1397 | *pos++ = WLAN_EID_HT_INFORMATION; | ||
1398 | *pos++ = sizeof(struct ieee80211_ht_info); | ||
1399 | ht_info = (struct ieee80211_ht_info *)pos; | ||
1400 | ht_info->control_chan = | ||
1401 | ieee80211_frequency_to_channel(channel->center_freq); | ||
1402 | switch (channel_type) { | ||
1403 | case NL80211_CHAN_HT40MINUS: | ||
1404 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
1405 | break; | ||
1406 | case NL80211_CHAN_HT40PLUS: | ||
1407 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
1408 | break; | ||
1409 | case NL80211_CHAN_HT20: | ||
1410 | default: | ||
1411 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
1412 | break; | ||
1413 | } | ||
1414 | if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
1415 | ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | ||
1416 | ht_info->operation_mode = 0x0000; | ||
1417 | ht_info->stbc_param = 0x0000; | ||
1418 | |||
1419 | /* It seems that Basic MCS set and Supported MCS set | ||
1420 | are identical for the first 10 bytes */ | ||
1421 | memset(&ht_info->basic_set, 0, 16); | ||
1422 | memcpy(&ht_info->basic_set, &ht_cap->mcs, 10); | ||
1423 | |||
1424 | return pos + sizeof(struct ieee80211_ht_info); | ||
1425 | } | ||
1426 | |||
1427 | enum nl80211_channel_type | ||
1428 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info) | ||
1429 | { | ||
1430 | enum nl80211_channel_type channel_type; | ||
1431 | |||
1432 | if (!ht_info) | ||
1433 | return NL80211_CHAN_NO_HT; | ||
1434 | |||
1435 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | ||
1436 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
1437 | channel_type = NL80211_CHAN_HT20; | ||
1438 | break; | ||
1439 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
1440 | channel_type = NL80211_CHAN_HT40PLUS; | ||
1441 | break; | ||
1442 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
1443 | channel_type = NL80211_CHAN_HT40MINUS; | ||
1444 | break; | ||
1445 | default: | ||
1446 | channel_type = NL80211_CHAN_NO_HT; | ||
1447 | } | ||
1448 | |||
1449 | return channel_type; | ||
1450 | } | ||
1451 | |||
1366 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) | 1452 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) |
1367 | { | 1453 | { |
1368 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1454 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |