source: trunk/minix/drivers/dpeth/wd.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

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