aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r--net/mac80211/wext.c46
1 files changed, 38 insertions, 8 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 15428048d01a..7162d5816f39 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -830,25 +830,56 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
830 struct iw_param *wrq, 830 struct iw_param *wrq,
831 char *extra) 831 char *extra)
832{ 832{
833 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
833 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 834 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
834 struct ieee80211_conf *conf = &local->hw.conf; 835 struct ieee80211_conf *conf = &local->hw.conf;
836 int ret = 0, timeout = 0;
837 bool ps;
838
839 if (sdata->vif.type != NL80211_IFTYPE_STATION)
840 return -EINVAL;
835 841
836 if (wrq->disabled) { 842 if (wrq->disabled) {
837 conf->flags &= ~IEEE80211_CONF_PS; 843 ps = false;
838 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 844 timeout = 0;
845 goto set;
839 } 846 }
840 847
841 switch (wrq->flags & IW_POWER_MODE) { 848 switch (wrq->flags & IW_POWER_MODE) {
842 case IW_POWER_ON: /* If not specified */ 849 case IW_POWER_ON: /* If not specified */
843 case IW_POWER_MODE: /* If set all mask */ 850 case IW_POWER_MODE: /* If set all mask */
844 case IW_POWER_ALL_R: /* If explicitely state all */ 851 case IW_POWER_ALL_R: /* If explicitely state all */
845 conf->flags |= IEEE80211_CONF_PS; 852 ps = true;
853 break;
854 default: /* Otherwise we ignore */
846 break; 855 break;
847 default: /* Otherwise we don't support it */
848 return -EINVAL;
849 } 856 }
850 857
851 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 858 if (wrq->flags & IW_POWER_TIMEOUT)
859 timeout = wrq->value / 1000;
860
861set:
862 if (ps == local->powersave && timeout == local->dynamic_ps_timeout)
863 return ret;
864
865 local->powersave = ps;
866 local->dynamic_ps_timeout = timeout;
867
868 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
869 if (!(local->hw.flags & IEEE80211_HW_NO_STACK_DYNAMIC_PS) &&
870 local->dynamic_ps_timeout > 0)
871 mod_timer(&local->dynamic_ps_timer, jiffies +
872 msecs_to_jiffies(local->dynamic_ps_timeout));
873 else {
874 if (local->powersave)
875 conf->flags |= IEEE80211_CONF_PS;
876 else
877 conf->flags &= ~IEEE80211_CONF_PS;
878 }
879 ret = ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
880 }
881
882 return ret;
852} 883}
853 884
854static int ieee80211_ioctl_giwpower(struct net_device *dev, 885static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -857,9 +888,8 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
857 char *extra) 888 char *extra)
858{ 889{
859 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 890 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
860 struct ieee80211_conf *conf = &local->hw.conf;
861 891
862 wrqu->power.disabled = !(conf->flags & IEEE80211_CONF_PS); 892 wrqu->power.disabled = !local->powersave;
863 893
864 return 0; 894 return 0;
865} 895}