## diffname pc/ether8003.c 1992/1222
## diff -e /dev/null /n/bootesdump/1992/1222/sys/src/9/pc/ether8003.c
0a
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "io.h"
#include "devtab.h"
#include "ether.h"
enum { /* 83C584 Bus Interface Controller */
Msr = 0x00, /* Memory Select Register */
Icr = 0x01, /* Interface Configuration Register */
Iar = 0x02, /* I/O Address Register */
Bio = 0x03, /* BIOS ROM Address Register */
Irr = 0x04, /* Interrupt Request Register */
Laar = 0x05, /* LA Address Register */
Ijr = 0x06, /* Initialisation Jumpers */
Gp2 = 0x07, /* General Purpose Data Register */
Lar = 0x08, /* LAN Address Registers */
Id = 0x0E, /* Board ID byte */
Cksum = 0x0F, /* Checksum */
};
enum { /* Msr */
Rst = 0x80, /* software reset */
Menb = 0x40, /* memory enable */
};
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 */
};
/*
* Mapping from configuration bits to interrupt level.
*/
static int intrmap[] = {
9, 3, 5, 7, 10, 11, 15, 4,
};
/*
* Get configuration parameters, enable memory.
*/
static int
reset(Ctlr *ctlr)
{
Board *board = ctlr->board;
int i;
uchar msr, icr, laar, irr, sum;
/*
* Look for the interface. We read the LAN address ROM
* and validate the checksum - the sum of all 8 bytes
* should be 0xFF.
*/
for(board->io = 0x200; board->io < 0x400; board->io += 0x20){
sum = 0;
for(i = 0; i < sizeof(ctlr->ea); i++){
ctlr->ea[i] = inb(board->io+Lar+i);
sum += ctlr->ea[i];
}
sum += inb(board->io+Id);
sum += inb(board->io+Cksum);
if(sum == 0xFF)
break;
}
if(board->io >= 0x400)
return -1;
/*
* Found it, reset it.
* Be careful to preserve the Msr address bits,
* they don't get reloaded from the EEPROM on reset.
*/
msr = inb(board->io+Msr);
outb(board->io+Msr, Rst|msr);
delay(1);
outb(board->io+Msr, msr);
delay(2);
/*
* Check for old, dumb 8003E, which doesn't have an interface
* chip. Only the msr exists out of the 1st eight registers, reads
* of the others just alias the 2nd eight registers, the LAN
* address ROM. We can check icr, irr and laar against the ethernet
* address read above and if they match it's an 8003E (or an
* 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which
* case the default irq gets used.
*/
msr = inb(board->io+Msr);
icr = inb(board->io+Icr);
laar = inb(board->io+Laar);
irr = inb(board->io+Irr);
if(icr != ctlr->ea[1] || irr != ctlr->ea[4] || laar != ctlr->ea[5])
board->irq = intrmap[((irr>>5) & 0x3)|(icr & 0x4)];
else {
msr = (((ulong)board->ramstart)>>13) & 0x3F;
icr = laar = 0;
board->watch = 0;
}
/*
* Set up the bus-size, RAM address and RAM size
* from the info in the configuration registers.
*/
board->bit16 = icr & 0x1;
board->ram = 1;
board->ramstart = KZERO|((msr & 0x3F)<<13);
if(board->bit16)
board->ramstart |= (laar & 0x1F)<<19;
else
board->ramstart |= 0x80000;
if(icr & (1<<3))
board->ramstop = 32*1024;
else
board->ramstop = 8*1024;
if(board->bit16)
board->ramstop <<= 1;
board->ramstop += board->ramstart;
/*
* Set the DP8390 ring addresses.
*/
board->dp8390 = board->io+0x10;
board->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
board->pstop = HOWMANY(board->ramstop-board->ramstart, Dp8390BufSz);
board->tstart = 0;
print("WD80x3 I/O addr %lux width %d addr %lux size %d irq %d:",
board->io, board->bit16 ? 16: 8, board->ramstart,
board->ramstop-board->ramstart, board->irq);
for(i = 0; i < sizeof(ctlr->ea); i++)
print(" %2.2ux", ctlr->ea[i]);
print("\n");
/*
* Enable interface RAM, set interface width.
*/
outb(board->io+Msr, Menb|msr);
if(board->bit16)
outb(board->io+Laar, laar|L16en|M16en|ZeroWS16);
/*
* Finally, init the 8390 and set the
* ethernet address.
*/
dp8390reset(ctlr);
dp8390setea(ctlr);
return 0;
}
static void
watch(Ctlr *ctlr)
{
Board *board = ctlr->board;
uchar msr;
int s;
s = splhi();
msr = inb(board->io+Msr);
/*
* If the board has reset itself,
* start again.
*/
if((msr & Menb) == 0){
delay(100);
dp8390reset(ctlr);
etherinit();
wakeup(&ctlr->tr);
wakeup(&ctlr->rr);
}
splx(s);
}
/*
* Defaults are set for the dumb 8003E
* which can't be autoconfigured.
*/
Board ether8003 = {
reset,
0, /* init */
dp8390attach,
dp8390mode,
dp8390receive,
dp8390transmit,
dp8390intr,
watch,
0x280, /* addr */
3, /* irq */
0, /* bit16 */
1, /* ram */
0xD0000, /* ramstart */
0xD0000+8*1024, /* ramstop */
};
.
## diffname pc/ether8003.c 1992/1224
## diff -e /n/bootesdump/1992/1222/sys/src/9/pc/ether8003.c /n/bootesdump/1992/1224/sys/src/9/pc/ether8003.c
197c
0x280, /* io */
.
134c
print("WD8003 I/O addr %lux width %d addr %lux size %d irq %d:",
.
## diffname pc/ether8003.c 1993/0212
## diff -e /n/bootesdump/1992/1224/sys/src/9/pc/ether8003.c /n/bootesdump/1993/0212/sys/src/9/pc/ether8003.c
201,203c
read, /* read */
write, /* write */
dp8390receive, /* receive */
dp8390transmit, /* transmit */
dp8390intr, /* interrupt */
watch, /* watch */
0, /* overflow */
0x280, /* io */
3, /* irq */
0, /* bit16 */
1, /* ram */
0xD0000, /* ramstart */
0xD0000+8*1024, /* ramstop */
.
197,199c
reset, /* reset */
0, /* init */
dp8390attach, /* attach */
dp8390mode, /* mode */
.
187,195c
Card ether8003 = {
"WD8003", /* ident */
.
168c
* If the card has reset itself,
.
166c
msr = inb(ctlr->card.io+Msr);
.
161d
157a
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.ramstart+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.ramstart+to), from, len);
return (void*)to;
}
.
144,146c
outb(ctlr->card.io+Msr, Menb|msr);
if(ctlr->card.bit16)
outb(ctlr->card.io+Laar, laar|L16en|M16en|ZeroWS16);
.
134,140d
129,132c
ctlr->card.dp8390 = ctlr->card.io+0x10;
ctlr->card.pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
ctlr->card.pstop = HOWMANY(ctlr->card.ramstop-ctlr->card.ramstart, Dp8390BufSz);
ctlr->card.tstart = 0;
.
121,124c
ctlr->card.ramstop = 8*1024;
if(ctlr->card.bit16)
ctlr->card.ramstop <<= 1;
ctlr->card.ramstop += ctlr->card.ramstart;
.
119c
ctlr->card.ramstop = 32*1024;
.
116c
ctlr->card.ramstart |= 0x80000;
.
111,114c
ctlr->card.ram = 1;
ctlr->card.ramstart = KZERO|((msr & 0x3F)<<13);
if(ctlr->card.bit16)
ctlr->card.ramstart |= (laar & 0x1F)<<19;
.
109c
ctlr->card.bit16 = icr & 0x1;
.
102c
ctlr->card.watch = 0;
.
100c
msr = (((ulong)ctlr->card.ramstart)>>13) & 0x3F;
.
98c
ctlr->card.irq = intrmap[((irr>>5) & 0x3)|(icr & 0x4)];
.
93,96c
msr = inb(ctlr->card.io+Msr);
icr = inb(ctlr->card.io+Icr);
laar = inb(ctlr->card.io+Laar);
irr = inb(ctlr->card.io+Irr);
.
81c
outb(ctlr->card.io+Msr, msr);
.
78,79c
msr = inb(ctlr->card.io+Msr);
outb(ctlr->card.io+Msr, Rst|msr);
.
70c
if(ctlr->card.io >= 0x400)
.
65,66c
sum += inb(ctlr->card.io+Id);
sum += inb(ctlr->card.io+Cksum);
.
62c
ctlr->ea[i] = inb(ctlr->card.io+Lar+i);
.
59c
for(ctlr->card.io = 0x200; ctlr->card.io < 0x400; ctlr->card.io += 0x20){
.
50d
22c
Id = 0x0E, /* Card ID byte */
.
## diffname pc/ether8003.c 1993/0223
## diff -e /n/bootesdump/1993/0212/sys/src/9/pc/ether8003.c /n/bootesdump/1993/0223/sys/src/9/pc/ether8003.c
138c
outb(ctlr->card.io+Laar, ic[Laar]|L16en|M16en|ZeroWS16);
.
136c
outb(ctlr->card.io+Msr, ic[Msr]|Menb);
.
117c
if(ic[Icr] & (1<<3))
.
113c
ctlr->card.ramstart |= (ic[Laar] & 0x1F)<<19;
.
110,111c
ic[Icr] = inb(ctlr->card.io+Icr);
if(ctlr->card.bit16 && (ic[Icr] & Bit16) == 0)
ctlr->card.bit16 = 0;
}
ctlr->card.ramstart = KZERO|((ic[Msr] & 0x3F)<<13);
.
104,108c
/*
* 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(ctlr->card.io+Icr, ic[Icr]^Bit16);
inb(ctlr->card.io+Msr); /* wiggle bus */
if((inb(ctlr->card.io+Icr) & Bit16) == (ic[Icr] & Bit16)){
ctlr->card.bit16 = 1;
ic[Icr] &= ~Bit16;
}
outb(ctlr->card.io+Icr, ic[Icr]);
.
102a
else{
/*
* As a final sanity check for the 8013EBT, which doesn't have
* the 83C584 interface chip, but has 2 real registers, write Gp2 and if
* it reads back the same, it's not an 8013EBT.
*/
outb(ctlr->card.io+Gp2, 0xAA);
inb(ctlr->card.io+Msr); /* wiggle bus */
if(inb(ctlr->card.io+Gp2) != 0xAA){
memset(ic, 0, sizeof(ic));
ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F;
ctlr->card.watch = 0;
ctlr->card.irq = 2; /* special */
}
else
ctlr->card.irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
.
92,100c
if(memcmp(&ctlr->ea[1], &ic[1], 5) == 0){
memset(ic, 0, sizeof(ic));
ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F;
.
73,83d
62a
ic[i] = inb(ctlr->card.io+i);
.
56a
* While we're at it, get the (possible) interface chip
* registers, we'll use them to check for aliasing later.
.
51c
uchar ic[8], sum;
.
45a
* There are opportunities here for buckets of code.
* We'll try to resist.
.
30a
enum { /* Icr */
Bit16 = 0x01, /* 16-bit bus */
Other = 0x02, /* other register access */
Ir2 = 0x04, /* IR2 */
Msz = 0x08, /* SRAM size */
Rla = 0x10, /* recall LAN address */
Rx7 = 0x20, /* recall all but I/O and LAN address */
Rio = 0x40, /* recall I/O address from EEROM */
Sto = 0x80, /* non-volatile EEROM store */
};
.
16a
Ear = 0x03, /* EEROM Address Register (shared with Bio) */
.
11a
/*
* Western Digital/Standard Microsystems Corporation cards (WD80[01]3).
* Configuration code based on that provided by SMC.
*/
.
## diffname pc/ether8003.c 1993/0302
## diff -e /n/bootesdump/1993/0223/sys/src/9/pc/ether8003.c /n/bootesdump/1993/0302/sys/src/9/pc/ether8003.c
137,138c
if(ctlr->card.bit16 && (inb(ctlr->card.io+Icr) & Bit16) == 0)
.
## diffname pc/ether8003.c 1993/0915
## diff -e /n/bootesdump/1993/0302/sys/src/9/pc/ether8003.c /n/fornaxdump/1993/0915/sys/src/brazil/pc/ether8003.c
189,252d
183,187c
addethercard("WD8003", wd8003reset);
.
180,181c
void
ether8003link(void)
.
168c
outb(wd8003+Laar, ic[Laar]|L16en|M16en|ZeroWS16);
.
166c
outb(wd8003+Msr, ic[Msr]|Menb);
.
161a
ctlr->card.pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
ctlr->card.pstop = HOWMANY(ctlr->card.size, Dp8390BufSz);
.
158,160c
ctlr->card.dp8390 = wd8003+0x10;
.
152,153c
ctlr->card.size <<= 1;
.
148,150c
ctlr->card.size = 32*1024;
.
145c
ctlr->card.mem |= 0x80000;
.
143c
ctlr->card.mem |= (ic[Laar] & 0x1F)<<19;
.
141c
ctlr->card.mem = KZERO|((ic[Msr] & 0x3F)<<13);
.
137c
if(ctlr->card.bit16 && (inb(wd8003+Icr) & Bit16) == 0)
.
135c
outb(wd8003+Icr, ic[Icr]);
.
129,131c
outb(wd8003+Icr, ic[Icr]^Bit16);
inb(wd8003+Msr); /* wiggle bus */
if((inb(wd8003+Icr) & Bit16) == (ic[Icr] & Bit16)){
.
119d
117c
ic[Msr] = (((ulong)ctlr->card.mem)>>13) & 0x3F;
.
113,115c
outb(wd8003+Gp2, 0xAA);
inb(wd8003+Msr); /* wiggle bus */
if(inb(wd8003+Gp2) != 0xAA){
.
104c
ic[Msr] = (((ulong)ctlr->card.mem)>>13) & 0x3F;
.
90c
sum += inb(wd8003+Id);
sum += inb(wd8003+Cksum);
if(sum != 0xFF)
.
78,88c
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);
.
71a
* 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(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;
/*
.
69a
ulong wd8003;
.
65,66c
int
wd8003reset(Ctlr *ctlr)
.
59a
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);
}
.
## diffname pc/ether8003.c 1993/1116
## diff -e /n/fornaxdump/1993/0915/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1993/1116/sys/src/brazil/pc/ether8003.c
247c
addethercard("WD8003", reset);
.
10c
#include "etherif.h"
.
8c
#include "../port/error.h"
#include "../port/netif.h"
.
6d
## diffname pc/ether8003.c 1993/1118
## diff -e /n/fornaxdump/1993/1116/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1993/1118/sys/src/brazil/pc/ether8003.c
238,239c
dp8390reset(ether);
dp8390setea(ether);
.
230,232c
outb(port+Msr, ic[Msr]|Menb);
if(dp8390->bit16)
outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16);
.
222,225c
dp8390->dp8390 = port+0x10;
dp8390->tstart = 0;
dp8390->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
dp8390->pstop = HOWMANY(ether->size, Dp8390BufSz);
.
215,217c
ether->size = 32*1024;
if(dp8390->bit16)
ether->size <<= 1;
.
212c
ether->mem |= 0x80000;
.
208,210c
ether->mem = KZERO|((ic[Msr] & 0x3F)<<13);
if(dp8390->bit16)
ether->mem |= (ic[Laar] & 0x1F)<<19;
.
204,205c
if(dp8390->bit16 && (inb(port+Icr) & Bit16) == 0)
dp8390->bit16 = 0;
.
202c
outb(port+Icr, ic[Icr]);
.
196,199c
outb(port+Icr, ic[Icr]^Bit16);
inb(port+Msr); /* wiggle bus */
if((inb(port+Icr) & Bit16) == (ic[Icr] & Bit16)){
dp8390->bit16 = 1;
.
189c
ether->irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
.
185,186c
ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
.
181,183c
outb(port+Gp2, 0xAA);
inb(port+Msr); /* wiggle bus */
if(inb(port+Gp2) != 0xAA){
.
172,173c
ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F;
.
170c
if(memcmp(ðer->ea[1], &ic[1], 5) == 0){
.
160a
ether->private = malloc(sizeof(Dp8390));
dp8390 = ether->private;
dp8390->ram = 1;
.
156,157c
sum += inb(port+Id);
sum += inb(port+Cksum);
.
151,154c
for(i = 0; i < sizeof(ether->ea); i++){
ether->ea[i] = inb(port+Lar+i);
sum += ether->ea[i];
ic[i] = inb(port+i);
.
149a
port = ether->port;
.
131,142d
122,129c
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;
.
114c
ulong port;
Dp8390 *dp8390;
.
109,110c
static int
reset(Ether *ether)
.
60,103d
## diffname pc/ether8003.c 1993/1119
## diff -e /n/fornaxdump/1993/1118/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1993/1119/sys/src/brazil/pc/ether8003.c
186a
memmove(ether->ea, debugea, 6);
.
59a
static uchar debugea[6] = {
0x00, 0x60, 0x8c, 0x00, 0x1a, 0x42,
};
.
## diffname pc/ether8003.c 1993/1120
## diff -e /n/fornaxdump/1993/1119/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1993/1120/sys/src/brazil/pc/ether8003.c
191d
60,63d
## diffname pc/ether8003.c 1994/0128
## diff -e /n/fornaxdump/1993/1120/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1994/0128/sys/src/brazil/pc/ether8003.c
186a
if((ether->ea[0]|ether->ea[1]|ether->ea[2]|ether->ea[3]|ether->ea[4]|ether->ea[5]) == 0){
for(i = 0; i < sizeof(ether->ea); i++)
ether->ea[i] = ea[i];
}
.
98c
ea[i] = inb(port+Lar+i);
.
69c
uchar ea[Eaddrlen], ic[8], sum;
.
## diffname pc/ether8003.c 1994/0202
## diff -e /n/fornaxdump/1994/0128/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1994/0202/sys/src/brazil/pc/ether8003.c
99c
sum += ea[i];
.
## diffname pc/ether8003.c 1994/0810
## diff -e /n/fornaxdump/1994/0202/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1994/0810/sys/src/brazil/pc/ether8003.c
97c
for(i = 0; i < sizeof(ea); i++){
.
## diffname pc/ether8003.c 1994/1210
## diff -e /n/fornaxdump/1994/0810/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1994/1210/sys/src/brazil/pc/ether8003.c
192a
if(getisa(ether->mem, ether->size, 0) == 0)
panic("ether8003: %lux reused", ether->mem);
.
## diffname pc/ether8003.c 1995/0126
## diff -e /n/fornaxdump/1994/1210/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1995/0126/sys/src/brazil/pc/ether8003.c
194c
panic("ether8003: 0x%lux reused", ether->mem);
.
## diffname pc/ether8003.c 1995/0721
## diff -e /n/fornaxdump/1995/0126/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1995/0721/sys/src/brazil/pc/ether8003.c
107,108c
ether->ctlr = malloc(sizeof(Dp8390));
dp8390 = ether->ctlr;
.
## diffname pc/ether8003.c 1995/0829
## diff -e /n/fornaxdump/1995/0721/sys/src/brazil/pc/ether8003.c /n/fornaxdump/1995/0829/sys/src/brazil/pc/ether8003.c
174,180d
167a
* 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);
/*
.
137c
ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)];
.
120c
if(memcmp(&ea[1], &ic[1], 5) == 0){
.
107,110d
96,105d
73,94c
dp8390 = ether->ctlr;
.
71a
ulong port;
.
68,70d
60,66c
static int irq8216[8] = {
0, 9, 3, 5, 7, 10, 11, 15,
};
static void
reset8003(Ether *ether, uchar ea[Eaddrlen], uchar ic[8])
.
56c
static int irq8003[8] = {
.
52a
enum { /* Ijr */
Ienable = 0x01, /* 8216 interrupt enable */
};
.
48,50c
ZeroWS16 = 0x20, /* zero wait states for 16-bit ops */
L16en = 0x40, /* enable 16-bit LAN operation */
M16en = 0x80, /* enable 16-bit memory access */
.
22a
Hcr = 0x04, /* 8216 hardware control */
.
13a
* Also handles 8216 cards (Elite Ultra).
.
## diffname pc/ether8003.c 1997/0327
## diff -e /n/fornaxdump/1995/0829/sys/src/brazil/pc/ether8003.c /n/emeliedump/1997/0327/sys/src/brazil/pc/ether8003.c
255c
if(umbmalloc(ether->mem, ether->size, 0) == 0)
.
249c
memset(nullea, 0, Eaddrlen);
if(memcmp(nullea, ether->ea, Eaddrlen) == 0){
.
245,246c
* Finally, init the 8390,set the ethernet address
* and claim the memory used.
.
239,242c
ctlr->port = port+0x10;
ctlr->tstart = 0;
ctlr->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz);
ctlr->pstop = HOWMANY(ether->size, Dp8390BufSz);
.
228,229c
ctlr = ether->ctlr;
ctlr->ram = 1;
.
190c
Dp8390 *ctlr;
.
188c
uchar ea[Eaddrlen], ic[8], id, nullea[Eaddrlen], sum;
.
185c
reset(Ether* ether)
.
181,182c
* There are opportunities here for buckets of code, try to resist.
.
169,170c
* Enable interface RAM, set interface width, and enable interrupts.
.
153a
ctlr->width = 2;
.
150,151c
ctlr = ether->ctlr;
.
148c
Dp8390 *ctlr;
.
144c
reset8216(Ether* ether, uchar[8])
.
139c
if(ctlr->width == 2)
.
132c
if(ctlr->width == 2)
.
125c
if(ctlr->width == 2)
.
120,121c
if(ctlr->width == 2 && (inb(port+Icr) & Bit16) == 0)
ctlr->width = 1;
.
115c
ctlr->width = 2;
.
109,110c
* If Bit16 is read/write, then it's an 8-bit card.
* If Bit16 is set, it's in a 16-bit slot.
.
95,96c
* the 83C584 interface chip, but has 2 real registers, write Gp2
* and if it reads back the same, it's not an 8013EBT.
.
85c
* 8003EBT, 8003S, 8003SH or 8003WT, doesn't matter), in which
.
83c
* address ROM. Can check Icr, Irr and Laar against the ethernet
.
81c
* chip. Only Msr exists out of the 1st eight registers, reads
.
76c
ctlr = ether->ctlr;
.
73c
Dp8390 *ctlr;
.
71c
reset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8])
.
15c
* Configuration code based on that provided by SMC a long time ago.
.
10a
#include "ether8390.h"
.
## diffname pc/ether8003.c 1997/0329
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/pc/ether8003.c /n/emeliedump/1997/0329/sys/src/brazil/pc/ether8003.c
256,257c
if(umbrmalloc(PADDR(ether->mem), ether->size, 0) == 0)
panic("ether8003: 0x%luX unavailable", PADDR(ether->mem));
.
245c
* Finally, init the 8390, set the ethernet address
.
## diffname pc/ether8003.c 1997/0331
## diff -e /n/emeliedump/1997/0329/sys/src/brazil/pc/ether8003.c /n/emeliedump/1997/0331/sys/src/brazil/pc/ether8003.c
256,257c
if(umbrwmalloc(PADDR(ether->mem), ether->size, 0) == 0)
print("ether8003: warning - 0x%luX unavailable", PADDR(ether->mem));
.
211,212c
* At the same time, get the (possible) interface chip
* registers, they'll be used later to check for aliasing.
.
208c
* Look for the interface. Read the LAN address ROM
.
## diffname pc/ether8003.c 1997/1101
## diff -e /n/emeliedump/1997/0331/sys/src/brazil/pc/ether8003.c /n/emeliedump/1997/1101/sys/src/brazil/pc/ether8003.c
166c
ether->mem = (ulong)KADDR(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13));
.
125c
ether->mem = (ulong)KADDR((ic[Msr] & 0x3F)<<13);
.
## diffname pc/ether8003.c 1999/0714
## diff -e /n/emeliedump/1997/1101/sys/src/brazil/pc/ether8003.c /n/emeliedump/1999/0714/sys/src/brazil/pc/ether8003.c
225a
}
.
224c
if(sum != 0xFF){
iofree(ether->port);
.
205a
if(ioalloc(ether->port, 0x20, 0, "wd8003") < 0)
return -1;
.
## diffname pc/ether8003.c 2000/0612
## diff -e /n/emeliedump/1999/0714/sys/src/brazil/pc/ether8003.c /n/emeliedump/2000/0612/sys/src/9/pc/ether8003.c
261c
print("ether8003: warning - 0x%luX unavailable\n",
PADDR(ether->mem));
.
|