summaryrefslogtreecommitdiff
path: root/sys/dev/tc/if_le_ibus.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1996-05-26 00:27:57 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1996-05-26 00:27:57 +0000
commit729a9d7ceffba9e7e741540048479eed9907601e (patch)
tree716f1614729ffc0b602e2fdfece3bc84b3e930b1 /sys/dev/tc/if_le_ibus.c
parent8102ec86d426fccfffa292d80d3e50914c22a932 (diff)
sync 0521
Diffstat (limited to 'sys/dev/tc/if_le_ibus.c')
-rw-r--r--sys/dev/tc/if_le_ibus.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/sys/dev/tc/if_le_ibus.c b/sys/dev/tc/if_le_ibus.c
new file mode 100644
index 00000000000..904e472bcf9
--- /dev/null
+++ b/sys/dev/tc/if_le_ibus.c
@@ -0,0 +1,191 @@
+/* $NetBSD: if_le_ibus.c,v 1.3 1996/05/20 23:19:16 jonathan Exp $ */
+
+/*
+ * Copyright 1996 The Board of Trustees of The Leland Stanford
+ * Junior University. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies. Stanford University
+ * makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * This driver was contributed by Jonathan Stone.
+ */
+
+/*
+ * LANCE on Decstation kn01/kn220(?) baseboard.
+ */
+
+#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>
+#include <machine/autoconf.h>
+#include <pmax/pmax/kn01.h>
+#include <pmax/pmax/kn01var.h>
+
+extern struct cfdriver mainbus_cd; /* should be in header but where? */
+
+extern void le_dec_copytobuf_gap2 __P((struct am7990_softc *, void *,
+ int, int));
+extern void le_dec_copyfrombuf_gap2 __P((struct am7990_softc *, void *,
+ int, int));
+
+hide void le_dec_zerobuf_gap2 __P((struct am7990_softc *, int, int));
+
+
+int le_pmax_match __P((struct device *, void *, void *));
+void le_pmax_attach __P((struct device *, struct device *, void *));
+
+struct cfattach le_pmax_ca = {
+ sizeof(struct le_softc), le_pmax_match, le_pmax_attach
+};
+
+
+int
+le_pmax_match(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ if (parent->dv_cfdata->cf_driver == &mainbus_cd) {
+ struct confargs *d = aux;
+ if (strcmp("lance", d->ca_name) == 0)
+ return (1);
+ }
+ return (0);
+}
+
+void
+le_pmax_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ register struct le_softc *lesc = (void *)self;
+ register struct am7990_softc *sc = &lesc->sc_am7990;
+ register u_char *cp;
+ register struct confargs *ca = aux;
+
+ /*
+ * It's on the baseboard, with a dedicated interrupt line.
+ */
+ lesc->sc_r1 = (struct lereg1 *)(ca->ca_addr);
+/*XXX*/ sc->sc_mem = (void *)TC_PHYS_TO_UNCACHED(0x19000000);
+/*XXX*/ cp = (u_char *)(TC_PHYS_TO_UNCACHED(KN01_SYS_CLOCK) + 1);
+
+ sc->sc_copytodesc = le_dec_copytobuf_gap2;
+ sc->sc_copyfromdesc = le_dec_copyfrombuf_gap2;
+ sc->sc_copytobuf = le_dec_copytobuf_gap2;
+ sc->sc_copyfrombuf = le_dec_copyfrombuf_gap2;
+ sc->sc_zerobuf = le_dec_zerobuf_gap2;
+
+ dec_le_common_attach(sc, cp);
+ /* XXX more thought about ca->slotpri */
+ kn01_intr_establish(parent, (void*)ca->ca_slotpri, TC_IPL_NET,
+ am7990_intr, sc);
+}
+
+/*
+ * 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_dec_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_dec_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;
+}
+
+void
+le_dec_zerobuf_gap2(sc, boff, len)
+ struct am7990_softc *sc;
+ int boff, len;
+{
+ volatile caddr_t buf = sc->sc_mem;
+ register volatile u_int16_t *bptr;
+
+ if ((unsigned)boff & 0x1) {
+ bptr = ((volatile u_int16_t *)buf) + (boff - 1);
+ *bptr &= 0xff;
+ bptr += 2;
+ len--;
+ } else
+ bptr = ((volatile u_int16_t *)buf) + boff;
+ while (len > 0) {
+ *bptr = 0;
+ bptr += 2;
+ len -= 2;
+ }
+}