Date: Wed, 15 Aug 2012 08:14:16 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r239290 - head/sys/dev/ath Message-ID: <201208150814.q7F8EGm8024602@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208150814.q7F8EGm8024602>