diff options
| author | bouyer <bouyer@NetBSD.org> | 2003-01-13 17:00:18 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2003-01-13 17:00:18 +0000 |
| commit | 4ceef3ad689f86cf3be14956efceab70bebc847d (patch) | |
| tree | c0c4536c7a6f09e826c8178ca2a44b814473ff70 /sys/dev | |
| parent | df4b5f766b7e6adcddfadf86ebea5f3cbf457407 (diff) | |
For short (< ETHER_MIN_LEN) packets, supply a zero'd buffer for the extra
bytes to make sure the chip won't send random data.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/smc83c170.c | 60 | ||||
| -rw-r--r-- | sys/dev/ic/smc83c170var.h | 4 |
2 files changed, 51 insertions, 13 deletions
diff --git a/sys/dev/ic/smc83c170.c b/sys/dev/ic/smc83c170.c index e76f15b6c30..92680628a46 100644 --- a/sys/dev/ic/smc83c170.c +++ b/sys/dev/ic/smc83c170.c @@ -1,4 +1,4 @@ -/* $NetBSD: smc83c170.c,v 1.51 2002/11/07 07:48:35 thorpej Exp $ */ +/* $NetBSD: smc83c170.c,v 1.52 2003/01/13 17:00:18 bouyer Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -43,7 +43,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.51 2002/11/07 07:48:35 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: smc83c170.c,v 1.52 2003/01/13 17:00:18 bouyer Exp $"); #include "bpfilter.h" @@ -106,6 +106,8 @@ void epic_mediastatus __P((struct ifnet *, struct ifmediareq *)); int epic_copy_small = 0; +#define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN) + /* * Attach an EPIC interface to the system. */ @@ -121,6 +123,7 @@ epic_attach(sc) bus_dma_segment_t seg; u_int8_t enaddr[ETHER_ADDR_LEN], devname[12 + 1]; u_int16_t myea[ETHER_ADDR_LEN / 2], mydevname[6]; + char *nullbuf; callout_init(&sc->sc_mii_callout); @@ -129,20 +132,24 @@ epic_attach(sc) * DMA map for it. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, - sizeof(struct epic_control_data), PAGE_SIZE, 0, &seg, 1, &rseg, - BUS_DMA_NOWAIT)) != 0) { + sizeof(struct epic_control_data) + ETHER_PAD_LEN, PAGE_SIZE, 0, + &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { printf("%s: unable to allocate control data, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_0; } if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, - sizeof(struct epic_control_data), (caddr_t *)&sc->sc_control_data, + sizeof(struct epic_control_data) + ETHER_PAD_LEN, + (caddr_t *)&sc->sc_control_data, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { printf("%s: unable to map control data, error = %d\n", sc->sc_dev.dv_xname, error); goto fail_1; } + nullbuf = + (char *)sc->sc_control_data + sizeof(struct epic_control_data); + memset(nullbuf, 0, ETHER_PAD_LEN); if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct epic_control_data), 1, @@ -188,6 +195,24 @@ epic_attach(sc) EPIC_DSRX(sc, i)->ds_mbuf = NULL; } + /* + * create and map the pad buffer + */ + if ((error = bus_dmamap_create(sc->sc_dmat, ETHER_PAD_LEN, 1, + ETHER_PAD_LEN, 0, BUS_DMA_NOWAIT,&sc->sc_nulldmamap)) != 0) { + printf("%s: unable to create pad buffer DMA map, " + "error = %d\n", sc->sc_dev.dv_xname, error); + goto fail_5; + } + + if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_nulldmamap, + nullbuf, ETHER_PAD_LEN, NULL, BUS_DMA_NOWAIT)) != 0) { + printf("%s: unable to load pad buffer DMA map, " + "error = %d\n", sc->sc_dev.dv_xname, error); + goto fail_6; + } + bus_dmamap_sync(sc->sc_dmat, sc->sc_nulldmamap, 0, ETHER_PAD_LEN, + BUS_DMASYNC_PREWRITE); /* * Bring the chip out of low-power mode and reset it to a known state. @@ -291,6 +316,8 @@ epic_attach(sc) * Free any resources we've allocated during the failed attach * attempt. Do this in reverse order and fall through. */ + fail_6: + bus_dmamap_destroy(sc->sc_dmat, sc->sc_nulldmamap); fail_5: for (i = 0; i < EPIC_NRXDESC; i++) { if (EPIC_DSRX(sc, i)->ds_dmamap != NULL) @@ -379,8 +406,13 @@ epic_start(ifp) * short on resources. In this case, we'll copy and try * again. */ - if (bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, - BUS_DMA_WRITE|BUS_DMA_NOWAIT) != 0) { + if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, + BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 || + (m0->m_pkthdr.len < ETHER_PAD_LEN && + dmamap-> dm_nsegs == EPIC_NFRAGS)) { + if (error == 0) + bus_dmamap_unload(sc->sc_dmat, dmamap); + MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { printf("%s: unable to allocate Tx mbuf\n", @@ -413,13 +445,19 @@ epic_start(ifp) } /* Initialize the fraglist. */ - fr->ef_nfrags = dmamap->dm_nsegs; for (seg = 0; seg < dmamap->dm_nsegs; seg++) { fr->ef_frags[seg].ef_addr = dmamap->dm_segs[seg].ds_addr; fr->ef_frags[seg].ef_length = dmamap->dm_segs[seg].ds_len; } + if (m0->m_pkthdr.len < ETHER_PAD_LEN) { + fr->ef_frags[seg].ef_addr = sc->sc_nulldma; + fr->ef_frags[seg].ef_length = + ETHER_PAD_LEN - m0->m_pkthdr.len; + seg++; + } + fr->ef_nfrags = seg; EPIC_CDFLSYNC(sc, nexttx, BUS_DMASYNC_PREWRITE); @@ -433,12 +471,10 @@ epic_start(ifp) ds->ds_mbuf = m0; /* - * Fill in the transmit descriptor. The EPIC doesn't - * auto-pad, so we have to do this ourselves. + * Fill in the transmit descriptor. */ txd->et_control = ET_TXCTL_LASTDESC | ET_TXCTL_FRAGLIST; - txd->et_txlength = max(m0->m_pkthdr.len, - ETHER_MIN_LEN - ETHER_CRC_LEN); + txd->et_txlength = max(m0->m_pkthdr.len, ETHER_PAD_LEN); /* * If this is the first descriptor we're enqueueing, diff --git a/sys/dev/ic/smc83c170var.h b/sys/dev/ic/smc83c170var.h index 04e20f0d48e..5695a65ecf9 100644 --- a/sys/dev/ic/smc83c170var.h +++ b/sys/dev/ic/smc83c170var.h @@ -1,4 +1,4 @@ -/* $NetBSD: smc83c170var.h,v 1.6 2002/11/07 07:48:36 thorpej Exp $ */ +/* $NetBSD: smc83c170var.h,v 1.7 2003/01/13 17:00:18 bouyer Exp $ */ /*- * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. @@ -117,6 +117,8 @@ struct epic_softc { bus_dmamap_t sc_cddmamap; /* control data DMA map */ #define sc_cddma sc_cddmamap->dm_segs[0].ds_addr + bus_dmamap_t sc_nulldmamap; /* DMA map for the pad buffer */ +#define sc_nulldma sc_nulldmamap->dm_segs[0].ds_addr /* * Software state for transmit and receive descriptors. |
