diff options
Diffstat (limited to 'sys/dev/tc')
-rw-r--r-- | sys/dev/tc/if_le.c | 171 | ||||
-rw-r--r-- | sys/dev/tc/if_le_dec.c | 158 | ||||
-rw-r--r-- | sys/dev/tc/if_le_ioasic.c | 182 | ||||
-rw-r--r-- | sys/dev/tc/if_le_tc.c | 12 | ||||
-rw-r--r-- | sys/dev/tc/if_levar.h | 41 |
5 files changed, 338 insertions, 226 deletions
diff --git a/sys/dev/tc/if_le.c b/sys/dev/tc/if_le.c index 51415a94208..67368f06e8d 100644 --- a/sys/dev/tc/if_le.c +++ b/sys/dev/tc/if_le.c @@ -1,170 +1 @@ -/* $OpenBSD: if_le.c,v 1.4 1996/05/02 13:51:48 deraadt Exp $ */ -/* $NetBSD: if_le.c,v 1.9 1996/04/22 02:54:10 christos Exp $ */ - -/*- - * Copyright (c) 1995 Charles M. Hannum. All rights reserved. - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ralph Campbell and Rick Macklem. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)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 <net/if.h> - -#ifdef INET -#include <netinet/in.h> -#include <netinet/if_ether.h> -#endif - -#include <dev/tc/if_levar.h> -#include <dev/ic/am7990reg.h> -#define LE_NEED_BUF_CONTIG -#define LE_NEED_BUF_GAP2 -#define LE_NEED_BUF_GAP16 -#include <dev/ic/am7990var.h> -#include <dev/tc/tcvar.h> - -/* access LANCE registers */ -void lewritereg __P((volatile u_short *regptr, u_short val)); -#define LERDWR(cntl, src, dst) { (dst) = (src); tc_mb(); } -#define LEWREG(src, dst) lewritereg(&(dst), (src)) - -#define LE_SOFTC(unit) le_cd.cd_devs[unit] -#define LE_DELAY(x) DELAY(x) - -struct cfdriver le_cd = { - NULL, "le", DV_IFNET -}; - -void -dec_le_common_attach(sc, eap) - struct le_softc *sc; - u_char *eap; -{ - int i; - - sc->sc_conf3 = 0; - sc->sc_addr = 0; - sc->sc_memsize = 65536; - - /* - * Get the ethernet address out of rom - */ - for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++) { - sc->sc_arpcom.ac_enaddr[i] = *eap; - eap += 4; - } - - sc->sc_arpcom.ac_if.if_name = le_cd.cd_name; - leconfig(sc); -} - -integrate void -lehwinit(sc) - struct le_softc *sc; -{ -} - -integrate void -lewrcsr(sc, port, val) - struct le_softc *sc; - u_int16_t port, val; -{ - struct lereg1 *ler1 = sc->sc_r1; - - LEWREG(port, ler1->ler1_rap); - LERDWR(port, val, ler1->ler1_rdp); -} - -integrate u_int16_t -lerdcsr(sc, port) - struct le_softc *sc; - u_int16_t port; -{ - struct lereg1 *ler1 = sc->sc_r1; - u_int16_t val; - - LEWREG(port, ler1->ler1_rap); - LERDWR(0, ler1->ler1_rdp, val); - return (val); -} - -/* - * Write a lance register port, reading it back to ensure success. This seems - * to be necessary during initialization, since the chip appears to be a bit - * pokey sometimes. - */ -void -lewritereg(regptr, val) - register volatile u_short *regptr; - register u_short val; -{ - register int i = 0; - - while (*regptr != val) { - *regptr = val; - tc_mb(); - if (++i > 10000) { - printf("le: Reg did not settle (to x%x): x%x\n", val, - *regptr); - return; - } - DELAY(100); - } -} - -/* - * Routines for accessing the transmit and receive buffers are provided - * by am7990.c, because of the LE_NEED_BUF_* macros defined above. - * Unfortunately, CPU addressing of these buffers is done in one of - * 3 ways: - * - contiguous (for the 3max and turbochannel option card) - * - gap2, which means shorts (2 bytes) interspersed with short (2 byte) - * spaces (for the pmax) - * - gap16, which means 16bytes interspersed with 16byte spaces - * for buffers which must begin on a 32byte boundary (for 3min, maxine, - * and alpha) - * The buffer offset is the logical byte offset, assuming contiguous storage. - */ - -#include <dev/ic/am7990.c> +/* $OpenBSD: if_le.c,v 1.5 1996/05/10 12:41:28 deraadt Exp $ */ diff --git a/sys/dev/tc/if_le_dec.c b/sys/dev/tc/if_le_dec.c new file mode 100644 index 00000000000..5e2093849f9 --- /dev/null +++ b/sys/dev/tc/if_le_dec.c @@ -0,0 +1,158 @@ +/* $NetBSD: if_le_dec.c,v 1.1 1996/05/07 02:24:55 thorpej Exp $ */ + +/*- + * Copyright (c) 1995 Charles M. Hannum. All rights reserved. + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ralph Campbell and Rick Macklem. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)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 <net/if.h> + +#ifdef INET +#include <netinet/in.h> +#include <netinet/if_ether.h> +#endif + +#include <dev/ic/am7990reg.h> +#include <dev/ic/am7990var.h> + +#include <dev/tc/if_levar.h> +#include <dev/tc/tcvar.h> + +/* access LANCE registers */ +void le_dec_writereg __P((volatile u_short *regptr, u_short val)); +#define LERDWR(cntl, src, dst) { (dst) = (src); tc_mb(); } +#define LEWREG(src, dst) le_dec_writereg(&(dst), (src)) + +hide void le_dec_wrcsr __P((struct am7990_softc *, u_int16_t, u_int16_t)); +hide u_int16_t le_dec_rdcsr __P((struct am7990_softc *, u_int16_t)); + +void +dec_le_common_attach(sc, eap) + struct am7990_softc *sc; + u_char *eap; +{ + int i; + + sc->sc_rdcsr = le_dec_rdcsr; + sc->sc_wrcsr = le_dec_wrcsr; + sc->sc_hwinit = NULL; + + sc->sc_conf3 = 0; + sc->sc_addr = 0; + sc->sc_memsize = 65536; + + /* + * Get the ethernet address out of rom + */ + for (i = 0; i < sizeof(sc->sc_arpcom.ac_enaddr); i++) { + sc->sc_arpcom.ac_enaddr[i] = *eap; + eap += 4; + } + + am7990_config(sc); +} + +hide void +le_dec_wrcsr(sc, port, val) + struct am7990_softc *sc; + u_int16_t port, val; +{ + struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; + + LEWREG(port, ler1->ler1_rap); + LERDWR(port, val, ler1->ler1_rdp); +} + +hide u_int16_t +le_dec_rdcsr(sc, port) + struct am7990_softc *sc; + u_int16_t port; +{ + struct lereg1 *ler1 = ((struct le_softc *)sc)->sc_r1; + u_int16_t val; + + LEWREG(port, ler1->ler1_rap); + LERDWR(0, ler1->ler1_rdp, val); + return (val); +} + +/* + * Write a lance register port, reading it back to ensure success. This seems + * to be necessary during initialization, since the chip appears to be a bit + * pokey sometimes. + */ +void +le_dec_writereg(regptr, val) + register volatile u_short *regptr; + register u_short val; +{ + register int i = 0; + + while (*regptr != val) { + *regptr = val; + tc_mb(); + if (++i > 10000) { + printf("le: Reg did not settle (to x%x): x%x\n", val, + *regptr); + return; + } + DELAY(100); + } +} + +/* + * Routines for accessing the transmit and receive buffers are provided + * by am7990.c, because of the LE_NEED_BUF_* macros defined above. + * Unfortunately, CPU addressing of these buffers is done in one of + * 3 ways: + * - contiguous (for the 3max and turbochannel option card) + * - gap2, which means shorts (2 bytes) interspersed with short (2 byte) + * spaces (for the pmax) + * - gap16, which means 16bytes interspersed with 16byte spaces + * for buffers which must begin on a 32byte boundary (for 3min, maxine, + * and alpha) + * The buffer offset is the logical byte offset, assuming contiguous storage. + */ diff --git a/sys/dev/tc/if_le_ioasic.c b/sys/dev/tc/if_le_ioasic.c index 2a1fea050b6..a0c22099583 100644 --- a/sys/dev/tc/if_le_ioasic.c +++ b/sys/dev/tc/if_le_ioasic.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_le_ioasic.c,v 1.1 1996/04/18 00:50:13 cgd Exp $ */ +/* $NetBSD: if_le_ioasic.c,v 1.2 1996/05/07 02:24:56 thorpej Exp $ */ /* * Copyright (c) 1996 Carnegie-Mellon University. @@ -45,12 +45,10 @@ #include <netinet/if_ether.h> #endif -#include <dev/tc/if_levar.h> #include <dev/ic/am7990reg.h> -#define LE_NEED_BUF_GAP2 -#define LE_NEED_BUF_GAP16 #include <dev/ic/am7990var.h> +#include <dev/tc/if_levar.h> #include <dev/tc/tcvar.h> #include <dev/tc/ioasicvar.h> @@ -59,6 +57,17 @@ extern caddr_t le_iomem; int le_ioasic_match __P((struct device *, void *, void *)); void le_ioasic_attach __P((struct device *, struct device *, void *)); +hide void le_ioasic_copytobuf_gap2 __P((struct am7990_softc *, void *, + int, int)); +hide void le_ioasic_copyfrombuf_gap2 __P((struct am7990_softc *, void *, + int, int)); + +hide void le_ioasic_copytobuf_gap16 __P((struct am7990_softc *, void *, + int, int)); +hide void le_ioasic_copyfrombuf_gap16 __P((struct am7990_softc *, void *, + int, int)); +hide void le_ioasic_zerobuf_gap16 __P((struct am7990_softc *, int, int)); + struct cfattach le_ioasic_ca = { sizeof(struct le_softc), le_ioasic_match, le_ioasic_attach }; @@ -84,21 +93,170 @@ le_ioasic_attach(parent, self, aux) void *aux; { struct ioasicdev_attach_args *d = aux; - register struct le_softc *sc = (void *)self; + register struct le_softc *lesc = (void *)self; + register struct am7990_softc *sc = &lesc->sc_am7990; - sc->sc_r1 = (struct lereg1 *) + lesc->sc_r1 = (struct lereg1 *) TC_DENSE_TO_SPARSE(TC_PHYS_TO_UNCACHED(d->iada_addr)); sc->sc_mem = (void *)TC_PHYS_TO_UNCACHED(le_iomem); - sc->sc_copytodesc = am7990_copytobuf_gap2; - sc->sc_copyfromdesc = am7990_copyfrombuf_gap2; - sc->sc_copytobuf = am7990_copytobuf_gap16; - sc->sc_copyfrombuf = am7990_copyfrombuf_gap16; - sc->sc_zerobuf = am7990_zerobuf_gap16; + sc->sc_copytodesc = le_ioasic_copytobuf_gap2; + sc->sc_copyfromdesc = le_ioasic_copyfrombuf_gap2; + sc->sc_copytobuf = le_ioasic_copytobuf_gap16; + sc->sc_copyfrombuf = le_ioasic_copyfrombuf_gap16; + sc->sc_zerobuf = le_ioasic_zerobuf_gap16; ioasic_lance_dma_setup(le_iomem); /* XXX more thought */ dec_le_common_attach(sc, ioasic_lance_ether_address()); - ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_NET, leintr, sc); + ioasic_intr_establish(parent, d->iada_cookie, TC_IPL_NET, + am7990_intr, sc); +} + +/* + * Special memory access functions needed by ioasic-attached LANCE + * chips. + */ + +/* + * gap2: two bytes of data followed by two bytes of pad. + * + * Buffers must be 4-byte aligned. The code doesn't worry about + * doing an extra byte. + */ + +void +le_ioasic_copytobuf_gap2(sc, fromv, boff, len) + struct am7990_softc *sc; + void *fromv; + int boff; + register int len; +{ + volatile caddr_t buf = sc->sc_mem; + register caddr_t from = fromv; + register volatile u_int16_t *bptr; + + if (boff & 0x1) { + /* handle unaligned first byte */ + bptr = ((volatile u_int16_t *)buf) + (boff - 1); + *bptr = (*from++ << 8) | (*bptr & 0xff); + bptr += 2; + len--; + } else + bptr = ((volatile u_int16_t *)buf) + boff; + while (len > 1) { + *bptr = (from[1] << 8) | (from[0] & 0xff); + bptr += 2; + from += 2; + len -= 2; + } + if (len == 1) + *bptr = (u_int16_t)*from; +} + +void +le_ioasic_copyfrombuf_gap2(sc, tov, boff, len) + struct am7990_softc *sc; + void *tov; + int boff, len; +{ + volatile caddr_t buf = sc->sc_mem; + register caddr_t to = tov; + register volatile u_int16_t *bptr; + register u_int16_t tmp; + + if (boff & 0x1) { + /* handle unaligned first byte */ + bptr = ((volatile u_int16_t *)buf) + (boff - 1); + *to++ = (*bptr >> 8) & 0xff; + bptr += 2; + len--; + } else + bptr = ((volatile u_int16_t *)buf) + boff; + while (len > 1) { + tmp = *bptr; + *to++ = tmp & 0xff; + *to++ = (tmp >> 8) & 0xff; + bptr += 2; + len -= 2; + } + if (len == 1) + *to = *bptr & 0xff; +} + +/* + * gap16: 16 bytes of data followed by 16 bytes of pad. + * + * Buffers must be 32-byte aligned. + */ + +void +le_ioasic_copytobuf_gap16(sc, fromv, boff, len) + struct am7990_softc *sc; + void *fromv; + int boff; + register int len; +{ + volatile caddr_t buf = sc->sc_mem; + register caddr_t from = fromv; + register caddr_t bptr; + register int xfer; + + bptr = buf + ((boff << 1) & ~0x1f); + boff &= 0xf; + xfer = min(len, 16 - boff); + while (len > 0) { + bcopy(from, bptr + boff, xfer); + from += xfer; + bptr += 32; + boff = 0; + len -= xfer; + xfer = min(len, 16); + } +} + +void +le_ioasic_copyfrombuf_gap16(sc, tov, boff, len) + struct am7990_softc *sc; + void *tov; + int boff, len; +{ + volatile caddr_t buf = sc->sc_mem; + register caddr_t to = tov; + register caddr_t bptr; + register int xfer; + + bptr = buf + ((boff << 1) & ~0x1f); + boff &= 0xf; + xfer = min(len, 16 - boff); + while (len > 0) { + bcopy(bptr + boff, to, xfer); + to += xfer; + bptr += 32; + boff = 0; + len -= xfer; + xfer = min(len, 16); + } +} + +void +le_ioasic_zerobuf_gap16(sc, boff, len) + struct am7990_softc *sc; + int boff, len; +{ + volatile caddr_t buf = sc->sc_mem; + register caddr_t bptr; + register int xfer; + + bptr = buf + ((boff << 1) & ~0x1f); + boff &= 0xf; + xfer = min(len, 16 - boff); + while (len > 0) { + bzero(bptr + boff, xfer); + bptr += 32; + boff = 0; + len -= xfer; + xfer = min(len, 16); + } } diff --git a/sys/dev/tc/if_le_tc.c b/sys/dev/tc/if_le_tc.c index 194a5e394d7..e329a3da2e3 100644 --- a/sys/dev/tc/if_le_tc.c +++ b/sys/dev/tc/if_le_tc.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_le_tc.c,v 1.1 1996/04/18 00:50:14 cgd Exp $ */ +/* $NetBSD: if_le_tc.c,v 1.2 1996/05/07 02:24:57 thorpej Exp $ */ /* * Copyright (c) 1996 Carnegie-Mellon University. @@ -45,11 +45,10 @@ #include <netinet/if_ether.h> #endif -#include <dev/tc/if_levar.h> #include <dev/ic/am7990reg.h> -#define LE_NEED_BUF_CONTIG #include <dev/ic/am7990var.h> +#include <dev/tc/if_levar.h> #include <dev/tc/tcvar.h> int le_tc_match __P((struct device *, void *, void *)); @@ -82,14 +81,15 @@ le_tc_attach(parent, self, aux) struct device *parent, *self; void *aux; { - register struct le_softc *sc = (void *)self; + register struct le_softc *lesc = (void *)self; + register struct am7990_softc *sc = &lesc->sc_am7990; struct tc_attach_args *d = aux; /* * It's on the turbochannel proper, or a kn02 * baseboard implementation of a TC option card. */ - sc->sc_r1 = (struct lereg1 *)(d->ta_addr + LE_OFFSET_LANCE); + lesc->sc_r1 = (struct lereg1 *)(d->ta_addr + LE_OFFSET_LANCE); sc->sc_mem = (void *)(d->ta_addr + LE_OFFSET_RAM); sc->sc_copytodesc = am7990_copytobuf_contig; @@ -106,5 +106,5 @@ le_tc_attach(parent, self, aux) dec_le_common_attach(sc, (u_char *)(d->ta_addr + LE_OFFSET_ROM + 2)); - tc_intr_establish(parent, d->ta_cookie, TC_IPL_NET, leintr, sc); + tc_intr_establish(parent, d->ta_cookie, TC_IPL_NET, am7990_intr, sc); } diff --git a/sys/dev/tc/if_levar.h b/sys/dev/tc/if_levar.h index 5d6f0c44e8f..a8180677036 100644 --- a/sys/dev/tc/if_levar.h +++ b/sys/dev/tc/if_levar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_levar.h,v 1.2 1996/04/18 00:50:15 cgd Exp $ */ +/* $NetBSD: if_levar.h,v 1.3 1996/05/07 02:24:58 thorpej Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -60,44 +60,9 @@ struct lereg1 { * This structure contains the output queue for the interface, its address, ... */ struct le_softc { - struct device sc_dev; /* base structure */ - struct arpcom sc_arpcom; /* Ethernet common part */ - - void (*sc_copytodesc) /* Copy to descriptor */ - __P((struct le_softc *, void *, int, int)); - void (*sc_copyfromdesc) /* Copy from descriptor */ - __P((struct le_softc *, void *, int, int)); - - void (*sc_copytobuf) /* Copy to buffer */ - __P((struct le_softc *, void *, int, int)); - void (*sc_copyfrombuf) /* Copy from buffer */ - __P((struct le_softc *, void *, int, int)); - void (*sc_zerobuf) /* and Zero bytes in buffer */ - __P((struct le_softc *, int, int)); - - u_int16_t sc_conf3; /* CSR3 value */ - - void *sc_mem; /* base addr of RAM -- CPU's view */ - u_long sc_addr; /* base addr of RAM -- LANCE's view */ - u_long sc_memsize; /* size of RAM */ - - int sc_nrbuf; /* number of receive buffers */ - int sc_ntbuf; /* number of transmit buffers */ - int sc_last_rd; - int sc_first_td, sc_last_td, sc_no_td; - - int sc_initaddr; - int sc_rmdaddr; - int sc_tmdaddr; - int sc_rbufaddr; - int sc_tbufaddr; - -#ifdef LEDEBUG - int sc_debug; -#endif + struct am7990_softc sc_am7990; /* glue to MI code */ struct lereg1 *sc_r1; /* LANCE registers */ }; -int leintr __P((void *)); -void dec_le_common_attach __P((struct le_softc *, u_char *)); +void dec_le_common_attach __P((struct am7990_softc *, u_char *)); |