aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-04-16 07:17:24 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:57:15 -0400
commit965bedadc01d34027455d5d5b67063ef0209c955 (patch)
tree012bb04559011498e0bdb5db1ba6ffad0ec8b89a /net/mac80211/wext.c
parentdc7d243d75b906cc964c12caa3b2eebe953a69be (diff)
mac80211: improve powersave implementation
When you have multiple virtual interfaces the current implementation requires setting them up properly from userspace, which is undesirable when we want to default to power save mode. Keep track of powersave requested from userspace per managed mode interface, and only enable powersave globally when exactly one managed mode interface is active and has powersave turned on. Second, only start the dynPS timer when PS is turned on, and properly turn it off when PS is turned off. Third, fix the scan_sdata abuse in the dynps code. Finally, also reorder the code and refactor the code that enables PS or the dynps timer instead of having it copied in two places. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c43
1 files changed, 10 insertions, 33 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index a52fb3a4a455..81f63e57027f 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -747,7 +747,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
747 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 747 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
748 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 748 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
749 struct ieee80211_conf *conf = &local->hw.conf; 749 struct ieee80211_conf *conf = &local->hw.conf;
750 int ret = 0, timeout = 0; 750 int timeout = 0;
751 bool ps; 751 bool ps;
752 752
753 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) 753 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -779,42 +779,19 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
779 timeout = wrq->value / 1000; 779 timeout = wrq->value / 1000;
780 780
781 set: 781 set:
782 if (ps == local->powersave && timeout == conf->dynamic_ps_timeout) 782 if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
783 return ret; 783 return 0;
784 784
785 local->powersave = ps; 785 sdata->u.mgd.powersave = ps;
786 conf->dynamic_ps_timeout = timeout; 786 conf->dynamic_ps_timeout = timeout;
787 787
788 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) 788 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
789 ret = ieee80211_hw_config(local, 789 ieee80211_hw_config(local,
790 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); 790 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
791
792 if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
793 return ret;
794 791
795 if (conf->dynamic_ps_timeout > 0 && 792 ieee80211_recalc_ps(local);
796 !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
797 mod_timer(&local->dynamic_ps_timer, jiffies +
798 msecs_to_jiffies(conf->dynamic_ps_timeout));
799 } else {
800 if (local->powersave) {
801 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
802 ieee80211_send_nullfunc(local, sdata, 1);
803 conf->flags |= IEEE80211_CONF_PS;
804 ret = ieee80211_hw_config(local,
805 IEEE80211_CONF_CHANGE_PS);
806 } else {
807 conf->flags &= ~IEEE80211_CONF_PS;
808 ret = ieee80211_hw_config(local,
809 IEEE80211_CONF_CHANGE_PS);
810 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
811 ieee80211_send_nullfunc(local, sdata, 0);
812 del_timer_sync(&local->dynamic_ps_timer);
813 cancel_work_sync(&local->dynamic_ps_enable_work);
814 }
815 }
816 793
817 return ret; 794 return 0;
818} 795}
819 796
820static int ieee80211_ioctl_giwpower(struct net_device *dev, 797static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -822,9 +799,9 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
822 union iwreq_data *wrqu, 799 union iwreq_data *wrqu,
823 char *extra) 800 char *extra)
824{ 801{
825 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 802 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
826 803
827 wrqu->power.disabled = !local->powersave; 804 wrqu->power.disabled = !sdata->u.mgd.powersave;
828 805
829 return 0; 806 return 0;
830} 807}