diff options
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 37 |
2 files changed, 36 insertions, 5 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7b701dcddb50..11866b42f1ed 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -834,6 +834,10 @@ static int ieee80211_change_station(struct wiphy *wiphy, | |||
834 | 834 | ||
835 | rcu_read_unlock(); | 835 | rcu_read_unlock(); |
836 | 836 | ||
837 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
838 | params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) | ||
839 | ieee80211_recalc_ps(local, -1); | ||
840 | |||
837 | return 0; | 841 | return 0; |
838 | } | 842 | } |
839 | 843 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index cc984bd861cf..64d92d5a7f40 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -613,6 +613,37 @@ static void ieee80211_change_ps(struct ieee80211_local *local) | |||
613 | } | 613 | } |
614 | } | 614 | } |
615 | 615 | ||
616 | static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | ||
617 | { | ||
618 | struct ieee80211_if_managed *mgd = &sdata->u.mgd; | ||
619 | struct sta_info *sta = NULL; | ||
620 | u32 sta_flags = 0; | ||
621 | |||
622 | if (!mgd->powersave) | ||
623 | return false; | ||
624 | |||
625 | if (!mgd->associated) | ||
626 | return false; | ||
627 | |||
628 | if (!mgd->associated->beacon_ies) | ||
629 | return false; | ||
630 | |||
631 | if (mgd->flags & (IEEE80211_STA_BEACON_POLL | | ||
632 | IEEE80211_STA_CONNECTION_POLL)) | ||
633 | return false; | ||
634 | |||
635 | rcu_read_lock(); | ||
636 | sta = sta_info_get(sdata, mgd->bssid); | ||
637 | if (sta) | ||
638 | sta_flags = get_sta_flags(sta); | ||
639 | rcu_read_unlock(); | ||
640 | |||
641 | if (!(sta_flags & WLAN_STA_AUTHORIZED)) | ||
642 | return false; | ||
643 | |||
644 | return true; | ||
645 | } | ||
646 | |||
616 | /* need to hold RTNL or interface lock */ | 647 | /* need to hold RTNL or interface lock */ |
617 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | 648 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) |
618 | { | 649 | { |
@@ -647,11 +678,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
647 | count++; | 678 | count++; |
648 | } | 679 | } |
649 | 680 | ||
650 | if (count == 1 && found->u.mgd.powersave && | 681 | if (count == 1 && ieee80211_powersave_allowed(found)) { |
651 | found->u.mgd.associated && | ||
652 | found->u.mgd.associated->beacon_ies && | ||
653 | !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL | | ||
654 | IEEE80211_STA_CONNECTION_POLL))) { | ||
655 | struct ieee80211_conf *conf = &local->hw.conf; | 682 | struct ieee80211_conf *conf = &local->hw.conf; |
656 | s32 beaconint_us; | 683 | s32 beaconint_us; |
657 | 684 | ||