svn commit: r227360 - head/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Tue Nov 8 21:25:36 UTC 2011
Author: adrian
Date: Tue Nov 8 21:25:36 2011
New Revision: 227360
URL: http://svn.freebsd.org/changeset/base/227360
Log:
Change the descriptor logic to use bf_lastds to point to the last
descriptor, rather than using the maths involving bf_desc[bf_nseg - 1].
When doing TX aggregation, the status will be updated in the -final-
descriptor of the -final- subframe in an aggregate. Thus bf_lastds
may point to the last descriptor in a completely different ath_buf.
Sponsored by: Hobnob, Inc.
Modified:
head/sys/dev/ath/if_ath.c
head/sys/dev/ath/if_ath_tx.c
Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c Tue Nov 8 21:13:05 2011 (r227359)
+++ head/sys/dev/ath/if_ath.c Tue Nov 8 21:25:36 2011 (r227360)
@@ -2503,6 +2503,8 @@ ath_beacon_setup(struct ath_softc *sc, s
/* setup descriptors */
ds = bf->bf_desc;
+ bf->bf_last = bf;
+ bf->bf_lastds = ds;
flags = HAL_TXDESC_NOACK;
if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol) {
@@ -2582,7 +2584,9 @@ ath_txqmove(struct ath_txq *dst, struct
dst->axq_link = src->axq_link;
src->axq_link = NULL;
dst->axq_depth += src->axq_depth;
+ dst->axq_aggr_depth += src->axq_aggr_depth;
src->axq_depth = 0;
+ src->axq_aggr_depth = 0;
}
/*
@@ -3227,6 +3231,7 @@ ath_descdma_setup(struct ath_softc *sc,
ath_descdma_cleanup(sc, dd, head);
return error;
}
+ bf->bf_lastds = bf->bf_desc; /* Just an initial value */
TAILQ_INSERT_TAIL(head, bf, bf_list);
}
return 0;
@@ -4284,7 +4289,7 @@ ath_tx_processq(struct ath_softc *sc, st
struct ifnet *ifp = sc->sc_ifp;
struct ieee80211com *ic = ifp->if_l2com;
struct ath_buf *bf, *last;
- struct ath_desc *ds, *ds0;
+ struct ath_desc *ds;
struct ath_tx_status *ts;
struct ieee80211_node *ni;
struct ath_node *an;
@@ -4304,8 +4309,7 @@ ath_tx_processq(struct ath_softc *sc, st
ATH_TXQ_UNLOCK(txq);
break;
}
- ds0 = &bf->bf_desc[0];
- ds = &bf->bf_desc[bf->bf_nseg - 1];
+ ds = bf->bf_lastds; /* XXX must be setup correctly! */
ts = &bf->bf_status.ds_txstat;
status = ath_hal_txprocdesc(ah, ds, ts);
#ifdef ATH_DEBUG
@@ -4324,13 +4328,19 @@ ath_tx_processq(struct ath_softc *sc, st
* More frames follow. Mark the buffer busy
* so it's not re-used while the hardware may
* still re-read the link field in the descriptor.
+ *
+ * Use the last buffer in an aggregate as that
+ * is where the hardware may be - intermediate
+ * descriptors won't be "busy".
*/
- bf->bf_flags |= ATH_BUF_BUSY;
+ bf->bf_last->bf_flags |= ATH_BUF_BUSY;
} else
#else
if (txq->axq_depth == 0)
#endif
txq->axq_link = NULL;
+ if (bf->bf_state.bfs_aggr)
+ txq->axq_aggr_depth--;
ATH_TXQ_UNLOCK(txq);
ni = bf->bf_node;
@@ -4565,13 +4575,15 @@ ath_tx_draintxq(struct ath_softc *sc, st
break;
}
ATH_TXQ_REMOVE(txq, bf, bf_list);
+ if (bf->bf_state.bfs_aggr)
+ txq->axq_aggr_depth--;
ATH_TXQ_UNLOCK(txq);
#ifdef ATH_DEBUG
if (sc->sc_debug & ATH_DEBUG_RESET) {
struct ieee80211com *ic = sc->sc_ifp->if_l2com;
ath_printtxbuf(sc, bf, txq->axq_qnum, ix,
- ath_hal_txprocdesc(ah, bf->bf_desc,
+ ath_hal_txprocdesc(ah, bf->bf_lastds,
&bf->bf_status.ds_txstat) == HAL_OK);
ieee80211_dump_pkt(ic, mtod(bf->bf_m, const uint8_t *),
bf->bf_m->m_len, 0, -1);
@@ -4657,7 +4669,7 @@ ath_draintxq(struct ath_softc *sc, ATH_R
struct ath_buf *bf = TAILQ_FIRST(&sc->sc_bbuf);
if (bf != NULL && bf->bf_m != NULL) {
ath_printtxbuf(sc, bf, sc->sc_bhalq, 0,
- ath_hal_txprocdesc(ah, bf->bf_desc,
+ ath_hal_txprocdesc(ah, bf->bf_lastds,
&bf->bf_status.ds_txstat) == HAL_OK);
ieee80211_dump_pkt(ifp->if_l2com,
mtod(bf->bf_m, const uint8_t *), bf->bf_m->m_len,
Modified: head/sys/dev/ath/if_ath_tx.c
==============================================================================
--- head/sys/dev/ath/if_ath_tx.c Tue Nov 8 21:13:05 2011 (r227359)
+++ head/sys/dev/ath/if_ath_tx.c Tue Nov 8 21:25:36 2011 (r227360)
@@ -225,6 +225,9 @@ ath_tx_dmasetup(struct ath_softc *sc, st
return 0;
}
+/*
+ * Chain together segments+descriptors for a non-11n frame.
+ */
static void
ath_tx_chaindesclist(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
{
@@ -252,8 +255,8 @@ ath_tx_chaindesclist(struct ath_softc *s
"%s: %d: %08x %08x %08x %08x %08x %08x\n",
__func__, i, ds->ds_link, ds->ds_data,
ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]);
+ bf->bf_lastds = ds;
}
-
}
static void
@@ -347,7 +350,9 @@ ath_tx_handoff(struct ath_softc *sc, str
(caddr_t)bf->bf_daddr, bf->bf_desc, txq->axq_depth);
}
#endif /* IEEE80211_SUPPORT_TDMA */
- txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link;
+ if (bf->bf_state.bfs_aggr)
+ txq->axq_aggr_depth++;
+ txq->axq_link = &bf->bf_lastds->ds_link;
ath_hal_txstart(ah, txq->axq_qnum);
} else {
if (txq->axq_link != NULL) {
More information about the svn-src-head
mailing list