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 eca0fad09709..3a00814699f0 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 |
@@ -1026,7 +1011,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1026 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1011 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
1027 | sdata->vif.type != NL80211_IFTYPE_MONITOR && | 1012 | sdata->vif.type != NL80211_IFTYPE_MONITOR && |
1028 | ieee80211_sdata_running(sdata)) | 1013 | ieee80211_sdata_running(sdata)) |
1029 | res = drv_add_interface(local, &sdata->vif); | 1014 | res = drv_add_interface(local, sdata); |
1030 | } | 1015 | } |
1031 | 1016 | ||
1032 | /* add STAs back */ | 1017 | /* add STAs back */ |
@@ -1077,7 +1062,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1077 | BSS_CHANGED_BEACON_INT | | 1062 | BSS_CHANGED_BEACON_INT | |
1078 | BSS_CHANGED_BSSID | | 1063 | BSS_CHANGED_BSSID | |
1079 | BSS_CHANGED_CQM | | 1064 | BSS_CHANGED_CQM | |
1080 | BSS_CHANGED_QOS; | 1065 | BSS_CHANGED_QOS | |
1066 | BSS_CHANGED_IDLE; | ||
1081 | 1067 | ||
1082 | switch (sdata->vif.type) { | 1068 | switch (sdata->vif.type) { |
1083 | case NL80211_IFTYPE_STATION: | 1069 | case NL80211_IFTYPE_STATION: |
@@ -1090,7 +1076,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1090 | changed |= BSS_CHANGED_IBSS; | 1076 | changed |= BSS_CHANGED_IBSS; |
1091 | /* fall through */ | 1077 | /* fall through */ |
1092 | case NL80211_IFTYPE_AP: | 1078 | case NL80211_IFTYPE_AP: |
1093 | changed |= BSS_CHANGED_SSID; | 1079 | changed |= BSS_CHANGED_SSID | |
1080 | BSS_CHANGED_AP_PROBE_RESP; | ||
1094 | /* fall through */ | 1081 | /* fall through */ |
1095 | case NL80211_IFTYPE_MESH_POINT: | 1082 | case NL80211_IFTYPE_MESH_POINT: |
1096 | changed |= BSS_CHANGED_BEACON | | 1083 | changed |= BSS_CHANGED_BEACON | |
@@ -1112,6 +1099,8 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1112 | } | 1099 | } |
1113 | } | 1100 | } |
1114 | 1101 | ||
1102 | ieee80211_recalc_ps(local, -1); | ||
1103 | |||
1115 | /* | 1104 | /* |
1116 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1105 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
1117 | * sessions can be established after a resume. | 1106 | * sessions can be established after a resume. |
@@ -1367,6 +1356,103 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif) | |||
1367 | } | 1356 | } |
1368 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); | 1357 | EXPORT_SYMBOL(ieee80211_disable_rssi_reports); |
1369 | 1358 | ||
1359 | u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_supported_band *sband, | ||
1360 | u16 cap) | ||
1361 | { | ||
1362 | __le16 tmp; | ||
1363 | |||
1364 | *pos++ = WLAN_EID_HT_CAPABILITY; | ||
1365 | *pos++ = sizeof(struct ieee80211_ht_cap); | ||
1366 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | ||
1367 | |||
1368 | /* capability flags */ | ||
1369 | tmp = cpu_to_le16(cap); | ||
1370 | memcpy(pos, &tmp, sizeof(u16)); | ||
1371 | pos += sizeof(u16); | ||
1372 | |||
1373 | /* AMPDU parameters */ | ||
1374 | *pos++ = sband->ht_cap.ampdu_factor | | ||
1375 | (sband->ht_cap.ampdu_density << | ||
1376 | IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT); | ||
1377 | |||
1378 | /* MCS set */ | ||
1379 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | ||
1380 | pos += sizeof(sband->ht_cap.mcs); | ||
1381 | |||
1382 | /* extended capabilities */ | ||
1383 | pos += sizeof(__le16); | ||
1384 | |||
1385 | /* BF capabilities */ | ||
1386 | pos += sizeof(__le32); | ||
1387 | |||
1388 | /* antenna selection */ | ||
1389 | pos += sizeof(u8); | ||
1390 | |||
1391 | return pos; | ||
1392 | } | ||
1393 | |||
1394 | u8 *ieee80211_ie_build_ht_info(u8 *pos, | ||
1395 | struct ieee80211_sta_ht_cap *ht_cap, | ||
1396 | struct ieee80211_channel *channel, | ||
1397 | enum nl80211_channel_type channel_type) | ||
1398 | { | ||
1399 | struct ieee80211_ht_info *ht_info; | ||
1400 | /* Build HT Information */ | ||
1401 | *pos++ = WLAN_EID_HT_INFORMATION; | ||
1402 | *pos++ = sizeof(struct ieee80211_ht_info); | ||
1403 | ht_info = (struct ieee80211_ht_info *)pos; | ||
1404 | ht_info->control_chan = | ||
1405 | ieee80211_frequency_to_channel(channel->center_freq); | ||
1406 | switch (channel_type) { | ||
1407 | case NL80211_CHAN_HT40MINUS: | ||
1408 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
1409 | break; | ||
1410 | case NL80211_CHAN_HT40PLUS: | ||
1411 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
1412 | break; | ||
1413 | case NL80211_CHAN_HT20: | ||
1414 | default: | ||
1415 | ht_info->ht_param = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
1416 | break; | ||
1417 | } | ||
1418 | if (ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
1419 | ht_info->ht_param |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY; | ||
1420 | ht_info->operation_mode = 0x0000; | ||
1421 | ht_info->stbc_param = 0x0000; | ||
1422 | |||
1423 | /* It seems that Basic MCS set and Supported MCS set | ||
1424 | are identical for the first 10 bytes */ | ||
1425 | memset(&ht_info->basic_set, 0, 16); | ||
1426 | memcpy(&ht_info->basic_set, &ht_cap->mcs, 10); | ||
1427 | |||
1428 | return pos + sizeof(struct ieee80211_ht_info); | ||
1429 | } | ||
1430 | |||
1431 | enum nl80211_channel_type | ||
1432 | ieee80211_ht_info_to_channel_type(struct ieee80211_ht_info *ht_info) | ||
1433 | { | ||
1434 | enum nl80211_channel_type channel_type; | ||
1435 | |||
1436 | if (!ht_info) | ||
1437 | return NL80211_CHAN_NO_HT; | ||
1438 | |||
1439 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | ||
1440 | case IEEE80211_HT_PARAM_CHA_SEC_NONE: | ||
1441 | channel_type = NL80211_CHAN_HT20; | ||
1442 | break; | ||
1443 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | ||
1444 | channel_type = NL80211_CHAN_HT40PLUS; | ||
1445 | break; | ||
1446 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | ||
1447 | channel_type = NL80211_CHAN_HT40MINUS; | ||
1448 | break; | ||
1449 | default: | ||
1450 | channel_type = NL80211_CHAN_NO_HT; | ||
1451 | } | ||
1452 | |||
1453 | return channel_type; | ||
1454 | } | ||
1455 | |||
1370 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) | 1456 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb) |
1371 | { | 1457 | { |
1372 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1458 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |