Index: ath_hal/ah.c =================================================================== --- ath_hal/ah.c (revision 312609) +++ ath_hal/ah.c (working copy) @@ -1415,6 +1415,8 @@ /* * Get CCA setting. + * + * XXX TODO: this may not actually be the same on all chips! Grr! */ int ath_hal_getcca(struct ath_hal *ah) Index: if_ath_tx.c =================================================================== --- if_ath_tx.c (revision 312609) +++ if_ath_tx.c (working copy) @@ -3129,7 +3129,21 @@ ATH_TID_INSERT_TAIL(atid, bf, bf_list); /* XXX sched? */ } else if (ath_tx_ampdu_running(sc, an, tid)) { - /* AMPDU running, attempt direct dispatch if possible */ + /* + * AMPDU running, queue single-frame if the hardware queue + * isn't busy. + * + * If the hardware queue is busy, sending an aggregate frame + * then just hold off so we can queue more aggregate frames. + * + * Otherwise we may end up with single frames leaking through + * because we are dispatching them too quickly. + * + * TODO: maybe we should treat this as two policies - minimise + * latency, or maximise throughput. Then for BE/BK we can + * maximise throughput, and VO/VI (if AMPDU is enabled!) + * minimise latency. + */ /* * Always queue the frame to the tail of the list. @@ -3138,18 +3152,19 @@ /* * If the hardware queue isn't busy, direct dispatch - * the head frame in the list. Don't schedule the - * TID - let it build some more frames first? + * the head frame in the list. * - * When running A-MPDU, always just check the hardware - * queue depth against the aggregate frame limit. - * We don't want to burst a large number of single frames - * out to the hardware; we want to aggressively hold back. + * Note: if we're say, configured to do ADDBA but not A-MPDU + * then maybe we want to still queue two non-aggregate frames + * to the hardware. Again with the per-TID policy + * configuration..) * * Otherwise, schedule the TID. */ /* XXX TXQ locking */ - if (txq->axq_depth + txq->fifo.axq_depth < sc->sc_hwq_limit_aggr) { + //if (txq->axq_depth + txq->fifo.axq_depth < sc->sc_hwq_limit_aggr) { + if (txq->axq_depth + txq->fifo.axq_depth == 0) { + bf = ATH_TID_FIRST(atid); ATH_TID_REMOVE(atid, bf, bf_list);