1 #include "u.h" 2 #include "../port/lib.h" 3 #include "mem.h" 4 #include "dat.h" 5 #include "fns.h" 6 #include "../port/error.h" 7 #include "io.h" 8 #include "devtab.h" 9 10 #include "ether.h" 11 12 /* 13 * Driver written for the 'Notebook Computer Ethernet LAN Adapter', 14 * a plug-in to the bus-slot on the rear of the Gateway NOMAD 425DXL 15 * laptop. The manual says NE2000 compatible. 16 * The interface appears to be pretty well described in the National 17 * Semiconductor Local Area Network Databook (1992) as one of the 18 * AT evaluation cards. 19 * 20 * The NE2000 is really just a DP8390[12] plus a data port 21 * and a reset port. 22 */ 23 enum { 24 Data = 0x10, /* offset from I/O base of data port */ 25 Reset = 0x18, /* offset from I/O base of reset port */ 26 }; 27 28 int 29 ne2000reset(Ctlr *ctlr) 30 { 31 ushort buf[16]; 32 int i; 33 34 /* 35 * Set up the software configuration. 36 * Use defaults for port, irq, mem and size 37 * if not specified. 38 */ 39 if(ctlr->card.port == 0) 40 ctlr->card.port = 0x300; 41 if(ctlr->card.irq == 0) 42 ctlr->card.irq = 2; 43 if(ctlr->card.mem == 0) 44 ctlr->card.mem = 0x4000; 45 if(ctlr->card.size == 0) 46 ctlr->card.size = 16*1024; 47 48 ctlr->card.reset = ne2000reset; 49 ctlr->card.attach = dp8390attach; 50 ctlr->card.mode = dp8390mode; 51 ctlr->card.read = dp8390read; 52 ctlr->card.write = dp8390write; 53 ctlr->card.receive = dp8390receive; 54 ctlr->card.transmit = dp8390transmit; 55 ctlr->card.intr = dp8390intr; 56 ctlr->card.watch = dp8390watch; 57 ctlr->card.overflow = dp8390overflow; 58 59 ctlr->card.bit16 = 1; 60 ctlr->card.dp8390 = ctlr->card.port; 61 ctlr->card.data = ctlr->card.port+Data; 62 63 ctlr->card.tstart = HOWMANY(ctlr->card.mem, Dp8390BufSz); 64 ctlr->card.pstart = ctlr->card.tstart + HOWMANY(sizeof(Etherpkt), Dp8390BufSz); 65 ctlr->card.pstop = ctlr->card.tstart + HOWMANY(ctlr->card.size, Dp8390BufSz); 66 67 /* 68 * Reset the board. This is done by doing a read 69 * followed by a write to the Reset address. 70 */ 71 buf[0] = inb(ctlr->card.port+Reset); 72 delay(2); 73 outb(ctlr->card.port+Reset, buf[0]); 74 75 /* 76 * Init the (possible) chip, then use the (possible) 77 * chip to read the (possible) PROM for ethernet address 78 * and a marker byte. 79 * We could just look at the DP8390 command register after 80 * initialisation has been tried, but that wouldn't be 81 * enough, there are other ethernet boards which could 82 * match. 83 */ 84 dp8390reset(ctlr); 85 memset(buf, 0, sizeof(buf)); 86 dp8390read(ctlr, buf, 0, sizeof(buf)); 87 if((buf[0x0E] & 0xFF) != 0x57 || (buf[0x0F] & 0xFF) != 0x57) 88 return -1; 89 90 /* 91 * Stupid machine. We asked for shorts, we got shorts, 92 * although the PROM is a byte array. 93 * Now we can set the ethernet address. 94 */ 95 if((ctlr->ea[0]|ctlr->ea[1]|ctlr->ea[2]|ctlr->ea[3]|ctlr->ea[4]|ctlr->ea[5]) == 0){ 96 for(i = 0; i < sizeof(ctlr->ea); i++) 97 ctlr->ea[i] = buf[i]; 98 } 99 dp8390setea(ctlr); 100 101 return 0; 102 } 103 104 void 105 ether2000link(void) 106 { 107 addethercard("NE2000", ne2000reset); 108 } 109