aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/net/mac80211.h12
-rw-r--r--net/mac80211/sta_info.c13
-rw-r--r--net/mac80211/sta_info.h3
3 files changed, 27 insertions, 1 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 361bc5d85b1a..162363b6cb62 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2227,6 +2227,18 @@ static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
2227#define IEEE80211_TX_STATUS_HEADROOM 13 2227#define IEEE80211_TX_STATUS_HEADROOM 13
2228 2228
2229/** 2229/**
2230 * ieee80211_sta_set_tim - set the TIM bit for a sleeping station
2231 *
2232 * If a driver buffers frames for a powersave station instead of passing
2233 * them back to mac80211 for retransmission, the station needs to be told
2234 * to wake up using the TIM bitmap in the beacon.
2235 *
2236 * This function sets the station's TIM bit - it will be cleared when the
2237 * station wakes up.
2238 */
2239void ieee80211_sta_set_tim(struct ieee80211_sta *sta);
2240
2241/**
2230 * ieee80211_tx_status - transmit status callback 2242 * ieee80211_tx_status - transmit status callback
2231 * 2243 *
2232 * Call this function for all transmitted frames after they have been 2244 * Call this function for all transmitted frames after they have been
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