From owner-svn-src-all@FreeBSD.ORG Wed Aug 15 08:14:17 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 277AD106564A; Wed, 15 Aug 2012 08:14:17 +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 117B18FC14; Wed, 15 Aug 2012 08:14:17 +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 q7F8EG8X024604; Wed, 15 Aug 2012 08:14:16 GMT (envelope-from adrian@svn.freebsd.org) Received: (from adrian@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7F8EGm8024602; Wed, 15 Aug 2012 08:14:16 GMT (envelope-from adrian@svn.freebsd.org) Message-Id: <201208150814.q7F8EGm8024602@svn.freebsd.org> From: Adrian Chadd Date: Wed, 15 Aug 2012 08:14:16 +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: r239290 - 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: Wed, 15 Aug 2012 08:14:17 -0000 Author: adrian Date: Wed Aug 15 08:14:16 2012 New Revision: 239290 URL: http://svn.freebsd.org/changeset/base/239290 Log: Extend the non-aggregate TX descriptor chain routine to be aware of: * the descriptor ID, and * the multi-buffer support that the EDMA chips support. This is required for successful MAC transmission of multi-descriptor frames. The MAC simply hangs if there are NULL buffers + 0 length pointers, but the descriptor did have TxMore set. This won't be done for the 11n aggregate path, as that will be modified to use the newer API (ie, ath_hal_filltxdesc() and then set first|middle| last_aggr), which will deprecate some of the current code. TODO: * Populate the numTxMaps field in the HAL, then make sure that's fetched by the driver. Then I can undo that hack. Tested: * AR9380, AP mode, TX'ing non-aggregate 802.11n frames; * AR9280, STA/AP mode, doing aggregate and non-aggregate traffic. 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 Wed Aug 15 08:06:06 2012 (r239289) +++ head/sys/dev/ath/if_ath_tx.c Wed Aug 15 08:14:16 2012 (r239290) @@ -302,9 +302,10 @@ ath_tx_chaindesclist(struct ath_softc *s { struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds, *ds0; - int i; + int i, bp, dsp; HAL_DMA_ADDR bufAddrList[4]; uint32_t segLenList[4]; + int numTxMaps = 1; /* * XXX There's txdma and txdma_mgmt; the descriptor @@ -315,20 +316,47 @@ ath_tx_chaindesclist(struct ath_softc *s /* * Fillin the remainder of the descriptor info. */ + + /* + * For now the HAL doesn't implement halNumTxMaps for non-EDMA + * (ie it's 0.) So just work around it. + * + * XXX TODO: populate halNumTxMaps for each HAL chip and + * then undo this hack. + */ + if (sc->sc_ah->ah_magic == 0x19741014) + numTxMaps = 4; + + /* + * For EDMA and later chips ensure the TX map is fully populated + * before advancing to the next descriptor. + */ ds0 = ds = bf->bf_desc; - for (i = 0; i < bf->bf_nseg; i++, ds++) { - bufAddrList[0] = bf->bf_segs[i].ds_addr; - segLenList[0] = bf->bf_segs[i].ds_len; + bp = dsp = 0; + bzero(bufAddrList, sizeof(bufAddrList)); + bzero(segLenList, sizeof(segLenList)); + for (i = 0; i < bf->bf_nseg; i++) { + bufAddrList[bp] = bf->bf_segs[i].ds_addr; + segLenList[bp] = bf->bf_segs[i].ds_len; + bp++; + + /* + * Go to the next segment if this isn't the last segment + * and there's space in the current TX map. + */ + if ((i != bf->bf_nseg - 1) && (bp < numTxMaps)) + continue; - /* Blank this out until multi-buf support is added for AR9300 */ - bufAddrList[1] = bufAddrList[2] = bufAddrList[3] = 0; - segLenList[1] = segLenList[2] = segLenList[3] = 0; + /* + * Last segment or we're out of buffer pointers. + */ + bp = 0; if (i == bf->bf_nseg - 1) ath_hal_settxdesclink(ah, ds, 0); else ath_hal_settxdesclink(ah, ds, - bf->bf_daddr + dd->dd_descsize * (i + 1)); + bf->bf_daddr + dd->dd_descsize * (dsp + 1)); /* * XXX this assumes that bfs_txq is the actual destination @@ -339,7 +367,7 @@ ath_tx_chaindesclist(struct ath_softc *s ath_hal_filltxdesc(ah, ds , bufAddrList , segLenList - , 0 /* XXX desc id */ + , bf->bf_descid /* XXX desc id */ , bf->bf_state.bfs_txq->axq_qnum /* XXX multicast? */ , i == 0 /* first segment */ , i == bf->bf_nseg - 1 /* last segment */ @@ -350,6 +378,18 @@ ath_tx_chaindesclist(struct ath_softc *s __func__, i, ds->ds_link, ds->ds_data, ds->ds_ctl0, ds->ds_ctl1, ds->ds_hw[0], ds->ds_hw[1]); bf->bf_lastds = ds; + + /* + * Don't forget to skip to the next descriptor. + */ + ds++; + dsp++; + + /* + * .. and don't forget to blank these out! + */ + bzero(bufAddrList, sizeof(bufAddrList)); + bzero(segLenList, sizeof(segLenList)); } bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); }