diff --git a/sys/arch/amiga/dev/if_es.c b/sys/arch/amiga/dev/if_es.c index 3daf3d2739c1..f95ee9749933 100644 --- a/sys/arch/amiga/dev/if_es.c +++ b/sys/arch/amiga/dev/if_es.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_es.c,v 1.11 1996/04/21 21:11:46 veego Exp $ */ +/* $NetBSD: if_es.c,v 1.12 1996/05/01 15:55:28 mhitch Exp $ */ /* * Copyright (c) 1995 Michael L. Hitch @@ -73,7 +73,6 @@ #define SWAP(x) (((x & 0xff) << 8) | ((x >> 8) & 0xff)) -#define ESDEBUG #define USEPKTBUF /* @@ -87,13 +86,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 }; @@ -164,15 +163,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. @@ -224,7 +214,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); @@ -315,7 +305,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); @@ -336,6 +326,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 @@ -371,7 +364,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; @@ -381,7 +374,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; @@ -440,7 +433,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 */ @@ -509,7 +504,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; @@ -531,7 +526,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; @@ -546,6 +540,9 @@ esrint(sc) #ifdef USEPKTBUF u_char *b, pktbuf[1530]; #endif +#ifdef ESDEBUG + int i; +#endif #ifdef ESDEBUG if (esdebug) @@ -555,7 +552,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; @@ -587,7 +584,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; @@ -786,14 +783,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. @@ -802,9 +801,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; @@ -826,21 +825,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; @@ -859,7 +857,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 @@ -874,10 +872,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; @@ -899,14 +908,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); - smc->b2.bsr = BSR_BANK2; - } + 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", @@ -921,7 +946,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;