summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2006-11-28 04:45:09 +0000
committerBrad Smith <brad@cvs.openbsd.org>2006-11-28 04:45:09 +0000
commit190019430f14ee0f4c750c354ec9636ef9157b2a (patch)
tree762105da08391c5e77db007fb7de102ee8466d9c
parentf83d6e276216af3560667ef8deb35394cbbd71f3 (diff)
Pre-allocate the TX DMA maps intead of creating and destroying a DMA map
per packet sent.
-rw-r--r--sys/dev/pci/if_ixgb.c104
-rw-r--r--sys/dev/pci/if_ixgb.h6
2 files changed, 72 insertions, 38 deletions
diff --git a/sys/dev/pci/if_ixgb.c b/sys/dev/pci/if_ixgb.c
index fa0a282d30e..93455c30d59 100644
--- a/sys/dev/pci/if_ixgb.c
+++ b/sys/dev/pci/if_ixgb.c
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_ixgb.c,v 1.34 2006/11/28 04:26:50 brad Exp $ */
+/* $OpenBSD: if_ixgb.c,v 1.35 2006/11/28 04:45:08 brad Exp $ */
#include <dev/pci/if_ixgb.h>
@@ -654,10 +654,10 @@ int
ixgb_encap(struct ixgb_softc *sc, struct mbuf *m_head)
{
u_int8_t txd_popts;
- int i, j, error;
+ int i, j, error = 0;
+ bus_dmamap_t map;
- struct ixgb_q q;
- struct ixgb_buffer *tx_buffer = NULL;
+ struct ixgb_buffer *tx_buffer;
struct ixgb_tx_desc *current_tx_desc = NULL;
/*
@@ -672,29 +672,23 @@ ixgb_encap(struct ixgb_softc *sc, struct mbuf *m_head)
return (ENOBUFS);
}
}
+
/*
* Map the packet for DMA.
*/
- if (bus_dmamap_create(sc->txtag, IXGB_MAX_JUMBO_FRAME_SIZE,
- IXGB_MAX_SCATTER, IXGB_MAX_JUMBO_FRAME_SIZE, 0,
- BUS_DMA_NOWAIT, &q.map)) {
- sc->no_tx_map_avail++;
- return (ENOMEM);
- }
- error = bus_dmamap_load_mbuf(sc->txtag, q.map,
+ tx_buffer = &sc->tx_buffer_area[sc->next_avail_tx_desc];
+ map = tx_buffer->map;
+
+ error = bus_dmamap_load_mbuf(sc->txtag, map,
m_head, BUS_DMA_NOWAIT);
if (error != 0) {
sc->no_tx_dma_setup++;
- bus_dmamap_destroy(sc->txtag, q.map);
return (error);
}
- IXGB_KASSERT(q.map->dm_nsegs != 0, ("ixgb_encap: empty packet"));
+ IXGB_KASSERT(map->dm_nsegs != 0, ("ixgb_encap: empty packet"));
- if (q.map->dm_nsegs > sc->num_tx_desc_avail) {
- sc->no_tx_desc_avail2++;
- bus_dmamap_destroy(sc->txtag, q.map);
- return (ENOBUFS);
- }
+ if (map->dm_nsegs > sc->num_tx_desc_avail)
+ goto fail;
#ifdef IXGB_CSUM_OFFLOAD
ixgb_transmit_checksum_setup(sc, m_head, &txd_popts);
@@ -703,12 +697,12 @@ ixgb_encap(struct ixgb_softc *sc, struct mbuf *m_head)
#endif
i = sc->next_avail_tx_desc;
- for (j = 0; j < q.map->dm_nsegs; j++) {
+ for (j = 0; j < map->dm_nsegs; j++) {
tx_buffer = &sc->tx_buffer_area[i];
current_tx_desc = &sc->tx_desc_base[i];
- current_tx_desc->buff_addr = htole64(q.map->dm_segs[j].ds_addr);
- current_tx_desc->cmd_type_len = htole32((sc->txd_cmd | q.map->dm_segs[j].ds_len));
+ current_tx_desc->buff_addr = htole64(map->dm_segs[j].ds_addr);
+ current_tx_desc->cmd_type_len = htole32((sc->txd_cmd | map->dm_segs[j].ds_len));
current_tx_desc->popts = txd_popts;
if (++i == sc->num_tx_desc)
i = 0;
@@ -716,12 +710,11 @@ ixgb_encap(struct ixgb_softc *sc, struct mbuf *m_head)
tx_buffer->m_head = NULL;
}
- sc->num_tx_desc_avail -= q.map->dm_nsegs;
+ sc->num_tx_desc_avail -= map->dm_nsegs;
sc->next_avail_tx_desc = i;
tx_buffer->m_head = m_head;
- tx_buffer->map = q.map;
- bus_dmamap_sync(sc->txtag, q.map, 0, q.map->dm_mapsize,
+ bus_dmamap_sync(sc->txtag, map, 0, map->dm_mapsize,
BUS_DMASYNC_PREWRITE);
/*
@@ -739,6 +732,11 @@ ixgb_encap(struct ixgb_softc *sc, struct mbuf *m_head)
IXGB_WRITE_REG(&sc->hw, TDT, i);
return (0);
+
+fail:
+ sc->no_tx_desc_avail2++;
+ bus_dmamap_unload(sc->txtag, map);
+ return (ENOBUFS);
}
void
@@ -1126,6 +1124,7 @@ fail_1:
fail_0:
dma->dma_map = NULL;
dma->dma_tag = NULL;
+
return (r);
}
@@ -1177,14 +1176,30 @@ ixgb_allocate_transmit_structures(struct ixgb_softc *sc)
int
ixgb_setup_transmit_structures(struct ixgb_softc *sc)
{
- sc->txtag = sc->osdep.ixgb_pa.pa_dmat;
+ struct ixgb_buffer *tx_buffer;
+ int error, i;
- if (ixgb_allocate_transmit_structures(sc))
- return (ENOMEM);
+ if ((error = ixgb_allocate_transmit_structures(sc)) != 0)
+ goto fail;
bzero((void *)sc->tx_desc_base,
(sizeof(struct ixgb_tx_desc)) * sc->num_tx_desc);
+ sc->txtag = sc->osdep.ixgb_pa.pa_dmat;
+
+ tx_buffer = sc->tx_buffer_area;
+ for (i = 0; i < sc->num_tx_desc; i++) {
+ error = bus_dmamap_create(sc->txtag, IXGB_MAX_JUMBO_FRAME_SIZE,
+ IXGB_MAX_SCATTER, IXGB_MAX_JUMBO_FRAME_SIZE, 0,
+ BUS_DMA_NOWAIT, &tx_buffer->map);
+ if (error != 0) {
+ printf("%s: Unable to create TX DMA map\n",
+ sc->sc_dv.dv_xname);
+ goto fail;
+ }
+ tx_buffer++;
+ }
+
sc->next_avail_tx_desc = 0;
sc->oldest_used_tx_desc = 0;
@@ -1193,8 +1208,14 @@ ixgb_setup_transmit_structures(struct ixgb_softc *sc)
/* Set checksum context */
sc->active_checksum_context = OFFLOAD_NONE;
+ bus_dmamap_sync(sc->txdma.dma_tag, sc->txdma.dma_map, 0,
+ sc->txdma.dma_size, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
return (0);
+
+fail:
+ ixgb_free_transmit_structures(sc);
+ return (error);
}
/*********************************************************************
@@ -1254,12 +1275,24 @@ ixgb_free_transmit_structures(struct ixgb_softc *sc)
if (sc->tx_buffer_area != NULL) {
tx_buffer = sc->tx_buffer_area;
for (i = 0; i < sc->num_tx_desc; i++, tx_buffer++) {
+ if (tx_buffer->map != NULL &&
+ tx_buffer->map->dm_nsegs > 0) {
+ bus_dmamap_sync(sc->txtag, tx_buffer->map,
+ 0, tx_buffer->map->dm_mapsize,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->txtag,
+ tx_buffer->map);
+ }
+
if (tx_buffer->m_head != NULL) {
- bus_dmamap_unload(sc->txtag, tx_buffer->map);
- bus_dmamap_destroy(sc->txtag, tx_buffer->map);
m_freem(tx_buffer->m_head);
+ tx_buffer->m_head = NULL;
+ }
+ if (tx_buffer->map != NULL) {
+ bus_dmamap_destroy(sc->txtag,
+ tx_buffer->map);
+ tx_buffer->map = NULL;
}
- tx_buffer->m_head = NULL;
}
}
if (sc->tx_buffer_area != NULL) {
@@ -1376,10 +1409,15 @@ ixgb_txeof(struct ixgb_softc *sc)
tx_desc->status = 0;
num_avail++;
- if (tx_buffer->m_head) {
+ if (tx_buffer->m_head != NULL) {
ifp->if_opackets++;
- bus_dmamap_unload(sc->txtag, tx_buffer->map);
- bus_dmamap_destroy(sc->txtag, tx_buffer->map);
+
+ if (tx_buffer->map->dm_nsegs > 0) {
+ bus_dmamap_sync(sc->txtag, tx_buffer->map,
+ 0, tx_buffer->map->dm_mapsize,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->txtag, tx_buffer->map);
+ }
m_freem(tx_buffer->m_head);
tx_buffer->m_head = NULL;
diff --git a/sys/dev/pci/if_ixgb.h b/sys/dev/pci/if_ixgb.h
index be708e5eeee..4b4f8e72aa0 100644
--- a/sys/dev/pci/if_ixgb.h
+++ b/sys/dev/pci/if_ixgb.h
@@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
***************************************************************************/
-/* $OpenBSD: if_ixgb.h,v 1.9 2006/11/18 18:46:20 brad Exp $ */
+/* $OpenBSD: if_ixgb.h,v 1.10 2006/11/28 04:45:08 brad Exp $ */
#ifndef _IXGB_H_DEFINED_
#define _IXGB_H_DEFINED_
@@ -207,10 +207,6 @@ struct ixgb_buffer {
bus_dmamap_t map; /* bus_dma map for packet */
};
-struct ixgb_q {
- bus_dmamap_t map; /* bus_dma map for packet */
-};
-
/*
* Bus dma allocation structure used by
* ixgb_dma_malloc and ixgb_dma_free.