diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 5 | ||||
-rw-r--r-- | net/mac80211/iface.c | 4 | ||||
-rw-r--r-- | net/mac80211/main.c | 31 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 36 | ||||
-rw-r--r-- | net/mac80211/wext.c | 2 |
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 | |||
938 | int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); | 939 | int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); |
939 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 940 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
940 | struct ieee80211_sub_if_data *sdata); | 941 | struct ieee80211_sub_if_data *sdata); |
941 | void ieee80211_recalc_ps(struct ieee80211_local *local); | 942 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); |
943 | int ieee80211_max_network_latency(struct notifier_block *nb, | ||
944 | unsigned long data, void *dummy); | ||
942 | 945 | ||
943 | /* IBSS code */ | 946 | /* IBSS code */ |
944 | int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata); | 947 | int 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 | ||
1043 | fail_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); |
1045 | fail_rate: | 1059 | fail_rate: |
1046 | unregister_netdevice(local->mdev); | 1060 | unregister_netdevice(local->mdev); |
1047 | local->mdev = NULL; | 1061 | local->mdev = NULL; |
1048 | fail_dev: | 1062 | fail_dev: |
1049 | rtnl_unlock(); | 1063 | rtnl_unlock(); |
1050 | sta_info_stop(local); | 1064 | sta_info_stop(local); |
1051 | fail_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); |
1054 | fail_workqueue: | 1068 | fail_workqueue: |
1055 | if (local->mdev) | 1069 | if (local->mdev) |
1056 | free_netdev(local->mdev); | 1070 | free_netdev(local->mdev); |
1057 | fail_mdev_alloc: | 1071 | fail_mdev_alloc: |
1058 | wiphy_unregister(local->hw.wiphy); | 1072 | wiphy_unregister(local->hw.wiphy); |
1059 | fail_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 */ |
518 | void ieee80211_recalc_ps(struct ieee80211_local *local) | 519 | void 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 | |||
2341 | int 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 | } |