diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-05-10 12:41:32 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1996-05-10 12:41:32 +0000 |
commit | b8c4a37a40fbc7dd0a9e13c6a19af16489874aa1 (patch) | |
tree | 5d3410536b0b327107d38972cd6de9edee2b705f /sys/dev/ic/am7990.c | |
parent | e1e97ed1b9981b214b4a1a85f0d6a2f17c7656b9 (diff) |
if_name/if_unit -> if_xname/if_softc
Diffstat (limited to 'sys/dev/ic/am7990.c')
-rw-r--r-- | sys/dev/ic/am7990.c | 308 |
1 files changed, 196 insertions, 112 deletions
diff --git a/sys/dev/ic/am7990.c b/sys/dev/ic/am7990.c index 2b243bd2095..5f89ebb8e63 100644 --- a/sys/dev/ic/am7990.c +++ b/sys/dev/ic/am7990.c @@ -1,5 +1,5 @@ -/* $OpenBSD: am7990.c,v 1.7 1996/05/05 13:39:31 mickey Exp $ */ -/* $NetBSD: am7990.c,v 1.18 1996/04/22 02:40:50 christos Exp $ */ +/* $OpenBSD: am7990.c,v 1.8 1996/05/10 12:41:10 deraadt Exp $ */ +/* $NetBSD: am7990.c,v 1.19 1996/05/07 01:38:35 thorpej Exp $ */ /*- * Copyright (c) 1995 Charles M. Hannum. All rights reserved. @@ -40,10 +40,23 @@ * @(#)if_le.c 8.2 (Berkeley) 11/16/93 */ +#include "bpfilter.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/mbuf.h> +#include <sys/syslog.h> +#include <sys/socket.h> +#include <sys/device.h> +#include <sys/malloc.h> #include <sys/ioctl.h> #include <sys/errno.h> +#include <net/if.h> + #ifdef INET +#include <netinet/in.h> +#include <netinet/if_ether.h> #include <netinet/in_systm.h> #include <netinet/in_var.h> #include <netinet/ip.h> @@ -54,31 +67,81 @@ #include <net/bpfdesc.h> #endif +#include <dev/ic/am7990reg.h> +#include <dev/ic/am7990var.h> + #ifdef LEDEBUG -void recv_print __P((struct le_softc *, int)); -void xmit_print __P((struct le_softc *, int)); +void am7990_recv_print __P((struct am7990_softc *, int)); +void am7990_xmit_print __P((struct am7990_softc *, int)); #endif +integrate void am7990_rint __P((struct am7990_softc *)); +integrate void am7990_tint __P((struct am7990_softc *)); + +integrate int am7990_put __P((struct am7990_softc *, int, struct mbuf *)); +integrate struct mbuf *am7990_get __P((struct am7990_softc *, int, int)); +integrate void am7990_read __P((struct am7990_softc *, int, int)); + +hide void am7990_shutdown __P((void *)); + #define ifp (&sc->sc_arpcom.ac_if) +#if 0 /* XXX what do we do about this?! --thorpej */ +static inline u_int16_t ether_cmp __P((void *, void *)); + +/* + * Compare two Ether/802 addresses for equality, inlined and + * unrolled for speed. I'd love to have an inline assembler + * version of this... XXX: Who wanted that? mycroft? + * I wrote one, but the following is just as efficient. + * This expands to 10 short m68k instructions! -gwr + * Note: use this like bcmp() + */ +static inline u_short +ether_cmp(one, two) + void *one, *two; +{ + register u_int16_t *a = (u_short *) one; + register u_int16_t *b = (u_short *) two; + register u_int16_t diff; + + diff = *a++ - *b++; + diff |= *a++ - *b++; + diff |= *a++ - *b++; + + return (diff); +} + +#define ETHER_CMP ether_cmp +#endif /* XXX */ + #ifndef ETHER_CMP #define ETHER_CMP(a, b) bcmp((a), (b), ETHER_ADDR_LEN) #endif +/* + * am7990 configuration driver. Attachments are provided by + * machine-dependent driver front-ends. + */ +struct cfdriver le_cd = { + NULL, "le", DV_IFNET +}; + void -leconfig(sc) - struct le_softc *sc; +am7990_config(sc) + struct am7990_softc *sc; { int mem; /* Make sure the chip is stopped. */ - lestop(sc); + am7990_stop(sc); /* Initialize ifnet structure. */ - ifp->if_unit = sc->sc_dev.dv_unit; - ifp->if_start = lestart; - ifp->if_ioctl = leioctl; - ifp->if_watchdog = lewatchdog; + bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); + ifp->if_softc = sc; + ifp->if_start = am7990_start; + ifp->if_ioctl = am7990_ioctl; + ifp->if_watchdog = am7990_watchdog; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST; #ifdef LANCE_REVC_BUG @@ -111,13 +174,17 @@ leconfig(sc) sc->sc_ntbuf = 8; break; default: - panic("leconfig: weird memory size"); + panic("am7990_config: weird memory size"); } printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr)); printf("%s: %d receive buffers, %d transmit buffers\n", sc->sc_dev.dv_xname, sc->sc_nrbuf, sc->sc_ntbuf); + sc->sc_sh = shutdownhook_establish(am7990_shutdown, sc); + if (sc->sc_sh == NULL) + panic("am7990_config: can't establish shutdownhook"); + mem = 0; sc->sc_initaddr = mem; mem += sizeof(struct leinit); @@ -136,34 +203,22 @@ leconfig(sc) } void -lereset(sc) - struct le_softc *sc; +am7990_reset(sc) + struct am7990_softc *sc; { int s; s = splimp(); - leinit(sc); + am7990_init(sc); splx(s); } -void -lewatchdog(unit) - int unit; -{ - struct le_softc *sc = LE_SOFTC(unit); - - log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); - ++ifp->if_oerrors; - - lereset(sc); -} - /* * Set up the initialization block and the descriptor rings. */ void -lememinit(sc) - register struct le_softc *sc; +am7990_meminit(sc) + register struct am7990_softc *sc; { u_long a; int bix; @@ -183,7 +238,7 @@ lememinit(sc) (sc->sc_arpcom.ac_enaddr[3] << 8) | sc->sc_arpcom.ac_enaddr[2]; init.init_padr[2] = (sc->sc_arpcom.ac_enaddr[5] << 8) | sc->sc_arpcom.ac_enaddr[4]; - lesetladrf(&sc->sc_arpcom, init.init_ladrf); + am7990_setladrf(&sc->sc_arpcom, init.init_ladrf); sc->sc_last_rd = 0; sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0; @@ -228,11 +283,11 @@ lememinit(sc) } void -lestop(sc) - struct le_softc *sc; +am7990_stop(sc) + struct am7990_softc *sc; { - lewrcsr(sc, LE_CSR0, LE_C0_STOP); + (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP); } /* @@ -240,45 +295,47 @@ lestop(sc) * and transmit/receive descriptor rings. */ void -leinit(sc) - register struct le_softc *sc; +am7990_init(sc) + register struct am7990_softc *sc; { register int timo; u_long a; - lewrcsr(sc, LE_CSR0, LE_C0_STOP); - LE_DELAY(100); + (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_STOP); + DELAY(100); /* Set the correct byte swapping mode, etc. */ - lewrcsr(sc, LE_CSR3, sc->sc_conf3); + (*sc->sc_wrcsr)(sc, LE_CSR3, sc->sc_conf3); /* Set up LANCE init block. */ - lememinit(sc); + am7990_meminit(sc); /* Give LANCE the physical address of its init block. */ a = sc->sc_addr + LE_INITADDR(sc); - lewrcsr(sc, LE_CSR1, a); - lewrcsr(sc, LE_CSR2, a >> 16); + (*sc->sc_wrcsr)(sc, LE_CSR1, a); + (*sc->sc_wrcsr)(sc, LE_CSR2, a >> 16); /* Try to initialize the LANCE. */ - LE_DELAY(100); - lewrcsr(sc, LE_CSR0, LE_C0_INIT); + DELAY(100); + (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INIT); /* Wait for initialization to finish. */ for (timo = 100000; timo; timo--) - if (lerdcsr(sc, LE_CSR0) & LE_C0_IDON) + if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) break; - if (lerdcsr(sc, LE_CSR0) & LE_C0_IDON) { + if ((*sc->sc_rdcsr)(sc, LE_CSR0) & LE_C0_IDON) { /* Start the LANCE. */ - lewrcsr(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT | LE_C0_IDON); + (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_STRT | + LE_C0_IDON); ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; ifp->if_timer = 0; - lestart(ifp); + am7990_start(ifp); } else printf("%s: card failed to initialize\n", sc->sc_dev.dv_xname); - lehwinit(sc); + if (sc->sc_hwinit) + (*sc->sc_hwinit)(sc); } /* @@ -286,8 +343,8 @@ leinit(sc) * network buffer memory. */ integrate int -leput(sc, boff, m) - struct le_softc *sc; +am7990_put(sc, boff, m) + struct am7990_softc *sc; int boff; register struct mbuf *m; { @@ -319,8 +376,8 @@ leput(sc, boff, m) * we copy into clusters. */ integrate struct mbuf * -leget(sc, boff, totlen) - struct le_softc *sc; +am7990_get(sc, boff, totlen) + struct am7990_softc *sc; int boff, totlen; { register struct mbuf *m; @@ -367,8 +424,8 @@ leget(sc, boff, totlen) * Pass a packet to the higher levels. */ integrate void -leread(sc, boff, len) - register struct le_softc *sc; +am7990_read(sc, boff, len) + register struct am7990_softc *sc; int boff, len; { struct mbuf *m; @@ -385,7 +442,7 @@ leread(sc, boff, len) } /* Pull packet off interface. */ - m = leget(sc, boff, len); + m = am7990_get(sc, boff, len); if (m == 0) { ifp->if_ierrors++; return; @@ -441,8 +498,8 @@ leread(sc, boff, len) } integrate void -lerint(sc) - struct le_softc *sc; +am7990_rint(sc) + struct am7990_softc *sc; { register int bix; int rp; @@ -487,9 +544,10 @@ lerint(sc) } else { #ifdef LEDEBUG if (sc->sc_debug) - recv_print(sc, sc->sc_last_rd); + am7990_recv_print(sc, sc->sc_last_rd); #endif - leread(sc, LE_RBUFADDR(sc, bix), (int)rmd.rmd3 - 4); + am7990_read(sc, LE_RBUFADDR(sc, bix), + (int)rmd.rmd3 - 4); } rmd.rmd1_bits = LE_R1_OWN; @@ -515,8 +573,8 @@ lerint(sc) } integrate void -letint(sc) - register struct le_softc *sc; +am7990_tint(sc) + register struct am7990_softc *sc; { register int bix; struct letmd tmd; @@ -546,20 +604,23 @@ letint(sc) if (tmd.tmd1_bits & LE_T1_ERR) { if (tmd.tmd3 & LE_T3_BUFF) - printf("%s: transmit buffer error\n", sc->sc_dev.dv_xname); + printf("%s: transmit buffer error\n", + sc->sc_dev.dv_xname); else if (tmd.tmd3 & LE_T3_UFLO) printf("%s: underflow\n", sc->sc_dev.dv_xname); if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) { - lereset(sc); + am7990_reset(sc); return; } if (tmd.tmd3 & LE_T3_LCAR) - printf("%s: lost carrier\n", sc->sc_dev.dv_xname); + printf("%s: lost carrier\n", + sc->sc_dev.dv_xname); if (tmd.tmd3 & LE_T3_LCOL) ifp->if_collisions++; if (tmd.tmd3 & LE_T3_RTRY) { printf("%s: excessive collisions, tdr %d\n", - sc->sc_dev.dv_xname, tmd.tmd3 & LE_T3_TDR_MASK); + sc->sc_dev.dv_xname, + tmd.tmd3 & LE_T3_TDR_MASK); ifp->if_collisions += 16; } ifp->if_oerrors++; @@ -580,7 +641,7 @@ letint(sc) sc->sc_first_td = bix; - lestart(ifp); + am7990_start(ifp); if (sc->sc_no_td == 0) ifp->if_timer = 0; @@ -590,22 +651,22 @@ letint(sc) * Controller interrupt. */ int -leintr(arg) +am7990_intr(arg) register void *arg; { - register struct le_softc *sc = arg; + register struct am7990_softc *sc = arg; register u_int16_t isr; - isr = lerdcsr(sc, LE_CSR0); + isr = (*sc->sc_rdcsr)(sc, LE_CSR0); #ifdef LEDEBUG if (sc->sc_debug) - printf("%s: leintr entering with isr=%04x\n", + printf("%s: am7990_intr entering with isr=%04x\n", sc->sc_dev.dv_xname, isr); #endif if ((isr & LE_C0_INTR) == 0) return (0); - lewrcsr(sc, LE_CSR0, + (*sc->sc_wrcsr)(sc, LE_CSR0, isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR | LE_C0_RINT | LE_C0_TINT | LE_C0_IDON)); if (isr & LE_C0_ERR) { @@ -629,7 +690,7 @@ leintr(arg) } if (isr & LE_C0_MERR) { printf("%s: memory error\n", sc->sc_dev.dv_xname); - lereset(sc); + am7990_reset(sc); return (1); } } @@ -637,26 +698,38 @@ leintr(arg) if ((isr & LE_C0_RXON) == 0) { printf("%s: receiver disabled\n", sc->sc_dev.dv_xname); ifp->if_ierrors++; - lereset(sc); + am7990_reset(sc); return (1); } if ((isr & LE_C0_TXON) == 0) { printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname); ifp->if_oerrors++; - lereset(sc); + am7990_reset(sc); return (1); } if (isr & LE_C0_RINT) - lerint(sc); + am7990_rint(sc); if (isr & LE_C0_TINT) - letint(sc); + am7990_tint(sc); return (1); } #undef ifp +void +am7990_watchdog(ifp) + struct ifnet *ifp; +{ + struct am7990_softc *sc = ifp->if_softc; + + log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname); + ++ifp->if_oerrors; + + am7990_reset(sc); +} + /* * Setup output on interface. * Get another datagram to send off of the interface queue, and map it to the @@ -664,10 +737,10 @@ leintr(arg) * Called only at splimp or interrupt level. */ void -lestart(ifp) +am7990_start(ifp) register struct ifnet *ifp; { - register struct le_softc *sc = LE_SOFTC(ifp->if_unit); + register struct am7990_softc *sc = ifp->if_softc; register int bix; register struct mbuf *m; struct letmd tmd; @@ -705,7 +778,7 @@ lestart(ifp) /* * Copy the mbuf chain into the transmit buffer. */ - len = leput(sc, LE_TBUFADDR(sc, bix), m); + len = am7990_put(sc, LE_TBUFADDR(sc, bix), m); #ifdef LEDEBUG if (len > ETHERMTU + sizeof(struct ether_header)) @@ -725,10 +798,10 @@ lestart(ifp) #ifdef LEDEBUG if (sc->sc_debug) - xmit_print(sc, sc->sc_last_td); + am7990_xmit_print(sc, sc->sc_last_td); #endif - lewrcsr(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); + (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); if (++bix == sc->sc_ntbuf) bix = 0; @@ -747,12 +820,12 @@ lestart(ifp) * Process an ioctl request. */ int -leioctl(ifp, cmd, data) +am7990_ioctl(ifp, cmd, data) register struct ifnet *ifp; u_long cmd; caddr_t data; { - struct le_softc *sc = LE_SOFTC(ifp->if_unit); + register struct am7990_softc *sc = ifp->if_softc; struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; int s, error = 0; @@ -772,12 +845,12 @@ leioctl(ifp, cmd, data) switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: - leinit(sc); + am7990_init(sc); arp_ifinit(&sc->sc_arpcom, ifa); break; #endif default: - leinit(sc); + am7990_init(sc); break; } break; @@ -789,7 +862,7 @@ leioctl(ifp, cmd, data) * If interface is marked down and it is running, then * stop it. */ - lestop(sc); + am7990_stop(sc); ifp->if_flags &= ~IFF_RUNNING; } else if ((ifp->if_flags & IFF_UP) != 0 && (ifp->if_flags & IFF_RUNNING) == 0) { @@ -797,14 +870,14 @@ leioctl(ifp, cmd, data) * If interface is marked up and it is stopped, then * start it. */ - leinit(sc); + am7990_init(sc); } else { /* * Reset the interface to pick up changes in any other * flags that affect hardware registers. */ - /*lestop(sc);*/ - leinit(sc); + /*am7990_stop(sc);*/ + am7990_init(sc); } #ifdef LEDEBUG if (ifp->if_flags & IFF_DEBUG) @@ -825,7 +898,7 @@ leioctl(ifp, cmd, data) * Multicast list has changed; set the hardware filter * accordingly. */ - lereset(sc); + am7990_reset(sc); error = 0; } break; @@ -839,10 +912,18 @@ leioctl(ifp, cmd, data) return (error); } +hide void +am7990_shutdown(arg) + void *arg; +{ + + am7990_stop((struct am7990_softc *)arg); +} + #ifdef LEDEBUG void -recv_print(sc, no) - struct le_softc *sc; +am7990_recv_print(sc, no) + struct am7990_softc *sc; int no; { struct lermd rmd; @@ -853,7 +934,8 @@ recv_print(sc, no) len = rmd.rmd3; printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, len); - printf("%s: status %04x\n", sc->sc_dev.dv_xname, lerdcsr(sc, LE_CSR0)); + printf("%s: status %04x\n", sc->sc_dev.dv_xname, + (*sc->sc_rdcsr)(sc, LE_CSR0)); printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", sc->sc_dev.dv_xname, rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3); @@ -867,8 +949,8 @@ recv_print(sc, no) } void -xmit_print(sc, no) - struct le_softc *sc; +am7990_xmit_print(sc, no) + struct am7990_softc *sc; int no; { struct letmd tmd; @@ -879,7 +961,8 @@ xmit_print(sc, no) len = -tmd.tmd2; printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no, len); - printf("%s: status %04x\n", sc->sc_dev.dv_xname, lerdcsr(sc, LE_CSR0)); + printf("%s: status %04x\n", sc->sc_dev.dv_xname, + (*sc->sc_rdcsr)(sc, LE_CSR0)); printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n", sc->sc_dev.dv_xname, tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3); @@ -897,7 +980,7 @@ xmit_print(sc, no) * Set up the logical address filter. */ void -lesetladrf(ac, af) +am7990_setladrf(ac, af) struct arpcom *ac; u_int16_t *af; { @@ -974,7 +1057,6 @@ allmulti: * (3) gap16 (16 bytes of data followed by 16 bytes of padding). */ -#ifdef LE_NEED_BUF_CONTIG /* * contig: contiguous data with no padding. * @@ -983,7 +1065,7 @@ allmulti: void am7990_copytobuf_contig(sc, from, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; void *from; int boff, len; { @@ -997,7 +1079,7 @@ am7990_copytobuf_contig(sc, from, boff, len) void am7990_copyfrombuf_contig(sc, to, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; void *to; int boff, len; { @@ -1011,7 +1093,7 @@ am7990_copyfrombuf_contig(sc, to, boff, len) void am7990_zerobuf_contig(sc, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; int boff, len; { volatile caddr_t buf = sc->sc_mem; @@ -1021,9 +1103,13 @@ am7990_zerobuf_contig(sc, boff, len) */ bzero(buf + boff, len); } -#endif /* LE_NEED_BUF_CONTIG */ -#ifdef LE_NEED_BUF_GAP2 +#if 0 +/* + * Examples only; duplicate these and tweak (if necessary) in + * machine-specific front-ends. + */ + /* * gap2: two bytes of data followed by two bytes of pad. * @@ -1033,7 +1119,7 @@ am7990_zerobuf_contig(sc, boff, len) void am7990_copytobuf_gap2(sc, fromv, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; void *fromv; int boff; register int len; @@ -1062,7 +1148,7 @@ am7990_copytobuf_gap2(sc, fromv, boff, len) void am7990_copyfrombuf_gap2(sc, tov, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; void *tov; int boff, len; { @@ -1092,7 +1178,7 @@ am7990_copyfrombuf_gap2(sc, tov, boff, len) void am7990_zerobuf_gap2(sc, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; int boff, len; { volatile caddr_t buf = sc->sc_mem; @@ -1111,9 +1197,7 @@ am7990_zerobuf_gap2(sc, boff, len) len -= 2; } } -#endif /* LE_NEED_BUF_GAP2 */ -#ifdef LE_NEED_BUF_GAP16 /* * gap16: 16 bytes of data followed by 16 bytes of pad. * @@ -1122,7 +1206,7 @@ am7990_zerobuf_gap2(sc, boff, len) void am7990_copytobuf_gap16(sc, fromv, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; void *fromv; int boff; register int len; @@ -1147,7 +1231,7 @@ am7990_copytobuf_gap16(sc, fromv, boff, len) void am7990_copyfrombuf_gap16(sc, tov, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; void *tov; int boff, len; { @@ -1171,7 +1255,7 @@ am7990_copyfrombuf_gap16(sc, tov, boff, len) void am7990_zerobuf_gap16(sc, boff, len) - struct le_softc *sc; + struct am7990_softc *sc; int boff, len; { volatile caddr_t buf = sc->sc_mem; @@ -1189,4 +1273,4 @@ am7990_zerobuf_gap16(sc, boff, len) xfer = min(len, 16); } } -#endif /* LE_NEED_BUF_GAP16 */ +#endif /* Example only */ |