Author: adrian
Date: Sat May  4 04:03:50 2013
New Revision: 250229
URL: http://svnweb.freebsd.org/changeset/base/250229

Log:
  The holding buffer logic needs to be used for _all_ transmission, not
  just "when the queue is busy."
  
  After talking with the MAC team, it turns out that the linked list
  implementation sometimes will not accept a TxDP update and will
  instead re-read the link pointer.  So even if the hardware has
  finished transmitting a chain and has hit EOL/VEOL, it may still
  re-read the link pointer to begin transmitting again.
  
  So, always set ATH_BUF_BUSY on the last buffer in the chain (to
  mark the last descriptor as the holding descriptor) and never
  blank the axq_link pointer.
  
  Tested:
  
  * AR5416, STA mode
  
  TODO:
  
  * much more thorough testing with the pre-11n NICs, just to verify
    that they behave the same way.
  * test TDMA on the 11n and non-11n hardware.

Modified:
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c   Sat May  4 00:31:41 2013        (r250228)
+++ head/sys/dev/ath/if_ath.c   Sat May  4 04:03:50 2013        (r250229)
@@ -3928,19 +3928,20 @@ ath_tx_processq(struct ath_softc *sc, st
                        break;
                }
                ATH_TXQ_REMOVE(txq, bf, bf_list);
-               if (txq->axq_depth > 0) {
-                       /*
-                        * 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_last->bf_flags |= ATH_BUF_BUSY;
-               } else
-                       txq->axq_link = NULL;
+
+               /*
+                * Always mark the last buffer in this list as busy.
+                *
+                * The hardware may re-read the holding descriptor
+                * even if we hit the end of the list and try writing
+                * a new TxDP.
+                *
+                * If there's no holding descriptor then this is the
+                * last buffer in the list of buffers after a fresh
+                * reset; it'll soon become the holding buffer.
+                */
+               bf->bf_last->bf_flags |= ATH_BUF_BUSY;
+
                if (bf->bf_state.bfs_aggr)
                        txq->axq_aggr_depth--;
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to