aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/wext.c
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2008-12-18 16:35:13 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-12-19 15:23:57 -0500
commite0cb686ff879dc9ac045ad7258ec687088d4e450 (patch)
tree4792dc94d6a36be8367987b88b922157acf59808 /net/mac80211/wext.c
parentd10d0e5707fb7b8afa7e68a14d69e752604ee294 (diff)
mac80211: enable IEEE80211_CONF_PS only when associated
Also disable power save when disassociated. It makes no sense to have power save enabled while disassociated. iwlwifi seems to have this check in the driver, but it's better to do this in mac80211 instead. Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Acked-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.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 15428048d01a..f6640d047157 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -830,25 +830,46 @@ 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;
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 goto set;
839 } 845 }
840 846
841 switch (wrq->flags & IW_POWER_MODE) { 847 switch (wrq->flags & IW_POWER_MODE) {
842 case IW_POWER_ON: /* If not specified */ 848 case IW_POWER_ON: /* If not specified */
843 case IW_POWER_MODE: /* If set all mask */ 849 case IW_POWER_MODE: /* If set all mask */
844 case IW_POWER_ALL_R: /* If explicitely state all */ 850 case IW_POWER_ALL_R: /* If explicitely state all */
845 conf->flags |= IEEE80211_CONF_PS; 851 ps = true;
846 break; 852 break;
847 default: /* Otherwise we don't support it */ 853 default: /* Otherwise we don't support it */
848 return -EINVAL; 854 return -EINVAL;
849 } 855 }
850 856
851 return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 857 if (ps == local->powersave)
858 return ret;
859
860set:
861 local->powersave = ps;
862
863 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
864 if (local->powersave)
865 conf->flags |= IEEE80211_CONF_PS;
866 else
867 conf->flags &= ~IEEE80211_CONF_PS;
868
869 ret = ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
870 }
871
872 return ret;
852} 873}
853 874
854static int ieee80211_ioctl_giwpower(struct net_device *dev, 875static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -857,9 +878,8 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
857 char *extra) 878 char *extra)
858{ 879{
859 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 880 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
860 struct ieee80211_conf *conf = &local->hw.conf;
861 881
862 wrqu->power.disabled = !(conf->flags & IEEE80211_CONF_PS); 882 wrqu->power.disabled = !local->powersave;
863 883
864 return 0; 884 return 0;
865} 885}