aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c78
1 files changed, 76 insertions, 2 deletions
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
900static 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
915static 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
929u32 __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
960void 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}