Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Jun 2016 22:45:19 +0000 (UTC)
From:      Andriy Voskoboinyk <avos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r302035 - head/sys/dev/rtwn
Message-ID:  <201606202245.u5KMjJLv046231@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606202245.u5KMjJLv046231>