From 2abcf0371dfd89ff01b61afb02b23be736daa96d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 18 Nov 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-11-18 --- pc/ether509.c | 16 ++- pc/ether8003.c | 160 +++++++++---------------- pc/ether8390.c | 314 +++++++++++++++++++++++++++---------------------- pc/etherif.h | 10 +- 4 files changed, 251 insertions(+), 249 deletions(-) diff --git a/pc/ether509.c b/pc/ether509.c index 90029d03562ee3d5e57a22c4c60db95e18f6e8b3..e0b1f2819ebe32a2a062357a8e1334223df1893c 100644 --- a/pc/ether509.c +++ b/pc/ether509.c @@ -220,13 +220,19 @@ write(Ether *ether, void *buf, long n) ulong port; port = ether->port; + + qlock(ðer->tlock); + if(waserror()) { + qunlock(ðer->tlock); + nexterror(); + } + ether->tlen = n; len = ROUNDUP(ether->tlen, 4); tsleep(ðer->tr, istxfifo, ether, 10000); - if(len+4 > ins(port+TxFreeBytes)){ + if(len+4 > ins(port+TxFreeBytes)) print("ether509: transmitter jammed\n"); - return 0; - } + /* * We know there's room, copy the packet to the FIFO. * To save copying the packet into a local buffer just @@ -240,6 +246,10 @@ write(Ether *ether, void *buf, long n) outss(port+Fifo, buf, Eaddrlen/2); outss(port+Fifo, ether->ea, Eaddrlen/2); outss(port+Fifo, (uchar*)buf+2*Eaddrlen, (len-2*Eaddrlen)/2); + + poperror(); + qunlock(ðer->tlock); + return n; } diff --git a/pc/ether8003.c b/pc/ether8003.c index 1bb6a7cc246e7e8c614cc104ece50ece97d3371a..ae899a15491b70bc3b1dd9662a5a6a20c59c2554 100644 --- a/pc/ether8003.c +++ b/pc/ether8003.c @@ -57,61 +57,18 @@ static int intrmap[] = { 9, 3, 5, 7, 10, 11, 15, 4, }; -static void* -read(Ctlr *ctlr, void *to, ulong from, ulong len) -{ - /* - * In this case, 'from' is an index into the shared memory. - */ - memmove(to, (void*)(ctlr->card.mem+from), len); - return to; -} - -static void* -write(Ctlr *ctlr, ulong to, void *from, ulong len) -{ - /* - * In this case, 'to' is an index into the shared memory. - */ - memmove((void*)(ctlr->card.mem+to), from, len); - return (void*)to; -} - -static void -watch(Ctlr *ctlr) -{ - uchar msr; - int s; - - s = splhi(); - msr = inb(ctlr->card.port+Msr); - /* - * If the card has reset itself, - * start again. - */ - if((msr & Menb) == 0){ - delay(100); - - dp8390reset(ctlr); - etherinit(); - - wakeup(&ctlr->tr); - wakeup(&ctlr->rr); - } - splx(s); -} - /* * Get configuration parameters, enable memory. * There are opportunities here for buckets of code. * We'll try to resist. */ -int -wd8003reset(Ctlr *ctlr) +static int +reset(Ether *ether) { int i; uchar ic[8], sum; - ulong wd8003; + ulong port; + Dp8390 *dp8390; /* * Set up the software configuration. @@ -119,27 +76,15 @@ wd8003reset(Ctlr *ctlr) * Defaults are set for the dumb 8003E which can't be * autoconfigured. */ - if(ctlr->card.port == 0) - ctlr->card.port = 0x280; - if(ctlr->card.irq == 0) - ctlr->card.irq = 3; - if(ctlr->card.mem == 0) - ctlr->card.mem = 0xD0000; - if(ctlr->card.size == 0) - ctlr->card.size = 8*1024; - - ctlr->card.reset = wd8003reset; - ctlr->card.attach = dp8390attach; - ctlr->card.mode = dp8390mode; - ctlr->card.read = read; - ctlr->card.write = write; - ctlr->card.receive = dp8390receive; - ctlr->card.transmit = dp8390transmit; - ctlr->card.intr = dp8390intr; - ctlr->card.watch = watch; - ctlr->card.ram = 1; - - wd8003 = ctlr->card.port; + if(ether->port == 0) + ether->port = 0x280; + if(ether->irq == 0) + ether->irq = 3; + if(ether->mem == 0) + ether->mem = 0xD0000; + if(ether->size == 0) + ether->size = 8*1024; + /* * Look for the interface. We read the LAN address ROM * and validate the checksum - the sum of all 8 bytes @@ -147,17 +92,22 @@ wd8003reset(Ctlr *ctlr) * While we're at it, get the (possible) interface chip * registers, we'll use them to check for aliasing later. */ + port = ether->port; sum = 0; - for(i = 0; i < sizeof(ctlr->ea); i++){ - ctlr->ea[i] = inb(wd8003+Lar+i); - sum += ctlr->ea[i]; - ic[i] = inb(wd8003+i); + for(i = 0; i < sizeof(ether->ea); i++){ + ether->ea[i] = inb(port+Lar+i); + sum += ether->ea[i]; + ic[i] = inb(port+i); } - sum += inb(wd8003+Id); - sum += inb(wd8003+Cksum); + sum += inb(port+Id); + sum += inb(port+Cksum); if(sum != 0xFF) return -1; + ether->private = malloc(sizeof(Dp8390)); + dp8390 = ether->private; + dp8390->ram = 1; + /* * Check for old, dumb 8003E, which doesn't have an interface * chip. Only the msr exists out of the 1st eight registers, reads @@ -167,10 +117,9 @@ wd8003reset(Ctlr *ctlr) * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which * case the default irq gets used. */ - if(memcmp(&ctlr->ea[1], &ic[1], 5) == 0){ + if(memcmp(ðer->ea[1], &ic[1], 5) == 0){ memset(ic, 0, sizeof(ic)); - ic[Msr] = (((ulong)ctlr->card.mem)>>13) & 0x3F; - ctlr->card.watch = 0; + ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; } else{ /* @@ -178,65 +127,64 @@ wd8003reset(Ctlr *ctlr) * the 83C584 interface chip, but has 2 real registers, write Gp2 and if * it reads back the same, it's not an 8013EBT. */ - outb(wd8003+Gp2, 0xAA); - inb(wd8003+Msr); /* wiggle bus */ - if(inb(wd8003+Gp2) != 0xAA){ + outb(port+Gp2, 0xAA); + inb(port+Msr); /* wiggle bus */ + if(inb(port+Gp2) != 0xAA){ memset(ic, 0, sizeof(ic)); - ic[Msr] = (((ulong)ctlr->card.mem)>>13) & 0x3F; - ctlr->card.watch = 0; + ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; } else - ctlr->card.irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; + ether->irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; /* * Check if 16-bit card. * If Bit16 is read/write, then we have an 8-bit card. * If Bit16 is set, we're in a 16-bit slot. */ - outb(wd8003+Icr, ic[Icr]^Bit16); - inb(wd8003+Msr); /* wiggle bus */ - if((inb(wd8003+Icr) & Bit16) == (ic[Icr] & Bit16)){ - ctlr->card.bit16 = 1; + outb(port+Icr, ic[Icr]^Bit16); + inb(port+Msr); /* wiggle bus */ + if((inb(port+Icr) & Bit16) == (ic[Icr] & Bit16)){ + dp8390->bit16 = 1; ic[Icr] &= ~Bit16; } - outb(wd8003+Icr, ic[Icr]); + outb(port+Icr, ic[Icr]); - if(ctlr->card.bit16 && (inb(wd8003+Icr) & Bit16) == 0) - ctlr->card.bit16 = 0; + if(dp8390->bit16 && (inb(port+Icr) & Bit16) == 0) + dp8390->bit16 = 0; } - ctlr->card.mem = KZERO|((ic[Msr] & 0x3F)<<13); - if(ctlr->card.bit16) - ctlr->card.mem |= (ic[Laar] & 0x1F)<<19; + ether->mem = KZERO|((ic[Msr] & 0x3F)<<13); + if(dp8390->bit16) + ether->mem |= (ic[Laar] & 0x1F)<<19; else - ctlr->card.mem |= 0x80000; + ether->mem |= 0x80000; if(ic[Icr] & (1<<3)) - ctlr->card.size = 32*1024; - if(ctlr->card.bit16) - ctlr->card.size <<= 1; + ether->size = 32*1024; + if(dp8390->bit16) + ether->size <<= 1; /* * Set the DP8390 ring addresses. */ - ctlr->card.dp8390 = wd8003+0x10; - ctlr->card.tstart = 0; - ctlr->card.pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); - ctlr->card.pstop = HOWMANY(ctlr->card.size, Dp8390BufSz); + dp8390->dp8390 = port+0x10; + dp8390->tstart = 0; + dp8390->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); + dp8390->pstop = HOWMANY(ether->size, Dp8390BufSz); /* * Enable interface RAM, set interface width. */ - outb(wd8003+Msr, ic[Msr]|Menb); - if(ctlr->card.bit16) - outb(wd8003+Laar, ic[Laar]|L16en|M16en|ZeroWS16); + outb(port+Msr, ic[Msr]|Menb); + if(dp8390->bit16) + outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16); /* * Finally, init the 8390 and set the * ethernet address. */ - dp8390reset(ctlr); - dp8390setea(ctlr); + dp8390reset(ether); + dp8390setea(ether); return 0; } diff --git a/pc/ether8390.c b/pc/ether8390.c index 4512a2a436dda8ae4847678f5ad933a4f15ed0ae..21997919a27209c31033923851487cc14d1490c2 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -14,6 +14,9 @@ #include "etherif.h" +extern int dp8390inb(ulong); +extern void dp8390outb(ulong, uchar); + enum { Cr = 0x00, /* command register, all pages */ @@ -149,10 +152,9 @@ typedef struct { static void dp8390disable(Dp8390 *dp8390) { - ulong port; + ulong port = dp8390->dp8390; int timo; - port = dp8390->dp8390; /* * Stop the chip. Set the Stp bit and wait for the chip * to finish whatever was on its tiny mind before it sets @@ -171,9 +173,8 @@ dp8390disable(Dp8390 *dp8390) static void dp8390ring(Dp8390 *dp8390) { - ulong port; + ulong port = dp8390->dp8390; - port = dp8390->dp8390; dp8390outb(port+Pstart, dp8390->pstart); dp8390outb(port+Pstop, dp8390->pstop); dp8390outb(port+Bnry, dp8390->pstop-1); @@ -188,11 +189,10 @@ dp8390ring(Dp8390 *dp8390) void dp8390setea(Ether *ether) { - ulong port; + ulong port = ((Dp8390*)ether->private)->dp8390; uchar cr; int i; - port = ((Dp8390*)ether->private)->dp8390; /* * Set the ethernet address into the chip. * Take care to restore the command register @@ -210,11 +210,10 @@ dp8390setea(Ether *ether) void dp8390getea(Ether *ether) { - ulong port; + ulong port = ((Dp8390*)ether->private)->dp8390; uchar cr; int i; - port = ((Dp8390*)ether->private)->dp8390; /* * Get the ethernet address from the chip. * Take care to restore the command register @@ -232,11 +231,10 @@ dp8390getea(Ether *ether) static void* dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len) { - ulong port; + ulong port = dp8390->dp8390; uchar cr; int timo; - port = dp8390->dp8390; /* * Read some data at offset 'from' in the card's memory * using the DP8390 remote DMA facility, and place it at @@ -282,22 +280,22 @@ dp8390read(Dp8390 *dp8390, void *to, ulong from, ulong len) } static void* -dp8390write(Ether *ether, ulong to, void *from, ulong len) +dp8390write(Dp8390 *dp8390, ulong to, void *from, ulong len) { - ulong dp8390, crda; + ulong port = dp8390->dp8390; + ulong crda; uchar cr; - dp8390 = ((Dp8390*)ether->private)->dp8390; /* * Write some data to offset 'to' in the card's memory * using the DP8390 remote DMA facility, reading it at * 'from' in main memory, via the I/O data port. */ - cr = dp8390inb(dp8390+Cr) & ~Txp; - dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); - dp8390outb(dp8390+Isr, Rdc); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Isr, Rdc); - if(ether->bit16) + if(dp8390->bit16) len = ROUNDUP(len, 2); /* @@ -305,25 +303,25 @@ dp8390write(Ether *ether, ulong to, void *from, ulong len) * This is straight from the DP8390[12D] datasheet, hence * the initial set up for read. */ - crda = to-1-ether->bit16; - dp8390outb(dp8390+Rbcr0, (len+1+ether->bit16) & 0xFF); - dp8390outb(dp8390+Rbcr1, ((len+1+ether->bit16)>>8) & 0xFF); - dp8390outb(dp8390+Rsar0, crda & 0xFF); - dp8390outb(dp8390+Rsar1, (crda>>8) & 0xFF); - dp8390outb(dp8390+Cr, Page0|RDMAread|Sta); + crda = to-1-dp8390->bit16; + dp8390outb(port+Rbcr0, (len+1+dp8390->bit16) & 0xFF); + dp8390outb(port+Rbcr1, ((len+1+dp8390->bit16)>>8) & 0xFF); + dp8390outb(port+Rsar0, crda & 0xFF); + dp8390outb(port+Rsar1, (crda>>8) & 0xFF); + dp8390outb(port+Cr, Page0|RDMAread|Sta); for(;;){ - crda = dp8390inb(dp8390+Crda0); - crda |= dp8390inb(dp8390+Crda1)<<8; + crda = dp8390inb(port+Crda0); + crda |= dp8390inb(port+Crda1)<<8; if(crda == to){ /* * Start the remote DMA write and make sure * the registers are correct. */ - dp8390outb(dp8390+Cr, Page0|RDMAwrite|Sta); + dp8390outb(port+Cr, Page0|RDMAwrite|Sta); - crda = dp8390inb(dp8390+Crda0); - crda |= dp8390inb(dp8390+Crda1)<<8; + crda = dp8390inb(port+Crda0); + crda |= dp8390inb(port+Crda1)<<8; if(crda != to) panic("crda write %d to %d\n", crda, to); @@ -334,61 +332,67 @@ dp8390write(Ether *ether, ulong to, void *from, ulong len) /* * Pump the data into the I/O port. */ - if(ether->bit16) - outss(ether->data, from, len/2); + if(dp8390->bit16) + outss(dp8390->data, from, len/2); else - outsb(ether->data, from, len); + outsb(dp8390->data, from, len); /* * Wait for the remote DMA to finish. We'll need * a timeout here if this ever gets called before * we know there really is a chip there. */ - while((dp8390inb(dp8390+Isr) & Rdc) == 0) + while((dp8390inb(port+Isr) & Rdc) == 0) ; - dp8390outb(dp8390+Isr, Rdc); - dp8390outb(dp8390+Cr, cr); + dp8390outb(port+Isr, Rdc); + dp8390outb(port+Cr, cr); return (void*)to; } static uchar -getcurr(ulong dp8390) +getcurr(Dp8390 *dp8390) { + ulong port = dp8390->dp8390; uchar cr, curr; - cr = dp8390inb(dp8390+Cr) & ~Txp; - dp8390outb(dp8390+Cr, Page1|(~(Ps1|Ps0) & cr)); - curr = dp8390inb(dp8390+Curr); - dp8390outb(dp8390+Cr, cr); + cr = dp8390inb(port+Cr) & ~Txp; + dp8390outb(port+Cr, Page1|(~(Ps1|Ps0) & cr)); + curr = dp8390inb(port+Curr); + dp8390outb(port+Cr, cr); return curr; } static void receive(Ether *ether) { - uchar curr, len1, *pkt; + Dp8390 *dp8390; + uchar curr, *pkt; Hdr hdr; - ulong dp8390, data, len; + ulong port, data, len, len1; ushort type; Netfile *f, **fp, **ep; - dp8390 = ((Dp8390*)ether->private)->dp8390; - for(curr = getcurr(dp8390); ether->nxtpkt != curr; curr = getcurr(dp8390)){ + dp8390 = ether->private; + port = dp8390->dp8390; + for(curr = getcurr(dp8390); dp8390->nxtpkt != curr; curr = getcurr(dp8390)){ ether->inpackets++; - data = ether->nxtpkt*Dp8390BufSz; - (*ether->read)(ctlr, &hdr, data, sizeof(Hdr)); + data = dp8390->nxtpkt*Dp8390BufSz; + if(dp8390->ram) + memmove(&hdr, (void*)(ether->mem+data), sizeof(Hdr)); + else + dp8390read(dp8390, &hdr, data, sizeof(Hdr)); /* * Don't believe the upper byte count, work it * out from the software next-page pointer and * the current next-page pointer. */ - if(hdr.next > ether->nxtpkt) - len1 = hdr.next - ether->nxtpkt - 1; + if(hdr.next > dp8390->nxtpkt) + len1 = hdr.next - dp8390->nxtpkt - 1; else - len1 = (ether->pstop-ether->nxtpkt) + (hdr.next-ether->pstart) - 1; + len1 = (dp8390->pstop-dp8390->nxtpkt) + (hdr.next-dp8390->pstart) - 1; if(hdr.len0 > (Dp8390BufSz-sizeof(Hdr))) len1--; @@ -397,13 +401,13 @@ receive(Ether *ether) /* * Chip is badly scrogged, reinitialise the ring. */ - if(hdr.next < ether->pstart || hdr.next >= ether->pstop + if(hdr.next < dp8390->pstart || hdr.next >= dp8390->pstop || len < 60 || len > sizeof(Etherpkt)){ - print("H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d|", + print("dp8390: H#%2.2ux#%2.2ux#%2.2ux#%2.2ux,%d\n", hdr.status, hdr.next, hdr.len0, hdr.len1, len); - dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); - dp8390ring(ether); - dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Cr, Page0|RDMAabort|Stp); + dp8390ring(dp8390); + dp8390outb(port+Cr, Page0|RDMAabort|Sta); return; } @@ -412,20 +416,27 @@ receive(Ether *ether) * If the packet wraps round the hardware ring, read it in two pieces. */ if((hdr.status & (Fo|Fae|Crce|Prxok)) == Prxok){ - pkt = ether->rpkt; + pkt = (uchar*)ðer->rpkt; data += sizeof(Hdr); - ring->len = len; + len1 = len; - if((data+len) >= ether->pstop*Dp8390BufSz){ - ulong count = ether->pstop*Dp8390BufSz - data; + if((data+len1) >= dp8390->pstop*Dp8390BufSz){ + ulong count = dp8390->pstop*Dp8390BufSz - data; - (*ether->read)(ctlr, pkt, data, count); + if(dp8390->ram) + memmove(pkt, (void*)(ether->mem+data), count); + else + dp8390read(dp8390, pkt, data, count); pkt += count; - data = ether->pstart*Dp8390BufSz; - len -= count; + data = dp8390->pstart*Dp8390BufSz; + len1 -= count; + } + if(len1){ + if(dp8390->ram) + memmove(pkt, (void*)(ether->mem+data), len1); + else + dp8390read(dp8390, pkt, data, len1); } - if(len) - (*ether->read)(ctlr, pkt, data, len); /* * Copy the packet to whoever wants it. @@ -440,91 +451,114 @@ receive(Ether *ether) } /* - * Finished woth this packet, update the + * Finished with this packet, update the * hardware and software ring pointers. */ - ether->nxtpkt = hdr.next; + dp8390->nxtpkt = hdr.next; hdr.next--; - if(hdr.next < ether->pstart) - hdr.next = ether->pstop-1; - dp8390outb(dp8390+Bnry, hdr.next); + if(hdr.next < dp8390->pstart) + hdr.next = dp8390->pstop-1; + dp8390outb(port+Bnry, hdr.next); } } -/* - * Initiate a transmission. Must be called splhi(). - */ -void -dp8390transmit(Ether *ether) +static int +istxbusy(void *arg) { - ulong dp8390; - RingBuf *ring; - - dp8390 = ((Dp8390*)ether->private)->dp8390; - ring = ðer->tb[ether->ti]; - if(ether->tbusy == 0 && ring->owner == Interface){ + return ((Dp8390*)arg)->busy == 0; +} - ether->tbusy = 1; +static long +write(Ether *ether, void *buf, long n) +{ + Dp8390 *dp8390; + ulong port; - (*ether->write)(ctlr, ether->tstart*Dp8390BufSz, ring->pkt, ring->len); + dp8390 = ether->private; + port = dp8390->dp8390; - dp8390outb(dp8390+Tbcr0, ring->len & 0xFF); - dp8390outb(dp8390+Tbcr1, (ring->len>>8) & 0xFF); - dp8390outb(dp8390+Cr, Page0|RDMAabort|Txp|Sta); + qlock(ðer->tlock); + if(waserror()) { + qunlock(ðer->tlock); + nexterror(); } + + tsleep(ðer->tr, istxbusy, dp8390, 10000); + if(dp8390->busy) + print("dp8390: transmitter jammed\n"); + dp8390->busy = 1; + + if(dp8390->ram) + memmove((void*)(ether->mem+dp8390->tstart*Dp8390BufSz), buf, n); + else + dp8390write(dp8390, dp8390->tstart*Dp8390BufSz, buf, n); + + dp8390outb(port+Tbcr0, n & 0xFF); + dp8390outb(port+Tbcr1, (n>>8) & 0xFF); + dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); + + poperror(); + qunlock(ðer->tlock); + + return n; } static void overflow(Ether *ether) { - ulong dp8390; + Dp8390 *dp8390; + ulong port; uchar txp; int resend; - dp8390 = ((Dp8390*)ether->private)->dp8390; + dp8390 = ether->private; + port = dp8390->dp8390; + /* * The following procedure is taken from the DP8390[12D] datasheet, * it seems pretty adamant that this is what has to be done. */ - txp = dp8390inb(dp8390+Cr) & Txp; - dp8390outb(dp8390+Cr, Page0|RDMAabort|Stp); + txp = dp8390inb(port+Cr) & Txp; + dp8390outb(port+Cr, Page0|RDMAabort|Stp); delay(2); - dp8390outb(dp8390+Rbcr0, 0); - dp8390outb(dp8390+Rbcr1, 0); + dp8390outb(port+Rbcr0, 0); + dp8390outb(port+Rbcr1, 0); resend = 0; - if(txp && (dp8390inb(dp8390+Isr) & (Txe|Ptx)) == 0) + if(txp && (dp8390inb(port+Isr) & (Txe|Ptx)) == 0) resend = 1; - dp8390outb(dp8390+Tcr, Lb); - dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); - (*ether->receive)(ether); - dp8390outb(dp8390+Isr, Ovw); - wakeup(ðer->rr); - dp8390outb(dp8390+Tcr, 0); + dp8390outb(port+Tcr, Lb); + dp8390outb(port+Cr, Page0|RDMAabort|Sta); + receive(ether); + dp8390outb(port+Isr, Ovw); + dp8390outb(port+Tcr, 0); if(resend) - dp8390outb(dp8390+Cr, Page0|RDMAabort|Txp|Sta); + dp8390outb(port+Cr, Page0|RDMAabort|Txp|Sta); } static void interrupt(Ether *ether) { - ulong dp8390; + Dp8390 *dp8390; + ulong port; uchar isr, r; - dp8390 = ((Dp8390*)ether->private)->dp8390; + dp8390 = ether->private; + port = dp8390->dp8390; + /* * While there is something of interest, * clear all the interrupts and process. */ - dp8390outb(dp8390+Imr, 0x00); - while(isr = dp8390inb(dp8390+Isr)){ + dp8390outb(port+Imr, 0x00); + while(isr = dp8390inb(port+Isr)){ if(isr & Ovw){ overflow(ether); - dp8390outb(dp8390+Isr, Ovw); + dp8390outb(port+Isr, Ovw); ether->overflows++; } @@ -534,7 +568,7 @@ interrupt(Ether *ether) */ if(isr & (Rxe|Prx)){ receive(ether); - dp8390outb(dp8390+Isr, Rxe|Prx); + dp8390outb(port+Isr, Rxe|Prx); } /* @@ -543,100 +577,102 @@ interrupt(Ether *ether) * and wake the output routine. */ if(isr & (Txe|Ptx)){ - r = dp8390inb(dp8390+Tsr); + r = dp8390inb(port+Tsr); if(isr & Txe){ - if((r & (Cdh|Fu|Crs|Abt)) && ether->debug) - print("Tsr#%2.2ux|", r); + if((r & (Cdh|Fu|Crs|Abt))) + print("dp8390: Tsr#%2.2ux\n", r); ether->oerrs++; } - dp8390outb(dp8390+Isr, Txe|Ptx); + dp8390outb(port+Isr, Txe|Ptx); if(isr & Ptx) ether->outpackets++; + dp8390->busy = 0; wakeup(ðer->tr); } if(isr & Cnt){ - ether->frames += dp8390inb(dp8390+Cntr0); - ether->crcs += dp8390inb(dp8390+Cntr1); - ether->buffs += dp8390inb(dp8390+Cntr2); - dp8390outb(dp8390+Isr, Cnt); + ether->frames += dp8390inb(port+Cntr0); + ether->crcs += dp8390inb(port+Cntr1); + ether->buffs += dp8390inb(port+Cntr2); + dp8390outb(port+Isr, Cnt); } } - dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); + dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); } static void -promiscuous(Ether *ether, int on) +promiscuous(void *arg, int on) { - ulong dp8390; + Dp8390 *dp8390 = ((Ether*)arg)->private; - dp8390 = ((Dp8390*)ether->private)->dp8390; /* * Set/reset promiscuous mode. */ if(on) - dp8390outb(ether->dp8390+Rcr, Pro|Ab); + dp8390outb(dp8390->dp8390+Rcr, Pro|Ab); else - dp8390outb(ether->dp8390+Rcr, Ab); + dp8390outb(dp8390->dp8390+Rcr, Ab); } -void -dp8390attach(Ether *ether) +static void +attach(Ether *ether) { - ulong dp8390; + Dp8390 *dp8390 = ether->private; - dp8390 = ((Dp8390*)ether->private)->dp8390; /* * Enable the chip for transmit/receive. * The init routine leaves the chip in monitor * mode. Clear the missed-packet counter, it * increments while in monitor mode. */ - dp8390outb(ether->dp8390+Rcr, Ab); - dp8390inb(ether->dp8390+Cntr2); + dp8390outb(dp8390->dp8390+Rcr, Ab); + dp8390inb(dp8390->dp8390+Cntr2); } -static int +int dp8390reset(Ether *ether) { - ulong dp8390; + Dp8390 *dp8390; + ulong port; + + dp8390 = ether->private; + port = dp8390->dp8390; - dp8390 = ((Dp8390*)ether->private)->dp8390; /* * This is the initialisation procedure described * as 'mandatory' in the datasheet, with references * to the 3Com503 technical reference manual. */ - dp8390disable(ether); - if(ether->bit16) - dp8390outb(dp8390+Dcr, Ft4|Ls|Wts); + dp8390disable(dp8390); + if(dp8390->bit16) + dp8390outb(port+Dcr, Ft4|Ls|Wts); else - dp8390outb(dp8390+Dcr, Ft4|Ls); + dp8390outb(port+Dcr, Ft4|Ls); - dp8390outb(dp8390+Rbcr0, 0); - dp8390outb(dp8390+Rbcr1, 0); + dp8390outb(port+Rbcr0, 0); + dp8390outb(port+Rbcr1, 0); - dp8390outb(dp8390+Tcr, 0); - dp8390outb(dp8390+Rcr, Mon); + dp8390outb(port+Tcr, 0); + dp8390outb(port+Rcr, Mon); /* * Init the ring hardware and software ring pointers. * Can't initialise ethernet address as we may not know * it yet. */ - dp8390ring(ether); - dp8390outb(dp8390+Tpsr, ether->tstart); + dp8390ring(dp8390); + dp8390outb(port+Tpsr, dp8390->tstart); - dp8390outb(dp8390+Isr, 0xFF); - dp8390outb(dp8390+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); + dp8390outb(port+Isr, 0xFF); + dp8390outb(port+Imr, Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe); /* * Leave the chip initialised, * but in monitor mode. */ - dp8390outb(dp8390+Cr, Page0|RDMAabort|Sta); + dp8390outb(port+Cr, Page0|RDMAabort|Sta); /* * Set up the software configuration. diff --git a/pc/etherif.h b/pc/etherif.h index db07cc68c22d4d1f710502c0ca05a4da795240f8..2cc48ea9f7abc6b9dd7869eae8cdf6f455f7ed0e 100644 --- a/pc/etherif.h +++ b/pc/etherif.h @@ -28,12 +28,20 @@ typedef struct { ulong dp8390; /* I/O address of 8390 */ ulong data; /* I/O data port if no shared memory */ - uchar nxtpkt; /* software bndry */ + + uchar nxtpkt; /* receive: software bndry */ + uchar busy; /* transmit: busy */ uchar tstart; /* 8390 ring addresses */ uchar pstart; uchar pstop; } Dp8390; +#define Dp8390BufSz 256 + +extern int dp8390reset(Ether*); +extern void dp8390getea(Ether*); +extern void dp8390setea(Ether*); + #define NEXT(x, l) (((x)+1)%(l)) #define HOWMANY(x, y) (((x)+((y)-1))/(y)) #define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))