1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-12 14:29:28 +00:00

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.
This commit is contained in:
Adrian Chadd 2012-08-15 08:14:16 +00:00
parent b74e3fbae4
commit 2b200bb4ce
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=239290

View File

@ -302,9 +302,10 @@ ath_tx_chaindesclist(struct ath_softc *sc, struct ath_buf *bf)
{
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 *sc, struct ath_buf *bf)
/*
* Fillin the remainder of the descriptor info.
*/
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;
/* 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;
/*
* 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;
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;
/*
* 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 *sc, struct ath_buf *bf)
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 *sc, struct ath_buf *bf)
__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);
}