rtwn: fix Tx processing, add some busdma synchronization.

1) Unload mbuf instead of descriptor in rtwn_tx_done().
2) Add more synchronization for device visible mappings before
touching the memory.
3) Improve watchdog timer logic.

Reported and tested by:		mva

Approved by:	re (gjb)
This commit is contained in:
avos 2016-06-20 22:45:19 +00:00
parent 39bab70fa6
commit 48e577c3c1

View File

@ -586,6 +586,9 @@ rtwn_free_rx_list(struct rtwn_softc *sc)
if (rx_ring->desc_dmat != NULL) {
if (rx_ring->desc != NULL) {
bus_dmamap_sync(rx_ring->desc_dmat,
rx_ring->desc_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(rx_ring->desc_dmat,
rx_ring->desc_map);
bus_dmamem_free(rx_ring->desc_dmat, rx_ring->desc,
@ -600,6 +603,8 @@ rtwn_free_rx_list(struct rtwn_softc *sc)
rx_data = &rx_ring->rx_data[i];
if (rx_data->m != NULL) {
bus_dmamap_sync(rx_ring->data_dmat,
rx_data->map, BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(rx_ring->data_dmat, rx_data->map);
m_freem(rx_data->m);
rx_data->m = NULL;
@ -643,6 +648,8 @@ rtwn_alloc_tx_list(struct rtwn_softc *sc, int qid)
device_printf(sc->sc_dev, "could not load desc DMA map\n");
goto fail;
}
bus_dmamap_sync(tx_ring->desc_dmat, tx_ring->desc_map,
BUS_DMASYNC_PREWRITE);
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
@ -691,6 +698,8 @@ rtwn_reset_tx_list(struct rtwn_softc *sc, int qid)
sizeof(desc->nextdescaddr)));
if (tx_data->m != NULL) {
bus_dmamap_sync(tx_ring->data_dmat, tx_data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(tx_ring->data_dmat, tx_data->map);
m_freem(tx_data->m);
tx_data->m = NULL;
@ -718,6 +727,8 @@ rtwn_free_tx_list(struct rtwn_softc *sc, int qid)
if (tx_ring->desc_dmat != NULL) {
if (tx_ring->desc != NULL) {
bus_dmamap_sync(tx_ring->desc_dmat,
tx_ring->desc_map, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(tx_ring->desc_dmat,
tx_ring->desc_map);
bus_dmamem_free(tx_ring->desc_dmat, tx_ring->desc,
@ -730,6 +741,8 @@ rtwn_free_tx_list(struct rtwn_softc *sc, int qid)
tx_data = &tx_ring->tx_data[i];
if (tx_data->m != NULL) {
bus_dmamap_sync(tx_ring->data_dmat, tx_data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(tx_ring->data_dmat, tx_data->map);
m_freem(tx_data->m);
tx_data->m = NULL;
@ -1761,7 +1774,10 @@ rtwn_tx_done(struct rtwn_softc *sc, int qid)
if (le32toh(tx_desc->txdw0) & R92C_TXDW0_OWN)
continue;
bus_dmamap_unload(tx_ring->desc_dmat, tx_ring->desc_map);
/* Unmap and free mbuf. */
bus_dmamap_sync(tx_ring->data_dmat, tx_data->map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(tx_ring->data_dmat, tx_data->map);
/*
* XXX TODO: figure out whether the transmit succeeded or not.
@ -1771,8 +1787,10 @@ rtwn_tx_done(struct rtwn_softc *sc, int qid)
tx_data->ni = NULL;
tx_data->m = NULL;
sc->sc_tx_timer = 0;
tx_ring->queued--;
if (--tx_ring->queued)
sc->sc_tx_timer = 5;
else
sc->sc_tx_timer = 0;
}
if (tx_ring->queued < (RTWN_TX_LIST_COUNT - 1))