Author: avos
Date: Mon Jun 20 22:45:19 2016
New Revision: 302035
URL: https://svnweb.freebsd.org/changeset/base/302035

Log:
  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)

Modified:
  head/sys/dev/rtwn/if_rtwn.c

Modified: head/sys/dev/rtwn/if_rtwn.c
==============================================================================
--- head/sys/dev/rtwn/if_rtwn.c Mon Jun 20 22:39:32 2016        (r302034)
+++ head/sys/dev/rtwn/if_rtwn.c Mon Jun 20 22:45:19 2016        (r302035)
@@ -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
                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
                    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,
 
        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,
                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 
                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 
                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))
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to