summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_nfe.c59
-rw-r--r--sys/dev/pci/if_nfevar.h3
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;