4 ** Driver for the Ethercard (WD80x3) and derivates
5 ** This file contains only the wd80x3 specific code,
6 ** the rest is in 8390.c
8 ** Created: March 14, 1994 by Philip Homburg
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>
20 #if (ENABLE_WDETH == 1)
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 /*===========================================================================*
45 *===========================================================================*/
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
;
67 /*===========================================================================*
69 *===========================================================================*/
70 static void we_init(dep
)
73 int i
, int_indx
, int_nr
;
74 int tlb
, rambit
, revision
;
75 int icr
, irr
, hwr
, b
, gcr
;
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
;
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 */
115 if (we_type
& WET_BRD_16BIT
) {
117 dep
->de_ramsize
= rambit
? 0x8000 : 0x4000;
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
);
135 outb_we(dep
, EPL_LAAR
, E_LAAR_A19
| E_LAAR_SOFTINT
|
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
);
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;
187 else if (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 - ",
200 we_type
& WET_BRD_16BIT
? 1 : 0,
201 dep
->de_ramsize
/ 1024,
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');
212 /*===========================================================================*
214 *===========================================================================*/
215 static void we_stop(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
);
226 /*===========================================================================*
228 *===========================================================================*/
229 static int we_aliasing(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;
243 /*===========================================================================*
244 * we_interface_chip *
245 *===========================================================================*/
246 static int we_interface_chip(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;
258 /*===========================================================================*
260 *===========================================================================*/
261 static int we_16bitboard(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
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
);
286 /*===========================================================================*
288 *===========================================================================*/
289 static int we_16bitslot(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 /*===========================================================================*
299 *===========================================================================*/
300 static int we_ultra(dep
)
303 /* Determine if we has an '790 chip. */
306 tlb
= inb_we(dep
, EPL_TLB
);
307 return tlb
== E_TLB_SMC8216C
;
310 #endif /* ENABLE_WDETH */