diff options
author | adrian <adrian@FreeBSD.org> | 2013-03-26 04:52:16 +0000 |
---|---|---|
committer | adrian <adrian@FreeBSD.org> | 2013-03-26 04:52:16 +0000 |
commit | 416044d85e6681c52345d23238e3d08d2ee703b5 (patch) | |
tree | b8d072c4e1de34cce8b3700e7b180542b575f157 | |
parent | 244deab9088e59efd49d1541e5ede504d732cda6 (diff) | |
download | FreeBSD-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.c | 23 |
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); /* |