aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/main.c31
-rw-r--r--net/mac80211/mlme.c36
-rw-r--r--net/mac80211/wext.c2
5 files changed, 63 insertions, 15 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ff40dd7b523a..b1d18d967d8c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -750,6 +750,7 @@ struct ieee80211_local {
750 struct work_struct dynamic_ps_enable_work; 750 struct work_struct dynamic_ps_enable_work;
751 struct work_struct dynamic_ps_disable_work; 751 struct work_struct dynamic_ps_disable_work;
752 struct timer_list dynamic_ps_timer; 752 struct timer_list dynamic_ps_timer;
753 struct notifier_block network_latency_notifier;
753 754
754 int user_power_level; /* in dBm */ 755 int user_power_level; /* in dBm */
755 int power_constr_level; /* in dBm */ 756 int power_constr_level; /* in dBm */
@@ -938,7 +939,9 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
938int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); 939int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
939void ieee80211_send_pspoll(struct ieee80211_local *local, 940void ieee80211_send_pspoll(struct ieee80211_local *local,
940 struct ieee80211_sub_if_data *sdata); 941 struct ieee80211_sub_if_data *sdata);
941void ieee80211_recalc_ps(struct ieee80211_local *local); 942void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
943int ieee80211_max_network_latency(struct notifier_block *nb,
944 unsigned long data, void *dummy);
942 945
943/* IBSS code */ 946/* IBSS code */
944int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata); 947int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6240f76e2a43..5d60deb219d3 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -317,7 +317,7 @@ static int ieee80211_open(struct net_device *dev)
317 ieee80211_set_wmm_default(sdata); 317 ieee80211_set_wmm_default(sdata);
318 } 318 }
319 319
320 ieee80211_recalc_ps(local); 320 ieee80211_recalc_ps(local, -1);
321 321
322 /* 322 /*
323 * ieee80211_sta_work is disabled while network interface 323 * ieee80211_sta_work is disabled while network interface
@@ -574,7 +574,7 @@ static int ieee80211_stop(struct net_device *dev)
574 hw_reconf_flags = 0; 574 hw_reconf_flags = 0;
575 } 575 }
576 576
577 ieee80211_recalc_ps(local); 577 ieee80211_recalc_ps(local, -1);
578 578
579 /* do after stop to avoid reconfiguring when we stop anyway */ 579 /* do after stop to avoid reconfiguring when we stop anyway */
580 if (hw_reconf_flags) 580 if (hw_reconf_flags)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 80c0e28bf549..049ce8639806 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -21,6 +21,7 @@
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
23#include <linux/bitmap.h> 23#include <linux/bitmap.h>
24#include <linux/pm_qos_params.h>
24#include <net/net_namespace.h> 25#include <net/net_namespace.h>
25#include <net/cfg80211.h> 26#include <net/cfg80211.h>
26 27
@@ -1038,25 +1039,38 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1038 } 1039 }
1039 } 1040 }
1040 1041
1042 local->network_latency_notifier.notifier_call =
1043 ieee80211_max_network_latency;
1044 result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
1045 &local->network_latency_notifier);
1046
1047 if (result) {
1048 rtnl_lock();
1049 goto fail_pm_qos;
1050 }
1051
1041 return 0; 1052 return 0;
1042 1053
1043fail_wep: 1054 fail_pm_qos:
1055 ieee80211_led_exit(local);
1056 ieee80211_remove_interfaces(local);
1057 fail_wep:
1044 rate_control_deinitialize(local); 1058 rate_control_deinitialize(local);
1045fail_rate: 1059 fail_rate:
1046 unregister_netdevice(local->mdev); 1060 unregister_netdevice(local->mdev);
1047 local->mdev = NULL; 1061 local->mdev = NULL;
1048fail_dev: 1062 fail_dev:
1049 rtnl_unlock(); 1063 rtnl_unlock();
1050 sta_info_stop(local); 1064 sta_info_stop(local);
1051fail_sta_info: 1065 fail_sta_info:
1052 debugfs_hw_del(local); 1066 debugfs_hw_del(local);
1053 destroy_workqueue(local->hw.workqueue); 1067 destroy_workqueue(local->hw.workqueue);
1054fail_workqueue: 1068 fail_workqueue:
1055 if (local->mdev) 1069 if (local->mdev)
1056 free_netdev(local->mdev); 1070 free_netdev(local->mdev);
1057fail_mdev_alloc: 1071 fail_mdev_alloc:
1058 wiphy_unregister(local->hw.wiphy); 1072 wiphy_unregister(local->hw.wiphy);
1059fail_wiphy_register: 1073 fail_wiphy_register:
1060 kfree(local->int_scan_req.channels); 1074 kfree(local->int_scan_req.channels);
1061 return result; 1075 return result;
1062} 1076}
@@ -1069,6 +1083,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1069 tasklet_kill(&local->tx_pending_tasklet); 1083 tasklet_kill(&local->tx_pending_tasklet);
1070 tasklet_kill(&local->tasklet); 1084 tasklet_kill(&local->tasklet);
1071 1085
1086 pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
1087 &local->network_latency_notifier);
1088
1072 rtnl_lock(); 1089 rtnl_lock();
1073 1090
1074 /* 1091 /*
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}
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 81f63e57027f..1c4664b8b1a0 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -789,7 +789,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
789 ieee80211_hw_config(local, 789 ieee80211_hw_config(local,
790 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT); 790 IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
791 791
792 ieee80211_recalc_ps(local); 792 ieee80211_recalc_ps(local, -1);
793 793
794 return 0; 794 return 0;
795} 795}