diff options
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 15 | ||||
-rw-r--r-- | net/mac80211/wext.c | 32 |
3 files changed, 40 insertions, 8 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a7dabaecfc72..18b91601770a 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -688,6 +688,7 @@ struct ieee80211_local { | |||
688 | */ | 688 | */ |
689 | int wifi_wme_noack_test; | 689 | int wifi_wme_noack_test; |
690 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 690 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
691 | bool powersave; | ||
691 | 692 | ||
692 | #ifdef CONFIG_MAC80211_DEBUGFS | 693 | #ifdef CONFIG_MAC80211_DEBUGFS |
693 | struct local_debugfsdentries { | 694 | struct local_debugfsdentries { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1374b8c750ab..dac8bd37dcf5 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -744,6 +744,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
744 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; | 744 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; |
745 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); | 745 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
746 | 746 | ||
747 | if (local->powersave) { | ||
748 | local->hw.conf.flags |= IEEE80211_CONF_PS; | ||
749 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
750 | } | ||
751 | |||
747 | netif_tx_start_all_queues(sdata->dev); | 752 | netif_tx_start_all_queues(sdata->dev); |
748 | netif_carrier_on(sdata->dev); | 753 | netif_carrier_on(sdata->dev); |
749 | 754 | ||
@@ -812,7 +817,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
812 | { | 817 | { |
813 | struct ieee80211_local *local = sdata->local; | 818 | struct ieee80211_local *local = sdata->local; |
814 | struct sta_info *sta; | 819 | struct sta_info *sta; |
815 | u32 changed = 0; | 820 | u32 changed = 0, config_changed = 0; |
816 | 821 | ||
817 | rcu_read_lock(); | 822 | rcu_read_lock(); |
818 | 823 | ||
@@ -859,8 +864,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
859 | 864 | ||
860 | local->hw.conf.ht.enabled = false; | 865 | local->hw.conf.ht.enabled = false; |
861 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 866 | local->oper_channel_type = NL80211_CHAN_NO_HT; |
862 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); | 867 | config_changed |= IEEE80211_CONF_CHANGE_HT; |
868 | |||
869 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
870 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
871 | config_changed |= IEEE80211_CONF_CHANGE_PS; | ||
872 | } | ||
863 | 873 | ||
874 | ieee80211_hw_config(local, config_changed); | ||
864 | ieee80211_bss_info_change_notify(sdata, changed); | 875 | ieee80211_bss_info_change_notify(sdata, changed); |
865 | 876 | ||
866 | rcu_read_lock(); | 877 | rcu_read_lock(); |
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 | |||
860 | set: | ||
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 | ||
854 | static int ieee80211_ioctl_giwpower(struct net_device *dev, | 875 | static 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 | } |