svn commit: r225685 - user/adrian/if_ath_tx/sys/dev/ath

Adrian Chadd adrian at FreeBSD.org
Tue Sep 20 04:20:56 UTC 2011


Author: adrian
Date: Tue Sep 20 04:20:55 2011
New Revision: 225685
URL: http://svn.freebsd.org/changeset/base/225685

Log:
  Undo the BAR TX stuff (as it's broken); correct what the new LH edge
  of the BAW should be.
  
  The BAR TX stuff I committed earlier is just plain wrong.
  What should happen is this (in ADDBA mode):
  
  * If a software retransmit completely fails, all TX for that
    given TID should be paused until all existing TXes for said
    TID are completed (failed or not);
  * Once all the hardware-queued transmissions are completed,
    the left-hand edge of the BAW (from the TX point of view)
    should be correct. Ie, there may be further packets queued
    in the software TX queue, but the left-hand edge of the BAW
    will point to one frame past the last hardware-queued frame
    (again, successful or not, it doesn't matter.)
  * At that point, a BAR should be sent reflecting what the new
    BAW left hand edge is.
  * Once that's been received, TX on the given TID should resume.
  * If it fails, net80211 will cancel the addba session for us; we
    just need to resume TX'ing on the TID anyway (newly downgraded
    to non-aggregation.)
  
  Now, the things to keep in mind when implementing the correct-er
  solution:
  
  * There may be plenty of outstanding frames on the hardware TX
    queue, so you can't just send one BAR for each of those.
  
  * Whilst the BAR is being TXed, the node may be reset; this
    SHOULD correctly be handled (ie, cancelling the frame will
    cause net80211 to reschedule another one)
  
  * You can't just call pause() and resume() like I was doing,
    as multiple outstanding frames may be on the hardware queue
    (and multiples ones may fail.) A new method of marking
    a TID as "BAR pending" needs to be added first.
    That way the TID can be paused and unpaused a total of once,
    no matter how many outstanding frames fail before the TID
    has no more frames on the hardware queue.
  
  * Finally, this all only works if tid->hwq_depth is completely
    accurate. This needs to be verified!

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	Tue Sep 20 00:37:35 2011	(r225684)
+++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c	Tue Sep 20 04:20:55 2011	(r225685)
@@ -2714,30 +2714,13 @@ ath_tx_aggr_retry_unaggr(struct ath_soft
 		 * This'll end up going into net80211 and back out
 		 * again, via ic->ic_raw_xmit().
 		 */
-		txseq = ni->ni_txseqs[tid];
+		txseq = tap->txa_start;
+		ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
+
 		device_printf(sc->sc_dev,
 		    "%s: TID %d: send BAR; seq %d\n", __func__, tid, txseq);
-		ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
-		/*
-		 * It's ok to unlock it now (and it's required at
-		 * the moment!) since we are purging "holes" in the
-		 * tx sequence up to this point; any subsequent
-		 * sequence numbers haven't been yet attempted to
-		 * TX.
-		 */
-		if (ieee80211_send_bar(ni, tap, txseq) == 0) {
-			/*
-			 * Pause the TID if this was successful.
-			 * An un-successful BAR TX would never call
-			 * the BAR complete / timeout methods.
-			 */
-			ath_tx_tid_pause(sc, atid);
-		} else {
-			/* BAR TX failed */
-			device_printf(sc->sc_dev,
-			    "%s: TID %d: BAR TX failed\n",
-			    __func__, tid);
-		}
+
+		/* XXX TODO: send BAR */
 
 		/* Free buffer, bf is free after this call */
 		ath_tx_default_comp(sc, bf, 0);
@@ -2885,31 +2868,13 @@ ath_tx_comp_aggr_error(struct ath_softc 
 	 * in the ifnet TX context or raw TX context.)
 	 */
 	if (drops) {
-		int txseq = ni->ni_txseqs[tid->tid];
+		int txseq = tap->txa_start;
+		ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]);
 		device_printf(sc->sc_dev,
 		    "%s: TID %d: send BAR; seq %d\n",
 		    __func__, tid->tid, txseq);
-		ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]);
-		/*
-		 * It's ok to unlock it now (and it's required at
-		 * the moment!) since we are purging "holes" in the
-		 * tx sequence up to this point; any subsequent
-		 * sequence numbers haven't been yet attempted to
-		 * TX.
-		 */
-		if (ieee80211_send_bar(ni, tap, txseq) == 0) {
-			/*
-			 * Pause the TID if this was successful.
-			 * An un-successful BAR TX would never call
-			 * the BAR complete / timeout methods.
-			 */
-			ath_tx_tid_pause(sc, tid);
-		} else {
-			/* BAR TX failed */
-			device_printf(sc->sc_dev,
-			    "%s: TID %d: BAR TX failed\n",
-			    __func__, tid->tid);
-		}
+
+		/* XXX TODO: send BAR */
 	} else {
 		ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]);
 	}
@@ -3138,7 +3103,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc *
 	 * Anything after this point will not yet have been
 	 * TXed.
 	 */
-	txseq = ni->ni_txseqs[tid];
+	txseq = tap->txa_start;
 	ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
 
 	if (nframes != nf)
@@ -3159,19 +3124,7 @@ ath_tx_aggr_comp_aggr(struct ath_softc *
 	if (drops) {
 		device_printf(sc->sc_dev,
 		    "%s: TID %d: send BAR; seq %d\n", __func__, tid, txseq);
-		if (ieee80211_send_bar(ni, tap, txseq) == 0) {
-			/*
-			 * Pause the TID if this was successful.
-			 * An un-successful BAR TX would never call
-			 * the BAR complete / timeout methods.
-			 */
-			ath_tx_tid_pause(sc, atid);
-		} else {
-			/* BAR TX failed */
-			device_printf(sc->sc_dev,
-			    "%s: TID %d: BAR TX failed\n",
-			    __func__, tid);
-		}
+		/* XXX TODO: send BAR */
 	}
 
 	/* Prepend all frames to the beginning of the queue */


More information about the svn-src-user mailing list