aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-06-26 05:06:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-06-27 15:09:42 -0400
commit77b7023afe93b5e3bdcf2c0faaa5e5caafb6ef44 (patch)
tree95816e9126dac6a5e0ebb999066bb4f781138b36 /net/mac80211/mlme.c
parenteef726994fc4ce2f9d0c880016bd104628ef44c9 (diff)
mac80211: dynamic PS - don't enter PS when TX frames are pending
Use the tx_frames_pending() driver callback to determine if Tx frames are pending for its internal queues. If so postpone the dynamic PS timeout to avoid interrupting Tx traffic. The commit e8306f989483e4b97a8b37dd268de6c8c6f35e75 enabled this behavior for drivers with IEEE80211_HW_PS_NULLFUNC_STACK. We enable this for all drivers supporting dynamic PS. This patch helps improve performance in noisy environments. Signed-off-by: Arik Nemtsov <arik@wizery.com> 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, 24 insertions, 12 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0f6052faeb45..b87420088c33 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -760,23 +760,34 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
760 if (local->hw.conf.flags & IEEE80211_CONF_PS) 760 if (local->hw.conf.flags & IEEE80211_CONF_PS)
761 return; 761 return;
762 762
763 /* 763 if (!local->disable_dynamic_ps &&
764 * transmission can be stopped by others which leads to 764 local->hw.conf.dynamic_ps_timeout > 0) {
765 * dynamic_ps_timer expiry. Postpond the ps timer if it 765 /* don't enter PS if TX frames are pending */
766 * is not the actual idle state. 766 if (drv_tx_frames_pending(local)) {
767 */
768 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
769 for (q = 0; q < local->hw.queues; q++) {
770 if (local->queue_stop_reasons[q]) {
771 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
772 flags);
773 mod_timer(&local->dynamic_ps_timer, jiffies + 767 mod_timer(&local->dynamic_ps_timer, jiffies +
774 msecs_to_jiffies( 768 msecs_to_jiffies(
775 local->hw.conf.dynamic_ps_timeout)); 769 local->hw.conf.dynamic_ps_timeout));
776 return; 770 return;
777 } 771 }
772
773 /*
774 * transmission can be stopped by others which leads to
775 * dynamic_ps_timer expiry. Postpone the ps timer if it
776 * is not the actual idle state.
777 */
778 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
779 for (q = 0; q < local->hw.queues; q++) {
780 if (local->queue_stop_reasons[q]) {
781 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
782 flags);
783 mod_timer(&local->dynamic_ps_timer, jiffies +
784 msecs_to_jiffies(
785 local->hw.conf.dynamic_ps_timeout));
786 return;
787 }
788 }
789 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
778 } 790 }
779 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
780 791
781 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 792 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
782 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { 793 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) {
@@ -801,7 +812,8 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
801 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 812 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
802 } 813 }
803 814
804 netif_tx_wake_all_queues(sdata->dev); 815 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
816 netif_tx_wake_all_queues(sdata->dev);
805} 817}
806 818
807void ieee80211_dynamic_ps_timer(unsigned long data) 819void ieee80211_dynamic_ps_timer(unsigned long data)