| plan 9 kernel history: overview | file list | diff list |
1993/0212/pc/ether8003.c (diff list | history)
| 1992/1222/sys/src/9/pc/ether8003.c:131,137 – 1992/1224/sys/src/9/pc/ether8003.c:131,137 (short | long) | ||
| 1992/1222 | board->pstop = HOWMANY(board->ramstop-board->ramstart, Dp8390BufSz); board->tstart = 0; | |
| 1992/1224 | print("WD8003 I/O addr %lux width %d addr %lux size %d irq %d:", | |
| 1992/1222 | board->io, board->bit16 ? 16: 8, board->ramstart, board->ramstop-board->ramstart, board->irq); for(i = 0; i < sizeof(ctlr->ea); i++) | |
| 1992/1222/sys/src/9/pc/ether8003.c:194,200 – 1992/1224/sys/src/9/pc/ether8003.c:194,200 | ||
| 1992/1222 | dp8390intr, watch, | |
| 1992/1224 | 0x280, /* io */ | |
| 1992/1222 | 3, /* irq */ 0, /* bit16 */ | |
| 1992/1224/sys/src/9/pc/ether8003.c:19,25 – 1993/0212/sys/src/9/pc/ether8003.c:19,25 (short | long) | ||
| 1992/1222 | Ijr = 0x06, /* Initialisation Jumpers */ Gp2 = 0x07, /* General Purpose Data Register */ Lar = 0x08, /* LAN Address Registers */ | |
| 1993/0212 | Id = 0x0E, /* Card ID byte */ | |
| 1992/1222 | Cksum = 0x0F, /* Checksum */ }; | |
| 1992/1224/sys/src/9/pc/ether8003.c:47,53 – 1993/0212/sys/src/9/pc/ether8003.c:47,52 | ||
| 1992/1222 | static int reset(Ctlr *ctlr) { | |
| 1992/1224/sys/src/9/pc/ether8003.c:56,73 – 1993/0212/sys/src/9/pc/ether8003.c:55,72 | ||
| 1992/1222 | * and validate the checksum - the sum of all 8 bytes * should be 0xFF. */ | |
| 1993/0212 | for(ctlr->card.io = 0x200; ctlr->card.io < 0x400; ctlr->card.io += 0x20){ | |
| 1992/1222 | sum = 0; for(i = 0; i < sizeof(ctlr->ea); i++){ | |
| 1993/0212 | ctlr->ea[i] = inb(ctlr->card.io+Lar+i); | |
| 1992/1222 | sum += ctlr->ea[i]; } | |
| 1993/0212 | sum += inb(ctlr->card.io+Id); sum += inb(ctlr->card.io+Cksum); | |
| 1992/1222 | if(sum == 0xFF) break; } | |
| 1993/0212 | if(ctlr->card.io >= 0x400) | |
| 1992/1222 | return -1; /* | |
| 1992/1224/sys/src/9/pc/ether8003.c:75,84 – 1993/0212/sys/src/9/pc/ether8003.c:74,83 | ||
| 1992/1222 | * Be careful to preserve the Msr address bits, * they don't get reloaded from the EEPROM on reset. */ | |
| 1993/0212 | msr = inb(ctlr->card.io+Msr); outb(ctlr->card.io+Msr, Rst|msr); | |
| 1992/1222 | delay(1); | |
| 1993/0212 | outb(ctlr->card.io+Msr, msr); | |
| 1992/1222 | delay(2); /* | |
| 1992/1224/sys/src/9/pc/ether8003.c:90,105 – 1993/0212/sys/src/9/pc/ether8003.c:89,104 | ||
| 1992/1222 | * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which * case the default irq gets used. */ | |
| 1993/0212 | msr = inb(ctlr->card.io+Msr); icr = inb(ctlr->card.io+Icr); laar = inb(ctlr->card.io+Laar); irr = inb(ctlr->card.io+Irr); | |
| 1992/1222 | if(icr != ctlr->ea[1] || irr != ctlr->ea[4] || laar != ctlr->ea[5]) | |
| 1993/0212 | ctlr->card.irq = intrmap[((irr>>5) & 0x3)|(icr & 0x4)]; | |
| 1992/1222 | else { | |
| 1993/0212 | msr = (((ulong)ctlr->card.ramstart)>>13) & 0x3F; | |
| 1992/1222 | icr = laar = 0; | |
| 1993/0212 | ctlr->card.watch = 0; | |
| 1992/1222 | } /* | |
| 1992/1224/sys/src/9/pc/ether8003.c:106,149 – 1993/0212/sys/src/9/pc/ether8003.c:105,141 | ||
| 1992/1222 | * Set up the bus-size, RAM address and RAM size * from the info in the configuration registers. */ | |
| 1993/0212 | ctlr->card.bit16 = icr & 0x1; | |
| 1992/1222 |
| |
| 1993/0212 | ctlr->card.ram = 1; ctlr->card.ramstart = KZERO|((msr & 0x3F)<<13); if(ctlr->card.bit16) ctlr->card.ramstart |= (laar & 0x1F)<<19; | |
| 1992/1222 | else | |
| 1993/0212 | ctlr->card.ramstart |= 0x80000; | |
| 1992/1222 | if(icr & (1<<3)) | |
| 1993/0212 | ctlr->card.ramstop = 32*1024; | |
| 1992/1222 | else | |
| 1993/0212 | ctlr->card.ramstop = 8*1024; if(ctlr->card.bit16) ctlr->card.ramstop <<= 1; ctlr->card.ramstop += ctlr->card.ramstart; | |
| 1992/1222 | /* * Set the DP8390 ring addresses. */ | |
| 1993/0212 | 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; | |
| 1992/1222 | ||
| 1992/1224 |
| |
| 1992/1222 |
| |
| 1993/0212 | outb(ctlr->card.io+Msr, Menb|msr); if(ctlr->card.bit16) outb(ctlr->card.io+Laar, laar|L16en|M16en|ZeroWS16); | |
| 1992/1222 | /* * Finally, init the 8390 and set the | |
| 1992/1224/sys/src/9/pc/ether8003.c:155,171 – 1993/0212/sys/src/9/pc/ether8003.c:147,182 | ||
| 1992/1222 | return 0; } | |
| 1993/0212 | 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; } | |
| 1992/1222 | static void watch(Ctlr *ctlr) { | |
| 1993/0212 | msr = inb(ctlr->card.io+Msr); | |
| 1992/1222 | /* | |
| 1993/0212 | * If the card has reset itself, | |
| 1992/1222 | * start again. */ if((msr & Menb) == 0){ | |
| 1992/1224/sys/src/9/pc/ether8003.c:184,204 – 1993/0212/sys/src/9/pc/ether8003.c:195,222 | ||
| 1992/1222 | * Defaults are set for the dumb 8003E * which can't be autoconfigured. */ | |
| 1993/0212 | Card ether8003 = { "WD8003", /* ident */ | |
| 1992/1222 | ||
| 1992/1224 |
| |
| 1992/1222 |
| |
| 1993/0212 | reset, /* reset */ 0, /* init */ dp8390attach, /* attach */ dp8390mode, /* mode */ | |
| 1992/1222 |
| |
| 1993/0212 | 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 */ | |
| 1992/1222 | }; | |
| 1993/0212/sys/src/9/pc/ether8003.c:9,19 – 1993/0223/sys/src/9/pc/ether8003.c:9,24 (short | long) | ||
| 1992/1222 | #include "ether.h" | |
| 1993/0223 | /* * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). * Configuration code based on that provided by SMC. */ | |
| 1992/1222 | 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 */ | |
| 1993/0223 | Ear = 0x03, /* EEROM Address Register (shared with Bio) */ | |
| 1992/1222 | Irr = 0x04, /* Interrupt Request Register */ Laar = 0x05, /* LA Address Register */ Ijr = 0x06, /* Initialisation Jumpers */ | |
| 1993/0212/sys/src/9/pc/ether8003.c:28,33 – 1993/0223/sys/src/9/pc/ether8003.c:33,49 | ||
| 1992/1222 | Menb = 0x40, /* memory enable */ }; | |
| 1993/0223 | 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 */ }; | |
| 1992/1222 | enum { /* Laar */ ZeroWS16 = (1<<5), /* zero wait states for 16-bit ops */ L16en = (1<<6), /* enable 16-bit LAN operation */ | |
| 1993/0212/sys/src/9/pc/ether8003.c:43,59 – 1993/0223/sys/src/9/pc/ether8003.c:59,79 | ||
| 1992/1222 | /* * Get configuration parameters, enable memory. | |
| 1993/0223 | * There are opportunities here for buckets of code. * We'll try to resist. | |
| 1992/1222 | */ static int reset(Ctlr *ctlr) { int i; | |
| 1993/0223 | uchar ic[8], sum; | |
| 1992/1222 | /* * Look for the interface. We read the LAN address ROM * and validate the checksum - the sum of all 8 bytes * should be 0xFF. | |
| 1993/0223 | * While we're at it, get the (possible) interface chip * registers, we'll use them to check for aliasing later. | |
| 1992/1222 | */ | |
| 1993/0212 | for(ctlr->card.io = 0x200; ctlr->card.io < 0x400; ctlr->card.io += 0x20){ | |
| 1992/1222 | sum = 0; | |
| 1993/0212/sys/src/9/pc/ether8003.c:60,65 – 1993/0223/sys/src/9/pc/ether8003.c:80,86 | ||
| 1992/1222 | for(i = 0; i < sizeof(ctlr->ea); i++){ | |
| 1993/0212 | ctlr->ea[i] = inb(ctlr->card.io+Lar+i); | |
| 1992/1222 | sum += ctlr->ea[i]; | |
| 1993/0223 | ic[i] = inb(ctlr->card.io+i); | |
| 1992/1222 | } | |
| 1993/0212 | sum += inb(ctlr->card.io+Id); sum += inb(ctlr->card.io+Cksum); | |
| 1993/0212/sys/src/9/pc/ether8003.c:70,86 – 1993/0223/sys/src/9/pc/ether8003.c:91,96 | ||
| 1992/1222 | return -1; /* | |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212/sys/src/9/pc/ether8003.c:89,120 – 1993/0223/sys/src/9/pc/ether8003.c:99,151 | ||
| 1992/1222 | * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which * case the default irq gets used. */ | |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0223 | if(memcmp(&ctlr->ea[1], &ic[1], 5) == 0){ memset(ic, 0, sizeof(ic)); ic[Msr] = (((ulong)ctlr->card.ramstart)>>13) & 0x3F; | |
| 1993/0212 | ctlr->card.watch = 0; | |
| 1992/1222 | } | |
| 1993/0223 | 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)]; | |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1993/0223 | /* * 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]); | |
| 1992/1222 | ||
| 1993/0212 |
| |
| 1993/0223 | 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); | |
| 1993/0212 | if(ctlr->card.bit16) | |
| 1993/0223 | ctlr->card.ramstart |= (ic[Laar] & 0x1F)<<19; | |
| 1992/1222 | else | |
| 1993/0212 | ctlr->card.ramstart |= 0x80000; | |
| 1992/1222 |
| |
| 1993/0223 | if(ic[Icr] & (1<<3)) | |
| 1993/0212 | ctlr->card.ramstop = 32*1024; | |
| 1992/1222 | else | |
| 1993/0212 | ctlr->card.ramstop = 8*1024; | |
| 1993/0212/sys/src/9/pc/ether8003.c:133,141 – 1993/0223/sys/src/9/pc/ether8003.c:164,172 | ||
| 1992/1222 | /* * Enable interface RAM, set interface width. */ | |
| 1993/0212 |
| |
| 1993/0223 | outb(ctlr->card.io+Msr, ic[Msr]|Menb); | |
| 1993/0212 | if(ctlr->card.bit16) | |
| 1993/0223 | outb(ctlr->card.io+Laar, ic[Laar]|L16en|M16en|ZeroWS16); | |
| 1992/1222 | /* * Finally, init the 8390 and set the | |
| 1993/0223/sys/src/9/pc/ether8003.c:134,141 – 1993/0302/sys/src/9/pc/ether8003.c:134,140 (short | long) | ||
| 1993/0223 | } outb(ctlr->card.io+Icr, ic[Icr]); | |
| 1992/1222 | ||
| 1993/0223 |
| |
| 1993/0302 | if(ctlr->card.bit16 && (inb(ctlr->card.io+Icr) & Bit16) == 0) | |
| 1993/0223 | ctlr->card.bit16 = 0; } | |
| 1993/0302/sys/src/9/pc/ether8003.c:57,74 – 1993/0915/sys/src/9/pc/ether8003.c:57,146 (short | long) | ||
| 1992/1222 | 9, 3, 5, 7, 10, 11, 15, 4, }; | |
| 1993/0915 | 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); } | |
| 1992/1222 | /* * Get configuration parameters, enable memory. | |
| 1993/0223 | * There are opportunities here for buckets of code. * We'll try to resist. | |
| 1992/1222 | */ | |
| 1993/0915 | int wd8003reset(Ctlr *ctlr) | |
| 1992/1222 | { int i; | |
| 1993/0223 | uchar ic[8], sum; | |
| 1993/0915 | ulong wd8003; | |
| 1992/1222 | /* | |
| 1993/0915 | * 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; /* | |
| 1992/1222 | * Look for the interface. We read the LAN address ROM * and validate the checksum - the sum of all 8 bytes * should be 0xFF. | |
| 1993/0302/sys/src/9/pc/ether8003.c:75,93 – 1993/0915/sys/src/9/pc/ether8003.c:147,161 | ||
| 1993/0223 | * While we're at it, get the (possible) interface chip * registers, we'll use them to check for aliasing later. | |
| 1992/1222 | */ | |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0223 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0915 | 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); | |
| 1992/1222 | } | |
| 1993/0212 |
| |
| 1993/0915 | sum += inb(wd8003+Id); sum += inb(wd8003+Cksum); if(sum != 0xFF) | |
| 1992/1222 | return -1; /* | |
| 1993/0302/sys/src/9/pc/ether8003.c:101,107 – 1993/0915/sys/src/9/pc/ether8003.c:169,175 | ||
| 1992/1222 | */ | |
| 1993/0223 | if(memcmp(&ctlr->ea[1], &ic[1], 5) == 0){ memset(ic, 0, sizeof(ic)); | |
| 1993/0915 | ic[Msr] = (((ulong)ctlr->card.mem)>>13) & 0x3F; | |
| 1993/0212 | ctlr->card.watch = 0; | |
| 1992/1222 | } | |
| 1993/0223 | else{ | |
| 1993/0302/sys/src/9/pc/ether8003.c:110,122 – 1993/0915/sys/src/9/pc/ether8003.c:178,189 | ||
| 1993/0223 | * the 83C584 interface chip, but has 2 real registers, write Gp2 and if * it reads back the same, it's not an 8013EBT. */ | |
| 1993/0915 | outb(wd8003+Gp2, 0xAA); inb(wd8003+Msr); /* wiggle bus */ if(inb(wd8003+Gp2) != 0xAA){ | |
| 1993/0223 | memset(ic, 0, sizeof(ic)); | |
| 1993/0915 | ic[Msr] = (((ulong)ctlr->card.mem)>>13) & 0x3F; | |
| 1993/0223 | ctlr->card.watch = 0; | |
| 1993/0302/sys/src/9/pc/ether8003.c:126,171 – 1993/0915/sys/src/9/pc/ether8003.c:193,235 | ||
| 1993/0223 | * If Bit16 is read/write, then we have an 8-bit card. * If Bit16 is set, we're in a 16-bit slot. */ | |
| 1993/0915 | outb(wd8003+Icr, ic[Icr]^Bit16); inb(wd8003+Msr); /* wiggle bus */ if((inb(wd8003+Icr) & Bit16) == (ic[Icr] & Bit16)){ | |
| 1993/0223 | ctlr->card.bit16 = 1; ic[Icr] &= ~Bit16; } | |
| 1993/0915 | outb(wd8003+Icr, ic[Icr]); | |
| 1992/1222 | ||
| 1993/0302 |
| |
| 1993/0915 | if(ctlr->card.bit16 && (inb(wd8003+Icr) & Bit16) == 0) | |
| 1993/0223 | ctlr->card.bit16 = 0; } | |
| 1993/0915 | ctlr->card.mem = KZERO|((ic[Msr] & 0x3F)<<13); | |
| 1993/0212 | if(ctlr->card.bit16) | |
| 1993/0223 |
| |
| 1993/0915 | ctlr->card.mem |= (ic[Laar] & 0x1F)<<19; | |
| 1992/1222 | else | |
| 1993/0212 |
| |
| 1993/0915 | ctlr->card.mem |= 0x80000; | |
| 1992/1222 | ||
| 1993/0223 | if(ic[Icr] & (1<<3)) | |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1993/0915 | ctlr->card.size = 32*1024; | |
| 1993/0212 | if(ctlr->card.bit16) | |
| 1993/0915 | ctlr->card.size <<= 1; | |
| 1992/1222 | /* * Set the DP8390 ring addresses. */ | |
| 1993/0212 |
| |
| 1993/0915 | ctlr->card.dp8390 = wd8003+0x10; | |
| 1993/0212 | ctlr->card.tstart = 0; | |
| 1993/0915 | ctlr->card.pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); ctlr->card.pstop = HOWMANY(ctlr->card.size, Dp8390BufSz); | |
| 1992/1222 | /* * Enable interface RAM, set interface width. */ | |
| 1993/0223 |
| |
| 1993/0915 | outb(wd8003+Msr, ic[Msr]|Menb); | |
| 1993/0212 | if(ctlr->card.bit16) | |
| 1993/0223 |
| |
| 1993/0915 | outb(wd8003+Laar, ic[Laar]|L16en|M16en|ZeroWS16); | |
| 1992/1222 | /* * Finally, init the 8390 and set the | |
| 1993/0302/sys/src/9/pc/ether8003.c:177,252 – 1993/0915/sys/src/9/pc/ether8003.c:241,248 | ||
| 1992/1222 | return 0; } | |
| 1993/0212 |
| |
| 1993/0915 | void ether8003link(void) | |
| 1993/0212 | { | |
| 1993/0915 | addethercard("WD8003", wd8003reset); | |
| 1993/0212 | } | |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0212 |
| |
| 1992/1222 | ||
| 1993/0212 |
| |
| 1992/1222 | ||
| 1993/0212 |
| |
| 1992/1222 |
| |
| 1993/0915/sys/src/9/pc/ether8003.c:3,13 – 1993/1116/sys/src/9/pc/ether8003.c:3,13 (short | long) | ||
| 1992/1222 | #include "mem.h" #include "dat.h" #include "fns.h" | |
| 1993/1116 | #include "../port/error.h" #include "../port/netif.h" | |
| 1992/1222 |
| |
| 1993/1116 | #include "etherif.h" | |
| 1992/1222 | ||
| 1993/0223 | /* * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). | |
| 1993/0915/sys/src/9/pc/ether8003.c:244,248 – 1993/1116/sys/src/9/pc/ether8003.c:244,248 | ||
| 1993/0915 | void ether8003link(void) | |
| 1993/0212 | { | |
| 1993/0915 |
| |
| 1993/1116 | addethercard("WD8003", reset); | |
| 1993/0212 | } | |
| 1993/1116/sys/src/9/pc/ether8003.c:57,117 – 1993/1118/sys/src/9/pc/ether8003.c:57,74 (short | long) | ||
| 1992/1222 | 9, 3, 5, 7, 10, 11, 15, 4, }; | |
| 1993/0915 |
| |
| 1992/1222 | /* * Get configuration parameters, enable memory. | |
| 1993/0223 | * There are opportunities here for buckets of code. * We'll try to resist. | |
| 1992/1222 | */ | |
| 1993/0915 |
| |
| 1993/1118 | static int reset(Ether *ether) | |
| 1992/1222 | { int i; | |
| 1993/0223 | uchar ic[8], sum; | |
| 1993/0915 |
| |
| 1993/1118 | ulong port; Dp8390 *dp8390; | |
| 1992/1222 | /* | |
| 1993/0915 | * Set up the software configuration. | |
| 1993/1116/sys/src/9/pc/ether8003.c:119,145 – 1993/1118/sys/src/9/pc/ether8003.c:76,90 | ||
| 1993/0915 | * Defaults are set for the dumb 8003E which can't be * autoconfigured. */ | |
| 1993/1118 | 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; | |
| 1993/0915 |
| |
| 1992/1222 | * Look for the interface. We read the LAN address ROM * and validate the checksum - the sum of all 8 bytes | |
| 1993/1116/sys/src/9/pc/ether8003.c:147,163 – 1993/1118/sys/src/9/pc/ether8003.c:92,113 | ||
| 1993/0223 | * While we're at it, get the (possible) interface chip * registers, we'll use them to check for aliasing later. | |
| 1992/1222 | */ | |
| 1993/1118 | port = ether->port; | |
| 1993/0915 | sum = 0; | |
| 1993/1118 | for(i = 0; i < sizeof(ether->ea); i++){ ether->ea[i] = inb(port+Lar+i); sum += ether->ea[i]; ic[i] = inb(port+i); | |
| 1992/1222 | } | |
| 1993/0915 |
| |
| 1993/1118 | sum += inb(port+Id); sum += inb(port+Cksum); | |
| 1993/0915 | if(sum != 0xFF) | |
| 1992/1222 | return -1; | |
| 1993/1118 | ether->private = malloc(sizeof(Dp8390)); dp8390 = ether->private; dp8390->ram = 1; | |
| 1992/1222 | /* * Check for old, dumb 8003E, which doesn't have an interface * chip. Only the msr exists out of the 1st eight registers, reads | |
| 1993/1116/sys/src/9/pc/ether8003.c:167,176 – 1993/1118/sys/src/9/pc/ether8003.c:117,125 | ||
| 1992/1222 | * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which * case the default irq gets used. */ | |
| 1993/0223 |
| |
| 1993/1118 | if(memcmp(ðer->ea[1], &ic[1], 5) == 0){ | |
| 1993/0223 | memset(ic, 0, sizeof(ic)); | |
| 1993/0915 |
| |
| 1993/0212 |
| |
| 1993/1118 | ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; | |
| 1992/1222 | } | |
| 1993/0223 | else{ /* | |
| 1993/1116/sys/src/9/pc/ether8003.c:178,192 – 1993/1118/sys/src/9/pc/ether8003.c:127,140 | ||
| 1993/0223 | * the 83C584 interface chip, but has 2 real registers, write Gp2 and if * it reads back the same, it's not an 8013EBT. */ | |
| 1993/0915 |
| |
| 1993/1118 | outb(port+Gp2, 0xAA); inb(port+Msr); /* wiggle bus */ if(inb(port+Gp2) != 0xAA){ | |
| 1993/0223 | memset(ic, 0, sizeof(ic)); | |
| 1993/0915 |
| |
| 1993/0223 |
| |
| 1993/1118 | ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; | |
| 1993/0223 | } else | |
| 1993/1118 | ether->irq = intrmap[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; | |
| 1992/1222 | ||
| 1993/0223 | /* * Check if 16-bit card. | |
| 1993/1116/sys/src/9/pc/ether8003.c:193,242 – 1993/1118/sys/src/9/pc/ether8003.c:141,190 | ||
| 1993/0223 | * If Bit16 is read/write, then we have an 8-bit card. * If Bit16 is set, we're in a 16-bit slot. */ | |
| 1993/0915 |
| |
| 1993/0223 |
| |
| 1993/1118 | outb(port+Icr, ic[Icr]^Bit16); inb(port+Msr); /* wiggle bus */ if((inb(port+Icr) & Bit16) == (ic[Icr] & Bit16)){ dp8390->bit16 = 1; | |
| 1993/0223 | ic[Icr] &= ~Bit16; } | |
| 1993/0915 |
| |
| 1993/1118 | outb(port+Icr, ic[Icr]); | |
| 1992/1222 | ||
| 1993/0915 |
| |
| 1993/0223 |
| |
| 1993/1118 | if(dp8390->bit16 && (inb(port+Icr) & Bit16) == 0) dp8390->bit16 = 0; | |
| 1993/0223 | } | |
| 1993/0915 |
| |
| 1993/0212 |
| |
| 1993/0915 |
| |
| 1993/1118 | ether->mem = KZERO|((ic[Msr] & 0x3F)<<13); if(dp8390->bit16) ether->mem |= (ic[Laar] & 0x1F)<<19; | |
| 1992/1222 | else | |
| 1993/0915 |
| |
| 1993/1118 | ether->mem |= 0x80000; | |
| 1992/1222 | ||
| 1993/0223 | if(ic[Icr] & (1<<3)) | |
| 1993/0915 |
| |
| 1993/0212 |
| |
| 1993/0915 |
| |
| 1993/1118 | ether->size = 32*1024; if(dp8390->bit16) ether->size <<= 1; | |
| 1992/1222 | /* * Set the DP8390 ring addresses. */ | |
| 1993/0915 |
| |
| 1993/0212 |
| |
| 1993/0915 |
| |
| 1993/1118 | dp8390->dp8390 = port+0x10; dp8390->tstart = 0; dp8390->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); dp8390->pstop = HOWMANY(ether->size, Dp8390BufSz); | |
| 1992/1222 | /* * Enable interface RAM, set interface width. */ | |
| 1993/0915 |
| |
| 1993/0212 |
| |
| 1993/0915 |
| |
| 1993/1118 | outb(port+Msr, ic[Msr]|Menb); if(dp8390->bit16) outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16); | |
| 1992/1222 | /* * Finally, init the 8390 and set the * ethernet address. */ | |
| 1993/1118 | dp8390reset(ether); dp8390setea(ether); | |
| 1992/1222 | return 0; } | |
| 1993/1118/sys/src/9/pc/ether8003.c:57,62 – 1993/1119/sys/src/9/pc/ether8003.c:57,66 (short | long) | ||
| 1992/1222 | 9, 3, 5, 7, 10, 11, 15, 4, }; | |
| 1993/1119 | static uchar debugea[6] = { 0x00, 0x60, 0x8c, 0x00, 0x1a, 0x42, }; | |
| 1992/1222 | /* * Get configuration parameters, enable memory. | |
| 1993/0223 | * There are opportunities here for buckets of code. | |
| 1993/1118/sys/src/9/pc/ether8003.c:184,189 – 1993/1119/sys/src/9/pc/ether8003.c:188,194 | ||
| 1992/1222 | * ethernet address. */ | |
| 1993/1118 | dp8390reset(ether); | |
| 1993/1119 | memmove(ether->ea, debugea, 6); | |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | return 0; | |
| 1993/1119/sys/src/9/pc/ether8003.c:57,66 – 1993/1120/sys/src/9/pc/ether8003.c:57,62 (short | long) | ||
| 1992/1222 | 9, 3, 5, 7, 10, 11, 15, 4, }; | |
| 1993/1119 |
| |
| 1992/1222 | /* * Get configuration parameters, enable memory. | |
| 1993/0223 | * There are opportunities here for buckets of code. | |
| 1993/1119/sys/src/9/pc/ether8003.c:188,194 – 1993/1120/sys/src/9/pc/ether8003.c:184,189 | ||
| 1992/1222 | * ethernet address. */ | |
| 1993/1118 | dp8390reset(ether); | |
| 1993/1119 |
| |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | return 0; | |
| 1993/1120/sys/src/9/pc/ether8003.c:66,72 – 1994/0128/sys/src/9/pc/ether8003.c:66,72 (short | long) | ||
| 1993/1118 | reset(Ether *ether) | |
| 1992/1222 | { int i; | |
| 1993/0223 |
| |
| 1994/0128 | uchar ea[Eaddrlen], ic[8], sum; | |
| 1993/1118 | ulong port; Dp8390 *dp8390; | |
| 1992/1222 | ||
| 1993/1120/sys/src/9/pc/ether8003.c:95,101 – 1994/0128/sys/src/9/pc/ether8003.c:95,101 | ||
| 1993/1118 | port = ether->port; | |
| 1993/0915 | sum = 0; | |
| 1993/1118 | for(i = 0; i < sizeof(ether->ea); i++){ | |
| 1994/0128 | ea[i] = inb(port+Lar+i); | |
| 1993/1118 | sum += ether->ea[i]; ic[i] = inb(port+i); | |
| 1992/1222 | } | |
| 1993/1120/sys/src/9/pc/ether8003.c:184,189 – 1994/0128/sys/src/9/pc/ether8003.c:184,193 | ||
| 1992/1222 | * ethernet address. */ | |
| 1993/1118 | dp8390reset(ether); | |
| 1994/0128 | 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]; } | |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | return 0; | |
| 1994/0128/sys/src/9/pc/ether8003.c:96,102 – 1994/0202/sys/src/9/pc/ether8003.c:96,102 (short | long) | ||
| 1993/0915 | sum = 0; | |
| 1993/1118 | for(i = 0; i < sizeof(ether->ea); i++){ | |
| 1994/0128 | ea[i] = inb(port+Lar+i); | |
| 1993/1118 |
| |
| 1994/0202 | sum += ea[i]; | |
| 1993/1118 | ic[i] = inb(port+i); | |
| 1992/1222 | } | |
| 1993/1118 | sum += inb(port+Id); | |
| 1994/0202/sys/src/9/pc/ether8003.c:94,100 – 1994/0810/sys/src/9/pc/ether8003.c:94,100 (short | long) | ||
| 1992/1222 | */ | |
| 1993/1118 | port = ether->port; | |
| 1993/0915 | sum = 0; | |
| 1993/1118 |
| |
| 1994/0810 | for(i = 0; i < sizeof(ea); i++){ | |
| 1994/0128 | ea[i] = inb(port+Lar+i); | |
| 1994/0202 | sum += ea[i]; | |
| 1993/1118 | ic[i] = inb(port+i); | |
| 1994/0810/sys/src/9/pc/ether8003.c:190,195 – 1994/1210/sys/src/9/pc/ether8003.c:190,198 (short | long) | ||
| 1994/0128 | } | |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | ||
| 1994/1210 | if(getisa(ether->mem, ether->size, 0) == 0) panic("ether8003: %lux reused", ether->mem); | |
| 1992/1222 | return 0; } | |
| 1994/1210/sys/src/9/pc/ether8003.c:191,197 – 1995/0126/sys/src/9/pc/ether8003.c:191,197 (short | long) | ||
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | ||
| 1994/1210 | if(getisa(ether->mem, ether->size, 0) == 0) | |
| 1995/0126 | panic("ether8003: 0x%lux reused", ether->mem); | |
| 1994/1210 | ||
| 1992/1222 | return 0; } | |
| 1995/0126/sys/src/9/pc/ether8003.c:104,111 – 1995/0721/sys/src/9/pc/ether8003.c:104,111 (short | long) | ||
| 1993/0915 | if(sum != 0xFF) | |
| 1992/1222 | return -1; | |
| 1993/1118 |
| |
| 1995/0721 | ether->ctlr = malloc(sizeof(Dp8390)); dp8390 = ether->ctlr; | |
| 1993/1118 | dp8390->ram = 1; | |
| 1992/1222 | /* | |
| 1995/0721/sys/src/9/pc/ether8003.c:11,16 – 1995/0829/sys/src/9/pc/ether8003.c:11,17 (short | long) | ||
| 1992/1222 | ||
| 1993/0223 | /* * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). | |
| 1995/0829 | * Also handles 8216 cards (Elite Ultra). | |
| 1993/0223 | * Configuration code based on that provided by SMC. */ | |
| 1992/1222 | enum { /* 83C584 Bus Interface Controller */ | |
| 1995/0721/sys/src/9/pc/ether8003.c:20,25 – 1995/0829/sys/src/9/pc/ether8003.c:21,27 | ||
| 1992/1222 | Bio = 0x03, /* BIOS ROM Address Register */ | |
| 1993/0223 | Ear = 0x03, /* EEROM Address Register (shared with Bio) */ | |
| 1992/1222 | Irr = 0x04, /* Interrupt Request Register */ | |
| 1995/0829 | Hcr = 0x04, /* 8216 hardware control */ | |
| 1992/1222 | Laar = 0x05, /* LA Address Register */ Ijr = 0x06, /* Initialisation Jumpers */ Gp2 = 0x07, /* General Purpose Data Register */ | |
| 1995/0721/sys/src/9/pc/ether8003.c:45,113 – 1995/0829/sys/src/9/pc/ether8003.c:47,81 | ||
| 1993/0223 | }; | |
| 1992/1222 | enum { /* Laar */ | |
| 1995/0829 | ZeroWS16 = 0x20, /* zero wait states for 16-bit ops */ L16en = 0x40, /* enable 16-bit LAN operation */ M16en = 0x80, /* enable 16-bit memory access */ | |
| 1992/1222 | }; | |
| 1995/0829 | enum { /* Ijr */ Ienable = 0x01, /* 8216 interrupt enable */ }; | |
| 1992/1222 | /* * Mapping from configuration bits to interrupt level. */ | |
| 1995/0829 | static int irq8003[8] = { | |
| 1992/1222 | 9, 3, 5, 7, 10, 11, 15, 4, }; | |
| 1993/0223 |
| |
| 1992/1222 |
| |
| 1993/1118 |
| |
| 1995/0829 | static int irq8216[8] = { 0, 9, 3, 5, 7, 10, 11, 15, }; static void reset8003(Ether *ether, uchar ea[Eaddrlen], uchar ic[8]) | |
| 1992/1222 | { | |
| 1994/0128 |
| |
| 1993/1118 |
| |
| 1995/0829 | ulong port; | |
| 1992/1222 |
| |
| 1993/0915 |
| |
| 1993/1118 |
| |
| 1993/0915 |
| |
| 1992/1222 |
| |
| 1993/0223 |
| |
| 1992/1222 |
| |
| 1995/0829 | dp8390 = ether->ctlr; | |
| 1993/1118 | port = ether->port; | |
| 1993/0915 |
| |
| 1994/0810 |
| |
| 1994/0128 |
| |
| 1994/0202 |
| |
| 1993/1118 |
| |
| 1992/1222 |
| |
| 1993/1118 |
| |
| 1993/0915 |
| |
| 1992/1222 |
| |
| 1995/0721 |
| |
| 1993/1118 |
| |
| 1992/1222 | /* * Check for old, dumb 8003E, which doesn't have an interface * chip. Only the msr exists out of the 1st eight registers, reads | |
| 1995/0721/sys/src/9/pc/ether8003.c:117,123 – 1995/0829/sys/src/9/pc/ether8003.c:85,91 | ||
| 1992/1222 | * 8003EBT, 8003S, 8003SH or 8003WT, we don't care), in which * case the default irq gets used. */ | |
| 1993/1118 |
| |
| 1995/0829 | if(memcmp(&ea[1], &ic[1], 5) == 0){ | |
| 1993/0223 | memset(ic, 0, sizeof(ic)); | |
| 1993/1118 | ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; | |
| 1992/1222 | } | |
| 1995/0721/sys/src/9/pc/ether8003.c:134,140 – 1995/0829/sys/src/9/pc/ether8003.c:102,108 | ||
| 1993/1118 | ic[Msr] = (((ulong)ether->mem)>>13) & 0x3F; | |
| 1993/0223 | } else | |
| 1993/1118 |
| |
| 1995/0829 | ether->irq = irq8003[((ic[Irr]>>5) & 0x3)|(ic[Icr] & 0x4)]; | |
| 1992/1222 | ||
| 1993/0223 | /* * Check if 16-bit card. | |
| 1995/0721/sys/src/9/pc/ether8003.c:165,170 – 1995/0829/sys/src/9/pc/ether8003.c:133,239 | ||
| 1993/1118 | ether->size <<= 1; | |
| 1992/1222 | /* | |
| 1995/0829 | * 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); /* | |
| 1992/1222 | * Set the DP8390 ring addresses. */ | |
| 1993/1118 | dp8390->dp8390 = port+0x10; | |
| 1995/0721/sys/src/9/pc/ether8003.c:171,183 – 1995/0829/sys/src/9/pc/ether8003.c:240,245 | ||
| 1993/1118 | dp8390->tstart = 0; dp8390->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); dp8390->pstop = HOWMANY(ether->size, Dp8390BufSz); | |
| 1992/1222 |
| |
| 1993/1118 |
| |
| 1992/1222 | /* * Finally, init the 8390 and set the | |
| 1995/0829/sys/src/9/pc/ether8003.c:8,18 – 1997/0327/sys/src/9/pc/ether8003.c:8,19 (short | long) | ||
| 1993/1116 | #include "../port/netif.h" | |
| 1992/1222 | ||
| 1993/1116 | #include "etherif.h" | |
| 1997/0327 | #include "ether8390.h" | |
| 1992/1222 | ||
| 1993/0223 | /* * Western Digital/Standard Microsystems Corporation cards (WD80[01]3). | |
| 1995/0829 | * Also handles 8216 cards (Elite Ultra). | |
| 1993/0223 |
| |
| 1997/0327 | * Configuration code based on that provided by SMC a long time ago. | |
| 1993/0223 | */ | |
| 1992/1222 | enum { /* 83C584 Bus Interface Controller */ Msr = 0x00, /* Memory Select Register */ | |
| 1995/0829/sys/src/9/pc/ether8003.c:68,88 – 1997/0327/sys/src/9/pc/ether8003.c:69,89 | ||
| 1995/0829 | }; static void | |
| 1997/0327 | reset8003(Ether* ether, uchar ea[Eaddrlen], uchar ic[8]) | |
| 1992/1222 | { | |
| 1993/1118 |
| |
| 1997/0327 | Dp8390 *ctlr; | |
| 1995/0829 | ulong port; | |
| 1992/1222 | ||
| 1995/0829 |
| |
| 1997/0327 | ctlr = ether->ctlr; | |
| 1993/1118 | port = ether->port; | |
| 1992/1222 | /* * Check for old, dumb 8003E, which doesn't have an interface | |
| 1997/0327 | * chip. Only Msr exists out of the 1st eight registers, reads | |
| 1992/1222 | * of the others just alias the 2nd eight registers, the LAN | |
| 1997/0327 | * address ROM. Can check Icr, Irr and Laar against the ethernet | |
| 1992/1222 | * address read above and if they match it's an 8003E (or an | |
| 1997/0327 | * 8003EBT, 8003S, 8003SH or 8003WT, doesn't matter), in which | |
| 1992/1222 | * case the default irq gets used. */ | |
| 1995/0829 | if(memcmp(&ea[1], &ic[1], 5) == 0){ | |
| 1995/0829/sys/src/9/pc/ether8003.c:92,99 – 1997/0327/sys/src/9/pc/ether8003.c:93,100 | ||
| 1993/0223 | else{ /* * As a final sanity check for the 8013EBT, which doesn't have | |
| 1997/0327 | * the 83C584 interface chip, but has 2 real registers, write Gp2 * and if it reads back the same, it's not an 8013EBT. | |
| 1993/0223 | */ | |
| 1993/1118 | outb(port+Gp2, 0xAA); inb(port+Msr); /* wiggle bus */ | |
| 1995/0829/sys/src/9/pc/ether8003.c:106,128 – 1997/0327/sys/src/9/pc/ether8003.c:107,129 | ||
| 1992/1222 | ||
| 1993/0223 | /* * Check if 16-bit card. | |
| 1997/0327 | * If Bit16 is read/write, then it's an 8-bit card. * If Bit16 is set, it's in a 16-bit slot. | |
| 1993/0223 | */ | |
| 1993/1118 | outb(port+Icr, ic[Icr]^Bit16); inb(port+Msr); /* wiggle bus */ if((inb(port+Icr) & Bit16) == (ic[Icr] & Bit16)){ | |
| 1997/0327 | ctlr->width = 2; | |
| 1993/0223 | ic[Icr] &= ~Bit16; } | |
| 1993/1118 | outb(port+Icr, ic[Icr]); | |
| 1992/1222 | ||
| 1993/1118 |
| |
| 1997/0327 | if(ctlr->width == 2 && (inb(port+Icr) & Bit16) == 0) ctlr->width = 1; | |
| 1993/0223 | } | |
| 1993/1118 | ether->mem = KZERO|((ic[Msr] & 0x3F)<<13); | |
| 1997/0327 | if(ctlr->width == 2) | |
| 1993/1118 | ether->mem |= (ic[Laar] & 0x1F)<<19; | |
| 1992/1222 | else | |
| 1993/1118 | ether->mem |= 0x80000; | |
| 1995/0829/sys/src/9/pc/ether8003.c:129,135 – 1997/0327/sys/src/9/pc/ether8003.c:130,136 | ||
| 1992/1222 | ||
| 1993/0223 | if(ic[Icr] & (1<<3)) | |
| 1993/1118 | ether->size = 32*1024; | |
| 1997/0327 | if(ctlr->width == 2) | |
| 1993/1118 | ether->size <<= 1; | |
| 1992/1222 | /* | |
| 1995/0829/sys/src/9/pc/ether8003.c:136,156 – 1997/0327/sys/src/9/pc/ether8003.c:137,158 | ||
| 1995/0829 | * Enable interface RAM, set interface width. */ outb(port+Msr, ic[Msr]|Menb); | |
| 1997/0327 | if(ctlr->width == 2) | |
| 1995/0829 | outb(port+Laar, ic[Laar]|L16en|M16en|ZeroWS16); } static void | |
| 1997/0327 | reset8216(Ether* ether, uchar[8]) | |
| 1995/0829 | { uchar hcr, irq, x; ulong addr, port; | |
| 1997/0327 | Dp8390 *ctlr; | |
| 1995/0829 |
| |
| 1997/0327 | ctlr = ether->ctlr; | |
| 1995/0829 | port = ether->port; | |
| 1997/0327 | ctlr->width = 2; | |
| 1995/0829 | /* * Switch to the alternate register set and retrieve the memory * and irq information. | |
| 1995/0829/sys/src/9/pc/ether8003.c:166,173 – 1997/0327/sys/src/9/pc/ether8003.c:168,174 | ||
| 1995/0829 | ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)]; /* | |
| 1997/0327 | * Enable interface RAM, set interface width, and enable interrupts. | |
| 1995/0829 | */ x = inb(port+Msr) & ~Rst; outb(port+Msr, Menb|x); | |
| 1995/0829/sys/src/9/pc/ether8003.c:178,193 – 1997/0327/sys/src/9/pc/ether8003.c:179,193 | ||
| 1995/0829 | /* * Get configuration parameters, enable memory. | |
| 1997/0327 | * There are opportunities here for buckets of code, try to resist. | |
| 1995/0829 | */ static int | |
| 1997/0327 | reset(Ether* ether) | |
| 1995/0829 | { int i; | |
| 1997/0327 | uchar ea[Eaddrlen], ic[8], id, nullea[Eaddrlen], sum; | |
| 1995/0829 | ulong port; | |
| 1997/0327 | Dp8390 *ctlr; | |
| 1995/0829 | /* * Set up the software configuration. | |
| 1995/0829/sys/src/9/pc/ether8003.c:225,232 – 1997/0327/sys/src/9/pc/ether8003.c:225,232 | ||
| 1995/0829 | return -1; ether->ctlr = malloc(sizeof(Dp8390)); | |
| 1997/0327 | ctlr = ether->ctlr; ctlr->ram = 1; | |
| 1995/0829 | if((id & 0xFE) == 0x2A) reset8216(ether, ic); | |
| 1995/0829/sys/src/9/pc/ether8003.c:236,258 – 1997/0327/sys/src/9/pc/ether8003.c:236,259 | ||
| 1995/0829 | /* | |
| 1992/1222 | * Set the DP8390 ring addresses. */ | |
| 1993/1118 |
| |
| 1997/0327 | ctlr->port = port+0x10; ctlr->tstart = 0; ctlr->pstart = HOWMANY(sizeof(Etherpkt), Dp8390BufSz); ctlr->pstop = HOWMANY(ether->size, Dp8390BufSz); | |
| 1992/1222 | /* | |
| 1997/0327 | * Finally, init the 8390,set the ethernet address * and claim the memory used. | |
| 1992/1222 | */ | |
| 1993/1118 | dp8390reset(ether); | |
| 1994/0128 |
| |
| 1997/0327 | memset(nullea, 0, Eaddrlen); if(memcmp(nullea, ether->ea, Eaddrlen) == 0){ | |
| 1994/0128 | for(i = 0; i < sizeof(ether->ea); i++) ether->ea[i] = ea[i]; } | |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | ||
| 1994/1210 |
| |
| 1997/0327 | if(umbmalloc(ether->mem, ether->size, 0) == 0) | |
| 1995/0126 | panic("ether8003: 0x%lux reused", ether->mem); | |
| 1994/1210 | ||
| 1992/1222 | return 0; | |
| 1997/0327/sys/src/9/pc/ether8003.c:242,248 – 1997/0329/sys/src/9/pc/ether8003.c:242,248 (short | long) | ||
| 1997/0327 | ctlr->pstop = HOWMANY(ether->size, Dp8390BufSz); | |
| 1992/1222 | /* | |
| 1997/0327 |
| |
| 1997/0329 | * Finally, init the 8390, set the ethernet address | |
| 1997/0327 | * and claim the memory used. | |
| 1992/1222 | */ | |
| 1993/1118 | dp8390reset(ether); | |
| 1997/0327/sys/src/9/pc/ether8003.c:253,260 – 1997/0329/sys/src/9/pc/ether8003.c:253,260 | ||
| 1994/0128 | } | |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | ||
| 1997/0327 |
| |
| 1995/0126 |
| |
| 1997/0329 | if(umbrmalloc(PADDR(ether->mem), ether->size, 0) == 0) panic("ether8003: 0x%luX unavailable", PADDR(ether->mem)); | |
| 1994/1210 | ||
| 1992/1222 | return 0; } | |
| 1997/0329/sys/src/9/pc/ether8003.c:205,215 – 1997/0331/sys/src/9/pc/ether8003.c:205,215 (short | long) | ||
| 1995/0829 | ether->size = 8*1024; /* | |
| 1997/0331 | * Look for the interface. Read the LAN address ROM | |
| 1995/0829 | * and validate the checksum - the sum of all 8 bytes * should be 0xFF. | |
| 1997/0331 | * At the same time, get the (possible) interface chip * registers, they'll be used later to check for aliasing. | |
| 1995/0829 | */ port = ether->port; sum = 0; | |
| 1997/0329/sys/src/9/pc/ether8003.c:253,260 – 1997/0331/sys/src/9/pc/ether8003.c:253,260 | ||
| 1994/0128 | } | |
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | ||
| 1997/0329 |
| |
| 1997/0331 | if(umbrwmalloc(PADDR(ether->mem), ether->size, 0) == 0) print("ether8003: warning - 0x%luX unavailable", PADDR(ether->mem)); | |
| 1994/1210 | ||
| 1992/1222 | return 0; } | |
| 1997/0331/sys/src/9/pc/ether8003.c:122,128 – 1997/1101/sys/src/9/pc/ether8003.c:122,128 (short | long) | ||
| 1997/0327 | ctlr->width = 1; | |
| 1993/0223 | } | |
| 1993/1118 |
| |
| 1997/1101 | ether->mem = (ulong)KADDR((ic[Msr] & 0x3F)<<13); | |
| 1997/0327 | if(ctlr->width == 2) | |
| 1993/1118 | ether->mem |= (ic[Laar] & 0x1F)<<19; | |
| 1992/1222 | else | |
| 1997/0331/sys/src/9/pc/ether8003.c:163,169 – 1997/1101/sys/src/9/pc/ether8003.c:163,169 | ||
| 1995/0829 | irq = inb(port+0x0D); outb(port+Hcr, hcr); | |
| 1997/1101 | ether->mem = (ulong)KADDR(0xC0000+((((addr>>2) & 0x30)|(addr & 0x0F))<<13)); | |
| 1995/0829 | ether->size = 8192*(1<<((addr>>4) & 0x03)); ether->irq = irq8216[((irq>>4) & 0x04)|((irq>>2) & 0x03)]; | |
| 1997/1101/sys/src/9/pc/ether8003.c:203,208 – 1999/0714/sys/src/9/pc/ether8003.c:203,210 (short | long) | ||
|
Use ioalloc.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1995/0829 | ether->mem = 0xD0000; if(ether->size == 0) ether->size = 8*1024; | |
| 1999/0714 | if(ioalloc(ether->port, 0x20, 0, "wd8003") < 0) return -1; | |
| 1995/0829 | /* | |
| 1997/0331 | * Look for the interface. Read the LAN address ROM | |
| 1997/1101/sys/src/9/pc/ether8003.c:221,228 – 1999/0714/sys/src/9/pc/ether8003.c:223,232 | ||
| 1995/0829 | id = inb(port+Id); sum += id; sum += inb(port+Cksum); | |
| 1999/0714 | if(sum != 0xFF){ iofree(ether->port); | |
| 1995/0829 | return -1; | |
| 1999/0714 | } | |
| 1995/0829 | ether->ctlr = malloc(sizeof(Dp8390)); | |
| 1997/0327 | ctlr = ether->ctlr; | |
| 1999/0714/sys/src/9/pc/ether8003.c:258,264 – 2000/0612/sys/src/9/pc/ether8003.c:258,265 (short | long) | ||
| 1993/1118 | dp8390setea(ether); | |
| 1992/1222 | ||
| 1997/0331 | if(umbrwmalloc(PADDR(ether->mem), ether->size, 0) == 0) | |
| 2000/0612 | print("ether8003: warning - 0x%luX unavailable\n", PADDR(ether->mem)); | |
| 1994/1210 | ||
| 1992/1222 | return 0; } | |