aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/beacon.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2008-08-22 10:31:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-29 16:24:08 -0400
commite022edbd2bfb5f9a7ddf1cca43544f7b54c6fe02 (patch)
tree4f46cfa403522902774e37b8cee7198eedde4119 /drivers/net/wireless/ath9k/beacon.c
parent87e8b64e6856a41c5204a22c47cc14b1b0b57332 (diff)
ath9k: Use mac80211 for multicast power save buffering
Replace the internal ath9k implementation of multicast/broadcast frame power save buffering (AP mode) in ath9k with use of mac80211 ieee80211_get_buffered_bc() mechanism. This removes quite a bit of duplicated functionality and simplifies the driver part. Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/beacon.c')
-rw-r--r--drivers/net/wireless/ath9k/beacon.c75
1 files changed, 7 insertions, 68 deletions
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index ee1185622ba6..fdbabc180228 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -140,56 +140,6 @@ static void ath_beacon_setup(struct ath_softc *sc,
140 ctsrate, ctsduration, series, 4, 0); 140 ctsrate, ctsduration, series, 4, 0);
141} 141}
142 142
143/* Move everything from the vap's mcast queue to the hardware cab queue.
144 * Caller must hold mcasq lock and cabq lock
145 * XXX MORE_DATA bit?
146 */
147static void empty_mcastq_into_cabq(struct ath_hal *ah,
148 struct ath_txq *mcastq, struct ath_txq *cabq)
149{
150 struct ath_buf *bfmcast;
151
152 BUG_ON(list_empty(&mcastq->axq_q));
153
154 bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
155
156 /* link the descriptors */
157 if (!cabq->axq_link)
158 ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
159 else
160 *cabq->axq_link = bfmcast->bf_daddr;
161
162 /* append the private vap mcast list to the cabq */
163
164 cabq->axq_depth += mcastq->axq_depth;
165 cabq->axq_totalqueued += mcastq->axq_totalqueued;
166 cabq->axq_linkbuf = mcastq->axq_linkbuf;
167 cabq->axq_link = mcastq->axq_link;
168 list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
169 mcastq->axq_depth = 0;
170 mcastq->axq_totalqueued = 0;
171 mcastq->axq_linkbuf = NULL;
172 mcastq->axq_link = NULL;
173}
174
175/* TODO: use ieee80211_get_buffered_bc() to fetch power saved mcast frames */
176/* This is only run at DTIM. We move everything from the vap's mcast queue
177 * to the hardware cab queue. Caller must hold the mcastq lock. */
178static void trigger_mcastq(struct ath_hal *ah,
179 struct ath_txq *mcastq, struct ath_txq *cabq)
180{
181 spin_lock_bh(&cabq->axq_lock);
182
183 if (!list_empty(&mcastq->axq_q))
184 empty_mcastq_into_cabq(ah, mcastq, cabq);
185
186 /* cabq is gated by beacon so it is safe to start here */
187 if (!list_empty(&cabq->axq_q))
188 ath9k_hw_txstart(ah, cabq->axq_qnum);
189
190 spin_unlock_bh(&cabq->axq_lock);
191}
192
193/* 143/*
194 * Generate beacon frame and queue cab data for a vap. 144 * Generate beacon frame and queue cab data for a vap.
195 * 145 *
@@ -200,19 +150,14 @@ static void trigger_mcastq(struct ath_hal *ah,
200*/ 150*/
201static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) 151static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
202{ 152{
203 struct ath_hal *ah = sc->sc_ah;
204 struct ath_buf *bf; 153 struct ath_buf *bf;
205 struct ath_vap *avp; 154 struct ath_vap *avp;
206 struct sk_buff *skb; 155 struct sk_buff *skb;
207 int cabq_depth; 156 int cabq_depth;
208 int mcastq_depth;
209 int is_beacon_dtim = 0;
210 struct ath_txq *cabq; 157 struct ath_txq *cabq;
211 struct ath_txq *mcastq;
212 struct ieee80211_tx_info *info; 158 struct ieee80211_tx_info *info;
213 avp = sc->sc_vaps[if_id]; 159 avp = sc->sc_vaps[if_id];
214 160
215 mcastq = &avp->av_mcastq;
216 cabq = sc->sc_cabq; 161 cabq = sc->sc_cabq;
217 162
218 ASSERT(avp); 163 ASSERT(avp);
@@ -250,11 +195,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
250 skb_end_pointer(skb) - skb->head, 195 skb_end_pointer(skb) - skb->head,
251 PCI_DMA_TODEVICE); 196 PCI_DMA_TODEVICE);
252 197
253 /* TODO: convert to use ieee80211_get_buffered_bc() */ 198 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
254 /* XXX: spin_lock_bh should not be used here, but sparse bitches
255 * otherwise. We should fix sparse :) */
256 spin_lock_bh(&mcastq->axq_lock);
257 mcastq_depth = avp->av_mcastq.axq_depth;
258 199
259 /* 200 /*
260 * if the CABQ traffic from previous DTIM is pending and the current 201 * if the CABQ traffic from previous DTIM is pending and the current
@@ -268,10 +209,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
268 cabq_depth = cabq->axq_depth; 209 cabq_depth = cabq->axq_depth;
269 spin_unlock_bh(&cabq->axq_lock); 210 spin_unlock_bh(&cabq->axq_lock);
270 211
271 if (avp->av_boff.bo_tim) 212 if (skb && cabq_depth) {
272 is_beacon_dtim = avp->av_boff.bo_tim[4] & 1;
273
274 if (mcastq_depth && is_beacon_dtim && cabq_depth) {
275 /* 213 /*
276 * Unlock the cabq lock as ath_tx_draintxq acquires 214 * Unlock the cabq lock as ath_tx_draintxq acquires
277 * the lock again which is a common function and that 215 * the lock again which is a common function and that
@@ -291,10 +229,11 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
291 * Enable the CAB queue before the beacon queue to 229 * Enable the CAB queue before the beacon queue to
292 * insure cab frames are triggered by this beacon. 230 * insure cab frames are triggered by this beacon.
293 */ 231 */
294 if (is_beacon_dtim) 232 while (skb) {
295 trigger_mcastq(ah, mcastq, cabq); 233 ath_tx_cabq(sc, skb);
234 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
235 }
296 236
297 spin_unlock_bh(&mcastq->axq_lock);
298 return bf; 237 return bf;
299} 238}
300 239
@@ -426,7 +365,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
426 * NB: the beacon data buffer must be 32-bit aligned; 365 * NB: the beacon data buffer must be 32-bit aligned;
427 * we assume the wbuf routines will return us something 366 * we assume the wbuf routines will return us something
428 * with this alignment (perhaps should assert). 367 * with this alignment (perhaps should assert).
429 * FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and 368 * FIXME: Fill avp->av_btxctl.txpower and
430 * avp->av_btxctl.shortPreamble 369 * avp->av_btxctl.shortPreamble
431 */ 370 */
432 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data); 371 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);