|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.