Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Nov 2009 18:07:09 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r198913 - stable/7/sys/dev/fxp
Message-ID:  <200911041807.nA4I79MQ041179@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Wed Nov  4 18:07:09 2009
New Revision: 198913
URL: http://svn.freebsd.org/changeset/base/198913

Log:
  MFC r194569:
    Introduce Rx mbuf dma tag and use it in Rx path. Previously it used
    common mbuf dma tag for both Tx and Rx path but Rx buffer should
    have single DMA segment and maximum buffer size of the segment
    should be less than MCLBYTES.
    fxp(4) also have to check Tx completion status which was updated by
    DMA so we need BUS_DMASYNC_PREREAD and BUS_DMASYNC_POSTWRITE
    synchronization in Tx path. Fix all misuse of bus_dmamap_sync(9) in
    fxp(4). I guess this change shall fix occasional driver breakage in
    PAE environments.
  
    While I'm here add error messages of dma tag/buffer creation and
    correct messages.

Modified:
  stable/7/sys/dev/fxp/if_fxp.c
  stable/7/sys/dev/fxp/if_fxpvar.h
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/fxp/if_fxp.c
==============================================================================
--- stable/7/sys/dev/fxp/if_fxp.c	Wed Nov  4 18:03:19 2009	(r198912)
+++ stable/7/sys/dev/fxp/if_fxp.c	Wed Nov  4 18:07:09 2009	(r198913)
@@ -643,9 +643,18 @@ fxp_attach(device_t dev)
 	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
 	    sc->maxsegsize * sc->maxtxseg + sizeof(struct ether_vlan_header),
 	    sc->maxtxseg, sc->maxsegsize, 0,
-	    busdma_lock_mutex, &Giant, &sc->fxp_mtag);
+	    busdma_lock_mutex, &Giant, &sc->fxp_txmtag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
+		device_printf(dev, "could not create TX DMA tag\n");
+		goto fail;
+	}
+
+	error = bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    MCLBYTES, 1, MCLBYTES, 0,
+	    busdma_lock_mutex, &Giant, &sc->fxp_rxmtag);
+	if (error) {
+		device_printf(dev, "could not create RX DMA tag\n");
 		goto fail;
 	}
 
@@ -654,18 +663,20 @@ fxp_attach(device_t dev)
 	    sizeof(struct fxp_stats), 1, sizeof(struct fxp_stats), 0,
 	    busdma_lock_mutex, &Giant, &sc->fxp_stag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
+		device_printf(dev, "could not create stats DMA tag\n");
 		goto fail;
 	}
 
 	error = bus_dmamem_alloc(sc->fxp_stag, (void **)&sc->fxp_stats,
 	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->fxp_smap);
-	if (error)
+	if (error) {
+		device_printf(dev, "could not allocate stats DMA memory\n");
 		goto fail;
+	}
 	error = bus_dmamap_load(sc->fxp_stag, sc->fxp_smap, sc->fxp_stats,
 	    sizeof(struct fxp_stats), fxp_dma_map_addr, &sc->stats_addr, 0);
 	if (error) {
-		device_printf(dev, "could not map the stats buffer\n");
+		device_printf(dev, "could not load the stats DMA buffer\n");
 		goto fail;
 	}
 
@@ -674,20 +685,22 @@ fxp_attach(device_t dev)
 	    FXP_TXCB_SZ, 1, FXP_TXCB_SZ, 0,
 	    busdma_lock_mutex, &Giant, &sc->cbl_tag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
+		device_printf(dev, "could not create TxCB DMA tag\n");
 		goto fail;
 	}
 
 	error = bus_dmamem_alloc(sc->cbl_tag, (void **)&sc->fxp_desc.cbl_list,
 	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->cbl_map);
-	if (error)
+	if (error) {
+		device_printf(dev, "could not allocate TxCB DMA memory\n");
 		goto fail;
+	}
 
 	error = bus_dmamap_load(sc->cbl_tag, sc->cbl_map,
 	    sc->fxp_desc.cbl_list, FXP_TXCB_SZ, fxp_dma_map_addr,
 	    &sc->fxp_desc.cbl_addr, 0);
 	if (error) {
-		device_printf(dev, "could not map DMA memory\n");
+		device_printf(dev, "could not load TxCB DMA buffer\n");
 		goto fail;
 	}
 
@@ -696,18 +709,23 @@ fxp_attach(device_t dev)
 	    sizeof(struct fxp_cb_mcs), 1, sizeof(struct fxp_cb_mcs), 0,
 	    busdma_lock_mutex, &Giant, &sc->mcs_tag);
 	if (error) {
-		device_printf(dev, "could not allocate dma tag\n");
+		device_printf(dev,
+		    "could not create multicast setup DMA tag\n");
 		goto fail;
 	}
 
 	error = bus_dmamem_alloc(sc->mcs_tag, (void **)&sc->mcsp,
-	    BUS_DMA_NOWAIT, &sc->mcs_map);
-	if (error)
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->mcs_map);
+	if (error) {
+		device_printf(dev,
+		    "could not allocate multicast setup DMA memory\n");
 		goto fail;
+	}
 	error = bus_dmamap_load(sc->mcs_tag, sc->mcs_map, sc->mcsp,
 	    sizeof(struct fxp_cb_mcs), fxp_dma_map_addr, &sc->mcs_addr, 0);
 	if (error) {
-		device_printf(dev, "can't map the multicast setup command\n");
+		device_printf(dev,
+		    "can't load the multicast setup DMA buffer\n");
 		goto fail;
 	}
 
@@ -719,13 +737,13 @@ fxp_attach(device_t dev)
 	tcbp = sc->fxp_desc.cbl_list;
 	for (i = 0; i < FXP_NTXCB; i++) {
 		txp[i].tx_cb = tcbp + i;
-		error = bus_dmamap_create(sc->fxp_mtag, 0, &txp[i].tx_map);
+		error = bus_dmamap_create(sc->fxp_txmtag, 0, &txp[i].tx_map);
 		if (error) {
 			device_printf(dev, "can't create DMA map for TX\n");
 			goto fail;
 		}
 	}
-	error = bus_dmamap_create(sc->fxp_mtag, 0, &sc->spare_map);
+	error = bus_dmamap_create(sc->fxp_rxmtag, 0, &sc->spare_map);
 	if (error) {
 		device_printf(dev, "can't create spare DMA map\n");
 		goto fail;
@@ -737,7 +755,7 @@ fxp_attach(device_t dev)
 	sc->fxp_desc.rx_head = sc->fxp_desc.rx_tail = NULL;
 	for (i = 0; i < FXP_NRFABUFS; i++) {
 		rxp = &sc->fxp_desc.rx_list[i];
-		error = bus_dmamap_create(sc->fxp_mtag, 0, &rxp->rx_map);
+		error = bus_dmamap_create(sc->fxp_rxmtag, 0, &rxp->rx_map);
 		if (error) {
 			device_printf(dev, "can't create DMA map for RX\n");
 			goto fail;
@@ -911,29 +929,32 @@ fxp_release(struct fxp_softc *sc)
 		bus_dmamem_free(sc->mcs_tag, sc->mcsp, sc->mcs_map);
 	}
 	bus_release_resources(sc->dev, sc->fxp_spec, sc->fxp_res);
-	if (sc->fxp_mtag) {
+	if (sc->fxp_rxmtag) {
 		for (i = 0; i < FXP_NRFABUFS; i++) {
 			rxp = &sc->fxp_desc.rx_list[i];
 			if (rxp->rx_mbuf != NULL) {
-				bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map,
+				bus_dmamap_sync(sc->fxp_rxmtag, rxp->rx_map,
 				    BUS_DMASYNC_POSTREAD);
-				bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map);
+				bus_dmamap_unload(sc->fxp_rxmtag, rxp->rx_map);
 				m_freem(rxp->rx_mbuf);
 			}
-			bus_dmamap_destroy(sc->fxp_mtag, rxp->rx_map);
+			bus_dmamap_destroy(sc->fxp_rxmtag, rxp->rx_map);
 		}
-		bus_dmamap_destroy(sc->fxp_mtag, sc->spare_map);
+		bus_dmamap_destroy(sc->fxp_rxmtag, sc->spare_map);
+		bus_dma_tag_destroy(sc->fxp_rxmtag);
+	}
+	if (sc->fxp_txmtag) {
 		for (i = 0; i < FXP_NTXCB; i++) {
 			txp = &sc->fxp_desc.tx_list[i];
 			if (txp->tx_mbuf != NULL) {
-				bus_dmamap_sync(sc->fxp_mtag, txp->tx_map,
+				bus_dmamap_sync(sc->fxp_txmtag, txp->tx_map,
 				    BUS_DMASYNC_POSTWRITE);
-				bus_dmamap_unload(sc->fxp_mtag, txp->tx_map);
+				bus_dmamap_unload(sc->fxp_txmtag, txp->tx_map);
 				m_freem(txp->tx_mbuf);
 			}
-			bus_dmamap_destroy(sc->fxp_mtag, txp->tx_map);
+			bus_dmamap_destroy(sc->fxp_txmtag, txp->tx_map);
 		}
-		bus_dma_tag_destroy(sc->fxp_mtag);
+		bus_dma_tag_destroy(sc->fxp_txmtag);
 	}
 	if (sc->fxp_stag)
 		bus_dma_tag_destroy(sc->fxp_stag);
@@ -1325,7 +1346,8 @@ fxp_start_body(struct ifnet *ifp)
 	 * going again if suspended.
 	 */
 	if (txqueued > 0) {
-		bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE);
+		bus_dmamap_sync(sc->cbl_tag, sc->cbl_map,
+		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 		fxp_scb_wait(sc);
 		fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
 		/*
@@ -1499,7 +1521,7 @@ fxp_encap(struct fxp_softc *sc, struct m
 		*m_head = m;
 	}
 
-	error = bus_dmamap_load_mbuf_sg(sc->fxp_mtag, txp->tx_map, *m_head,
+	error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, *m_head,
 	    segs, &nseg, 0);
 	if (error == EFBIG) {
 		m = m_collapse(*m_head, M_DONTWAIT, sc->maxtxseg);
@@ -1509,7 +1531,7 @@ fxp_encap(struct fxp_softc *sc, struct m
 			return (ENOMEM);
 		}
 		*m_head = m;
-		error = bus_dmamap_load_mbuf_sg(sc->fxp_mtag, txp->tx_map,
+		error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map,
 	    	    *m_head, segs, &nseg, 0);
 		if (error != 0) {
 			m_freem(*m_head);
@@ -1525,7 +1547,7 @@ fxp_encap(struct fxp_softc *sc, struct m
 	}
 
 	KASSERT(nseg <= sc->maxtxseg, ("too many DMA segments"));
-	bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->fxp_txmtag, txp->tx_map, BUS_DMASYNC_PREWRITE);
 
 	cbp = txp->tx_cb;
 	for (i = 0; i < nseg; i++) {
@@ -1705,14 +1727,15 @@ fxp_txeof(struct fxp_softc *sc)
 	struct fxp_tx *txp;
 
 	ifp = sc->ifp;
-	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREREAD);
+	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map,
+	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 	for (txp = sc->fxp_desc.tx_first; sc->tx_queued &&
 	    (le16toh(txp->tx_cb->cb_status) & FXP_CB_STATUS_C) != 0;
 	    txp = txp->tx_next) {
 		if (txp->tx_mbuf != NULL) {
-			bus_dmamap_sync(sc->fxp_mtag, txp->tx_map,
+			bus_dmamap_sync(sc->fxp_txmtag, txp->tx_map,
 			    BUS_DMASYNC_POSTWRITE);
-			bus_dmamap_unload(sc->fxp_mtag, txp->tx_map);
+			bus_dmamap_unload(sc->fxp_txmtag, txp->tx_map);
 			m_freem(txp->tx_mbuf);
 			txp->tx_mbuf = NULL;
 			/* clear this to reset csum offload bits */
@@ -1722,7 +1745,8 @@ fxp_txeof(struct fxp_softc *sc)
 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	}
 	sc->fxp_desc.tx_first = txp;
-	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	if (sc->tx_queued == 0) {
 		sc->watchdog_timer = 0;
 		if (sc->need_mcsetup)
@@ -1874,7 +1898,7 @@ fxp_intr_body(struct fxp_softc *sc, stru
 		m = rxp->rx_mbuf;
 		rfa = (struct fxp_rfa *)(m->m_ext.ext_buf +
 		    RFA_ALIGNMENT_FUDGE);
-		bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map,
+		bus_dmamap_sync(sc->fxp_rxmtag, rxp->rx_map,
 		    BUS_DMASYNC_POSTREAD);
 
 #ifdef DEVICE_POLLING /* loop at most count times if count >=0 */
@@ -2107,9 +2131,10 @@ fxp_stop(struct fxp_softc *sc)
 	if (txp != NULL) {
 		for (i = 0; i < FXP_NTXCB; i++) {
  			if (txp[i].tx_mbuf != NULL) {
-				bus_dmamap_sync(sc->fxp_mtag, txp[i].tx_map,
+				bus_dmamap_sync(sc->fxp_txmtag, txp[i].tx_map,
 				    BUS_DMASYNC_POSTWRITE);
-				bus_dmamap_unload(sc->fxp_mtag, txp[i].tx_map);
+				bus_dmamap_unload(sc->fxp_txmtag,
+				    txp[i].tx_map);
 				m_freem(txp[i].tx_mbuf);
 				txp[i].tx_mbuf = NULL;
 				/* clear this to reset csum offload bits */
@@ -2117,7 +2142,8 @@ fxp_stop(struct fxp_softc *sc)
 			}
 		}
 	}
-	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	sc->tx_queued = 0;
 }
 
@@ -2389,7 +2415,8 @@ fxp_init_body(struct fxp_softc *sc)
 	 * unit. It will execute the NOP and then suspend.
 	 */
 	tcbp->cb_command = htole16(FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S);
-	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->cbl_tag, sc->cbl_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	sc->fxp_desc.tx_first = sc->fxp_desc.tx_last = txp;
 	sc->tx_queued = 1;
 
@@ -2539,7 +2566,7 @@ fxp_new_rfabuf(struct fxp_softc *sc, str
 	le32enc(&rfa->rbd_addr, 0xffffffff);
 
 	/* Map the RFA into DMA memory. */
-	error = bus_dmamap_load(sc->fxp_mtag, sc->spare_map, rfa,
+	error = bus_dmamap_load(sc->fxp_rxmtag, sc->spare_map, rfa,
 	    MCLBYTES - RFA_ALIGNMENT_FUDGE, fxp_dma_map_addr,
 	    &rxp->rx_addr, 0);
 	if (error) {
@@ -2548,13 +2575,13 @@ fxp_new_rfabuf(struct fxp_softc *sc, str
 	}
 
 	if (rxp->rx_mbuf != NULL)
-		bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map);
+		bus_dmamap_unload(sc->fxp_rxmtag, rxp->rx_map);
 	tmp_map = sc->spare_map;
 	sc->spare_map = rxp->rx_map;
 	rxp->rx_map = tmp_map;
 	rxp->rx_mbuf = m;
 
-	bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map,
+	bus_dmamap_sync(sc->fxp_rxmtag, rxp->rx_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	return (0);
 }
@@ -2576,7 +2603,7 @@ fxp_add_rfabuf(struct fxp_softc *sc, str
 		p_rx->rx_next = rxp;
 		le32enc(&p_rfa->link_addr, rxp->rx_addr);
 		p_rfa->rfa_control = 0;
-		bus_dmamap_sync(sc->fxp_mtag, p_rx->rx_map,
+		bus_dmamap_sync(sc->fxp_rxmtag, p_rx->rx_map,
 		    BUS_DMASYNC_PREWRITE);
 	} else {
 		rxp->rx_next = NULL;
@@ -2620,7 +2647,7 @@ fxp_discard_rfabuf(struct fxp_softc *sc,
 	le32enc(&rfa->link_addr, 0xffffffff);
 	le32enc(&rfa->rbd_addr, 0xffffffff);
 
-	bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map,
+	bus_dmamap_sync(sc->fxp_rxmtag, rxp->rx_map,
 	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 }
 
@@ -2939,7 +2966,8 @@ fxp_mc_setup(struct fxp_softc *sc)
 	 * Start the multicast setup command.
 	 */
 	fxp_scb_wait(sc);
-	bus_dmamap_sync(sc->mcs_tag, sc->mcs_map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->mcs_tag, sc->mcs_map,
+	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 	CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->mcs_addr);
 	fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
 

Modified: stable/7/sys/dev/fxp/if_fxpvar.h
==============================================================================
--- stable/7/sys/dev/fxp/if_fxpvar.h	Wed Nov  4 18:03:19 2009	(r198912)
+++ stable/7/sys/dev/fxp/if_fxpvar.h	Wed Nov  4 18:07:09 2009	(r198913)
@@ -152,7 +152,8 @@ struct fxp_softc {
 	struct resource_spec *fxp_spec;	/* the resource spec we used */
 	void *ih;			/* interrupt handler cookie */
 	struct mtx sc_mtx;
-	bus_dma_tag_t fxp_mtag;		/* bus DMA tag for mbufs */
+	bus_dma_tag_t fxp_txmtag;	/* bus DMA tag for Tx mbufs */
+	bus_dma_tag_t fxp_rxmtag;	/* bus DMA tag for Rx mbufs */
 	bus_dma_tag_t fxp_stag;		/* bus DMA tag for stats */
 	bus_dmamap_t fxp_smap;		/* bus DMA map for stats */
 	bus_dma_tag_t cbl_tag;		/* DMA tag for the TxCB list */



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