diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ibss.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 78 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 11 | ||||
-rw-r--r-- | net/mac80211/scan.c | 17 |
5 files changed, 101 insertions, 12 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index a8e23232267e..aa537681f87c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -862,6 +862,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
862 | 862 | ||
863 | sdata->u.ibss.ssid_len = params->ssid_len; | 863 | sdata->u.ibss.ssid_len = params->ssid_len; |
864 | 864 | ||
865 | ieee80211_recalc_idle(sdata->local); | ||
866 | |||
865 | set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); | 867 | set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); |
866 | queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); | 868 | queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); |
867 | 869 | ||
@@ -889,6 +891,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
889 | 891 | ||
890 | skb_queue_purge(&sdata->u.ibss.skb_queue); | 892 | skb_queue_purge(&sdata->u.ibss.skb_queue); |
891 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | 893 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); |
894 | sdata->u.ibss.ssid_len = 0; | ||
895 | |||
896 | ieee80211_recalc_idle(sdata->local); | ||
892 | 897 | ||
893 | return 0; | 898 | return 0; |
894 | } | 899 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 236ea098bb6c..03e0d22603c8 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -985,6 +985,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | |||
985 | enum nl80211_iftype type); | 985 | enum nl80211_iftype type); |
986 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | 986 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); |
987 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 987 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
988 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); | ||
989 | void ieee80211_recalc_idle(struct ieee80211_local *local); | ||
988 | 990 | ||
989 | /* tx handling */ | 991 | /* tx handling */ |
990 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); | 992 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 256fa19e14ec..8b6daf0219f4 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -301,6 +301,8 @@ static int ieee80211_open(struct net_device *dev) | |||
301 | if (sdata->flags & IEEE80211_SDATA_PROMISC) | 301 | if (sdata->flags & IEEE80211_SDATA_PROMISC) |
302 | atomic_inc(&local->iff_promiscs); | 302 | atomic_inc(&local->iff_promiscs); |
303 | 303 | ||
304 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | ||
305 | |||
304 | local->open_count++; | 306 | local->open_count++; |
305 | if (hw_reconf_flags) { | 307 | if (hw_reconf_flags) { |
306 | ieee80211_hw_config(local, hw_reconf_flags); | 308 | ieee80211_hw_config(local, hw_reconf_flags); |
@@ -548,6 +550,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
548 | 550 | ||
549 | sdata->bss = NULL; | 551 | sdata->bss = NULL; |
550 | 552 | ||
553 | hw_reconf_flags |= __ieee80211_recalc_idle(local); | ||
554 | |||
555 | ieee80211_recalc_ps(local, -1); | ||
556 | |||
551 | if (local->open_count == 0) { | 557 | if (local->open_count == 0) { |
552 | if (netif_running(local->mdev)) | 558 | if (netif_running(local->mdev)) |
553 | dev_close(local->mdev); | 559 | dev_close(local->mdev); |
@@ -565,8 +571,6 @@ static int ieee80211_stop(struct net_device *dev) | |||
565 | hw_reconf_flags = 0; | 571 | hw_reconf_flags = 0; |
566 | } | 572 | } |
567 | 573 | ||
568 | ieee80211_recalc_ps(local, -1); | ||
569 | |||
570 | /* do after stop to avoid reconfiguring when we stop anyway */ | 574 | /* do after stop to avoid reconfiguring when we stop anyway */ |
571 | if (hw_reconf_flags) | 575 | if (hw_reconf_flags) |
572 | ieee80211_hw_config(local, hw_reconf_flags); | 576 | ieee80211_hw_config(local, hw_reconf_flags); |
@@ -892,3 +896,73 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
892 | unregister_netdevice(sdata->dev); | 896 | unregister_netdevice(sdata->dev); |
893 | } | 897 | } |
894 | } | 898 | } |
899 | |||
900 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | ||
901 | const char *reason) | ||
902 | { | ||
903 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | ||
904 | return 0; | ||
905 | |||
906 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
907 | printk(KERN_DEBUG "%s: device no longer idle - %s\n", | ||
908 | wiphy_name(local->hw.wiphy), reason); | ||
909 | #endif | ||
910 | |||
911 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; | ||
912 | return IEEE80211_CONF_CHANGE_IDLE; | ||
913 | } | ||
914 | |||
915 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | ||
916 | { | ||
917 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | ||
918 | return 0; | ||
919 | |||
920 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
921 | printk(KERN_DEBUG "%s: device now idle\n", | ||
922 | wiphy_name(local->hw.wiphy)); | ||
923 | #endif | ||
924 | |||
925 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | ||
926 | return IEEE80211_CONF_CHANGE_IDLE; | ||
927 | } | ||
928 | |||
929 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | ||
930 | { | ||
931 | struct ieee80211_sub_if_data *sdata; | ||
932 | int count = 0; | ||
933 | |||
934 | if (local->hw_scanning || local->sw_scanning) | ||
935 | return ieee80211_idle_off(local, "scanning"); | ||
936 | |||
937 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
938 | if (!netif_running(sdata->dev)) | ||
939 | continue; | ||
940 | /* do not count disabled managed interfaces */ | ||
941 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
942 | sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED) | ||
943 | continue; | ||
944 | /* do not count unused IBSS interfaces */ | ||
945 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
946 | !sdata->u.ibss.ssid_len) | ||
947 | continue; | ||
948 | /* count everything else */ | ||
949 | count++; | ||
950 | } | ||
951 | |||
952 | if (!count) | ||
953 | return ieee80211_idle_on(local); | ||
954 | else | ||
955 | return ieee80211_idle_off(local, "in use"); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
961 | { | ||
962 | u32 chg; | ||
963 | |||
964 | mutex_lock(&local->iflist_mtx); | ||
965 | chg = __ieee80211_recalc_idle(local); | ||
966 | mutex_unlock(&local->iflist_mtx); | ||
967 | ieee80211_hw_config(local, chg); | ||
968 | } | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2ded4766d014..5509c5aa6beb 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -890,6 +890,7 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata) | |||
890 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", | 890 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", |
891 | sdata->dev->name, ifmgd->bssid); | 891 | sdata->dev->name, ifmgd->bssid); |
892 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 892 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
893 | ieee80211_recalc_idle(local); | ||
893 | cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid); | 894 | cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid); |
894 | 895 | ||
895 | /* | 896 | /* |
@@ -938,6 +939,7 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata) | |||
938 | " timed out\n", | 939 | " timed out\n", |
939 | sdata->dev->name, ifmgd->bssid); | 940 | sdata->dev->name, ifmgd->bssid); |
940 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 941 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
942 | ieee80211_recalc_idle(local); | ||
941 | cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid); | 943 | cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid); |
942 | ieee80211_rx_bss_remove(sdata, ifmgd->bssid, | 944 | ieee80211_rx_bss_remove(sdata, ifmgd->bssid, |
943 | sdata->local->hw.conf.channel->center_freq, | 945 | sdata->local->hw.conf.channel->center_freq, |
@@ -1041,6 +1043,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1041 | 1043 | ||
1042 | rcu_read_unlock(); | 1044 | rcu_read_unlock(); |
1043 | 1045 | ||
1046 | ieee80211_recalc_idle(local); | ||
1047 | |||
1044 | /* channel(_type) changes are handled by ieee80211_hw_config */ | 1048 | /* channel(_type) changes are handled by ieee80211_hw_config */ |
1045 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 1049 | local->oper_channel_type = NL80211_CHAN_NO_HT; |
1046 | 1050 | ||
@@ -1121,6 +1125,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata) | |||
1121 | " timed out\n", | 1125 | " timed out\n", |
1122 | sdata->dev->name, ifmgd->bssid); | 1126 | sdata->dev->name, ifmgd->bssid); |
1123 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 1127 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
1128 | ieee80211_recalc_idle(local); | ||
1124 | cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid); | 1129 | cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid); |
1125 | ieee80211_rx_bss_remove(sdata, ifmgd->bssid, | 1130 | ieee80211_rx_bss_remove(sdata, ifmgd->bssid, |
1126 | sdata->local->hw.conf.channel->center_freq, | 1131 | sdata->local->hw.conf.channel->center_freq, |
@@ -1141,6 +1146,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata) | |||
1141 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " | 1146 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " |
1142 | "mixed-cell disabled - abort association\n", sdata->dev->name); | 1147 | "mixed-cell disabled - abort association\n", sdata->dev->name); |
1143 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 1148 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
1149 | ieee80211_recalc_idle(local); | ||
1144 | return; | 1150 | return; |
1145 | } | 1151 | } |
1146 | 1152 | ||
@@ -1279,6 +1285,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata) | |||
1279 | if (ifmgd->flags & IEEE80211_STA_EXT_SME) { | 1285 | if (ifmgd->flags & IEEE80211_STA_EXT_SME) { |
1280 | /* Wait for SME to request association */ | 1286 | /* Wait for SME to request association */ |
1281 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 1287 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
1288 | ieee80211_recalc_idle(sdata->local); | ||
1282 | } else | 1289 | } else |
1283 | ieee80211_associate(sdata); | 1290 | ieee80211_associate(sdata); |
1284 | } | 1291 | } |
@@ -1515,6 +1522,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1515 | if (ifmgd->flags & IEEE80211_STA_EXT_SME) { | 1522 | if (ifmgd->flags & IEEE80211_STA_EXT_SME) { |
1516 | /* Wait for SME to decide what to do next */ | 1523 | /* Wait for SME to decide what to do next */ |
1517 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 1524 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
1525 | ieee80211_recalc_idle(local); | ||
1518 | } | 1526 | } |
1519 | return; | 1527 | return; |
1520 | } | 1528 | } |
@@ -2083,6 +2091,7 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata) | |||
2083 | } else { | 2091 | } else { |
2084 | ifmgd->assoc_scan_tries = 0; | 2092 | ifmgd->assoc_scan_tries = 0; |
2085 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; | 2093 | ifmgd->state = IEEE80211_STA_MLME_DISABLED; |
2094 | ieee80211_recalc_idle(local); | ||
2086 | } | 2095 | } |
2087 | } | 2096 | } |
2088 | return -1; | 2097 | return -1; |
@@ -2126,6 +2135,8 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2126 | } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request)) | 2135 | } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request)) |
2127 | return; | 2136 | return; |
2128 | 2137 | ||
2138 | ieee80211_recalc_idle(local); | ||
2139 | |||
2129 | switch (ifmgd->state) { | 2140 | switch (ifmgd->state) { |
2130 | case IEEE80211_STA_MLME_DISABLED: | 2141 | case IEEE80211_STA_MLME_DISABLED: |
2131 | break; | 2142 | break; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 127bd54e0e38..c99ef8d04d3d 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -302,17 +302,9 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
302 | /* we only have to protect scan_req and hw/sw scan */ | 302 | /* we only have to protect scan_req and hw/sw scan */ |
303 | mutex_unlock(&local->scan_mtx); | 303 | mutex_unlock(&local->scan_mtx); |
304 | 304 | ||
305 | if (was_hw_scan) { | ||
306 | /* | ||
307 | * Somebody might have requested channel change during scan | ||
308 | * that we won't have acted upon, try now. ieee80211_hw_config | ||
309 | * will set the flag based on actual changes. | ||
310 | */ | ||
311 | ieee80211_hw_config(local, 0); | ||
312 | goto done; | ||
313 | } | ||
314 | |||
315 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 305 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
306 | if (was_hw_scan) | ||
307 | goto done; | ||
316 | 308 | ||
317 | netif_tx_lock_bh(local->mdev); | 309 | netif_tx_lock_bh(local->mdev); |
318 | netif_addr_lock(local->mdev); | 310 | netif_addr_lock(local->mdev); |
@@ -351,6 +343,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
351 | mutex_unlock(&local->iflist_mtx); | 343 | mutex_unlock(&local->iflist_mtx); |
352 | 344 | ||
353 | done: | 345 | done: |
346 | ieee80211_recalc_idle(local); | ||
354 | ieee80211_mlme_notify_scan_completed(local); | 347 | ieee80211_mlme_notify_scan_completed(local); |
355 | ieee80211_ibss_notify_scan_completed(local); | 348 | ieee80211_ibss_notify_scan_completed(local); |
356 | ieee80211_mesh_notify_scan_completed(local); | 349 | ieee80211_mesh_notify_scan_completed(local); |
@@ -471,6 +464,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
471 | * dependency, so that the scan completed calls | 464 | * dependency, so that the scan completed calls |
472 | * have more locking freedom. | 465 | * have more locking freedom. |
473 | */ | 466 | */ |
467 | |||
468 | ieee80211_recalc_idle(local); | ||
474 | mutex_unlock(&local->scan_mtx); | 469 | mutex_unlock(&local->scan_mtx); |
475 | 470 | ||
476 | if (local->ops->hw_scan) | 471 | if (local->ops->hw_scan) |
@@ -487,6 +482,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
487 | } else | 482 | } else |
488 | local->sw_scanning = false; | 483 | local->sw_scanning = false; |
489 | 484 | ||
485 | ieee80211_recalc_idle(local); | ||
486 | |||
490 | local->scan_req = NULL; | 487 | local->scan_req = NULL; |
491 | local->scan_sdata = NULL; | 488 | local->scan_sdata = NULL; |
492 | } | 489 | } |