diff options
author | Vivek Natarajan <vnatarajan@atheros.com> | 2011-04-06 11:41:10 +0530 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-12 16:57:34 -0400 |
commit | e8306f989483e4b97a8b37dd268de6c8c6f35e75 (patch) | |
tree | 452bb50b9e7dbfc9a6fa68f8da388a17c2f76875 /net/mac80211/mlme.c | |
parent | 6fc3ba999994b675c4e6af77ac4e1a6bfd8e6128 (diff) |
mac80211: Check for queued frames before entering power save.
In a highly noisy environment, the tx rate of the driver drops and
the application slows down since it has not yet received ACKs for
the frames already queued in the hardware. Since this ACK may take
more than 100ms, stopping the dev queues for entering PS at this
stage breaks applications, WMM test cases in my testing.
If there are frames already pending in the tx queue, postponing the
PS logic helps to avoid redundant queue stops. When power save is
enabled by default and in a noisy environment, this API certainly
helps in improving the average throughput.
Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 865fed4cc18b..a41f234bd486 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -761,15 +761,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED))) { netif_tx_stop_all_queues(sdata->dev); - /* - * Flush all the frames queued in the driver before - * going to power save - */ - drv_flush(local, false); - ieee80211_send_nullfunc(local, sdata, 1); - /* Flush once again to get the tx status of nullfunc frame */ - drv_flush(local, false); + if (drv_tx_frames_pending(local)) + mod_timer(&local->dynamic_ps_timer, jiffies + + msecs_to_jiffies( + local->hw.conf.dynamic_ps_timeout)); + else { + ieee80211_send_nullfunc(local, sdata, 1); + /* Flush to get the tx status of nullfunc frame */ + drv_flush(local, false); + } } if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) && |