From owner-svn-src-user@FreeBSD.ORG Mon Jun 6 01:53:31 2011 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B803B106564A; Mon, 6 Jun 2011 01:53:31 +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 AA1098FC0A; Mon, 6 Jun 2011 01:53:31 +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 p561rVsT006403; Mon, 6 Jun 2011 01:53:31 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p561rVrw006401; Mon, 6 Jun 2011 01:53:31 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201106060153.p561rVrw006401@svn.freebsd.org> From: Adrian Chadd Date: Mon, 6 Jun 2011 01:53:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r222727 - user/adrian/if_ath_tx/sys/dev/ath X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jun 2011 01:53:31 -0000 Author: adrian Date: Mon Jun 6 01:53:31 2011 New Revision: 222727 URL: http://svn.freebsd.org/changeset/base/222727 Log: Begin separating out the "setup descriptor", "setup descriptor list" and "handoff" from the actual TX path. Packets going onto a software TX queue will need to be setup as per normal but won't be added to the hardware TX queue until later. Details: * ath_tx_start() is now ath_tx_normal_setup() - it sets up the packet, configures the first descriptor but doesn't add it to the TX queue via ath_tx_handoff(); * ath_tx_handoff() now doesn't call ath_tx_chaindesclist() to chain together descriptors as required by the MAC; * a new ath_tx_start() now: + determines the destination TX queue; + calls ath_tx_normal_setup() to do the packet and descriptor setup; + calls ath_tx_chaindesclist() to chain the descriptors together for the MAC; + calls ath_tx_handoff() to dispatch to the hardware. The packets going onto the mcast software TXQ (which is implemented just like a hardware TXQ, but with no hardware dispatch :) already do this but the decision not to dispatch them directly is done in ath_tx_handoff() which is something that needs to be uncoupled a bit better. Whilst I'm here (and having to do development on an 80x50 VGA console, due to needing to interpret kernel panics) undo some of my brain damaged non-style(9) commits. Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Modified: user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c ============================================================================== --- user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Mon Jun 6 01:52:15 2011 (r222726) +++ user/adrian/if_ath_tx/sys/dev/ath/if_ath_tx.c Mon Jun 6 01:53:31 2011 (r222727) @@ -226,7 +226,8 @@ ath_tx_dmasetup(struct ath_softc *sc, st } static void -ath_tx_chaindesclist(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf) +ath_tx_chaindesclist(struct ath_softc *sc, struct ath_txq *txq, + struct ath_buf *bf) { struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds, *ds0; @@ -261,9 +262,6 @@ ath_tx_handoff(struct ath_softc *sc, str { struct ath_hal *ah = sc->sc_ah; - /* Fill in the details in the descriptor list */ - ath_tx_chaindesclist(sc, txq, bf); - /* * Insert the frame on the outbound list and pass it on * to the hardware. Multicast frames buffered for power @@ -488,9 +486,9 @@ ath_tx_calc_ctsduration(struct ath_hal * return ctsduration; } -int -ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, - struct mbuf *m0) +static int +ath_tx_normal_setup(struct ath_softc *sc, struct ieee80211_node *ni, + struct ath_buf *bf, struct mbuf *m0) { struct ieee80211vap *vap = ni->ni_vap; struct ath_vap *avp = ATH_VAP(vap); @@ -528,7 +526,8 @@ ath_tx_start(struct ath_softc *sc, struc pktlen = m0->m_pkthdr.len - (hdrlen & 3); /* Handle encryption twiddling if needed */ - if (! ath_tx_tag_crypto(sc, ni, m0, iswep, isfrag, &hdrlen, &pktlen, &keyix)) { + if (! ath_tx_tag_crypto(sc, ni, m0, iswep, isfrag, &hdrlen, + &pktlen, &keyix)) { ath_freetx(m0); return EIO; } @@ -774,6 +773,32 @@ ath_tx_start(struct ath_softc *sc, struc } else ctsrate = 0; + + /* + * Determine if a tx interrupt should be generated for + * this descriptor. We take a tx interrupt to reap + * descriptors when the h/w hits an EOL condition or + * when the descriptor is specifically marked to generate + * an interrupt. We periodically mark descriptors in this + * way to insure timely replenishing of the supply needed + * for sending frames. Defering interrupts reduces system + * load and potentially allows more concurrent work to be + * done but if done to aggressively can cause senders to + * backup. + * + * NB: use >= to deal with sc_txintrperiod changing + * dynamically through sysctl. + */ + if (flags & HAL_TXDESC_INTREQ) { + txq->axq_intrcnt = 0; + } else if (++txq->axq_intrcnt >= sc->sc_txintrperiod) { + flags |= HAL_TXDESC_INTREQ; + txq->axq_intrcnt = 0; + } + + /* This point forward is actual TX bits */ + + /* * At this point we are committed to sending the frame * and we don't need to look at m_nextpkt; clear it in @@ -801,27 +826,6 @@ ath_tx_start(struct ath_softc *sc, struc ieee80211_radiotap_tx(vap, m0); } - /* - * Determine if a tx interrupt should be generated for - * this descriptor. We take a tx interrupt to reap - * descriptors when the h/w hits an EOL condition or - * when the descriptor is specifically marked to generate - * an interrupt. We periodically mark descriptors in this - * way to insure timely replenishing of the supply needed - * for sending frames. Defering interrupts reduces system - * load and potentially allows more concurrent work to be - * done but if done to aggressively can cause senders to - * backup. - * - * NB: use >= to deal with sc_txintrperiod changing - * dynamically through sysctl. - */ - if (flags & HAL_TXDESC_INTREQ) { - txq->axq_intrcnt = 0; - } else if (++txq->axq_intrcnt >= sc->sc_txintrperiod) { - flags |= HAL_TXDESC_INTREQ; - txq->axq_intrcnt = 0; - } if (ath_tx_is_11n(sc)) { rate[0] = rix; @@ -862,10 +866,57 @@ ath_tx_start(struct ath_softc *sc, struc } if (ath_tx_is_11n(sc)) { - ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, (atype == HAL_PKT_TYPE_PSPOLL), rate, try); + ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, + (atype == HAL_PKT_TYPE_PSPOLL), rate, try); } + return 0; +} + +/* + * Direct-dispatch the current frame to the hardware. + */ +int +ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, + struct ath_buf *bf, struct mbuf *m0) +{ + struct ieee80211vap *vap = ni->ni_vap; + struct ath_vap *avp = ATH_VAP(vap); + int r; + u_int pri; + struct ath_txq *txq; + int ismcast; + const struct ieee80211_frame *wh; + + /* Determine the target hardware queue! */ + pri = M_WME_GETAC(m0); /* honor classification */ + txq = sc->sc_ac2q[pri]; + wh = mtod(m0, struct ieee80211_frame *); + ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); + + /* Multicast frames go onto the software multicat queue */ + if (ismcast && (vap->iv_ps_sta || avp->av_mcastq.axq_depth)) + txq = &avp->av_mcastq; + + /* Do the generic frame setup */ + /* This also sets up the DMA map */ + r = ath_tx_normal_setup(sc, ni, bf, m0); + + if (r != 0) + return r; + + /* At this point m0 could have changed! */ + //m0 = bf->bf_m; + + /* Fill in the details in the descriptor list */ + ath_tx_chaindesclist(sc, txq, bf); + + /* + * For now, since there's no software queue, + * direct-dispatch to the hardware. + */ ath_tx_handoff(sc, txq, bf); + return 0; } @@ -1051,10 +1102,14 @@ ath_tx_raw_start(struct ath_softc *sc, s * notice that rix doesn't include any of the "magic" flags txrate * does for communicating "other stuff" to the HAL. */ - ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, (atype == HAL_PKT_TYPE_PSPOLL), rate, try); + ath_buf_set_rate(sc, ni, bf, pktlen, flags, ctsrate, + (atype == HAL_PKT_TYPE_PSPOLL), rate, try); } /* NB: no buffered multicast in power save support */ + + /* Fill in the details in the descriptor list */ + ath_tx_chaindesclist(sc, sc->sc_ac2q[pri], bf); ath_tx_handoff(sc, sc->sc_ac2q[pri], bf); return 0; }