summaryrefslogtreecommitdiffstats
path: root/sys/dev/em
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2006-07-27 00:43:34 +0000
committeryongari <yongari@FreeBSD.org>2006-07-27 00:43:34 +0000
commitef22f9e0e57f7311cd6c6dc9145d01d23bcfe968 (patch)
tree5ea14bfb0098099d32b38c4ee1eba6f2c1f73007 /sys/dev/em
parent7b2f14a8addf041e3597d946240db34c98fa58d8 (diff)
downloadFreeBSD-src-ef22f9e0e57f7311cd6c6dc9145d01d23bcfe968.zip
FreeBSD-src-ef22f9e0e57f7311cd6c6dc9145d01d23bcfe968.tar.gz
Prepending an mbuf after loading a DMA map results in unexpected
result. So, modify mbuf chains before loading a DMA map.
Diffstat (limited to 'sys/dev/em')
-rw-r--r--sys/dev/em/if_em.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c
index 02494b5..cd6d716 100644
--- a/sys/dev/em/if_em.c
+++ b/sys/dev/em/if_em.c
@@ -1412,31 +1412,6 @@ em_encap(struct em_softc *sc, struct mbuf **m_headp)
}
}
- /*
- * Map the packet for DMA.
- */
- tx_buffer = &sc->tx_buffer_area[sc->next_avail_tx_desc];
- tx_buffer_last = tx_buffer;
- map = tx_buffer->map;
- error = bus_dmamap_load_mbuf_sg(sc->txtag, map, m_head, segs, &nsegs,
- BUS_DMA_NOWAIT);
- if (error != 0) {
- sc->no_tx_dma_setup++;
- return (error);
- }
- KASSERT(nsegs != 0, ("em_encap: empty packet"));
-
- if (nsegs > sc->num_tx_desc_avail) {
- sc->no_tx_desc_avail2++;
- error = ENOBUFS;
- goto encap_fail;
- }
-
- if (ifp->if_hwassist > 0)
- em_transmit_checksum_setup(sc, m_head, &txd_upper, &txd_lower);
- else
- txd_upper = txd_lower = 0;
-
/* Find out if we are in vlan mode. */
mtag = VLAN_OUTPUT_TAG(ifp, m_head);
@@ -1453,21 +1428,18 @@ em_encap(struct em_softc *sc, struct mbuf **m_headp)
m_head = m_pullup(m_head, sizeof(eh));
if (m_head == NULL) {
*m_headp = NULL;
- error = ENOBUFS;
- goto encap_fail;
+ return (ENOBUFS);
}
eh = *mtod(m_head, struct ether_header *);
M_PREPEND(m_head, sizeof(*evl), M_DONTWAIT);
if (m_head == NULL) {
*m_headp = NULL;
- error = ENOBUFS;
- goto encap_fail;
+ return (ENOBUFS);
}
m_head = m_pullup(m_head, sizeof(*evl));
if (m_head == NULL) {
*m_headp = NULL;
- error = ENOBUFS;
- goto encap_fail;
+ return (ENOBUFS);
}
evl = mtod(m_head, struct ether_vlan_header *);
bcopy(&eh, evl, sizeof(*evl));
@@ -1479,6 +1451,31 @@ em_encap(struct em_softc *sc, struct mbuf **m_headp)
*m_headp = m_head;
}
+ /*
+ * Map the packet for DMA.
+ */
+ tx_buffer = &sc->tx_buffer_area[sc->next_avail_tx_desc];
+ tx_buffer_last = tx_buffer;
+ map = tx_buffer->map;
+ error = bus_dmamap_load_mbuf_sg(sc->txtag, map, m_head, segs, &nsegs,
+ BUS_DMA_NOWAIT);
+ if (error != 0) {
+ sc->no_tx_dma_setup++;
+ return (error);
+ }
+ KASSERT(nsegs != 0, ("em_encap: empty packet"));
+
+ if (nsegs > sc->num_tx_desc_avail) {
+ sc->no_tx_desc_avail2++;
+ error = ENOBUFS;
+ goto encap_fail;
+ }
+
+ if (ifp->if_hwassist > 0)
+ em_transmit_checksum_setup(sc, m_head, &txd_upper, &txd_lower);
+ else
+ txd_upper = txd_lower = 0;
+
i = sc->next_avail_tx_desc;
if (sc->pcix_82544) {
txd_saved = i;
OpenPOWER on IntegriCloud