summaryrefslogtreecommitdiff
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
authorVivek Natarajan <vnatarajan@atheros.com>2010-03-11 13:10:03 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-04-01 15:58:52 -0700
commit10275a53c5ed0ddc826449d6df052bb41a1fcbce (patch)
tree1ef854bd44e2b3c325ae69b162d728a96ccf175b /net/mac80211/main.c
parent525ad995580f1d760cbf4a3b42df1cba3df6821b (diff)
mac80211: Retry null data frame for power save
commit 375177bf35efc08e1bd37bbda4cc0c8cc4db8500 upstream. Even if the null data frame is not acked by the AP, mac80211 goes into power save. This might lead to loss of frames from the AP. Prevent this by restarting dynamic_ps_timer when ack is not received for null data frames. Cc: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 797f53942e5f..19fbd25a705b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -441,6 +441,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
rcu_read_lock();
sband = local->hw.wiphy->bands[info->band];
+ fc = hdr->frame_control;
sta = sta_info_get(local, hdr->addr1);
@@ -522,6 +523,20 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
local->dot11FailedCount++;
}
+ if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc) &&
+ (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
+ !(info->flags & IEEE80211_TX_CTL_INJECTED) &&
+ local->ps_sdata && !(local->scanning)) {
+ if (info->flags & IEEE80211_TX_STAT_ACK) {
+ local->ps_sdata->u.mgd.flags |=
+ IEEE80211_STA_NULLFUNC_ACKED;
+ ieee80211_queue_work(&local->hw,
+ &local->dynamic_ps_enable_work);
+ } else
+ mod_timer(&local->dynamic_ps_timer, jiffies +
+ msecs_to_jiffies(10));
+ }
+
/* this was a transmitted frame, but now we want to reuse it */
skb_orphan(skb);