svn commit: r222727 - user/adrian/if_ath_tx/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Mon Jun 6 01:53:31 UTC 2011
Author: adrian
Date: Mon Jun 6 01:53:31 2011
New Revision: 222727
URL: http://svn.freebsd.org/changeset/base/222727
Log:
Begin separating out the "setup descriptor", "setup descriptor list"
and "handoff" from the actual TX path.
Packets going onto a software TX queue will need to be setup as per
normal but won't be added to the hardware TX queue until later.
Details:
* ath_tx_start() is now ath_tx_normal_setup() - it sets up the packet,
configures the first descriptor but doesn't add it to the TX queue
via ath_tx_handoff();
* ath_tx_handoff() now doesn't call ath_tx_chaindesclist() to chain
together descriptors as required by the MAC;
* a new ath_tx_start() now:
+ determines the destination TX queue;
+ calls ath_tx_normal_setup() to do the packet and descriptor setup;
+ calls ath_tx_chaindesclist() to chain the descriptors together
for the MAC;
+ calls ath_tx_handoff() to dispatch to the hardware.
The packets going onto the mcast software TXQ (which is implemented
just like a hardware TXQ, but with no hardware dispatch :) already do
this but the decision not to dispatch them directly is done in
ath_tx_handoff() which is something that needs to be uncoupled a bit better.
Whilst I'm here (and having to do development on an 80x50 VGA console,
due to needing to interpret kernel panics) undo some of my brain damaged
non-style(9) commits.
Modified:
user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c
==============================================================================
--- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Mon Jun 6 01:52:15 2011 (r222726)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Mon Jun 6 01:53:31 2011 (r222727)
@@ -226,7 +226,8 @@ ath_tx_dmasetup(struct ath_softc *sc, st
}
static void
-ath_tx_chaindesclist(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf)
+ath_tx_chaindesclist(struct ath_softc *sc, struct ath_txq *txq,
+ struct ath_buf *bf)
{
struct ath_hal *ah = sc->sc_ah;
struct ath_desc *ds, *ds0;
@@ -261,9 +262,6 @@ ath_tx_handoff(struct ath_softc *sc, str
{
struct ath_hal *ah = sc->sc_ah;
- /* Fill in the details in the descriptor list */
- ath_tx_chaindesclist(sc, txq, bf);
-
/*
* Insert the frame on the outbound list and pass it on
* to the hardware. Multicast frames buffered for power
@@ -488,9 +486,9 @@ ath_tx_calc_ctsduration(struct ath_hal *
return ctsduration;
}
-int
-ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf,
- struct mbuf *m0)
+static int
+ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni,
+ struct ath_buf *bf, struct mbuf *m0)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ath_vap *avp = ATH_VAP(vap);
@@ -528,7 +526,8 @@ ath_tx_start(struct ath_softc *sc, struc
pktlen = m0->m_pkthdr.len - (hdrlen & 3);
/* Handle encryption twiddling if needed */
- if (! ath_tx_tag_crypto(sc, ni, m0, iswep, isfrag, &hdrlen, &pktlen, &keyix)) {
+ if (! ath_tx_tag_crypto(sc, ni, m0, iswep, isfrag, &hdrlen,
+ &pktlen, &keyix)) {
ath_freetx(m0);
return EIO;
}
@@ -774,6 +773,32 @@ ath_tx_start(struct ath_softc *sc, struc
} else
ctsrate = 0;
+
+ /*
+ * Determine if a tx interrupt should be generated for
+ * this descriptor. We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt. We periodically mark descriptors in this
+ * way to insure timely replenishing of the supply needed
+ * for sending frames. Defering interrupts reduces system
+ * load and potentially allows more concurrent work to be
+ * done but if done to aggressively can cause senders to
+ * backup.
+ *
+ * NB: use >= to deal with sc_txintrperiod changing
+ * dynamically through sysctl.
+ */
+ if (flags & HAL_TXDESC_INTREQ) {
+ txq->axq_intrcnt = 0;
+ } else if (++txq->axq_intrcnt >= sc->sc_txintrperiod) {
+ flags |= HAL_TXDESC_INTREQ;
+ txq->axq_intrcnt = 0;
+ }
+
+ /* This point forward is actual TX bits */
+
+
/*
* At this point we are committed to sending the frame
* and we don't need to look at m_nextpkt; clear it in
@@ -801,27 +826,6 @@ ath_tx_start(struct ath_softc *sc, struc
ieee80211_radiotap_tx(vap, m0);
}
- /*
- * Determine if a tx interrupt should be generated for
- * this descriptor. We take a tx interrupt to reap
- * descriptors when the h/w hits an EOL condition or
- * when the descriptor is specifically marked to generate
- * an interrupt. We periodically mark descriptors in this
- * way to insure timely replenishing of the supply needed
- * for sending frames. Defering interrupts reduces system
- * load and potentially allows more concurrent work to be
- * done but if done to aggressively can cause senders to
- * backup.
- *
- * NB: use >= to deal with sc_txintrperiod changing
- * dynamically through sysctl.
- */
- if (flags & HAL_TXDESC_INTREQ) {
- txq->axq_intrcnt = 0;
- } else if (++txq->axq_intrcnt >= sc->sc_txintrperiod) {
- flags |= HAL_TXDESC_INTREQ;
- txq->axq_intrcnt = 0;
- }
if (ath_tx_is_11n(sc)) {
rate[0] = rix;
@@ -862,10 +866,57 @@ ath_tx_start(struct ath_softc *sc, struc
}
if (ath_tx_is_11n(sc)) {
- ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, (atype == HAL_PKT_TYPE_PSPOLL), rate, try);
+ ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate,
+ (atype == HAL_PKT_TYPE_PSPOLL), rate, try);
}
+ return 0;
+}
+
+/*
+ * Direct-dispatch the current frame to the hardware.
+ */
+int
+ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni,
+ struct ath_buf *bf, struct mbuf *m0)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ath_vap *avp = ATH_VAP(vap);
+ int r;
+ u_int pri;
+ struct ath_txq *txq;
+ int ismcast;
+ const struct ieee80211_frame *wh;
+
+ /* Determine the target hardware queue! */
+ pri = M_WME_GETAC(m0); /* honor classification */
+ txq = sc->sc_ac2q[pri];
+ wh = mtod(m0, struct ieee80211_frame *);
+ ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
+
+ /* Multicast frames go onto the software multicat queue */
+ if (ismcast && (vap->iv_ps_sta || avp->av_mcastq.axq_depth))
+ txq = &avp->av_mcastq;
+
+ /* Do the generic frame setup */
+ /* This also sets up the DMA map */
+ r = ath_tx_normal_setup(sc, ni, bf, m0);
+
+ if (r != 0)
+ return r;
+
+ /* At this point m0 could have changed! */
+ //m0 = bf->bf_m;
+
+ /* Fill in the details in the descriptor list */
+ ath_tx_chaindesclist(sc, txq, bf);
+
+ /*
+ * For now, since there's no software queue,
+ * direct-dispatch to the hardware.
+ */
ath_tx_handoff(sc, txq, bf);
+
return 0;
}
@@ -1051,10 +1102,14 @@ ath_tx_raw_start(struct ath_softc *sc, s
* notice that rix doesn't include any of the "magic" flags txrate
* does for communicating "other stuff" to the HAL.
*/
- ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, (atype == HAL_PKT_TYPE_PSPOLL), rate, try);
+ ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate,
+ (atype == HAL_PKT_TYPE_PSPOLL), rate, try);
}
/* NB: no buffered multicast in power save support */
+
+ /* Fill in the details in the descriptor list */
+ ath_tx_chaindesclist(sc, sc->sc_ac2q[pri], bf);
ath_tx_handoff(sc, sc->sc_ac2q[pri], bf);
return 0;
}
More information about the svn-src-user
mailing list