From 945d71338cd4332fbbd846f9f9256d7eb9939ff7 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 4 Jun 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-06-04 --- pc/ether8390.c | 20 +++++++++++++++----- pc/etherec2t.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/pc/ether8390.c b/pc/ether8390.c index 1eb8b79f7785b47129b6741525b44a63fdbfdd2a..a60d8c7d2c60f89cd7cee2520a034e934e223937 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -535,7 +535,7 @@ overflow(Ether *ether) regw(ctlr, Cr, Page0|RdABORT|Sta); receive(ether); regw(ctlr, Isr, Ovw); - regw(ctlr, Tcr, 0); + regw(ctlr, Tcr, LpbkNORMAL); if(resend) regw(ctlr, Cr, Page0|RdABORT|Txp|Sta); @@ -555,7 +555,7 @@ interrupt(Ureg*, void* arg) * While there is something of interest, * clear all the interrupts and process. */ - lock(ctlr); + ilock(ctlr); regw(ctlr, Imr, 0x00); while(isr = (regr(ctlr, Isr) & (Cnt|Ovw|Txe|Rxe|Ptx|Prx))){ if(isr & Ovw){ @@ -601,7 +601,7 @@ interrupt(Ureg*, void* arg) } } regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx); - unlock(ctlr); + iunlock(ctlr); } static uchar allmar[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; @@ -705,6 +705,10 @@ attach(Ether* ether) * The init routine leaves the chip in monitor * mode. Clear the missed-packet counter, it * increments while in monitor mode. + * Sometimes there's an interrupt pending at this + * point but there's nothing in the Isr, so + * any pending interrupts are cleared and the + * mask of acceptable interrupts is enabled here. */ r = Ab; if(ether->prom) @@ -712,8 +716,11 @@ attach(Ether* ether) if(ether->nmaddr) r |= Am; ilock(ctlr); + regw(ctlr, Isr, 0xFF); + regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx); regw(ctlr, Rcr, r); r = regr(ctlr, Cntr2); + regw(ctlr, Tcr, LpbkNORMAL); iunlock(ctlr); USED(r); } @@ -759,7 +766,7 @@ dp8390reset(Ether* ether) regw(ctlr, Rbcr0, 0); regw(ctlr, Rbcr1, 0); - regw(ctlr, Tcr, 0); + regw(ctlr, Tcr, LpbkNIC); regw(ctlr, Rcr, Mon); /* @@ -770,8 +777,11 @@ dp8390reset(Ether* ether) ringinit(ctlr); regw(ctlr, Tpsr, ctlr->tstart); + /* + * Clear any pending interrupts and mask then all off. + */ regw(ctlr, Isr, 0xFF); - regw(ctlr, Imr, Cnt|Ovw|Txe|Rxe|Ptx|Prx); + regw(ctlr, Imr, 0); /* * Leave the chip initialised, diff --git a/pc/etherec2t.c b/pc/etherec2t.c index 1e78de08201475355c2542bc079dc8ea8846f95e..72a5ba3a729d562d340b9ffa85740c01f7805885 100644 --- a/pc/etherec2t.c +++ b/pc/etherec2t.c @@ -1,6 +1,7 @@ /* - * Linksys Combo PCMCIA EthernetCard (EC2T). - * Supposedly an NE2000 clone, see the comments in ether2000.c + * Linksys Combo PCMCIA EthernetCard (EC2T) + * and EtherFast 10/100 PC Card (PCMPC100). + * Supposedly NE2000 clones, see the comments in ether2000.c */ #include "u.h" #include "../port/lib.h" @@ -13,11 +14,18 @@ #include "etherif.h" #include "ether8390.h" + enum { Data = 0x10, /* offset from I/O base of data port */ Reset = 0x1F, /* offset from I/O base of reset port */ }; +static char* ec2tpcmcia[] = { + "EC2T", + "PCMPC100", + nil, +}; + static int reset(Ether* ether) { @@ -25,7 +33,8 @@ reset(Ether* ether) ulong port; Dp8390 *ctlr; int i, slot; - uchar ea[Eaddrlen]; + uchar ea[Eaddrlen], sum, x; + char *type; /* * Set up the software configuration. @@ -46,7 +55,14 @@ reset(Ether* ether) if(ioalloc(ether->port, 0x20, 0, "ec2t") < 0) return -1; - if((slot = pcmspecial(ether->type, ether)) < 0){ + slot = -1; + type = nil; + for(i = 0; ec2tpcmcia[i] != nil; i++){ + type = ec2tpcmcia[i]; + if((slot = pcmspecial(type, ether)) >= 0) + break; + } + if(slot < 0){ iofree(port); return -1; } @@ -79,7 +95,7 @@ reset(Ether* ether) delay(2); outb(port+Reset, buf[0]); delay(2); - + /* * Init the (possible) chip, then use the (possible) * chip to read the (possible) PROM for ethernet address @@ -90,9 +106,25 @@ reset(Ether* ether) * match. */ dp8390reset(ether); - memset(buf, 0, sizeof(buf)); - dp8390read(ctlr, buf, 0, sizeof(buf)); - if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57){ + sum = 0; + if(strcmp(type, "PCMPC100")){ + memset(buf, 0, sizeof(buf)); + dp8390read(ctlr, buf, 0, sizeof(buf)); + if((buf[0x0E] & 0xFF) == 0x57 && (buf[0x0F] & 0xFF) == 0x57) + sum = 0xFF; + } + else{ + /* + * The PCMPC100 has the ethernet address in I/O space. + * There's a checksum over 8 bytes which sums to 0xFF. + */ + for(i = 0; i < 8; i++){ + x = inb(port+0x14+i); + sum += x; + buf[i] = (x<<8)|x; + } + } + if(sum != 0xFF){ pcmspecialclose(slot); iofree(ether->port); free(ether->ctlr);