summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/mac68k/dev/if_sn_obio.c76
1 files changed, 71 insertions, 5 deletions
diff --git a/sys/arch/mac68k/dev/if_sn_obio.c b/sys/arch/mac68k/dev/if_sn_obio.c
index 0384337c402..6d691a87fe7 100644
--- a/sys/arch/mac68k/dev/if_sn_obio.c
+++ b/sys/arch/mac68k/dev/if_sn_obio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sn_obio.c,v 1.6 1997/04/04 14:48:56 briggs Exp $ */
+/* $OpenBSD: if_sn_obio.c,v 1.7 1997/04/06 01:02:13 briggs Exp $ */
/*
* Copyright (C) 1997 Allen Briggs
@@ -56,7 +56,8 @@
static int sn_obio_match __P((struct device *, void *, void *));
static void sn_obio_attach __P((struct device *, struct device *, void *));
-static void sn_obio_getaddr __P((struct sn_softc *));
+static int sn_obio_getaddr __P((struct sn_softc *));
+static int sn_obio_getaddr_kludge __P((struct sn_softc *));
struct cfattach sn_obio_ca = {
sizeof(struct sn_softc), sn_obio_match, sn_obio_attach
@@ -114,6 +115,7 @@ sn_obio_attach(parent, self, aux)
}
sc->sc_regt = oa->oa_tag;
+
if (bus_space_map(sc->sc_regt, SONIC_REG_BASE, SN_REGSIZE,
0, &sc->sc_regh)) {
panic("failed to map space for SONIC regs.\n");
@@ -121,13 +123,20 @@ sn_obio_attach(parent, self, aux)
sc->slotno = 9;
- sn_obio_getaddr(sc);
-
/* regs are addressed as words, big-endian. */
for (i = 0; i < SN_NREGS; i++) {
sc->sc_reg_map[i] = (bus_size_t)((i * 4) + 2);
}
+ if (sn_obio_getaddr(sc)) {
+ printf("Failed to get MAC address. Trying kludge.\n");
+ if (sn_obio_getaddr_kludge(sc)) {
+ printf("Kludge failed, too. Attachment failed.\n");
+ bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
+ return;
+ }
+ }
+
/* snsetup returns 1 if something fails */
if (snsetup(sc)) {
bus_space_unmap(sc->sc_regt, sc->sc_regh, SN_REGSIZE);
@@ -140,7 +149,7 @@ sn_obio_attach(parent, self, aux)
static u_char bbr4[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
#define bbr(v) ((bbr4[(v)&0xf] << 4) | bbr4[((v)>>4) & 0xf])
-static void
+static int
sn_obio_getaddr(sc)
struct sn_softc *sc;
{
@@ -152,6 +161,11 @@ sn_obio_getaddr(sc)
panic("failed to map space to read SONIC address.\n");
}
+ if (bus_space_bad_addr(sc->sc_regt, bsh, 0, 1)) {
+ bus_space_unmap(sc->sc_regt, bsh, NBPG);
+ return -1;
+ }
+
/*
* For reasons known only to Apple, MAC addresses in the ethernet
* PROM are stored in Token Ring (IEEE 802.5) format, that is
@@ -194,4 +208,56 @@ sn_obio_getaddr(sc)
}
bus_space_unmap(sc->sc_regt, bsh, NBPG);
+
+ return 0;
+}
+
+/*
+ * Assume that the SONIC was initialized in MacOS. This should go away
+ * when we can properly get the MAC address on the PBs.
+ */
+static int
+sn_obio_getaddr_kludge(sc)
+ struct sn_softc *sc;
+{
+ int i, ors=0;
+
+ /* Shut down NIC */
+ NIC_PUT(sc, SNR_CR, CR_RST);
+ wbflush();
+ NIC_PUT(sc, SNR_CR, CR_STP);
+ wbflush();
+ NIC_PUT(sc, SNR_IMR, 0);
+ wbflush();
+ NIC_PUT(sc, SNR_ISR, ISR_ALL);
+ wbflush();
+
+ NIC_PUT(sc, SNR_CEP, 15); /* For some reason, Apple fills top first. */
+ wbflush();
+ i = NIC_GET(sc, SNR_CAP2);
+ wbflush();
+
+ ors |= i;
+ sc->sc_enaddr[5] = i >> 8;
+ sc->sc_enaddr[4] = i;
+
+ i = NIC_GET(sc, SNR_CAP1);
+ wbflush();
+
+ ors |= i;
+ sc->sc_enaddr[3] = i >> 8;
+ sc->sc_enaddr[2] = i;
+
+ i = NIC_GET(sc, SNR_CAP0);
+ wbflush();
+
+ ors |= i;
+ sc->sc_enaddr[1] = i >> 8;
+ sc->sc_enaddr[0] = i;
+
+ NIC_PUT(sc, SNR_CR, 0);
+ wbflush();
+
+ if (ors == 0) return -1;
+ return (0);
}