diff options
author | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2002-07-29 23:41:25 +0000 |
---|---|---|
committer | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2002-07-29 23:41:25 +0000 |
commit | 3a09641674d4bd7cac8f1070c9a4e8ea0cbca0c1 (patch) | |
tree | ab03ae5f0548789a800ee53b86109551cdf15124 | |
parent | 558c3c6a7f3b729da65e2a18092d5b5924c9a949 (diff) |
switch to ether_input_mbuf(); mickey@ tested and ok.
-rw-r--r-- | sys/dev/ic/i82596.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/sys/dev/ic/i82596.c b/sys/dev/ic/i82596.c index 5c025ab8afb..2592888c356 100644 --- a/sys/dev/ic/i82596.c +++ b/sys/dev/ic/i82596.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i82596.c,v 1.9 2002/03/14 01:26:54 millert Exp $ */ +/* $OpenBSD: i82596.c,v 1.10 2002/07/29 23:41:24 fgsch Exp $ */ /* $NetBSD: i82586.c,v 1.18 1998/08/15 04:42:42 mycroft Exp $ */ /*- @@ -998,18 +998,20 @@ i82596_chk_rx_ring(sc) * operation considerably. (Provided that it works, of course.) */ static __inline__ struct mbuf * -i82596_get(struct ie_softc *sc, struct ether_header *ehp, int head, int totlen) +i82596_get(struct ie_softc *sc, int head, int totlen) { struct mbuf *top, **mp, *m; int off, len, resid; int thisrboff, thismboff; + struct ether_header eh; /* * Snarf the Ethernet header. */ - (sc->memcopyin)(sc, ehp, IE_RBUF_ADDR(sc,head), sizeof *ehp); + (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head), + sizeof(struct ether_header)); - resid = totlen -= (thisrboff = sizeof *ehp); + resid = totlen; MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == 0) @@ -1041,6 +1043,13 @@ i82596_get(struct ie_softc *sc, struct ether_header *ehp, int head, int totlen) } len = MCLBYTES; } + if (mp == top) { + caddr_t newdata = (caddr_t) + ALIGN(m->m_data + sizeof(struct ether_header)) - + sizeof(struct ether_header); + len -= newdata - m->m_data; + m->m_data = newdata; + } m->m_len = len = min(totlen, len); totlen -= len; *mp = m; @@ -1051,6 +1060,14 @@ i82596_get(struct ie_softc *sc, struct ether_header *ehp, int head, int totlen) thismboff = 0; /* + * Copy the Ethernet header into the mbuf chain. + */ + bcopy(&eh, mtod(m, caddr_t), sizeof(struct ether_header)); + thismboff = sizeof(struct ether_header); + thisrboff = sizeof(struct ether_header); + resid -= sizeof(struct ether_header); + + /* * Now we take the mbuf chain (hopefully only one mbuf most of the * time) and stuff the data into it. There are no possible failures * at or after this point. @@ -1103,7 +1120,6 @@ i82596_readframe(sc, num) { struct ifnet *ifp = &sc->sc_arpcom.ac_if; struct mbuf *m; - struct ether_header eh; u_int16_t bstart, bend; int pktlen; @@ -1112,7 +1128,7 @@ i82596_readframe(sc, num) return (1); } - m = i82596_get(sc, &eh, bstart, pktlen); + m = i82596_get(sc, bstart, pktlen); i82596_release_rbd_list(sc, bstart, bend); if (m == 0) { @@ -1121,38 +1137,27 @@ i82596_readframe(sc, num) } #ifdef I82596_DEBUG - if (sc->sc_debug & IED_READFRAME) + if (sc->sc_debug & IED_READFRAME) { + struct ether_header *eh = mtod(m, struct ether_header *); + printf("%s: frame from ether %s type 0x%x len %d\n", - sc->sc_dev.dv_xname, - ether_sprintf(eh.ether_shost), - (u_int)eh.ether_type, pktlen); + sc->sc_dev.dv_xname, ether_sprintf(eh->ether_shost), + (u_int)eh->ether_type, pktlen); + } #endif #if NBPFILTER > 0 - /* - * Check for a BPF filter; if so, hand it up. - * Note that we have to stick an extra mbuf up front, because bpf_mtap - * expects to have the ether header at the front. - * It doesn't matter that this results in an ill-formatted mbuf chain, - * since BPF just looks at the data. (It doesn't try to free the mbuf, - * tho' it will make a copy for tcpdump.) - */ + /* Check for a BPF filter; if so, hand it up. */ if (ifp->if_bpf) { - struct mbuf m0; - m0.m_len = sizeof eh; - m0.m_data = (caddr_t)&eh; - m0.m_next = m; - /* Pass it up. */ - bpf_mtap(ifp->if_bpf, &m0); - + bpf_mtap(ifp->if_bpf, m); } #endif /* NBPFILTER > 0 */ /* * Finally pass this packet up to higher layers. */ - ether_input(ifp, &eh, m); + ether_input_mbuf(ifp, m); ifp->if_ipackets++; return (0); } |