summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1996-05-04 14:04:11 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1996-05-04 14:04:11 +0000
commitfef4cf7047f835deac357a8c8681756cdac54865 (patch)
treefc13669e5001168d15ec486f62cc6f78bff26d0f
parent5163b96392f1b69cd1929fec589fb1ca55a93635 (diff)
From NetBSD:
Define BSR_MASK and use BSR_MASK to get the current bank select register. Clean up the debugging code a bit and the warnings from -Wall. Don't define ESDEBUG - it can now be set from the config file. If the Ethernet chip gets reset during the copy of the transmit buffer, requeue the current packet and reinitialize the controller. This recovers from an apparent hardware bug when running on my A2000/Zeus system.
-rw-r--r--sys/arch/amiga/dev/if_es.c103
-rw-r--r--sys/arch/amiga/dev/if_esreg.h3
2 files changed, 66 insertions, 40 deletions
diff --git a/sys/arch/amiga/dev/if_es.c b/sys/arch/amiga/dev/if_es.c
index 7878d299583..b8da7a192bf 100644
--- a/sys/arch/amiga/dev/if_es.c
+++ b/sys/arch/amiga/dev/if_es.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: if_es.c,v 1.4 1996/05/02 06:44:05 niklas Exp $ */
-/* $NetBSD: if_es.c,v 1.11 1996/04/21 21:11:46 veego Exp $ */
+/* $OpenBSD: if_es.c,v 1.5 1996/05/04 14:04:04 niklas Exp $ */
+/* $NetBSD: if_es.c,v 1.12 1996/05/01 15:55:28 mhitch Exp $ */
/*
* Copyright (c) 1995 Michael L. Hitch
@@ -74,7 +74,6 @@
#define SWAP(x) (((x & 0xff) << 8) | ((x >> 8) & 0xff))
-#define ESDEBUG
#define USEPKTBUF
/*
@@ -88,13 +87,13 @@ struct es_softc {
struct device sc_dev;
struct isr sc_isr;
struct arpcom sc_arpcom; /* common Ethernet structures */
- void *sc_base; /* base address of board */
+ void *sc_base; /* base address of board */
short sc_iflags;
unsigned short sc_intctl;
#ifdef ESDEBUG
int sc_debug;
- short sc_intbusy;
- short sc_smcbusy;
+ short sc_intbusy; /* counter for interrupt rentered */
+ short sc_smcbusy; /* counter for other rentry checks */
#endif
};
@@ -165,15 +164,6 @@ esattach(parent, self, aux)
unsigned long ser;
sc->sc_base = zap->va;
-#ifdef ESDEBUG
- /* MLHDEBUG
- * MLHDEBUG remove first 4 and last 3 pages of the A4066 memory
- * MLHDEBUG and use the 5th page to access the SMC
- */
- sc->sc_base = zap->va + 0x8000; /* MLHDEBUG */
- physunaccess(zap->va, 0x8000); /* MLHDEBUG */
- physunaccess(zap->va + 0xa000, 0x6000); /* MLHDEBUG */
-#endif
/*
* Manufacturer decides the 3 first bytes, i.e. ethernet vendor ID.
@@ -225,7 +215,7 @@ es_dump_smcregs(where, smc)
char *where;
union smcregs *smc;
{
- u_short cur_bank = smc->b0.bsr & 0x0300;
+ u_short cur_bank = smc->b0.bsr & BSR_MASK;
printf("SMC registers %p from %s bank %04x\n", smc, where,
smc->b0.bsr);
@@ -316,7 +306,7 @@ esintr(arg)
smc = sc->sc_base;
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2 &&
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2 &&
sc->sc_arpcom.ac_if.if_flags & IFF_RUNNING) {
printf("%s: intr BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
@@ -337,6 +327,9 @@ esintr(arg)
printf("%s: esintr re-entered\n", sc->sc_dev.dv_xname);
panic("esintr re-entered");
}
+ if (sc->sc_smcbusy)
+ printf("%s: esintr interrupted busy %d\n", sc->sc_dev.dv_xname,
+ sc->sc_smcbusy);
#endif
smc->b2.msk = 0;
#ifdef ESDEBUG
@@ -372,7 +365,7 @@ esintr(arg)
#endif
}
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: intr+ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
@@ -382,7 +375,7 @@ esintr(arg)
esrint(sc);
}
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: intr++ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
@@ -441,7 +434,9 @@ esintr(arg)
++estxint3; /* count # IST_TX */
#endif
zzzz:
+#ifdef ESDEBUG
++estxint4; /* count # ~TEMPTY */
+#endif
smc->b0.bsr = BSR_BANK0;
ephsr = smc->b0.ephsr; /* get EPHSR */
tcr = smc->b0.tcr; /* and TCR */
@@ -510,7 +505,7 @@ zzzz:
/* output packets */
estint(sc);
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: intr+++ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
@@ -532,7 +527,6 @@ esrint(sc)
struct es_softc *sc;
{
union smcregs *smc = sc->sc_base;
- int i;
u_short len;
short cnt;
u_short pktctlw, pktlen, *buf;
@@ -547,6 +541,9 @@ esrint(sc)
#ifdef USEPKTBUF
u_char *b, pktbuf[1530];
#endif
+#ifdef ESDEBUG
+ int i;
+#endif
#ifdef ESDEBUG
if (esdebug)
@@ -556,7 +553,7 @@ esrint(sc)
printf("%s: esrint re-entered\n", sc->sc_dev.dv_xname);
panic("esrint re-entered");
}
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: rint BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
@@ -588,7 +585,7 @@ esrint(sc)
sc->sc_dev.dv_xname, pktctlw, pktlen, len, smc->b2.bsr);
/* XXX ignore packet, or just truncate? */
#if defined(ESDEBUG) && defined(DDB)
- if ((smc->b2.bsr & 0x0300) != BSR_BANK2)
+ if ((smc->b2.bsr & BSR_MASK) != BSR_BANK2)
Debugger();
#endif
smc->b2.bsr = BSR_BANK2;
@@ -787,14 +784,16 @@ esstart(ifp)
printf("%s: esstart re-entered\n", sc->sc_dev.dv_xname);
panic("esstart re-entred");
}
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: esstart BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
}
#endif
for (;;) {
-int xxx;
+#ifdef ESDEBUG
+ u_short start_ptr, end_ptr;
+#endif
/*
* Sneak a peek at the next packet to get the length
* and see if the SMC 91C90 can accept it.
@@ -803,9 +802,9 @@ int xxx;
if (!m)
break;
#ifdef ESDEBUG
-if (esdebug && (m->m_next || m->m_len & 1))
- printf("%s: esstart m_next %p m_len %d\n", sc->sc_dev.dv_xname,
- m->m_next, m->m_len);
+ if (esdebug && (m->m_next || m->m_len & 1))
+ printf("%s: esstart m_next %p m_len %d\n",
+ sc->sc_dev.dv_xname, m->m_next, m->m_len);
#endif
for (m0 = m, pktlen = 0; m0; m0 = m0->m_next)
pktlen += m0->m_len;
@@ -827,21 +826,20 @@ if (esdebug && (m->m_next || m->m_len & 1))
active_pnr = smc->b2.pnr = smc->b2.arr;
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: esstart+ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
}
#endif
IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m);
-xxx = splhigh();
smc->b2.ptr = PTR_AUTOINCR;
(void) smc->b2.mmucr;
data = (u_short *)&smc->b2.data;
*data = SWAP(pktctlw);
*data = SWAP(pktlen);
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: esstart++ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
@@ -860,7 +858,7 @@ xxx = splhigh();
pktbuf[i/2] = 0;
pktlen -= 4;
#ifdef ESDEBUG
- if (pktlen > sizeof(pktbuf))
+ if (pktlen > sizeof(pktbuf) && i > (sizeof(pktbuf) * 2))
printf("%s: esstart packet longer than pktbuf\n",
sc->sc_dev.dv_xname);
#endif
@@ -875,10 +873,21 @@ xxx = splhigh();
*data = *buf;
}
#else
+#ifdef ESDEBUG
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
+ printf("%s: esstart++2 BSR not 2: %04x\n", sc->sc_dev.dv_xname,
+ smc->b2.bsr);
+ smc->b2.bsr = BSR_BANK2;
+ }
+ start_ptr = SWAP(smc->b2.ptr); /* save PTR before copy */
+#endif
buf = pktbuf;
cnt = pktlen / 2;
while (cnt--)
*data = *buf++;
+#ifdef ESDEBUG
+ end_ptr = SWAP(smc->b2.ptr); /* save PTR after copy */
+#endif
#endif
#else /* USEPKTBUF */
pktctlw = 0;
@@ -900,14 +909,30 @@ xxx = splhigh();
}
*data = pktctlw;
#endif /* USEPKTBUF */
-splx(xxx);
-#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
- printf("%s: esstart+++ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
- smc->b2.bsr);
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
+ /*
+ * The bank select register has changed. This seems
+ * to happen with my A2000/Zeus once in a while. It
+ * appears that the Ethernet chip resets while
+ * copying the transmit buffer. Requeue the current
+ * transmit buffer and reinitialize the interface.
+ * The initialize routine will take care of
+ * retransmitting the buffer. mhitch
+ */
+#ifdef DIAGNOSTIC
+ printf("%s: esstart+++ BSR not 2: %04x\n",
+ sc->sc_dev.dv_xname, smc->b2.bsr);
+#endif
smc->b2.bsr = BSR_BANK2;
- }
+#ifdef ESDEBUG
+ printf("start_ptr %04x end_ptr %04x cur ptr %04x\n",
+ start_ptr, end_ptr, SWAP(smc->b2.ptr));
+ --sc->sc_smcbusy;
#endif
+ IF_PREPEND(&sc->sc_arpcom.ac_if.if_snd, m0);
+ esinit(sc); /* It's really hosed - reset */
+ return;
+ }
smc->b2.mmucr = MMUCR_ENQ_TX;
if (smc->b2.pnr != active_pnr)
printf("%s: esstart - PNR changed %x->%x\n",
@@ -922,7 +947,7 @@ splx(xxx);
}
smc->b2.msk = sc->sc_intctl;
#ifdef ESDEBUG
- while ((smc->b2.bsr & 0x0300) != BSR_BANK2) {
+ while ((smc->b2.bsr & BSR_MASK) != BSR_BANK2) {
printf("%s: esstart++++ BSR not 2: %04x\n", sc->sc_dev.dv_xname,
smc->b2.bsr);
smc->b2.bsr = BSR_BANK2;
diff --git a/sys/arch/amiga/dev/if_esreg.h b/sys/arch/amiga/dev/if_esreg.h
index 553379501cb..e3cb9d4eed1 100644
--- a/sys/arch/amiga/dev/if_esreg.h
+++ b/sys/arch/amiga/dev/if_esreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_esreg.h,v 1.3 1995/08/18 15:27:58 chopps Exp $ */
+/* $NetBSD: if_esreg.h,v 1.4 1996/05/01 15:51:08 mhitch Exp $ */
/*
* Copyright (c) 1995 Michael L. Hitch
@@ -166,6 +166,7 @@ union smcregs {
#define MSK_RX 0x01 /* RX complete */
/* Bank Select Register */
+#define BSR_MASK 0x0300
#define BSR_BANK0 0x0000 /* Select bank 0 */
#define BSR_BANK1 0x0100 /* Select bank 1 */
#define BSR_BANK2 0x0200 /* Select bank 2 */