diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
commit | d834a9dcecae834cd6b2bc5e50e1907738d9cf6a (patch) | |
tree | 0589d753465d3fe359ba451ba6cb7798df03aaa2 /net/mac80211/util.c | |
parent | a38c5380ef9f088be9f49b6e4c5d80af8b1b5cd4 (diff) | |
parent | f658bcfb2607bf0808966a69cf74135ce98e5c2d (diff) |
Merge branch 'x86/amd-nb' into x86/apic-cleanups
Reason: apic cleanup series depends on x86/apic, x86/amd-nb x86/platform
Conflicts:
arch/x86/include/asm/io_apic.h
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 102 |
1 files changed, 50 insertions, 52 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 748387d45bc0..0b6fc92bc0d7 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -283,8 +283,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, | |||
283 | 283 | ||
284 | if (skb_queue_empty(&local->pending[queue])) { | 284 | if (skb_queue_empty(&local->pending[queue])) { |
285 | rcu_read_lock(); | 285 | rcu_read_lock(); |
286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 286 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
287 | netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); | 287 | if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) |
288 | continue; | ||
289 | netif_wake_subqueue(sdata->dev, queue); | ||
290 | } | ||
288 | rcu_read_unlock(); | 291 | rcu_read_unlock(); |
289 | } else | 292 | } else |
290 | tasklet_schedule(&local->tx_pending_tasklet); | 293 | tasklet_schedule(&local->tx_pending_tasklet); |
@@ -323,7 +326,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, | |||
323 | 326 | ||
324 | rcu_read_lock(); | 327 | rcu_read_lock(); |
325 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 328 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
326 | netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); | 329 | netif_stop_subqueue(sdata->dev, queue); |
327 | rcu_read_unlock(); | 330 | rcu_read_unlock(); |
328 | } | 331 | } |
329 | 332 | ||
@@ -471,16 +474,10 @@ void ieee80211_iterate_active_interfaces( | |||
471 | 474 | ||
472 | list_for_each_entry(sdata, &local->interfaces, list) { | 475 | list_for_each_entry(sdata, &local->interfaces, list) { |
473 | switch (sdata->vif.type) { | 476 | switch (sdata->vif.type) { |
474 | case __NL80211_IFTYPE_AFTER_LAST: | ||
475 | case NL80211_IFTYPE_UNSPECIFIED: | ||
476 | case NL80211_IFTYPE_MONITOR: | 477 | case NL80211_IFTYPE_MONITOR: |
477 | case NL80211_IFTYPE_AP_VLAN: | 478 | case NL80211_IFTYPE_AP_VLAN: |
478 | continue; | 479 | continue; |
479 | case NL80211_IFTYPE_AP: | 480 | default: |
480 | case NL80211_IFTYPE_STATION: | ||
481 | case NL80211_IFTYPE_ADHOC: | ||
482 | case NL80211_IFTYPE_WDS: | ||
483 | case NL80211_IFTYPE_MESH_POINT: | ||
484 | break; | 481 | break; |
485 | } | 482 | } |
486 | if (ieee80211_sdata_running(sdata)) | 483 | if (ieee80211_sdata_running(sdata)) |
@@ -505,16 +502,10 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
505 | 502 | ||
506 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 503 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
507 | switch (sdata->vif.type) { | 504 | switch (sdata->vif.type) { |
508 | case __NL80211_IFTYPE_AFTER_LAST: | ||
509 | case NL80211_IFTYPE_UNSPECIFIED: | ||
510 | case NL80211_IFTYPE_MONITOR: | 505 | case NL80211_IFTYPE_MONITOR: |
511 | case NL80211_IFTYPE_AP_VLAN: | 506 | case NL80211_IFTYPE_AP_VLAN: |
512 | continue; | 507 | continue; |
513 | case NL80211_IFTYPE_AP: | 508 | default: |
514 | case NL80211_IFTYPE_STATION: | ||
515 | case NL80211_IFTYPE_ADHOC: | ||
516 | case NL80211_IFTYPE_WDS: | ||
517 | case NL80211_IFTYPE_MESH_POINT: | ||
518 | break; | 509 | break; |
519 | } | 510 | } |
520 | if (ieee80211_sdata_running(sdata)) | 511 | if (ieee80211_sdata_running(sdata)) |
@@ -904,26 +895,34 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
904 | 895 | ||
905 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 896 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
906 | const u8 *ie, size_t ie_len, | 897 | const u8 *ie, size_t ie_len, |
907 | enum ieee80211_band band) | 898 | enum ieee80211_band band, u32 rate_mask, |
899 | u8 channel) | ||
908 | { | 900 | { |
909 | struct ieee80211_supported_band *sband; | 901 | struct ieee80211_supported_band *sband; |
910 | u8 *pos; | 902 | u8 *pos; |
911 | size_t offset = 0, noffset; | 903 | size_t offset = 0, noffset; |
912 | int supp_rates_len, i; | 904 | int supp_rates_len, i; |
905 | u8 rates[32]; | ||
906 | int num_rates; | ||
907 | int ext_rates_len; | ||
913 | 908 | ||
914 | sband = local->hw.wiphy->bands[band]; | 909 | sband = local->hw.wiphy->bands[band]; |
915 | 910 | ||
916 | pos = buffer; | 911 | pos = buffer; |
917 | 912 | ||
918 | supp_rates_len = min_t(int, sband->n_bitrates, 8); | 913 | num_rates = 0; |
914 | for (i = 0; i < sband->n_bitrates; i++) { | ||
915 | if ((BIT(i) & rate_mask) == 0) | ||
916 | continue; /* skip rate */ | ||
917 | rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); | ||
918 | } | ||
919 | |||
920 | supp_rates_len = min_t(int, num_rates, 8); | ||
919 | 921 | ||
920 | *pos++ = WLAN_EID_SUPP_RATES; | 922 | *pos++ = WLAN_EID_SUPP_RATES; |
921 | *pos++ = supp_rates_len; | 923 | *pos++ = supp_rates_len; |
922 | 924 | memcpy(pos, rates, supp_rates_len); | |
923 | for (i = 0; i < supp_rates_len; i++) { | 925 | pos += supp_rates_len; |
924 | int rate = sband->bitrates[i].bitrate; | ||
925 | *pos++ = (u8) (rate / 5); | ||
926 | } | ||
927 | 926 | ||
928 | /* insert "request information" if in custom IEs */ | 927 | /* insert "request information" if in custom IEs */ |
929 | if (ie && ie_len) { | 928 | if (ie && ie_len) { |
@@ -941,14 +940,18 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
941 | offset = noffset; | 940 | offset = noffset; |
942 | } | 941 | } |
943 | 942 | ||
944 | if (sband->n_bitrates > i) { | 943 | ext_rates_len = num_rates - supp_rates_len; |
944 | if (ext_rates_len > 0) { | ||
945 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 945 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
946 | *pos++ = sband->n_bitrates - i; | 946 | *pos++ = ext_rates_len; |
947 | memcpy(pos, rates + supp_rates_len, ext_rates_len); | ||
948 | pos += ext_rates_len; | ||
949 | } | ||
947 | 950 | ||
948 | for (; i < sband->n_bitrates; i++) { | 951 | if (channel && sband->band == IEEE80211_BAND_2GHZ) { |
949 | int rate = sband->bitrates[i].bitrate; | 952 | *pos++ = WLAN_EID_DS_PARAMS; |
950 | *pos++ = (u8) (rate / 5); | 953 | *pos++ = 1; |
951 | } | 954 | *pos++ = channel; |
952 | } | 955 | } |
953 | 956 | ||
954 | /* insert custom IEs that go before HT */ | 957 | /* insert custom IEs that go before HT */ |
@@ -1017,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1017 | struct ieee80211_mgmt *mgmt; | 1020 | struct ieee80211_mgmt *mgmt; |
1018 | size_t buf_len; | 1021 | size_t buf_len; |
1019 | u8 *buf; | 1022 | u8 *buf; |
1023 | u8 chan; | ||
1020 | 1024 | ||
1021 | /* FIXME: come up with a proper value */ | 1025 | /* FIXME: come up with a proper value */ |
1022 | buf = kmalloc(200 + ie_len, GFP_KERNEL); | 1026 | buf = kmalloc(200 + ie_len, GFP_KERNEL); |
@@ -1026,8 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
1026 | return; | 1030 | return; |
1027 | } | 1031 | } |
1028 | 1032 | ||
1033 | chan = ieee80211_frequency_to_channel( | ||
1034 | local->hw.conf.channel->center_freq); | ||
1035 | |||
1029 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1036 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1030 | local->hw.conf.channel->band); | 1037 | local->hw.conf.channel->band, |
1038 | sdata->rc_rateidx_mask | ||
1039 | [local->hw.conf.channel->band], | ||
1040 | chan); | ||
1031 | 1041 | ||
1032 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1042 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1033 | ssid, ssid_len, | 1043 | ssid, ssid_len, |
@@ -1189,7 +1199,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1189 | /* ignore virtual */ | 1199 | /* ignore virtual */ |
1190 | break; | 1200 | break; |
1191 | case NL80211_IFTYPE_UNSPECIFIED: | 1201 | case NL80211_IFTYPE_UNSPECIFIED: |
1192 | case __NL80211_IFTYPE_AFTER_LAST: | 1202 | case NUM_NL80211_IFTYPES: |
1203 | case NL80211_IFTYPE_P2P_CLIENT: | ||
1204 | case NL80211_IFTYPE_P2P_GO: | ||
1193 | WARN_ON(1); | 1205 | WARN_ON(1); |
1194 | break; | 1206 | break; |
1195 | } | 1207 | } |
@@ -1209,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1209 | mutex_lock(&local->sta_mtx); | 1221 | mutex_lock(&local->sta_mtx); |
1210 | 1222 | ||
1211 | list_for_each_entry(sta, &local->sta_list, list) { | 1223 | list_for_each_entry(sta, &local->sta_list, list) { |
1212 | ieee80211_sta_tear_down_BA_sessions(sta); | 1224 | ieee80211_sta_tear_down_BA_sessions(sta, true); |
1213 | clear_sta_flags(sta, WLAN_STA_BLOCK_BA); | 1225 | clear_sta_flags(sta, WLAN_STA_BLOCK_BA); |
1214 | } | 1226 | } |
1215 | 1227 | ||
@@ -1285,17 +1297,13 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, | |||
1285 | } | 1297 | } |
1286 | 1298 | ||
1287 | /* must hold iflist_mtx */ | 1299 | /* must hold iflist_mtx */ |
1288 | void ieee80211_recalc_smps(struct ieee80211_local *local, | 1300 | void ieee80211_recalc_smps(struct ieee80211_local *local) |
1289 | struct ieee80211_sub_if_data *forsdata) | ||
1290 | { | 1301 | { |
1291 | struct ieee80211_sub_if_data *sdata; | 1302 | struct ieee80211_sub_if_data *sdata; |
1292 | enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; | 1303 | enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; |
1293 | int count = 0; | 1304 | int count = 0; |
1294 | 1305 | ||
1295 | if (forsdata) | 1306 | lockdep_assert_held(&local->iflist_mtx); |
1296 | WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx)); | ||
1297 | |||
1298 | WARN_ON(!mutex_is_locked(&local->iflist_mtx)); | ||
1299 | 1307 | ||
1300 | /* | 1308 | /* |
1301 | * This function could be improved to handle multiple | 1309 | * This function could be improved to handle multiple |
@@ -1308,22 +1316,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local, | |||
1308 | */ | 1316 | */ |
1309 | 1317 | ||
1310 | list_for_each_entry(sdata, &local->interfaces, list) { | 1318 | list_for_each_entry(sdata, &local->interfaces, list) { |
1311 | if (!netif_running(sdata->dev)) | 1319 | if (!ieee80211_sdata_running(sdata)) |
1312 | continue; | 1320 | continue; |
1313 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 1321 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
1314 | goto set; | 1322 | goto set; |
1315 | if (sdata != forsdata) { | 1323 | |
1316 | /* | 1324 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); |
1317 | * This nested is ok -- we are holding the iflist_mtx | ||
1318 | * so can't get here twice or so. But it's required | ||
1319 | * since normally we acquire it first and then the | ||
1320 | * iflist_mtx. | ||
1321 | */ | ||
1322 | mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING); | ||
1323 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); | ||
1324 | mutex_unlock(&sdata->u.mgd.mtx); | ||
1325 | } else | ||
1326 | count += check_mgd_smps(&sdata->u.mgd, &smps_mode); | ||
1327 | 1325 | ||
1328 | if (count > 1) { | 1326 | if (count > 1) { |
1329 | smps_mode = IEEE80211_SMPS_OFF; | 1327 | smps_mode = IEEE80211_SMPS_OFF; |