diff options
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/pci/if_nfe.c | 59 | ||||
| -rw-r--r-- | sys/dev/pci/if_nfevar.h | 3 |
2 files changed, 42 insertions, 20 deletions
diff --git a/sys/dev/pci/if_nfe.c b/sys/dev/pci/if_nfe.c index 967782c1345..203bc23788f 100644 --- a/sys/dev/pci/if_nfe.c +++ b/sys/dev/pci/if_nfe.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_nfe.c,v 1.18 2007/09/24 13:11:08 cube Exp $ */ +/* $NetBSD: if_nfe.c,v 1.19 2007/09/24 13:17:53 cube Exp $ */ /* $OpenBSD: if_nfe.c,v 1.52 2006/03/02 09:04:00 jsg Exp $ */ /*- @@ -21,7 +21,7 @@ /* Driver for NVIDIA nForce MCP Fast Ethernet and Gigabit Ethernet */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.18 2007/09/24 13:11:08 cube Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_nfe.c,v 1.19 2007/09/24 13:17:53 cube Exp $"); #include "opt_inet.h" #include "bpfilter.h" @@ -94,7 +94,7 @@ void nfe_start(struct ifnet *); void nfe_watchdog(struct ifnet *); int nfe_init(struct ifnet *); void nfe_stop(struct ifnet *, int); -struct nfe_jbuf *nfe_jalloc(struct nfe_softc *); +struct nfe_jbuf *nfe_jalloc(struct nfe_softc *, int); void nfe_jfree(struct mbuf *, void *, size_t, void *); int nfe_jpool_alloc(struct nfe_softc *); void nfe_jpool_free(struct nfe_softc *); @@ -765,18 +765,34 @@ nfe_rxeof(struct nfe_softc *sc) } if (sc->sc_flags & NFE_USE_JUMBO) { - if ((jbuf = nfe_jalloc(sc)) == NULL) { - m_freem(mnew); - ifp->if_ierrors++; - goto skip; - } - MEXTADD(mnew, jbuf->buf, NFE_JBYTES, 0, nfe_jfree, sc); + physaddr = + sc->rxq.jbuf[sc->rxq.jbufmap[i]].physaddr; + if ((jbuf = nfe_jalloc(sc, i)) == NULL) { + if (len > MCLBYTES) { + m_freem(mnew); + ifp->if_ierrors++; + goto skip1; + } + MCLGET(mnew, M_DONTWAIT); + if ((mnew->m_flags & M_EXT) == 0) { + m_freem(mnew); + ifp->if_ierrors++; + goto skip1; + } - bus_dmamap_sync(sc->sc_dmat, sc->rxq.jmap, - mtod(data->m, char *) - (char *)sc->rxq.jpool, - NFE_JBYTES, BUS_DMASYNC_POSTREAD); + memcpy(mtod(mnew, void *), + mtod(data->m, const void *), len); + m = mnew; + goto mbufcopied; + } else { + MEXTADD(mnew, jbuf->buf, NFE_JBYTES, 0, nfe_jfree, sc); - physaddr = jbuf->physaddr; + bus_dmamap_sync(sc->sc_dmat, sc->rxq.jmap, + mtod(data->m, char *) - (char *)sc->rxq.jpool, + NFE_JBYTES, BUS_DMASYNC_POSTREAD); + + physaddr = jbuf->physaddr; + } } else { MCLGET(mnew, M_DONTWAIT); if ((mnew->m_flags & M_EXT) == 0) { @@ -789,14 +805,15 @@ nfe_rxeof(struct nfe_softc *sc) data->map->dm_mapsize, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->sc_dmat, data->map); - error = bus_dmamap_load_mbuf(sc->sc_dmat, data->map, - mnew, BUS_DMA_READ | BUS_DMA_NOWAIT); + error = bus_dmamap_load(sc->sc_dmat, data->map, + mtod(mnew, void *), MCLBYTES, NULL, + BUS_DMA_READ | BUS_DMA_NOWAIT); if (error != 0) { m_freem(mnew); /* try to reload the old mbuf */ - error = bus_dmamap_load_mbuf(sc->sc_dmat, - data->map, data->m, + error = bus_dmamap_load(sc->sc_dmat, data->map, + mtod(data->m, void *), MCLBYTES, NULL, BUS_DMA_READ | BUS_DMA_NOWAIT); if (error != 0) { /* very unlikely that it will fail.. */ @@ -816,6 +833,7 @@ nfe_rxeof(struct nfe_softc *sc) m = data->m; data->m = mnew; +mbufcopied: /* finalize mbuf */ m->m_pkthdr.len = m->m_len = len; m->m_pkthdr.rcvif = ifp; @@ -853,6 +871,7 @@ nfe_rxeof(struct nfe_softc *sc) ifp->if_ipackets++; (*ifp->if_input)(ifp, m); +skip1: /* update mapping address in h/w descriptor */ if (sc->sc_flags & NFE_40BIT_ADDR) { #if defined(__LP64__) @@ -1371,7 +1390,7 @@ nfe_alloc_rx_ring(struct nfe_softc *sc, struct nfe_rx_ring *ring) } if (sc->sc_flags & NFE_USE_JUMBO) { - if ((jbuf = nfe_jalloc(sc)) == NULL) { + if ((jbuf = nfe_jalloc(sc, i)) == NULL) { printf("%s: could not allocate jumbo buffer\n", sc->sc_dev.dv_xname); goto fail; @@ -1492,13 +1511,15 @@ nfe_free_rx_ring(struct nfe_softc *sc, struct nfe_rx_ring *ring) } struct nfe_jbuf * -nfe_jalloc(struct nfe_softc *sc) +nfe_jalloc(struct nfe_softc *sc, int i) { struct nfe_jbuf *jbuf; jbuf = SLIST_FIRST(&sc->rxq.jfreelist); if (jbuf == NULL) return NULL; + sc->rxq.jbufmap[i] = + ((char *)jbuf->buf - (char *)sc->rxq.jpool) / NFE_JBYTES; SLIST_REMOVE_HEAD(&sc->rxq.jfreelist, jnext); return jbuf; } diff --git a/sys/dev/pci/if_nfevar.h b/sys/dev/pci/if_nfevar.h index cd10a3f390b..368cedf5964 100644 --- a/sys/dev/pci/if_nfevar.h +++ b/sys/dev/pci/if_nfevar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_nfevar.h,v 1.2 2007/03/04 06:02:22 christos Exp $ */ +/* $NetBSD: if_nfevar.h,v 1.3 2007/09/24 13:17:54 cube Exp $ */ /* $OpenBSD: if_nfevar.h,v 1.11 2006/02/19 13:57:02 damien Exp $ */ /*- @@ -59,6 +59,7 @@ struct nfe_rx_ring { void * jpool; struct nfe_rx_data data[NFE_RX_RING_COUNT]; struct nfe_jbuf jbuf[NFE_JPOOL_COUNT]; + int jbufmap[NFE_RX_RING_COUNT]; SLIST_HEAD(, nfe_jbuf) jfreelist; int bufsz; int cur; |
