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:
parent
b74e3fbae4
commit
2b200bb4ce
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=239290
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user