diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-04-17 17:28:09 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-19 15:38:06 -0400 |
commit | 5519541d5a5f19893546883547e2f0f2e5934df7 (patch) | |
tree | ae581edfed4ce3382b22076cb03174756e004830 /drivers/net/wireless/ath/ath9k/ath9k.h | |
parent | 8e22ad323fb5b7cefb572bd8730e3abef95cdf90 (diff) |
ath9k: fix powersave frame filtering/buffering in AP mode
This patch fixes a long standing issue of pending packets in the queue being
sent (and retransmitted many times) to sleeping stations.
This was made worse by aggregation through driver-internal retransmitting
of A-MDPU subframes.
Previously the hardware tx filter was cleared unconditionally for every
single packet - with this patch it uses the IEEE80211_TX_CTL_CLEAR_PS_FILT
for unaggregated frames.
A sta_notify driver op is added to stop aggregation for stations when they
enter powersave mode. Subframes stay buffered inside the driver, to ensure
that the BlockAck window keeps a sane state.
Since the driver uses software aggregation, the clearing of the tx filter
needs to be handled by the driver instead of mac80211 for aggregated frames.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ath9k.h')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 77ad407e9fa3..a2ddabf0ca2f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -200,6 +200,7 @@ struct ath_atx_ac { | |||
200 | int sched; | 200 | int sched; |
201 | struct list_head list; | 201 | struct list_head list; |
202 | struct list_head tid_q; | 202 | struct list_head tid_q; |
203 | bool clear_ps_filter; | ||
203 | }; | 204 | }; |
204 | 205 | ||
205 | struct ath_frame_info { | 206 | struct ath_frame_info { |
@@ -257,6 +258,8 @@ struct ath_node { | |||
257 | struct ath_atx_ac ac[WME_NUM_AC]; | 258 | struct ath_atx_ac ac[WME_NUM_AC]; |
258 | u16 maxampdu; | 259 | u16 maxampdu; |
259 | u8 mpdudensity; | 260 | u8 mpdudensity; |
261 | |||
262 | bool sleeping; | ||
260 | }; | 263 | }; |
261 | 264 | ||
262 | #define AGGR_CLEANUP BIT(1) | 265 | #define AGGR_CLEANUP BIT(1) |
@@ -338,6 +341,9 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
338 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 341 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
339 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 342 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
340 | 343 | ||
344 | void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); | ||
345 | bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); | ||
346 | |||
341 | /********/ | 347 | /********/ |
342 | /* VIFs */ | 348 | /* VIFs */ |
343 | /********/ | 349 | /********/ |