summaryrefslogtreecommitdiffstats
path: root/sys/dev/hme
diff options
context:
space:
mode:
authortmm <tmm@FreeBSD.org>2003-01-21 17:22:52 +0000
committertmm <tmm@FreeBSD.org>2003-01-21 17:22:52 +0000
commit866ea3751f9bbf265de3d0fc59cd2771c14d51bc (patch)
tree42574237a2dea022cb41c48ecabf60a2628cbf52 /sys/dev/hme
parent2fe5a13b8fa5331d001f3121a47f56057423648f (diff)
downloadFreeBSD-src-866ea3751f9bbf265de3d0fc59cd2771c14d51bc.zip
FreeBSD-src-866ea3751f9bbf265de3d0fc59cd2771c14d51bc.tar.gz
bus_dmamap_sync() overhaul:
- Remove NetBSD-style or-ed together BUS_DMASYNC operations, in some cases relaxing the (intended) syncing operation a bit. - Add syncs before reading the descriptor rings. - Try to combine syncs where possible to avoid overhead. - Sync all maps before unloading them.
Diffstat (limited to 'sys/dev/hme')
-rw-r--r--sys/dev/hme/if_hme.c45
1 files changed, 24 insertions, 21 deletions
diff --git a/sys/dev/hme/if_hme.c b/sys/dev/hme/if_hme.c
index 9db0856..aadbe47 100644
--- a/sys/dev/hme/if_hme.c
+++ b/sys/dev/hme/if_hme.c
@@ -361,6 +361,8 @@ hme_detach(struct hme_softc *sc)
bus_dmamap_destroy(sc->sc_rdmatag,
sc->sc_rb.rb_rxdesc[i].hrx_dmamap);
}
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cdmamap);
bus_dmamem_free(sc->sc_cdmatag, sc->sc_rb.rb_membase, sc->sc_cdmamap);
bus_dma_tag_destroy(sc->sc_tdmatag);
@@ -457,8 +459,8 @@ hme_rxdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs,
* Discard the contents of an mbuf in the RX ring, freeing the buffer in the
* ring for subsequent use.
*/
-static void
-hme_discard_rxbuf(struct hme_softc *sc, int ix, int sync)
+static __inline void
+hme_discard_rxbuf(struct hme_softc *sc, int ix)
{
/*
@@ -467,10 +469,6 @@ hme_discard_rxbuf(struct hme_softc *sc, int ix, int sync)
*/
HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_rxd, ix, HME_XD_OWN |
HME_XD_ENCODE_RSIZE(HME_DESC_RXLEN(sc, &sc->sc_rb.rb_rxdesc[ix])));
- if (sync) {
- bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- }
}
static int
@@ -490,7 +488,7 @@ hme_add_rxbuf(struct hme_softc *sc, unsigned int ri, int keepold)
* Reinitialize the descriptor flags, as they may have been
* altered by the hardware.
*/
- hme_discard_rxbuf(sc, ri, 0);
+ hme_discard_rxbuf(sc, ri);
return (0);
}
if ((m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR)) == NULL)
@@ -581,6 +579,8 @@ hme_meminit(struct hme_softc *sc)
td = &sc->sc_rb.rb_txdesc[i];
if (td->htx_m != NULL) {
m_freem(td->htx_m);
+ bus_dmamap_sync(sc->sc_tdmatag, td->htx_dmamap,
+ BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap);
td->htx_m = NULL;
}
@@ -596,8 +596,8 @@ hme_meminit(struct hme_softc *sc)
return (error);
}
- bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_PREREAD);
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_PREWRITE);
hr->rb_tdhead = hr->rb_tdtail = 0;
hr->rb_td_nbusy = 0;
@@ -928,9 +928,6 @@ hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri, flags);
} while (ri != si);
- bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
/* start the transmission. */
HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP);
return (0);
@@ -955,7 +952,7 @@ hme_read(struct hme_softc *sc, int ix, int len)
len);
#endif
ifp->if_ierrors++;
- hme_discard_rxbuf(sc, ix, 1);
+ hme_discard_rxbuf(sc, ix);
return;
}
@@ -969,16 +966,12 @@ hme_read(struct hme_softc *sc, int ix, int len)
* drop the packet, but leave the interface up.
*/
ifp->if_iqdrops++;
- hme_discard_rxbuf(sc, ix, 1);
+ hme_discard_rxbuf(sc, ix);
return;
}
ifp->if_ipackets++;
- /* Changed the rings; sync. */
- bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
m->m_pkthdr.rcvif = ifp;
m->m_pkthdr.len = m->m_len = len + HME_RXOFFS;
m_adj(m, HME_RXOFFS);
@@ -1019,8 +1012,11 @@ hme_start(struct ifnet *ifp)
if (sc->sc_rb.rb_td_nbusy == HME_NTXDESC || error == -1)
ifp->if_flags |= IFF_OACTIVE;
/* Set watchdog timer if a packet was queued */
- if (enq)
+ if (enq) {
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
+ BUS_DMASYNC_PREWRITE);
ifp->if_timer = 5;
+ }
}
/*
@@ -1051,6 +1047,7 @@ hme_tint(struct hme_softc *sc)
HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0);
htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq);
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD);
/* Fetch current position in the transmit ring */
for (ri = sc->sc_rb.rb_tdtail;; ri = (ri + 1) % HME_NTXDESC) {
if (sc->sc_rb.rb_td_nbusy <= 0) {
@@ -1108,28 +1105,34 @@ hme_rint(struct hme_softc *sc)
caddr_t xdr = sc->sc_rb.rb_rxd;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
unsigned int ri, len;
+ int progress = 0;
u_int32_t flags;
/*
* Process all buffers with valid data.
*/
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD);
for (ri = sc->sc_rb.rb_rdtail;; ri = (ri + 1) % HME_NRXDESC) {
flags = HME_XD_GETFLAGS(sc->sc_pci, xdr, ri);
CTR2(KTR_HME, "hme_rint: index %d, flags %#x", ri, flags);
if ((flags & HME_XD_OWN) != 0)
break;
+ progress++;
if ((flags & HME_XD_OFL) != 0) {
device_printf(sc->sc_dev, "buffer overflow, ri=%d; "
"flags=0x%x\n", ri, flags);
ifp->if_ierrors++;
- hme_discard_rxbuf(sc, ri, 1);
+ hme_discard_rxbuf(sc, ri);
} else {
len = HME_XD_DECODE_RSIZE(flags);
hme_read(sc, ri, len);
}
}
-
+ if (progress) {
+ bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
+ BUS_DMASYNC_PREWRITE);
+ }
sc->sc_rb.rb_rdtail = ri;
}
OpenPOWER on IntegriCloud