summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2008-04-09 12:50:12 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2008-04-09 12:50:12 +0000
commite675ec16cb7dfda9c967e725d6d9fa9eeb4b6add (patch)
treed09a4349a3591fd1d14396e56e6f6a0a1c4a1b76
parentbc5de14653d56c8b6ff079e7290f53330cf142cf (diff)
dma sync the tx ring and post new packets to the chip once per call to
the start routine instead of once per packet. tested on various archs including amd64, i386, and sparc64.
-rw-r--r--sys/dev/pci/if_em.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c
index 10502bd2130..788f9072566 100644
--- a/sys/dev/pci/if_em.c
+++ b/sys/dev/pci/if_em.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_em.c,v 1.180 2008/03/02 01:28:16 brad Exp $ */
+/* $OpenBSD: if_em.c,v 1.181 2008/04/09 12:50:11 dlg Exp $ */
/* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */
#include <dev/pci/if_em.h>
@@ -457,6 +457,7 @@ em_start(struct ifnet *ifp)
{
struct mbuf *m_head;
struct em_softc *sc = ifp->if_softc;
+ int post = 0;
if ((ifp->if_flags & (IFF_OACTIVE | IFF_RUNNING)) != IFF_RUNNING)
return;
@@ -464,9 +465,14 @@ em_start(struct ifnet *ifp)
if (!sc->link_active)
return;
+ if (sc->hw.mac_type != em_82547) {
+ bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
+ sc->txdma.dma_map->dm_mapsize,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ }
+
for (;;) {
IFQ_POLL(&ifp->if_snd, m_head);
-
if (m_head == NULL)
break;
@@ -485,7 +491,22 @@ em_start(struct ifnet *ifp)
/* Set timeout in case hardware has problems transmitting */
ifp->if_timer = EM_TX_TIMEOUT;
- }
+
+ post = 1;
+ }
+
+ if (sc->hw.mac_type != em_82547) {
+ bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
+ sc->txdma.dma_map->dm_mapsize,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ /*
+ * Advance the Transmit Descriptor Tail (Tdt),
+ * this tells the E1000 that this frame is
+ * available to transmit.
+ */
+ if (post)
+ E1000_WRITE_REG(&sc->hw, TDT, sc->next_avail_tx_desc);
+ }
}
/*********************************************************************
@@ -986,6 +1007,12 @@ em_encap(struct em_softc *sc, struct mbuf *m_head)
}
}
+ if (sc->hw.mac_type == em_82547) {
+ bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
+ sc->txdma.dma_map->dm_mapsize,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ }
+
/*
* Map the packet for DMA.
*
@@ -1002,7 +1029,7 @@ em_encap(struct em_softc *sc, struct mbuf *m_head)
error = bus_dmamap_load_mbuf(sc->txtag, map, m_head, BUS_DMA_NOWAIT);
if (error != 0) {
sc->no_tx_dma_setup++;
- return (error);
+ goto loaderr;
}
EM_KASSERT(map->dm_nsegs!= 0, ("em_encap: empty packet"));
@@ -1102,16 +1129,16 @@ em_encap(struct em_softc *sc, struct mbuf *m_head)
* this tells the E1000 that this frame is
* available to transmit.
*/
- bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
- sc->txdma.dma_map->dm_mapsize,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
- if (sc->hw.mac_type == em_82547 &&
- sc->link_duplex == HALF_DUPLEX) {
- em_82547_move_tail_locked(sc);
- } else {
- E1000_WRITE_REG(&sc->hw, TDT, i);
- if (sc->hw.mac_type == em_82547)
+ if (sc->hw.mac_type == em_82547) {
+ bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
+ sc->txdma.dma_map->dm_mapsize,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ if (sc->link_duplex == HALF_DUPLEX)
+ em_82547_move_tail_locked(sc);
+ else {
+ E1000_WRITE_REG(&sc->hw, TDT, i);
em_82547_update_fifo_head(sc, m_head->m_pkthdr.len);
+ }
}
return (0);
@@ -1119,7 +1146,14 @@ em_encap(struct em_softc *sc, struct mbuf *m_head)
fail:
sc->no_tx_desc_avail2++;
bus_dmamap_unload(sc->txtag, map);
- return (ENOBUFS);
+ error = ENOBUFS;
+loaderr:
+ if (sc->hw.mac_type == em_82547) {
+ bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
+ sc->txdma.dma_map->dm_mapsize,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+ }
+ return (error);
}
/*********************************************************************