aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Young <a.young.jason@gmail.com>2011-03-10 19:43:19 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-03-11 14:15:37 -0500
commit808118cb41dfe12a1ac0e35515ac4d91b170bdf9 (patch)
tree98939cd9a6e66bcd70597ba33fdf071914e109ac
parentd89dba7a275f40757d27ba16c8bc6aa424656bbe (diff)
mac80211: do not enable ps if 802.1x controlled port is unblocked
If dynamic_ps is disabled, enabling power save before the 4-way handshake completes may delay the station from being authorized to send/receive traffic, i.e. increase roaming times. It also may result in a failed 4-way handshake depending on the AP's timing requirements and beacon interval, and the station's listen interval. To fix this, prevent power save from being enabled while the station isn't authorized and recalculate power save whenever the station's authorized state changes. Signed-off-by: Jason Young <a.young.jason@gmail.com> Acked-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/mlme.c37
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
616static 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 */
617void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) 648void 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