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.
This commit is contained in:
parent
bb91ff2547
commit
b1d1cbe84b
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -92,8 +91,8 @@ struct es_softc {
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue