Date: Tue, 8 Nov 2011 21:25:36 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r227360 - head/sys/dev/ath Message-ID: <201111082125.pA8LPaMe049907@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111082125.pA8LPaMe049907>