kernel: fix sanity check
[minix.git] / drivers / dpeth / wd.c
blob1ce57fdd9d70be464911f3ef71198e030455272c
1 /*
2 ** File: wd.c
3 **
4 ** Driver for the Ethercard (WD80x3) and derivates
5 ** This file contains only the wd80x3 specific code,
6 ** the rest is in 8390.c
7 **
8 ** Created: March 14, 1994 by Philip Homburg
9 ** PchId:
11 ** Modified: Jun. 08, 2000 by Giovanni Falzoni <gfalzoni@inwind.it>
12 ** Adaptation to interfacing new main network task.
15 #include <minix/drivers.h>
16 #include <net/gen/ether.h>
17 #include <net/gen/eth_io.h>
18 #include "dp.h"
20 #if (ENABLE_WDETH == 1)
22 #include "8390.h"
23 #include "wd.h"
25 #define WET_ETHERNET 0x01 /* Ethernet transceiver */
26 #define WET_STARLAN 0x02 /* Starlan transceiver */
27 #define WET_INTERF_CHIP 0x04 /* has a WD83C583 interface chip */
28 #define WET_BRD_16BIT 0x08 /* 16 bit board */
29 #define WET_SLT_16BIT 0x10 /* 16 bit slot */
30 #define WET_790 0x20 /* '790 chip */
32 static const int we_int_table[8] = {9, 3, 5, 7, 10, 11, 15, 4};
33 static const int we_790int_table[8] = {0, 9, 3, 5, 7, 10, 11, 15};
35 static void we_init(dpeth_t * dep);
36 static void we_stop(dpeth_t * dep);
37 static int we_aliasing(dpeth_t * dep);
38 static int we_interface_chip(dpeth_t * dep);
39 static int we_16bitboard(dpeth_t * dep);
40 static int we_16bitslot(dpeth_t * dep);
41 static int we_ultra(dpeth_t * dep);
43 /*===========================================================================*
44 * wdeth_probe *
45 *===========================================================================*/
46 int wdeth_probe(dep)
47 dpeth_t *dep;
49 int sum;
51 if (dep->de_linmem == 0)
52 return FALSE; /* No shared memory, so no WD board */
54 sum = inb_we(dep, EPL_EA0) + inb_we(dep, EPL_EA1) +
55 inb_we(dep, EPL_EA2) + inb_we(dep, EPL_EA3) +
56 inb_we(dep, EPL_EA4) + inb_we(dep, EPL_EA5) +
57 inb_we(dep, EPL_TLB) + inb_we(dep, EPL_CHKSUM);
58 if ((sum & 0xFF) != 0xFF)
59 return FALSE; /* No ethernet board at this address */
61 dep->de_initf = we_init;
62 dep->de_stopf = we_stop;
63 dep->de_prog_IO = 0;
64 return TRUE;
67 /*===========================================================================*
68 * we_init *
69 *===========================================================================*/
70 static void we_init(dep)
71 dpeth_t *dep;
73 int i, int_indx, int_nr;
74 int tlb, rambit, revision;
75 int icr, irr, hwr, b, gcr;
76 int we_type;
77 int sendq_nr;
79 for (i = 0; i < 6; i += 1) {
80 dep->de_address.ea_addr[i] = inb_we(dep, EPL_EA0 + i);
83 dep->de_dp8390_port = dep->de_base_port + EPL_DP8390;
85 dep->de_16bit = 0;
87 we_type = 0;
88 we_type |= WET_ETHERNET; /* assume ethernet */
89 if (we_ultra(dep)) we_type |= WET_790;
90 if (!we_aliasing(dep)) {
91 if (we_interface_chip(dep)) we_type |= WET_INTERF_CHIP;
92 if (we_16bitboard(dep)) {
93 we_type |= WET_BRD_16BIT;
94 if (we_16bitslot(dep)) we_type |= WET_SLT_16BIT;
97 if (we_type & WET_SLT_16BIT) dep->de_16bit = 1;
99 /* Look at the on board ram size. */
100 tlb = inb_we(dep, EPL_TLB);
101 revision = tlb & E_TLB_REV;
102 rambit = tlb & E_TLB_RAM;
104 if (dep->de_ramsize != 0) {
105 /* Size set from boot environment. */
106 } else if (revision < 2) {
107 dep->de_ramsize = 0x2000; /* 8K */
108 if (we_type & WET_BRD_16BIT)
109 dep->de_ramsize = 0x4000; /* 16K */
110 else if ((we_type & WET_INTERF_CHIP) &&
111 inb_we(dep, EPL_ICR) & E_ICR_MEMBIT) {
112 dep->de_ramsize = 0x8000; /* 32K */
114 } else {
115 if (we_type & WET_BRD_16BIT) {
116 /* 32K or 16K */
117 dep->de_ramsize = rambit ? 0x8000 : 0x4000;
118 } else {
119 /* 32K or 8K */
120 dep->de_ramsize = rambit ? 0x8000 : 0x2000;
124 if (we_type & WET_790) {
125 outb_we(dep, EPL_MSR, E_MSR_RESET);
126 if ((we_type & (WET_BRD_16BIT | WET_SLT_16BIT)) ==
127 (WET_BRD_16BIT | WET_SLT_16BIT)) {
128 outb_we(dep, EPL_LAAR, E_LAAR_LAN16E | E_LAAR_MEM16E);
130 } else if (we_type & WET_BRD_16BIT) {
131 if (we_type & WET_SLT_16BIT) {
132 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT |
133 E_LAAR_LAN16E | E_LAAR_MEM16E);
134 } else {
135 outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_SOFTINT |
136 E_LAAR_LAN16E);
139 if (we_type & WET_790) {
140 outb_we(dep, EPL_MSR, E_MSR_MENABLE);
141 hwr = inb_we(dep, EPL_790_HWR);
142 outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH);
143 b = inb_we(dep, EPL_790_B);
144 outb_we(dep, EPL_790_B, ((dep->de_linmem >> 13) & 0x0f) |
145 ((dep->de_linmem >> 11) & 0x40) | (b & 0xb0));
146 outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH);
147 } else {
148 outb_we(dep, EPL_MSR, E_MSR_RESET);
149 outb_we(dep, EPL_MSR, E_MSR_MENABLE |
150 ((dep->de_linmem >> 13) & E_MSR_MEMADDR));
153 if ((we_type & WET_INTERF_CHIP) && !(we_type & WET_790)) {
154 icr = inb_we(dep, EPL_ICR);
155 irr = inb_we(dep, EPL_IRR);
156 int_indx = (icr & E_ICR_IR2) | ((irr & (E_IRR_IR0 | E_IRR_IR1)) >> 5);
157 int_nr = we_int_table[int_indx];
158 DEBUG(printf("%s: encoded irq= %d\n", dep->de_name, int_nr));
159 if (dep->de_irq & DEI_DEFAULT) dep->de_irq = int_nr;
160 outb_we(dep, EPL_IRR, irr | E_IRR_IEN);
162 if (we_type & WET_790) {
163 hwr = inb_we(dep, EPL_790_HWR);
164 outb_we(dep, EPL_790_HWR, hwr | E_790_HWR_SWH);
166 gcr = inb_we(dep, EPL_790_GCR);
168 outb_we(dep, EPL_790_HWR, hwr & ~E_790_HWR_SWH);
170 int_indx = ((gcr & E_790_GCR_IR2) >> 4) |
171 ((gcr & (E_790_GCR_IR1 | E_790_GCR_IR0)) >> 2);
172 int_nr = we_790int_table[int_indx];
173 DEBUG(printf("%s: encoded irq= %d\n", dep->de_name, int_nr));
174 if (dep->de_irq & DEI_DEFAULT) dep->de_irq = int_nr;
175 icr = inb_we(dep, EPL_790_ICR);
176 outb_we(dep, EPL_790_ICR, icr | E_790_ICR_EIL);
179 /* Strip the "default flag." */
180 dep->de_irq &= ~DEI_DEFAULT;
182 dep->de_offset_page = 0; /* Shared memory starts at 0 */
183 /* Allocate one send buffer (1.5KB) per 8KB of on board memory.
184 sendq_nr = dep->de_ramsize / 0x2000;
185 if (sendq_nr < 1)
186 sendq_nr = 1;
187 else if (sendq_nr > SENDQ_NR) */
188 sendq_nr = SENDQ_NR;
189 dep->de_sendq_nr = sendq_nr;
190 for (i = 0; i < sendq_nr; i++) {
191 dep->de_sendq[i].sq_sendpage = i * SENDQ_PAGES;
193 dep->de_startpage = i * SENDQ_PAGES;
194 dep->de_stoppage = dep->de_ramsize / DP_PAGESIZE;
196 ns_init(dep); /* Initialize DP controller */
198 printf("%s: WD80%d3 (%dkB RAM) at %X:%d:%lX - ",
199 dep->de_name,
200 we_type & WET_BRD_16BIT ? 1 : 0,
201 dep->de_ramsize / 1024,
202 dep->de_base_port,
203 dep->de_irq,
204 dep->de_linmem);
205 for (i = 0; i < SA_ADDR_LEN; i += 1)
206 printf("%02X%c", dep->de_address.ea_addr[i],
207 i < SA_ADDR_LEN - 1 ? ':' : '\n');
209 return;
212 /*===========================================================================*
213 * we_stop *
214 *===========================================================================*/
215 static void we_stop(dep)
216 dpeth_t *dep;
219 if (dep->de_16bit) outb_we(dep, EPL_LAAR, E_LAAR_A19 | E_LAAR_LAN16E);
220 outb_we(dep, EPL_MSR, E_MSR_RESET);
221 outb_we(dep, EPL_MSR, 0);
222 sys_irqdisable(&dep->de_hook);
223 return;
226 /*===========================================================================*
227 * we_aliasing *
228 *===========================================================================*/
229 static int we_aliasing(dep)
230 dpeth_t *dep;
232 /* Determine whether wd8003 hardware performs register aliasing. This implies
233 * an old WD8003E board. */
235 if (inb_we(dep, EPL_REG1) != inb_we(dep, EPL_EA1)) return 0;
236 if (inb_we(dep, EPL_REG2) != inb_we(dep, EPL_EA2)) return 0;
237 if (inb_we(dep, EPL_REG3) != inb_we(dep, EPL_EA3)) return 0;
238 if (inb_we(dep, EPL_REG4) != inb_we(dep, EPL_EA4)) return 0;
239 if (inb_we(dep, EPL_REG7) != inb_we(dep, EPL_CHKSUM)) return 0;
240 return 1;
243 /*===========================================================================*
244 * we_interface_chip *
245 *===========================================================================*/
246 static int we_interface_chip(dep)
247 dpeth_t *dep;
249 /* Determine if the board has an interface chip. */
251 outb_we(dep, EPL_GP2, 0x35);
252 if (inb_we(dep, EPL_GP2) != 0x35) return 0;
253 outb_we(dep, EPL_GP2, 0x3A);
254 if (inb_we(dep, EPL_GP2) != 0x3A) return 0;
255 return 1;
258 /*===========================================================================*
259 * we_16bitboard *
260 *===========================================================================*/
261 static int we_16bitboard(dep)
262 dpeth_t *dep;
264 /* Determine whether the board is capable of doing 16 bit memory moves.
265 * If the 16 bit enable bit is unchangable by software we'll assume an
266 * 8 bit board.
268 int icr;
269 u8_t tlb;
271 icr = inb_we(dep, EPL_ICR);
273 outb_we(dep, EPL_ICR, icr ^ E_ICR_16BIT);
274 if (inb_we(dep, EPL_ICR) == icr) {
275 tlb = inb_we(dep, EPL_TLB);
277 DEBUG(printf("%s: tlb= 0x%x\n", dep->de_name, tlb));
279 return tlb == E_TLB_EB || tlb == E_TLB_E ||
280 tlb == E_TLB_SMCE || tlb == E_TLB_SMC8216C;
282 outb_we(dep, EPL_ICR, icr);
283 return 1;
286 /*===========================================================================*
287 * we_16bitslot *
288 *===========================================================================*/
289 static int we_16bitslot(dep)
290 dpeth_t *dep;
292 /* Determine if the 16 bit board in plugged into a 16 bit slot. */
294 return !!(inb_we(dep, EPL_ICR) & E_ICR_16BIT);
297 /*===========================================================================*
298 * we_ultra *
299 *===========================================================================*/
300 static int we_ultra(dep)
301 dpeth_t *dep;
303 /* Determine if we has an '790 chip. */
304 u8_t tlb;
306 tlb = inb_we(dep, EPL_TLB);
307 return tlb == E_TLB_SMC8216C;
310 #endif /* ENABLE_WDETH */
312 /** wd.c **/