aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-04-17 11:45:00 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-19 15:38:05 -0400
commitdcf55fb5d43bd82e1e3bf94f065cfe8f75a4bc5a (patch)
tree34b8bb4d1c1dcb45d0e5e134fd6373b8fcc1e689 /net/mac80211
parentcea3235cf578b5e952f5a0cec9bc6c2e862eb697 (diff)
mac80211: add a function for setting the TIM bit for a specific station
This allows a driver to buffer frames for a PS station and tell mac80211 to wake it up even though mac80211 does not have any buffered frames for it. This is necessary for properly handling aggregation related buffering, in ath9k, because the driver needs to keep its frames in order to keep track of the Block-ACK window. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/sta_info.c13
-rw-r--r--net/mac80211/sta_info.h3
2 files changed, 15 insertions, 1 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 8a9068ac0673..7c5c6da01bea 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -612,7 +612,8 @@ static bool sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
612#endif 612#endif
613 dev_kfree_skb(skb); 613 dev_kfree_skb(skb);
614 614
615 if (skb_queue_empty(&sta->ps_tx_buf)) 615 if (skb_queue_empty(&sta->ps_tx_buf) &&
616 !test_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF))
616 sta_info_clear_tim_bit(sta); 617 sta_info_clear_tim_bit(sta);
617 } 618 }
618 619
@@ -896,6 +897,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
896 struct ieee80211_local *local = sdata->local; 897 struct ieee80211_local *local = sdata->local;
897 int sent, buffered; 898 int sent, buffered;
898 899
900 clear_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
899 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) 901 if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS))
900 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta); 902 drv_sta_notify(local, sdata, STA_NOTIFY_AWAKE, &sta->sta);
901 903
@@ -988,3 +990,12 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
988 ieee80211_queue_work(hw, &sta->drv_unblock_wk); 990 ieee80211_queue_work(hw, &sta->drv_unblock_wk);
989} 991}
990EXPORT_SYMBOL(ieee80211_sta_block_awake); 992EXPORT_SYMBOL(ieee80211_sta_block_awake);
993
994void ieee80211_sta_set_tim(struct ieee80211_sta *pubsta)
995{
996 struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
997
998 set_sta_flags(sta, WLAN_STA_PS_DRIVER_BUF);
999 sta_info_set_tim_bit(sta);
1000}
1001EXPORT_SYMBOL(ieee80211_sta_set_tim);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 984a03db3553..af1a7f8c8675 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -43,6 +43,8 @@
43 * be in the queues 43 * be in the queues
44 * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping 44 * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping
45 * station in power-save mode, reply when the driver unblocks. 45 * station in power-save mode, reply when the driver unblocks.
46 * @WLAN_STA_PS_DRIVER_BUF: Station has frames pending in driver internal
47 * buffers. Automatically cleared on station wake-up.
46 */ 48 */
47enum ieee80211_sta_info_flags { 49enum ieee80211_sta_info_flags {
48 WLAN_STA_AUTH = 1<<0, 50 WLAN_STA_AUTH = 1<<0,
@@ -58,6 +60,7 @@ enum ieee80211_sta_info_flags {
58 WLAN_STA_BLOCK_BA = 1<<11, 60 WLAN_STA_BLOCK_BA = 1<<11,
59 WLAN_STA_PS_DRIVER = 1<<12, 61 WLAN_STA_PS_DRIVER = 1<<12,
60 WLAN_STA_PSPOLL = 1<<13, 62 WLAN_STA_PSPOLL = 1<<13,
63 WLAN_STA_PS_DRIVER_BUF = 1<<14,
61}; 64};
62 65
63#define STA_TID_NUM 16 66#define STA_TID_NUM 16