From owner-svn-src-head@FreeBSD.ORG Thu Sep 20 03:13:20 2012 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id DF9EF106566C; Thu, 20 Sep 2012 03:13:20 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C9D748FC0C; Thu, 20 Sep 2012 03:13:20 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q8K3DKuK028961; Thu, 20 Sep 2012 03:13:20 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q8K3DKlO028959; Thu, 20 Sep 2012 03:13:20 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201209200313.q8K3DKlO028959@svn.freebsd.org> From: Adrian Chadd Date: Thu, 20 Sep 2012 03:13:20 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r240724 - head/sys/dev/ath X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Sep 2012 03:13:21 -0000 Author: adrian Date: Thu Sep 20 03:13:20 2012 New Revision: 240724 URL: http://svn.freebsd.org/changeset/base/240724 Log: Introduce the CLRDMASK gating based on tid->clrdmask, enabling filtered frames to occur. * Create a new function which will set the bf_flags CLRDMASK bit if required. * For raw frames, always set CLRDMASK. * For BAR, ADDBA frames, always set CLRDMASK. * For everything else, check if CLRDMASK needs to be set before calling tx_setds() or tx_setds11n(). * When unpausing a queue or drain/resetting it, set tid->clrdmask=1 just to ensure traffic starts flowing. What I need to do: * Modify that function to _clear_ the CLRDMASK if it's not required, or retried frames may have CLRDMASK set when they don't need to. (Which isn't a huge deal, but..) Whilst I'm here: * ath_tx_normal_xmit() should really act like the AMPDU session TX functions - any incomplete frames will end up being assigned ath_tx_normal_comp() which will decrement tid->hwq_depth - but that won't have been incremented. So whilst I'm here, add a comment to do that. * Fix the debug print function to be slightly clearer about things; it's not a good sign when I can't interpret my own debugging output. I've done some testing on AR9280/AR5416/AR9160 STA and AP modes. Modified: head/sys/dev/ath/if_ath_tx.c Modified: head/sys/dev/ath/if_ath_tx.c ============================================================================== --- head/sys/dev/ath/if_ath_tx.c Thu Sep 20 03:09:58 2012 (r240723) +++ head/sys/dev/ath/if_ath_tx.c Thu Sep 20 03:13:20 2012 (r240724) @@ -1285,6 +1285,9 @@ ath_tx_xmit_normal(struct ath_softc *sc, ath_tx_rate_fill_rcflags(sc, bf); ath_tx_setds(sc, bf); + /* XXX Bump TID HWQ counter */ + /* XXX Assign a completion handler */ + /* Hand off to hardware */ ath_tx_handoff(sc, txq, bf); } @@ -1384,7 +1387,8 @@ ath_tx_normal_setup(struct ath_softc *sc } an = ATH_NODE(ni); - flags = HAL_TXDESC_CLRDMASK; /* XXX needed for crypto errs */ + //flags = HAL_TXDESC_CLRDMASK; /* XXX needed for crypto errs */ + flags = 0; ismrr = 0; /* default no multi-rate retry*/ pri = M_WME_GETAC(m0); /* honor classification */ /* XXX use txparams instead of fixed values */ @@ -1598,12 +1602,15 @@ ath_tx_normal_setup(struct ath_softc *sc } /* - * Direct-dispatch the current frame to the hardware. + * Queue a frame to the hardware or software queue. * * This can be called by the net80211 code. * * XXX what about locking? Or, push the seqno assign into the * XXX aggregate scheduler so its serialised? + * + * XXX When sending management frames via ath_raw_xmit(), + * should CLRDMASK be set unconditionally? */ int ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, @@ -1774,11 +1781,13 @@ ath_tx_start(struct ath_softc *sc, struc if (txq == &avp->av_mcastq) { DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: mcastq: TX'ing\n", __func__, bf); + bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; ath_tx_xmit_normal(sc, txq, bf); } else if (type == IEEE80211_FC0_TYPE_CTL && subtype == IEEE80211_FC0_SUBTYPE_BAR) { DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: BAR: TX'ing direct\n", __func__); + bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; ath_tx_xmit_normal(sc, txq, bf); } else { /* add to software queue */ @@ -1791,6 +1800,7 @@ ath_tx_start(struct ath_softc *sc, struc * For now, since there's no software queue, * direct-dispatch to the hardware. */ + bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; ath_tx_xmit_normal(sc, txq, bf); #endif done: @@ -1874,6 +1884,7 @@ ath_tx_raw_start(struct ath_softc *sc, s wh = mtod(m0, struct ieee80211_frame *); bf->bf_node = ni; /* NB: held reference */ + /* Always enable CLRDMASK for raw frames for now.. */ flags = HAL_TXDESC_CLRDMASK; /* XXX needed for crypto errs */ flags |= HAL_TXDESC_INTREQ; /* force interrupt */ if (params->ibp_flags & IEEE80211_BPF_RTS) @@ -2002,6 +2013,7 @@ ath_tx_raw_start(struct ath_softc *sc, s __func__, do_override); if (do_override) { + bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; ath_tx_xmit_normal(sc, sc->sc_ac2q[pri], bf); } else { /* Queue to software queue */ @@ -2467,6 +2479,22 @@ ath_tx_tid_unsched(struct ath_softc *sc, } /* + * Update the CLRDMASK bit in the ath_buf if it needs to be set. + */ +static void +ath_tx_update_clrdmask(struct ath_softc *sc, struct ath_tid *tid, + struct ath_buf *bf) +{ + + ATH_TID_LOCK_ASSERT(sc, tid); + + if (tid->clrdmask == 1) { + bf->bf_state.bfs_txflags |= HAL_TXDESC_CLRDMASK; + tid->clrdmask = 0; + } +} + +/* * Assign a sequence number manually to the given frame. * * This should only be called for A-MPDU TX frames. @@ -2582,6 +2610,9 @@ ath_tx_xmit_aggr(struct ath_softc *sc, s bf->bf_state.bfs_nframes = 1; } + /* Update CLRDMASK just before this frame is queued */ + ath_tx_update_clrdmask(sc, tid, bf); + /* Direct dispatch to hardware */ ath_tx_do_ratelookup(sc, bf); ath_tx_calc_duration(sc, bf); @@ -2701,6 +2732,7 @@ ath_tx_swq(struct ath_softc *sc, struct } else if (txq->axq_depth < sc->sc_hwq_limit) { /* AMPDU not running, attempt direct dispatch */ DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: xmit_normal\n", __func__); + ath_tx_update_clrdmask(sc, atid, bf); ath_tx_xmit_normal(sc, txq, bf); } else { /* Busy; queue */ @@ -2789,6 +2821,12 @@ ath_tx_tid_resume(struct ath_softc *sc, return; } + /* + * Override the clrdmask configuration for the next frame, + * just to get the ball rolling. + */ + tid->clrdmask = 1; + ath_tx_tid_sched(sc, tid); /* Punt some frames to the hardware if needed */ //ath_txq_sched(sc, sc->sc_ac2q[tid->ac]); @@ -3109,6 +3147,12 @@ ath_tx_tid_bar_tx(struct ath_softc *sc, tid->bar_tx = 1; /* + * Override the clrdmask configuration for the next frame, + * just to get the ball rolling. + */ + tid->clrdmask = 1; + + /* * Calculate new BAW left edge, now that all frames have either * succeeded or failed. * @@ -3189,6 +3233,12 @@ ath_tx_tid_drain_print(struct ath_softc SEQNO(bf->bf_state.bfs_seqno), bf->bf_state.bfs_retries); device_printf(sc->sc_dev, + "%s: node %p: bf=%p: txq axq_depth=%d, axq_aggr_depth=%d\n", + __func__, ni, bf, + txq->axq_depth, + txq->axq_aggr_depth); + + device_printf(sc->sc_dev, "%s: node %p: bf=%p: tid txq_depth=%d hwq_depth=%d, bar_wait=%d, isfiltered=%d\n", __func__, ni, bf, tid->axq_depth, @@ -3196,13 +3246,13 @@ ath_tx_tid_drain_print(struct ath_softc tid->bar_wait, tid->isfiltered); device_printf(sc->sc_dev, - "%s: node %p: tid %d: txq_depth=%d, " - "txq_aggr_depth=%d, sched=%d, paused=%d, " - "hwq_depth=%d, incomp=%d, baw_head=%d, " + "%s: node %p: tid %d: " + "sched=%d, paused=%d, " + "incomp=%d, baw_head=%d, " "baw_tail=%d txa_start=%d, ni_txseqs=%d\n", - __func__, ni, tid->tid, txq->axq_depth, - txq->axq_aggr_depth, tid->sched, tid->paused, - tid->hwq_depth, tid->incomp, tid->baw_head, + __func__, ni, tid->tid, + tid->sched, tid->paused, + tid->incomp, tid->baw_head, tid->baw_tail, tap == NULL ? -1 : tap->txa_start, ni->ni_txseqs[tid->tid]); @@ -3274,6 +3324,15 @@ ath_tx_tid_drain(struct ath_softc *sc, s } /* + * Override the clrdmask configuration for the next frame + * in case there is some future transmission, just to get + * the ball rolling. + * + * This won't hurt things if the TID is about to be freed. + */ + tid->clrdmask = 1; + + /* * Now that it's completed, grab the TID lock and update * the sequence number and BAW window. * Because sequence numbers have been assigned to frames @@ -4511,6 +4570,9 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft bf->bf_state.bfs_aggr = 0; bf->bf_state.bfs_nframes = 1; + /* Update CLRDMASK just before this frame is queued */ + ath_tx_update_clrdmask(sc, tid, bf); + ath_tx_do_ratelookup(sc, bf); ath_tx_calc_duration(sc, bf); ath_tx_calc_protection(sc, bf); @@ -4573,6 +4635,10 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft if (bf->bf_state.bfs_nframes == 1) { DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: single-frame aggregate\n", __func__); + + /* Update CLRDMASK just before this frame is queued */ + ath_tx_update_clrdmask(sc, tid, bf); + bf->bf_state.bfs_aggr = 0; bf->bf_state.bfs_ndelim = 0; ath_tx_setds(sc, bf); @@ -4591,6 +4657,9 @@ ath_tx_tid_hw_queue_aggr(struct ath_soft sc->sc_aggr_stats.aggr_pkts[bf->bf_state.bfs_nframes]++; sc->sc_aggr_stats.aggr_aggr_pkt++; + /* Update CLRDMASK just before this frame is queued */ + ath_tx_update_clrdmask(sc, tid, bf); + /* * Calculate the duration/protection as required. */ @@ -4654,7 +4723,7 @@ ath_tx_tid_hw_queue_norm(struct ath_soft DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: node %p: TID %d: called\n", __func__, an, tid->tid); - ATH_TXQ_LOCK_ASSERT(txq); + ATH_TID_LOCK_ASSERT(sc, tid); /* Check - is AMPDU pending or running? then print out something */ if (ath_tx_ampdu_pending(sc, an, tid->tid)) @@ -4691,6 +4760,9 @@ ath_tx_tid_hw_queue_norm(struct ath_soft /* Normal completion handler */ bf->bf_comp = ath_tx_normal_comp; + /* Update CLRDMASK just before this frame is queued */ + ath_tx_update_clrdmask(sc, tid, bf); + /* Program descriptors + rate control */ ath_tx_do_ratelookup(sc, bf); ath_tx_calc_duration(sc, bf);