diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-09-29 16:04:26 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-30 15:57:10 -0400 |
commit | 042ec4533720122e6cb93dd9f3b6a75fe2fcff16 (patch) | |
tree | ed8fad40c171ab54155ce316496f68d79b438b01 /drivers/net | |
parent | 941c93cd039852b7ab02c74f4698c99d82bd6cfe (diff) |
mac80211: let drivers inform it about per TID buffered frames
For uAPSD implementation, it is necessary to know on
which ACs frames are buffered. mac80211 obviously
knows about the frames it has buffered itself, but
with aggregation many drivers buffer frames. Thus,
mac80211 needs to be informed about this.
For now, since we don't have APSD in any form, this
will unconditionally set the TIM bit for the station
but later with uAPSD only some ACs might cause the
TIM bit to be set.
ath9k is the only driver using this API and I only
modify it in the most basic way, it won't be able
to implement uAPSD with this yet. But it can't do
that anyway since there's no way to selectively
release frames to the peer yet.
Since drivers will buffer frames per TID, let them
inform mac80211 on a per TID basis, mac80211 will
then sort out the AC mapping itself.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 14 |
3 files changed, 10 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 94d887b65e6..1e861478318 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -340,7 +340,8 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); -bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an); +void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, + struct ath_node *an); /********/ /* VIFs */ diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index edaa7843bf4..0ebf7321df1 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1833,8 +1833,7 @@ static void ath9k_sta_notify(struct ieee80211_hw *hw, switch (cmd) { case STA_NOTIFY_SLEEP: an->sleeping = true; - if (ath_tx_aggr_sleep(sc, an)) - ieee80211_sta_set_tim(sta); + ath_tx_aggr_sleep(sta, sc, an); break; case STA_NOTIFY_AWAKE: an->sleeping = false; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f5d4764888b..c2bfc57958d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -542,7 +542,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, /* prepend un-acked frames to the beginning of the pending frame queue */ if (!skb_queue_empty(&bf_pending)) { if (an->sleeping) - ieee80211_sta_set_tim(sta); + ieee80211_sta_set_buffered(sta, tid->tidno, true); spin_lock_bh(&txq->axq_lock); if (clear_filter) @@ -1153,12 +1153,13 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) ath_tx_flush_tid(sc, txtid); } -bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) +void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, + struct ath_node *an) { struct ath_atx_tid *tid; struct ath_atx_ac *ac; struct ath_txq *txq; - bool buffered = false; + bool buffered; int tidno; for (tidno = 0, tid = &an->tid[tidno]; @@ -1172,8 +1173,7 @@ bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) spin_lock_bh(&txq->axq_lock); - if (!skb_queue_empty(&tid->buf_q)) - buffered = true; + buffered = !skb_queue_empty(&tid->buf_q); tid->sched = false; list_del(&tid->list); @@ -1184,9 +1184,9 @@ bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an) } spin_unlock_bh(&txq->axq_lock); - } - return buffered; + ieee80211_sta_set_buffered(sta, tidno, buffered); + } } void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) |