aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-04-16 07:17:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:57:16 -0400
commit10f644a47b76d3e61b98f2d02ce9690b94c51ee5 (patch)
treefc344d0f888ea0b97608cd53eec1d2dc17672087 /net/mac80211/mlme.c
parent965bedadc01d34027455d5d5b67063ef0209c955 (diff)
mac80211: disable powersave if pm_qos asks for low latency
When an application asks for a latency lower than the beacon interval there's nothing we can do -- we need to stay awake and not have the AP buffer frames for us. Add code to automatically calculate this constraint in mac80211 so drivers need not concern themselves with it. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 06d9a1d23252..c39a214e7ad0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -17,6 +17,7 @@
17#include <linux/if_arp.h> 17#include <linux/if_arp.h>
18#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/pm_qos_params.h>
20#include <net/mac80211.h> 21#include <net/mac80211.h>
21#include <asm/unaligned.h> 22#include <asm/unaligned.h>
22 23
@@ -515,7 +516,7 @@ static void ieee80211_change_ps(struct ieee80211_local *local)
515} 516}
516 517
517/* need to hold RTNL or interface lock */ 518/* need to hold RTNL or interface lock */
518void ieee80211_recalc_ps(struct ieee80211_local *local) 519void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
519{ 520{
520 struct ieee80211_sub_if_data *sdata, *found = NULL; 521 struct ieee80211_sub_if_data *sdata, *found = NULL;
521 int count = 0; 522 int count = 0;
@@ -534,10 +535,22 @@ void ieee80211_recalc_ps(struct ieee80211_local *local)
534 count++; 535 count++;
535 } 536 }
536 537
537 if (count == 1 && found->u.mgd.powersave) 538 if (count == 1 && found->u.mgd.powersave) {
538 local->ps_sdata = found; 539 s32 beaconint_us;
539 else 540
541 if (latency < 0)
542 latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
543
544 beaconint_us = ieee80211_tu_to_usec(
545 found->vif.bss_conf.beacon_int);
546
547 if (beaconint_us > latency)
548 local->ps_sdata = NULL;
549 else
550 local->ps_sdata = found;
551 } else {
540 local->ps_sdata = NULL; 552 local->ps_sdata = NULL;
553 }
541 554
542 ieee80211_change_ps(local); 555 ieee80211_change_ps(local);
543} 556}
@@ -2324,3 +2337,18 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2324 ieee80211_restart_sta_timer(sdata); 2337 ieee80211_restart_sta_timer(sdata);
2325 rcu_read_unlock(); 2338 rcu_read_unlock();
2326} 2339}
2340
2341int ieee80211_max_network_latency(struct notifier_block *nb,
2342 unsigned long data, void *dummy)
2343{
2344 s32 latency_usec = (s32) data;
2345 struct ieee80211_local *local =
2346 container_of(nb, struct ieee80211_local,
2347 network_latency_notifier);
2348
2349 mutex_lock(&local->iflist_mtx);
2350 ieee80211_recalc_ps(local, latency_usec);
2351 mutex_unlock(&local->iflist_mtx);
2352
2353 return 0;
2354}