summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2006-02-12 13:08:43 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2006-02-12 13:08:43 +0000
commite677d92674d1ff3dd7f92bd2b035994053bc6d56 (patch)
tree7b9ef8c99b4de8d319808b45e31544531b0346a1 /sys/dev/pci
parent6db89a73532faaef0af97dd785d4c7fbb0af9a43 (diff)
reduce the number of DMA sync operations by sincing multiple TX descriptors
at once.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_nfe.c64
1 files changed, 52 insertions, 12 deletions
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c
index e88233bc2bc..d1ab113a1a8 100644
--- a/sys/dev/pci/if_nfe.c
+++ b/sys/dev/pci/if_nfe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_nfe.c,v 1.30 2006/02/12 10:28:07 damien Exp $ */
+/* $OpenBSD: if_nfe.c,v 1.31 2006/02/12 13:08:42 damien Exp $ */
/*-
* Copyright (c) 2006 Damien Bergamini <damien.bergamini@free.fr>
@@ -77,6 +77,8 @@ int nfe_intr(void *);
int nfe_ioctl(struct ifnet *, u_long, caddr_t);
void nfe_txdesc32_sync(struct nfe_softc *, struct nfe_desc32 *, int);
void nfe_txdesc64_sync(struct nfe_softc *, struct nfe_desc64 *, int);
+void nfe_txdesc32_rsync(struct nfe_softc *, int, int, int);
+void nfe_txdesc64_rsync(struct nfe_softc *, int, int, int);
void nfe_rxdesc32_sync(struct nfe_softc *, struct nfe_desc32 *, int);
void nfe_rxdesc64_sync(struct nfe_softc *, struct nfe_desc64 *, int);
void nfe_rxeof(struct nfe_softc *);
@@ -546,6 +548,48 @@ nfe_txdesc64_sync(struct nfe_softc *sc, struct nfe_desc64 *desc64, int ops)
}
void
+nfe_txdesc32_rsync(struct nfe_softc *sc, int start, int end, int ops)
+{
+ if (end >= start) {
+ bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
+ (caddr_t)&sc->txq.desc32[start] - (caddr_t)sc->txq.desc32,
+ (caddr_t)&sc->txq.desc32[end] -
+ (caddr_t)&sc->txq.desc32[start], ops);
+ return;
+ }
+ /* sync from 'start' to end of ring */
+ bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
+ (caddr_t)&sc->txq.desc32[start] - (caddr_t)sc->txq.desc32,
+ (caddr_t)&sc->txq.desc32[NFE_TX_RING_COUNT] -
+ (caddr_t)&sc->txq.desc32[start], ops);
+
+ /* sync from start of ring to 'end' */
+ bus_dmamap_sync(sc->sc_dmat, sc->txq.map, 0,
+ (caddr_t)&sc->txq.desc32[end] - (caddr_t)sc->txq.desc32, ops);
+}
+
+void
+nfe_txdesc64_rsync(struct nfe_softc *sc, int start, int end, int ops)
+{
+ if (end >= start) {
+ bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
+ (caddr_t)&sc->txq.desc64[start] - (caddr_t)sc->txq.desc64,
+ (caddr_t)&sc->txq.desc64[end] -
+ (caddr_t)&sc->txq.desc64[start], ops);
+ return;
+ }
+ /* sync from 'start' to end of ring */
+ bus_dmamap_sync(sc->sc_dmat, sc->txq.map,
+ (caddr_t)&sc->txq.desc64[start] - (caddr_t)sc->txq.desc64,
+ (caddr_t)&sc->txq.desc64[NFE_TX_RING_COUNT] -
+ (caddr_t)&sc->txq.desc64[start], ops);
+
+ /* sync from start of ring to 'end' */
+ bus_dmamap_sync(sc->sc_dmat, sc->txq.map, 0,
+ (caddr_t)&sc->txq.desc64[end] - (caddr_t)sc->txq.desc64, ops);
+}
+
+void
nfe_rxdesc32_sync(struct nfe_softc *sc, struct nfe_desc32 *desc32, int ops)
{
bus_dmamap_sync(sc->sc_dmat, sc->rxq.map,
@@ -877,16 +921,12 @@ nfe_encap(struct nfe_softc *sc, struct mbuf *m0)
htole32(map->dm_segs[i].ds_addr & 0xffffffff);
desc64->length = htole16(map->dm_segs[i].ds_len - 1);
desc64->flags = htole16(flags);
-
- nfe_txdesc64_sync(sc, desc64, BUS_DMASYNC_PREWRITE);
} else {
desc32 = &sc->txq.desc32[sc->txq.cur];
desc32->physaddr = htole32(map->dm_segs[i].ds_addr);
desc32->length = htole16(map->dm_segs[i].ds_len - 1);
desc32->flags = htole16(flags);
-
- nfe_txdesc32_sync(sc, desc32, BUS_DMASYNC_PREWRITE);
}
/* csum flags belong to the first fragment only */
@@ -900,17 +940,13 @@ nfe_encap(struct nfe_softc *sc, struct mbuf *m0)
/* the whole mbuf chain has been DMA mapped, fix last descriptor */
if (sc->sc_flags & NFE_40BIT_ADDR) {
flags |= NFE_TX_LASTFRAG_V2;
-
desc64->flags = htole16(flags);
- nfe_txdesc64_sync(sc, desc64, BUS_DMASYNC_PREWRITE);
} else {
if (sc->sc_flags & NFE_JUMBO_SUP)
flags |= NFE_TX_LASTFRAG_V2;
else
flags |= NFE_TX_LASTFRAG_V1;
-
desc32->flags = htole16(flags);
- nfe_txdesc32_sync(sc, desc32, BUS_DMASYNC_PREWRITE);
}
data->m = m0;
@@ -926,9 +962,9 @@ void
nfe_start(struct ifnet *ifp)
{
struct nfe_softc *sc = ifp->if_softc;
+ int old = sc->txq.cur;
struct mbuf *m0;
uint32_t txctl;
- int pkts = 0;
for (;;) {
IFQ_POLL(&ifp->if_snd, m0);
@@ -942,16 +978,20 @@ nfe_start(struct ifnet *ifp)
/* packet put in h/w queue, remove from s/w queue */
IFQ_DEQUEUE(&ifp->if_snd, m0);
- pkts++;
#if NBPFILTER > 0
if (ifp->if_bpf != NULL)
bpf_mtap(ifp->if_bpf, m0);
#endif
}
- if (pkts == 0)
+ if (sc->txq.cur == old) /* nothing sent */
return;
+ if (sc->sc_flags & NFE_40BIT_ADDR)
+ nfe_txdesc64_rsync(sc, old, sc->txq.cur, BUS_DMASYNC_PREWRITE);
+ else
+ nfe_txdesc32_rsync(sc, old, sc->txq.cur, BUS_DMASYNC_PREWRITE);
+
txctl = NFE_RXTX_KICKTX;
if (sc->sc_flags & NFE_40BIT_ADDR)
txctl |= NFE_RXTX_V3MAGIC;