diff options
Diffstat (limited to 'net/mac80211/wext.c')
-rw-r--r-- | net/mac80211/wext.c | 46 |
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 | |||
861 | set: | ||
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 | ||
854 | static int ieee80211_ioctl_giwpower(struct net_device *dev, | 885 | static 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 | } |