From owner-svn-src-head@FreeBSD.ORG Tue Nov 8 18:45:15 2011 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D75FF106566C; Tue, 8 Nov 2011 18:45:15 +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 C68D08FC19; Tue, 8 Nov 2011 18:45:15 +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 pA8IjFTt043844; Tue, 8 Nov 2011 18:45:15 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pA8IjFN8043842; Tue, 8 Nov 2011 18:45:15 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201111081845.pA8IjFN8043842@svn.freebsd.org> From: Adrian Chadd Date: Tue, 8 Nov 2011 18:45:15 +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: r227351 - 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: Tue, 08 Nov 2011 18:45:15 -0000 Author: adrian Date: Tue Nov 8 18:45:15 2011 New Revision: 227351 URL: http://svn.freebsd.org/changeset/base/227351 Log: Preparation for correct 802.11n tx/rx handling. * Change ath_rx_proc() to ath_rx_tasklet(); make that the taskqueue function. This way (eventually) ath_rx_proc() can be called from elsewhere in the packet reset/processing queue so frames aren't just "flushed" during interface resets/reconfigure. This breaks 802.11n RX aggregation tracking. * Extend ath_tx_proc() to take a 'resched' flag, which marks whether to reschedule further RX PCU reads or not. * Change ath_tx_processq() to take a "dosched" flag, which will eventually be used to indicate whether to reschedule the software TX scheduler. Sponsored by: Hobnob, Inc. Modified: head/sys/dev/ath/if_ath.c Modified: head/sys/dev/ath/if_ath.c ============================================================================== --- head/sys/dev/ath/if_ath.c Tue Nov 8 18:37:52 2011 (r227350) +++ head/sys/dev/ath/if_ath.c Tue Nov 8 18:45:15 2011 (r227351) @@ -170,7 +170,8 @@ static int ath_rxbuf_init(struct ath_sof static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi, int nf); static void ath_setdefantenna(struct ath_softc *, u_int); -static void ath_rx_proc(void *, int); +static void ath_rx_proc(struct ath_softc *sc, int); +static void ath_rx_tasklet(void *, int); static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int); static struct ath_txq *ath_txq_setup(struct ath_softc*, int qtype, int subtype); static int ath_tx_setup(struct ath_softc *, int, int); @@ -382,7 +383,7 @@ ath_attach(u_int16_t devid, struct ath_s taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", ifp->if_xname); - TASK_INIT(&sc->sc_rxtask, 0, ath_rx_proc, sc); + TASK_INIT(&sc->sc_rxtask, 0, ath_rx_tasklet, sc); TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc); @@ -3505,13 +3506,27 @@ ath_handle_micerror(struct ieee80211com } } +/* + * Only run the RX proc if it's not already running. + * Since this may get run as part of the reset/flush path, + * the task can't clash with an existing, running tasklet. + */ static void -ath_rx_proc(void *arg, int npending) +ath_rx_tasklet(void *arg, int npending) +{ + struct ath_softc *sc = arg; + + CTR1(ATH_KTR_INTR, "ath_rx_proc: pending=%d", npending); + DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); + ath_rx_proc(sc, 1); +} + +static void +ath_rx_proc(struct ath_softc *sc, int resched) { #define PA2DESC(_sc, _pa) \ ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \ ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) - struct ath_softc *sc = arg; struct ath_buf *bf; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; @@ -3526,7 +3541,7 @@ ath_rx_proc(void *arg, int npending) u_int64_t tsf; int npkts = 0; - DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); + DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: called\n", __func__); ngood = 0; nf = ath_hal_getchannoise(ah, sc->sc_curchan); sc->sc_stats.ast_rx_noise = nf; @@ -3862,7 +3877,7 @@ rx_next: sc->sc_lastrx = tsf; /* Queue DFS tasklet if needed */ - if (ath_dfs_tasklet_needed(sc, sc->sc_curchan)) + if (resched && ath_dfs_tasklet_needed(sc, sc->sc_curchan)) taskqueue_enqueue(sc->sc_tq, &sc->sc_dfstask); /* @@ -3870,7 +3885,7 @@ rx_next: * need to be handled, kick the PCU if there's * been an RXEOL condition. */ - if (sc->sc_kickpcu) { + if (resched && sc->sc_kickpcu) { device_printf(sc->sc_dev, "%s: kickpcu; handled %d packets\n", __func__, npkts); @@ -3887,7 +3902,7 @@ rx_next: ATH_UNLOCK(sc); } - if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { + if (resched && (ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) { #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_ff_age_all(ic, 100); #endif @@ -4121,7 +4136,7 @@ ath_tx_findrix(const struct ath_softc *s * Process completed xmit descriptors from the specified queue. */ static int -ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) +ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq, int dosched) { struct ath_hal *ah = sc->sc_ah; struct ifnet *ifp = sc->sc_ifp; @@ -4287,11 +4302,11 @@ ath_tx_proc_q0(void *arg, int npending) sc->sc_txq_active &= ~txqs; ATH_UNLOCK(sc); - if (TXQACTIVE(txqs, 0) && ath_tx_processq(sc, &sc->sc_txq[0])) + if (TXQACTIVE(txqs, 0) && ath_tx_processq(sc, &sc->sc_txq[0], 1)) /* XXX why is lastrx updated in tx code? */ sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum)) - ath_tx_processq(sc, sc->sc_cabq); + ath_tx_processq(sc, sc->sc_cabq, 1); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; sc->sc_wd_timer = 0; @@ -4323,15 +4338,15 @@ ath_tx_proc_q0123(void *arg, int npendin */ nacked = 0; if (TXQACTIVE(txqs, 0)) - nacked += ath_tx_processq(sc, &sc->sc_txq[0]); + nacked += ath_tx_processq(sc, &sc->sc_txq[0], 1); if (TXQACTIVE(txqs, 1)) - nacked += ath_tx_processq(sc, &sc->sc_txq[1]); + nacked += ath_tx_processq(sc, &sc->sc_txq[1], 1); if (TXQACTIVE(txqs, 2)) - nacked += ath_tx_processq(sc, &sc->sc_txq[2]); + nacked += ath_tx_processq(sc, &sc->sc_txq[2], 1); if (TXQACTIVE(txqs, 3)) - nacked += ath_tx_processq(sc, &sc->sc_txq[3]); + nacked += ath_tx_processq(sc, &sc->sc_txq[3], 1); if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum)) - ath_tx_processq(sc, sc->sc_cabq); + ath_tx_processq(sc, sc->sc_cabq, 1); if (nacked) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah); @@ -4366,7 +4381,7 @@ ath_tx_proc(void *arg, int npending) nacked = 0; for (i = 0; i < HAL_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i) && TXQACTIVE(txqs, i)) - nacked += ath_tx_processq(sc, &sc->sc_txq[i]); + nacked += ath_tx_processq(sc, &sc->sc_txq[i], 1); if (nacked) sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);