Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 6 Jun 2011 01:53:31 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r222727 - user/adrian/if_ath_tx/sys/dev/ath
Message-ID:  <201106060153.p561rVrw006401@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106060153.p561rVrw006401>