summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2013-03-26 04:52:16 +0000
committeradrian <adrian@FreeBSD.org>2013-03-26 04:52:16 +0000
commit416044d85e6681c52345d23238e3d08d2ee703b5 (patch)
treeb8d072c4e1de34cce8b3700e7b180542b575f157
parent244deab9088e59efd49d1541e5ede504d732cda6 (diff)
downloadFreeBSD-src-416044d85e6681c52345d23238e3d08d2ee703b5.zip
FreeBSD-src-416044d85e6681c52345d23238e3d08d2ee703b5.tar.gz
Convert the CABQ queue code over to use the HAL link pointer method
instead of axq_link. This (among a bunch of uncommitted work) is required for EDMA chips to correctly transmit frames on the CABQ. Tested: * AR9280, hostap mode * AR9380/AR9580, hostap mode (staggered beacons) TODO: * This code only really gets called when burst beacons are used; it glues multiple CABQ queues together when sending to the hardware. * More thorough bursted beacon testing! (first requires some work with the beacon queue code for bursted beacons, as that currently uses the link pointer and will fail on EDMA chips.)
-rw-r--r--sys/dev/ath/if_ath_beacon.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/sys/dev/ath/if_ath_beacon.c b/sys/dev/ath/if_ath_beacon.c
index e847f93..0da019d 100644
--- a/sys/dev/ath/if_ath_beacon.c
+++ b/sys/dev/ath/if_ath_beacon.c
@@ -632,7 +632,7 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
/* NB: only at DTIM */
ATH_TXQ_LOCK(&avp->av_mcastq);
if (nmcastq) {
- struct ath_buf *bfm;
+ struct ath_buf *bfm, *bfc_last;
/*
* Move frames from the s/w mcast q to the h/w cab q.
@@ -645,16 +645,23 @@ ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap)
* MORE data bit set on the last frame of each
* intermediary VAP (ie, only clear the MORE
* bit of the last frame on the last vap?)
- *
- * XXX TODO: once we append this, what happens
- * to cabq->axq_link? It'll point at the avp
- * mcastq link pointer, so things should be OK.
- * Just double-check this is what actually happens.
*/
bfm = TAILQ_FIRST(&avp->av_mcastq.axq_q);
ATH_TXQ_LOCK(cabq);
- if (cabq->axq_link != NULL)
- *cabq->axq_link = bfm->bf_daddr;
+
+ /*
+ * If there's already a frame on the CABQ, we
+ * need to link to the end of the last frame.
+ * We can't use axq_link here because
+ * EDMA descriptors require some recalculation
+ * (checksum) to occur.
+ */
+ bfc_last = ATH_TXQ_LAST(cabq, axq_q_s);
+ if (bfc_last != NULL) {
+ ath_hal_settxdesclink(sc->sc_ah,
+ bfc_last->bf_lastds,
+ bfm->bf_daddr);
+ }
ath_txqmove(cabq, &avp->av_mcastq);
ATH_TXQ_UNLOCK(cabq);
/*
OpenPOWER on IntegriCloud