From c72c7bfb5ed0e041df271cb3ebdbbfa79383ebf3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 29 Aug 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-08-29 --- pc/ether8003.c | 180 +++++++++++++++++++++++++++++++++---------------- pc/ether8390.c | 8 +-- 2 files changed, 124 insertions(+), 64 deletions(-) diff --git a/pc/ether8003.c b/pc/ether8003.c index 5349c1f3832a0c7c83b967e527f7488e757dd738..11b8b11e89800af3cb95c5ff48ce6fcf9894849f 100644 --- a/pc/ether8003.c +++ b/pc/ether8003.c @@ -11,6 +11,7 @@ /* * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). + * Also handles 8216 cards (Elite Ultra). * Configuration code based on that provided by SMC. */ enum { /* 83C584 Bus Interface Controller */ @@ -20,6 +21,7 @@ enum { /* 83C584 Bus Interface Controller */ Bio = 0x03, /* BIOS ROM Address Register */ Ear = 0x03, /* EEROM Address Register (shared with Bio) */ Irr = 0x04, /* Interrupt Request Register */ + Hcr = 0x04, /* 8216 hardware control */ Laar = 0x05, /* LA Address Register */ Ijr = 0x06, /* Initialisation Jumpers */ Gp2 = 0x07, /* General Purpose Data Register */ @@ -45,68 +47,34 @@ enum { /* Icr */ }; enum { /* Laar */ - ZeroWS16 = (1<<5), /* zero wait states for 16-bit ops */ - L16en = (1<<6), /* enable 16-bit LAN operation */ - M16en = (1<<7), /* enable 16-bit memory access */ + ZeroWS16 = 0x20, /* zero wait states for 16-bit ops */ + L16en = 0x40, /* enable 16-bit LAN operation */ + M16en = 0x80, /* enable 16-bit memory access */ +}; + +enum { /* Ijr */ + Ienable = 0x01, /* 8216 interrupt enable */ }; /* * Mapping from configuration bits to interrupt level. */ -static int intrmap[] = { +static int irq8003[8] = { 9, 3, 5, 7, 10, 11, 15, 4, }; -/* - * Get configuration parameters, enable memory. - * There are opportunities here for buckets of code. - * We'll try to resist. - */ -static int -reset(Ether *ether) +static int irq8216[8] = { + 0, 9, 3, 5, 7, 10, 11, 15, +}; + +static void +reset8003(Ether *ether, uchar ea[Eaddrlen], uchar ic[8]) { - int i; - uchar ea[Eaddrlen], ic[8], sum; - ulong port; Dp8390 *dp8390; + ulong port; - /* - * Set up the software configuration. - * Use defaults for port, irq, mem and size if not specified. - * Defaults are set for the dumb 8003E which can't be - * autoconfigured. - */ - 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 - * should be 0xFF. - * 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(ea); i++){ - ea[i] = inb(port+Lar+i); - sum += ea[i]; - ic[i] = inb(port+i); - } - sum += inb(port+Id); - sum += inb(port+Cksum); - if(sum != 0xFF) - return -1; - - ether->ctlr = malloc(sizeof(Dp8390)); dp8390 = ether->ctlr; - dp8390->ram = 1; + port = ether->port; /* * Check for old, dumb 8003E, which doesn't have an interface @@ -117,7 +85,7 @@ reset(Ether *ether) * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which * case the default irq gets used. */ - if(memcmp(ðer->ea[1], &ic[1], 5) == 0){ + if(memcmp(&ea[1], &ic[1], 5) == 0){ memset(ic, 0, sizeof(ic)); ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; } @@ -134,7 +102,7 @@ reset(Ether *ether) ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; } else - ether->irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; + ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; /* * Check if 16-bit card. @@ -164,6 +132,107 @@ reset(Ether *ether) if(dp8390->bit16) ether->size <<= 1; + /* + * Enable interface RAM, set interface width. + */ + outb(port+Msr, ic[Msr]|Menb); + if(dp8390->bit16) + outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16); +} + +static void +reset8216(Ether *ether, uchar[8]) +{ + uchar hcr, irq, x; + ulong addr, port; + Dp8390 *dp8390; + + dp8390 = ether->ctlr; + dp8390->bit16 = 1; + port = ether->port; + + /* + * Switch to the alternate register set and retrieve the memory + * and irq information. + */ + hcr = inb(port+Hcr); + outb(port+Hcr, 0x80|hcr); + addr = inb(port+0x0B) & 0xFF; + irq = inb(port+0x0D); + outb(port+Hcr, hcr); + + ether->mem = KZERO|(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13)); + ether->size = 8192*(1<<((addr>>4) & 0x03)); + ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)]; + + /* + * Enable interface RAM, set interface width, + * and enable interrupts. + */ + x = inb(port+Msr) & ~Rst; + outb(port+Msr, Menb|x); + x = inb(port+Laar); + outb(port+Laar, M16en|x); + outb(port+Ijr, Ienable); +} + +/* + * Get configuration parameters, enable memory. + * There are opportunities here for buckets of code. + * We'll try to resist. + */ +static int +reset(Ether *ether) +{ + int i; + uchar ea[Eaddrlen], ic[8], id, sum; + ulong port; + Dp8390 *dp8390; + + /* + * Set up the software configuration. + * Use defaults for port, irq, mem and size if not specified. + * Defaults are set for the dumb 8003E which can't be + * autoconfigured. + */ + 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 + * should be 0xFF. + * 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(ea); i++){ + ea[i] = inb(port+Lar+i); + sum += ea[i]; + ic[i] = inb(port+i); + } + id = inb(port+Id); + sum += id; + sum += inb(port+Cksum); + if(sum != 0xFF) + return -1; + + ether->ctlr = malloc(sizeof(Dp8390)); + dp8390 = ether->ctlr; + dp8390->ram = 1; + + if((id & 0xFE) == 0x2A) + reset8216(ether, ic); + else + reset8003(ether, ea, ic); + /* * Set the DP8390 ring addresses. */ @@ -172,13 +241,6 @@ reset(Ether *ether) dp8390->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); dp8390->pstop = HOWMANY(ether->size, Dp8390BufSz); - /* - * Enable interface RAM, set interface width. - */ - 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. diff --git a/pc/ether8390.c b/pc/ether8390.c index 5afd89b09a32a9ad471aaa3405ad0451b883e850..ad680b9da68e092e2d67adae415d2f7ce37e4747 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -562,15 +562,13 @@ overflow(Ether *ether) } static void -interrupt(Ureg *ur, void *arg) +interrupt(Ureg*, void *arg) { Ether *ether; Dp8390 *dp8390; ulong port; uchar isr, r; - USED(ur); - ether = arg; dp8390 = ether->ctlr; port = dp8390->dp8390; @@ -580,7 +578,7 @@ interrupt(Ureg *ur, void *arg) * clear all the interrupts and process. */ slowoutb(port+Imr, 0x00); - while(isr = slowinb(port+Isr)){ + while(isr = (slowinb(port+Isr) & (Cnte|Ovwe|Txee|Rxee|Ptxe|Prxe))){ if(isr & Ovw){ overflow(ether); @@ -657,7 +655,7 @@ attach(Ether *ether) x = Ab; if(ether->prom) x |= Pro; - slowoutb(dp8390->dp8390+Rcr, Ab); + slowoutb(dp8390->dp8390+Rcr, x); slowinb(dp8390->dp8390+Cntr2); }