From 77dd8f0bc2a7f8dc8d1d137c48f54561f9c011e3 Mon Sep 17 00:00:00 2001 From: miod Date: Mon, 25 May 2015 12:40:04 +0000 Subject: [PATCH] Convert from ether_input() with separate mbuf data and Ethernet header, to if_input(). Based upon an initial diff from mpi@, and then painfully made STRICT_ALIGNMENT-compliant. Tested on 4/260. ok mpi@ --- sys/arch/sparc/dev/if_ie.c | 202 ++++++++++--------------------------- 1 file changed, 54 insertions(+), 148 deletions(-) diff --git a/sys/arch/sparc/dev/if_ie.c b/sys/arch/sparc/dev/if_ie.c index 168a67ba3dd..6930e5e784c 100644 --- a/sys/arch/sparc/dev/if_ie.c +++ b/sys/arch/sparc/dev/if_ie.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ie.c,v 1.51 2015/04/07 10:46:20 mpi Exp $ */ +/* $OpenBSD: if_ie.c,v 1.52 2015/05/25 12:40:04 miod Exp $ */ /* $NetBSD: if_ie.c,v 1.33 1997/07/29 17:55:38 fair Exp $ */ /*- @@ -142,7 +142,6 @@ Mode of operation: #include #include -static struct mbuf *last_not_for_us; struct vm_map *ie_map; /* for obio */ #define IED_RINT 0x01 @@ -282,12 +281,12 @@ struct ie_softc { #endif }; -static void ie_obreset(struct ie_softc *); -static void ie_obattend(struct ie_softc *); -static void ie_obrun(struct ie_softc *); -static void ie_vmereset(struct ie_softc *); -static void ie_vmeattend(struct ie_softc *); -static void ie_vmerun(struct ie_softc *); +void ie_obreset(struct ie_softc *); +void ie_obattend(struct ie_softc *); +void ie_obrun(struct ie_softc *); +void ie_vmereset(struct ie_softc *); +void ie_vmeattend(struct ie_softc *); +void ie_vmerun(struct ie_softc *); void iewatchdog(struct ifnet *); int ieintr(void *); @@ -295,32 +294,30 @@ int ieinit(struct ie_softc *); int ieioctl(struct ifnet *, u_long, caddr_t); void iestart(struct ifnet *); void iereset(struct ie_softc *); -static void ie_readframe(struct ie_softc *, int); -static void ie_drop_packet_buffer(struct ie_softc *); +void ie_readframe(struct ie_softc *, int); +void ie_drop_packet_buffer(struct ie_softc *); int ie_setupram(struct ie_softc *); -static int command_and_wait(struct ie_softc *, int, +int command_and_wait(struct ie_softc *, int, void volatile *, int); -/*static*/ void ierint(struct ie_softc *); -/*static*/ void ietint(struct ie_softc *); -static int ieget(struct ie_softc *, struct mbuf **, - struct ether_header *, int *); -static void setup_bufs(struct ie_softc *); -static int mc_setup(struct ie_softc *, void *); -static void mc_reset(struct ie_softc *); +void ierint(struct ie_softc *); +void ietint(struct ie_softc *); +int ieget(struct ie_softc *, struct mbuf **); +void setup_bufs(struct ie_softc *); +int mc_setup(struct ie_softc *, void *); +void mc_reset(struct ie_softc *); static __inline int ether_equal(u_char *, u_char *); static __inline void ie_ack(struct ie_softc *, u_int); static __inline void ie_setup_config(volatile struct ie_config_cmd *, int, int); -static __inline int check_eh(struct ie_softc *, struct ether_header *, - int *); +static __inline int check_eh(struct ie_softc *, struct ether_header *); static __inline int ie_buflen(struct ie_softc *, int); static __inline int ie_packet_len(struct ie_softc *); static __inline void iexmit(struct ie_softc *); static __inline caddr_t Align(caddr_t); -static void chan_attn_timeout(void *); -static void run_tdr(struct ie_softc *, struct ie_tdr_cmd *); -static void iestop(struct ie_softc *); +void chan_attn_timeout(void *); +void run_tdr(struct ie_softc *, struct ie_tdr_cmd *); +void iestop(struct ie_softc *); void wzero(void *, size_t); void wcopy(const void *, void *, size_t); @@ -884,22 +881,13 @@ ether_equal(one, two) } /* - * Check for a valid address. to_bpf is filled in with one of the following: - * 0 -> BPF doesn't get this packet - * 1 -> BPF does get this packet - * 2 -> BPF does get this packet, but we don't + * Check for a valid address. * Return value is true if the packet is for us, and false otherwise. - * - * This routine is a mess, but it's also critical that it be as fast - * as possible. It could be made cleaner if we can assume that the - * only client which will fiddle with IFF_PROMISC is BPF. This is - * probably a good assumption, but we do not make it here. (Yet.) */ static __inline int -check_eh(sc, eh, to_bpf) +check_eh(sc, eh) struct ie_softc *sc; struct ether_header *eh; - int *to_bpf; { int i; @@ -909,9 +897,6 @@ check_eh(sc, eh, to_bpf) * Receiving all multicasts, but no unicasts except those * destined for us. */ -#if NBPFILTER > 0 - *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0); /* BPF gets this packet if anybody cares */ -#endif if (eh->ether_dhost[0] & 1) return 1; if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr)) return 1; @@ -921,20 +906,9 @@ check_eh(sc, eh, to_bpf) /* * Receiving all packets. These need to be passed on to BPF. */ -#if NBPFILTER > 0 - *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) || - (sc->sc_arpcom.ac_if.if_bridgeport != NULL); -#else - *to_bpf = (sc->sc_arpcom.ac_if.if_bridgeport != NULL); -#endif /* If for us, accept and hand up to BPF */ if (ether_equal(eh->ether_dhost, sc->sc_arpcom.ac_enaddr)) return 1; -#if NBPFILTER > 0 - if (*to_bpf && sc->sc_arpcom.ac_if.if_bridgeport == NULL) - *to_bpf = 2; /* we don't need to see it */ -#endif - /* * Not a multicast, so BPF wants to see it but we don't. */ @@ -947,26 +921,12 @@ check_eh(sc, eh, to_bpf) */ for (i = 0; i < sc->mcast_count; i++) { if (ether_equal(eh->ether_dhost, (u_char *)&sc->mcast_addrs[i])) { -#if NBPFILTER > 0 - if (*to_bpf) - *to_bpf = 1; -#endif return 1; } } return 1; case IFF_ALLMULTI | IFF_PROMISC: - /* - * Acting as a multicast router, and BPF running at the same - * time. Whew! (Hope this is a fast machine...) - */ -#if NBPFILTER > 0 - *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0) || - (sc->sc_arpcom.ac_if.if_bridgeport != NULL); -#else - *to_bpf = (sc->sc_arpcom.ac_if.if_bridgeport != 0); -#endif /* We want to see multicasts. */ if (eh->ether_dhost[0] & 1) return 1; @@ -976,10 +936,6 @@ check_eh(sc, eh, to_bpf) return 1; /* Anything else goes to BPF but nothing else. */ -#if NBPFILTER > 0 - if (*to_bpf && sc->sc_arpcom.ac_if.if_bridgeport == NULL) - *to_bpf = 2; -#endif return 1; default: @@ -991,9 +947,6 @@ check_eh(sc, eh, to_bpf) * filter), but it will do in this case, and we want to get out * of here as quickly as possible. */ -#if NBPFILTER > 0 - *to_bpf = (sc->sc_arpcom.ac_if.if_bpf != 0); -#endif return 1; } return 0; @@ -1095,30 +1048,28 @@ iexmit(sc) * chain of partially-full mbufs. This should help to speed up the * operation considerably. (Provided that it works, of course.) */ -static inline int -ieget(sc, mp, ehp, to_bpf) +int +ieget(sc, mp) struct ie_softc *sc; struct mbuf **mp; - struct ether_header *ehp; - int *to_bpf; { struct mbuf *m, *top, **mymp; - int i; int offset; int totlen, resid; int thismboff; int head; + struct ether_header eh; totlen = ie_packet_len(sc); if (totlen <= 0) return -1; - i = sc->rbhead; + head = sc->rbhead; /* * Snarf the Ethernet header. */ - (sc->memcopy)((caddr_t)sc->cbuffs[i], (caddr_t)ehp, sizeof *ehp); + (sc->memcopy)((caddr_t)sc->cbuffs[head], (caddr_t)&eh, sizeof eh); /* * As quickly as possible, check if this packet is for us. @@ -1127,12 +1078,11 @@ ieget(sc, mp, ehp, to_bpf) * This is only a consideration when FILTER is defined; i.e., when * we are either running BPF or doing multicasting. */ - if (!check_eh(sc, ehp, to_bpf)) { + if (!check_eh(sc, &eh)) { ie_drop_packet_buffer(sc); sc->sc_arpcom.ac_if.if_ierrors--; /* just this case, it's not an error */ return -1; } - totlen -= (offset = sizeof *ehp); MGETHDR(*mp, M_DONTWAIT, MT_DATA); if (!*mp) { @@ -1141,10 +1091,9 @@ ieget(sc, mp, ehp, to_bpf) } m = *mp; - m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if; m->m_len = MHLEN; - resid = m->m_pkthdr.len = totlen; - top = 0; + resid = m->m_pkthdr.len = totlen + ETHER_ALIGN; + top = NULL; mymp = ⊤ /* @@ -1189,8 +1138,9 @@ ieget(sc, mp, ehp, to_bpf) resid = totlen; m = top; + m_adj(m, ETHER_ALIGN); thismboff = 0; - head = sc->rbhead; + offset = 0; /* * Now we take the mbuf chain (hopefully only one mbuf most of the @@ -1271,17 +1221,14 @@ ieget(sc, mp, ehp, to_bpf) * on confusing code to deal with them. Hopefully, this machine will never ARP * for trailers anyway. */ -static void +void ie_readframe(sc, num) struct ie_softc *sc; int num; /* frame number to read */ { int status; - struct mbuf *m = 0; - struct ether_header eh; -#if NBPFILTER > 0 - int bpf_gets_it = 0; -#endif + struct mbuf *m = NULL; + struct mbuf_list ml = MBUF_LIST_INITIALIZER(); status = sc->rframes[num]->ie_fd_status; @@ -1293,71 +1240,30 @@ ie_readframe(sc, num) sc->rfhead = (sc->rfhead + 1) % sc->nframes; if (status & IE_FD_OK) { -#if NBPFILTER > 0 - if (ieget(sc, &m, &eh, &bpf_gets_it)) { -#else - if (ieget(sc, &m, &eh, 0)) { -#endif + if (ieget(sc, &m)) { sc->sc_arpcom.ac_if.if_ierrors++; return; } } + if (m == NULL) + return; + #ifdef IEDEBUG - 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\n", sc->sc_dev.dv_xname, - ether_sprintf(eh.ether_shost), (u_int)eh.ether_type); -#endif - - if (!m) - return; - - if (last_not_for_us) { - m_freem(last_not_for_us); - last_not_for_us = 0; - } - -#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.) - */ - if (bpf_gets_it) { - /* Pass it up. */ - bpf_mtap_hdr(sc->sc_arpcom.ac_if.if_bpf, (caddr_t)&eh, - sizeof(eh), m, BPF_DIRECTION_IN, NULL); - } - /* - * A signal passed up from the filtering code indicating that the - * packet is intended for BPF but not for the protocol machinery. - * We can save a few cycles by not handing it off to them. - */ - if (bpf_gets_it == 2) { - last_not_for_us = m; - return; + ether_sprintf(eh->ether_shost), (u_int)eh->ether_type); } -#endif /* NBPFILTER > 0 */ - - /* - * In here there used to be code to check destination addresses upon - * receipt of a packet. We have deleted that code, and replaced it - * with code to check the address much earlier in the cycle, before - * copying the data in; this saves us valuable cycles when operating - * as a multicast router or when using BPF. - */ +#endif - /* - * Finally pass this packet up to higher layers. - */ - ether_input(m, &eh); + ml_enqueue(&ml, m); + if_input(&sc->sc_arpcom.ac_if, &ml); + sc->sc_arpcom.ac_if.if_ipackets++; } -static void +void ie_drop_packet_buffer(sc) struct ie_softc *sc; { @@ -1531,7 +1437,7 @@ iereset(sc) /* * This is called if we time out. */ -static void +void chan_attn_timeout(rock) void *rock; { @@ -1548,7 +1454,7 @@ chan_attn_timeout(rock) * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK * to become true. */ -static int +int command_and_wait(sc, cmd, pcmd, mask) struct ie_softc *sc; int cmd; @@ -1610,7 +1516,7 @@ command_and_wait(sc, cmd, pcmd, mask) /* * Run the time-domain reflectometer. */ -static void +void run_tdr(sc, cmd) struct ie_softc *sc; struct ie_tdr_cmd *cmd; @@ -1681,7 +1587,7 @@ Align(ptr) * note: this function was written to be easy to understand, rather than * highly efficient (it isn't in the critical path). */ -static void +void setup_bufs(sc) struct ie_softc *sc; { @@ -1809,7 +1715,7 @@ setup_bufs(sc) * Run the multicast setup command. * Called at splnet(). */ -static int +int mc_setup(sc, ptr) struct ie_softc *sc; void *ptr; @@ -1924,7 +1830,7 @@ ieinit(sc) return 0; } -static void +void iestop(sc) struct ie_softc *sc; { @@ -2006,7 +1912,7 @@ ieioctl(ifp, cmd, data) return error; } -static void +void mc_reset(sc) struct ie_softc *sc; { -- 2.20.1