aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorVivek Natarajan <vnatarajan@atheros.com>2010-02-09 04:20:28 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-02-09 14:10:05 -0500
commit375177bf35efc08e1bd37bbda4cc0c8cc4db8500 (patch)
tree88774b1a46072fd3b0418b36d39d447b78fbfc51 /net/mac80211/mlme.c
parente15276a4b220c54db665cf46a92bd9ceb9aeb052 (diff)
mac80211: Retry null data frame for power save.
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>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7a7921476582..ee9443dc20ff 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -434,8 +434,11 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
434 } else { 434 } else {
435 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 435 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
436 ieee80211_send_nullfunc(local, sdata, 1); 436 ieee80211_send_nullfunc(local, sdata, 1);
437 conf->flags |= IEEE80211_CONF_PS; 437
438 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 438 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
439 conf->flags |= IEEE80211_CONF_PS;
440 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
441 }
439 } 442 }
440} 443}
441 444
@@ -541,6 +544,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
541 container_of(work, struct ieee80211_local, 544 container_of(work, struct ieee80211_local,
542 dynamic_ps_enable_work); 545 dynamic_ps_enable_work);
543 struct ieee80211_sub_if_data *sdata = local->ps_sdata; 546 struct ieee80211_sub_if_data *sdata = local->ps_sdata;
547 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
544 548
545 /* can only happen when PS was just disabled anyway */ 549 /* can only happen when PS was just disabled anyway */
546 if (!sdata) 550 if (!sdata)
@@ -549,11 +553,16 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
549 if (local->hw.conf.flags & IEEE80211_CONF_PS) 553 if (local->hw.conf.flags & IEEE80211_CONF_PS)
550 return; 554 return;
551 555
552 if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) 556 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
557 (!(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)))
553 ieee80211_send_nullfunc(local, sdata, 1); 558 ieee80211_send_nullfunc(local, sdata, 1);
554 559
555 local->hw.conf.flags |= IEEE80211_CONF_PS; 560 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) ||
556 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 561 (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
562 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
563 local->hw.conf.flags |= IEEE80211_CONF_PS;
564 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
565 }
557} 566}
558 567
559void ieee80211_dynamic_ps_timer(unsigned long data) 568void ieee80211_dynamic_ps_timer(unsigned long data)
@@ -1892,6 +1901,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1892 return -ENOMEM; 1901 return -ENOMEM;
1893 1902
1894 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; 1903 ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N;
1904 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
1895 1905
1896 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) 1906 for (i = 0; i < req->crypto.n_ciphers_pairwise; i++)
1897 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || 1907 if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||