diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2008-04-09 12:50:12 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2008-04-09 12:50:12 +0000 |
commit | e675ec16cb7dfda9c967e725d6d9fa9eeb4b6add (patch) | |
tree | d09a4349a3591fd1d14396e56e6f6a0a1c4a1b76 | |
parent | bc5de14653d56c8b6ff079e7290f53330cf142cf (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.c | 62 |
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); } /********************************************************************* |