From owner-svn-src-all@FreeBSD.ORG Sun Aug 12 00:37:29 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C7E1A106566B; Sun, 12 Aug 2012 00:37:29 +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 B121D8FC0A; Sun, 12 Aug 2012 00:37:29 +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 q7C0bTZr017208; Sun, 12 Aug 2012 00:37:29 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7C0bTZo017201; Sun, 12 Aug 2012 00:37:29 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201208120037.q7C0bTZo017201@svn.freebsd.org> From: Adrian Chadd Date: Sun, 12 Aug 2012 00:37:29 +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: r239204 - head/sys/dev/ath X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Aug 2012 00:37:29 -0000 Author: adrian Date: Sun Aug 12 00:37:29 2012 New Revision: 239204 URL: http://svn.freebsd.org/changeset/base/239204 Log: Break out ath_draintxq() into a method and un-methodize ath_tx_processq(). Now that I understand what's going on with this, I've realised that it's going to be quite difficult to implement a processq method in the EDMA case. Because there's a separate TX status FIFO, I can't just run processq() on each EDMA TXQ to see what's finished. i have to actually run the TX status queue and handle individual TXQs. So: * unmethodize ath_tx_processq(); * leave ath_tx_draintxq() as a method, as it only uses the completion status for debugging rather than actively completing the frames (ie, all frames here are failed); * Methodize ath_draintxq(). The EDMA ath_draintxq() will have to take care of running the TX completion FIFO before (potentially) freeing frames in the queue. The only two places where ath_tx_draintxq() (on a single TXQ) are used: * ath_draintxq(); and * the CABQ handling in the beacon setup code - it drains the CABQ before populating the CABQ with frames for a new beacon (when doing multi-VAP operation.) So it's quite possible that once I methodize the CABQ and beacon handling, I can just drop ath_tx_draintxq() in its entirety. Finally, it's also quite possible that I can remove ath_tx_draintxq() in the future and just "teach" it to not check the status when doing EDMA. Modified: head/sys/dev/ath/if_ath.c head/sys/dev/ath/if_ath_misc.h head/sys/dev/ath/if_ath_tx.c head/sys/dev/ath/if_ath_tx.h head/sys/dev/ath/if_ath_tx_edma.c head/sys/dev/ath/if_athvar.h Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Sun Aug 12 00:25:35 2012 (r239203) +++ head/sys/dev/ath/if_ath.c Sun Aug 12 00:37:29 2012 (r239204) @@ -168,12 +168,13 @@ static struct ath_txq *ath_txq_setup(str static int ath_tx_setup(struct ath_softc *, int, int); static void ath_tx_cleanupq(struct ath_softc *, struct ath_txq *); static void ath_tx_cleanup(struct ath_softc *); +static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, + int dosched); static void ath_tx_proc_q0(void *, int); static void ath_tx_proc_q0123(void *, int); static void ath_tx_proc(void *, int); static void ath_txq_sched_tasklet(void *, int); static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *); -static void ath_draintxq(struct ath_softc *, ATH_RESET_TYPE reset_type); static void ath_chan_change(struct ath_softc *, struct ieee80211_channel *); static void ath_scan_start(struct ieee80211com *); static void ath_scan_end(struct ieee80211com *); @@ -3585,8 +3586,8 @@ ath_tx_update_busy(struct ath_softc *sc) * Kick the packet scheduler if needed. This can occur from this * particular task. */ -int -ath_legacy_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) +static int +ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) { struct ath_hal *ah = sc->sc_ah; struct ath_buf *bf; @@ -4093,8 +4094,8 @@ ath_stoptxdma(struct ath_softc *sc) /* * Drain the transmit queues and reclaim resources. */ -static void -ath_draintxq(struct ath_softc *sc, ATH_RESET_TYPE reset_type) +void +ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) { #ifdef ATH_DEBUG struct ath_hal *ah = sc->sc_ah; Modified: head/sys/dev/ath/if_ath_misc.h ============================================================================== --- head/sys/dev/ath/if_ath_misc.h Sun Aug 12 00:25:35 2012 (r239203) +++ head/sys/dev/ath/if_ath_misc.h Sun Aug 12 00:37:29 2012 (r239204) @@ -96,9 +96,10 @@ extern void ath_descdma_cleanup(struct a struct ath_descdma *dd, ath_bufhead *head); extern void ath_legacy_attach_comp_func(struct ath_softc *sc); + extern void ath_legacy_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq); -extern int ath_legacy_tx_processq(struct ath_softc *sc, struct ath_txq *txq, - int dosched); +extern void ath_legacy_tx_drain(struct ath_softc *sc, + ATH_RESET_TYPE reset_type); /* * This is only here so that the RX proc function can call it. Modified: head/sys/dev/ath/if_ath_tx.c ============================================================================== --- head/sys/dev/ath/if_ath_tx.c Sun Aug 12 00:25:35 2012 (r239203) +++ head/sys/dev/ath/if_ath_tx.c Sun Aug 12 00:37:29 2012 (r239204) @@ -4571,6 +4571,7 @@ ath_xmit_setup_legacy(struct ath_softc * sc->sc_tx.xmit_dma_restart = ath_legacy_tx_dma_restart; sc->sc_tx.xmit_handoff = ath_legacy_xmit_handoff; - sc->sc_tx.xmit_processq = ath_legacy_tx_processq; + sc->sc_tx.xmit_drainq = ath_legacy_tx_draintxq; + sc->sc_tx.xmit_drain = ath_legacy_tx_drain; } Modified: head/sys/dev/ath/if_ath_tx.h ============================================================================== --- head/sys/dev/ath/if_ath_tx.h Sun Aug 12 00:25:35 2012 (r239203) +++ head/sys/dev/ath/if_ath_tx.h Sun Aug 12 00:37:29 2012 (r239204) @@ -134,10 +134,11 @@ extern void ath_addba_response_timeout(s (_sc)->sc_tx.xmit_dma_restart((_sc), (_txq)) #define ath_tx_handoff(_sc, _txq, _bf) \ (_sc)->sc_tx.xmit_handoff((_sc), (_txq), (_bf)) + #define ath_tx_draintxq(_sc, _txq) \ (_sc)->sc_tx.xmit_drainq((_sc), (_txq)) -#define ath_tx_processq(_sc, _txq, _dosched) \ - (_sc)->sc_tx.xmit_processq((_sc), (_txq), (_dosched)) +#define ath_draintxq(_sc, _rtype) \ + (_sc)->sc_tx.xmit_drain((_sc), (_rtype)) extern void ath_xmit_setup_legacy(struct ath_softc *sc); Modified: head/sys/dev/ath/if_ath_tx_edma.c ============================================================================== --- head/sys/dev/ath/if_ath_tx_edma.c Sun Aug 12 00:25:35 2012 (r239203) +++ head/sys/dev/ath/if_ath_tx_edma.c Sun Aug 12 00:37:29 2012 (r239204) @@ -349,26 +349,21 @@ ath_edma_dma_txteardown(struct ath_softc } /* - * Process frames in the current queue and if necessary, re-schedule the - * software TXQ scheduler for this TXQ. - * - * XXX This is again a pain in the ass to do because the status descriptor - * information is in the TX status FIFO, not with the current descriptor. + * Drain all TXQs, potentially after completing the existing completed + * frames. */ -static int -ath_edma_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) +static void +ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type) { device_printf(sc->sc_dev, "%s: called\n", __func__); - return (0); } /* * Completely drain the TXQ, completing frames that were completed. * - * XXX this is going to be a complete pain in the ass because the - * completion status is in the TX status FIFO, not with the descriptor - * itself. Sigh. + * This is only called to _explictly_ drain the frames from a queue + * without caring if they were completed or not. */ static void ath_edma_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) @@ -446,6 +441,6 @@ ath_xmit_setup_edma(struct ath_softc *sc sc->sc_tx.xmit_dma_restart = ath_edma_dma_restart; sc->sc_tx.xmit_handoff = ath_edma_xmit_handoff; - sc->sc_tx.xmit_processq = ath_edma_tx_processq; sc->sc_tx.xmit_drainq = ath_edma_tx_draintxq; + sc->sc_tx.xmit_drain = ath_edma_tx_drain; } Modified: head/sys/dev/ath/if_athvar.h ============================================================================== --- head/sys/dev/ath/if_athvar.h Sun Aug 12 00:25:35 2012 (r239203) +++ head/sys/dev/ath/if_athvar.h Sun Aug 12 00:37:29 2012 (r239204) @@ -417,10 +417,15 @@ struct ath_tx_methods { void (*xmit_handoff)(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf); + /* + * This is only required by the CABQ code as well as + * xmit_drain(). + */ void (*xmit_drainq)(struct ath_softc *sc, struct ath_txq *txq); - int (*xmit_processq)(struct ath_softc *sc, - struct ath_txq *txq, int dosched); + + void (*xmit_drain)(struct ath_softc *sc, + ATH_RESET_TYPE reset_type); }; struct ath_softc {