unstack - fix ipcvecs
[minix.git] / sys / arch / i386 / stand / lib / netif / wd80x3.c
blobe913f8d719e8116775ac0ced632f0c7878da967a
1 /* $NetBSD: wd80x3.c,v 1.10 2008/12/14 18:46:33 christos Exp $ */
3 /*-
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
35 * adapters.
37 * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
39 * Copyright (C) 1993, David Greenman. This software may be used, modified,
40 * copied, distributed, and sold, in both source and binary form provided that
41 * the above copyright and these terms are retained. Under no circumstances is
42 * the author responsible for the proper functioning of this software, nor does
43 * the author assume any responsibility for damages incurred with its use.
47 * Device driver for the Western Digital/SMC 8003 and 8013 series,
48 * and the SMC Elite Ultra (8216).
51 #include <sys/types.h>
52 #include <machine/pio.h>
54 #include <lib/libsa/stand.h>
55 #include <libi386.h>
57 #ifdef _STANDALONE
58 #include <lib/libkern/libkern.h>
59 #include <bootinfo.h>
60 #endif
62 #include "etherdrv.h"
63 #include <dev/ic/dp8390reg.h>
64 #include "dp8390.h"
65 #include <dev/ic/wereg.h>
67 #ifndef BASEREG
68 #define BASEREG 0x240
69 #define BASEMEM 0xd0000
70 #endif
72 #define WD_BASEREG BASEREG
73 #define WD_BASEMEM BASEMEM
75 #ifndef _STANDALONE
76 extern int mapio(void);
77 #endif
79 u_char eth_myaddr[6];
81 static uint8_t we_type;
82 static int we_is16bit;
84 #ifdef _STANDALONE
85 static struct btinfo_netif bi_netif;
86 #endif
88 const char *
89 we_params(void)
91 const char *typestr;
93 dp8390_memsize = 8192;
95 we_type = inb(WD_BASEREG + WE_CARD_ID);
96 switch (we_type) {
97 #ifdef SUPPORT_WD80X3
98 case WE_TYPE_WD8003S:
99 typestr = "WD8003S";
100 break;
101 case WE_TYPE_WD8003E:
102 typestr = "WD8003E";
103 break;
104 case WE_TYPE_WD8003EB:
105 typestr = "WD8003EB";
106 break;
107 case WE_TYPE_WD8003W:
108 typestr = "WD8003W";
109 break;
110 case WE_TYPE_WD8013EBT:
111 typestr = "WD8013EBT";
112 dp8390_memsize = 16384;
113 we_is16bit = 1;
114 break;
115 case WE_TYPE_WD8013W:
116 typestr = "WD8013W";
117 dp8390_memsize = 16384;
118 we_is16bit = 1;
119 break;
120 case WE_TYPE_WD8013EP: /* also WD8003EP */
121 if (inb(WD_BASEREG + WE_ICR) & WE_ICR_16BIT) {
122 we_is16bit = 1;
123 dp8390_memsize = 16384;
124 typestr = "WD8013EP";
125 } else
126 typestr = "WD8003EP";
127 break;
128 case WE_TYPE_WD8013WC:
129 typestr = "WD8013WC";
130 dp8390_memsize = 16384;
131 we_is16bit = 1;
132 break;
133 case WE_TYPE_WD8013EBP:
134 typestr = "WD8013EBP";
135 dp8390_memsize = 16384;
136 we_is16bit = 1;
137 break;
138 case WE_TYPE_WD8013EPC:
139 typestr = "WD8013EPC";
140 dp8390_memsize = 16384;
141 we_is16bit = 1;
142 break;
143 #endif
144 #ifdef SUPPORT_SMC_ULTRA
145 case WE_TYPE_SMC8216C:
146 case WE_TYPE_SMC8216T:
148 uint8_t hwr;
150 typestr = (we_type == WE_TYPE_SMC8216C) ?
151 "SMC8216/SMC8216C" : "SMC8216T";
153 hwr = inb(WD_BASEREG + WE790_HWR);
154 outb(WD_BASEREG + WE790_HWR, hwr | WE790_HWR_SWH);
155 switch (inb(WD_BASEREG + WE790_RAR) & WE790_RAR_SZ64) {
156 case WE790_RAR_SZ64:
157 dp8390_memsize = 65536;
158 break;
159 case WE790_RAR_SZ32:
160 dp8390_memsize = 32768;
161 break;
162 case WE790_RAR_SZ16:
163 dp8390_memsize = 16384;
164 break;
165 case WE790_RAR_SZ8:
166 /* 8216 has 16K shared mem -- 8416 has 8K */
167 typestr = (we_type == WE_TYPE_SMC8216C) ?
168 "SMC8416C/SMC8416BT" : "SMC8416T";
169 dp8390_memsize = 8192;
170 break;
172 outb(WD_BASEREG + WE790_HWR, hwr);
174 we_is16bit = 1;
175 #ifdef SUPPORT_WD80X3
176 dp8390_is790 = 1;
177 #endif
178 break;
180 #endif
181 default:
182 /* Not one we recognize. */
183 return NULL;
187 * Make some adjustments to initial values depending on what is
188 * found in the ICR.
190 if (we_is16bit && (we_type != WE_TYPE_WD8013EBT) &&
191 (inb(WD_BASEREG + WE_ICR) & WE_ICR_16BIT) == 0) {
192 we_is16bit = 0;
193 dp8390_memsize = 8192;
196 #ifdef WE_DEBUG
198 int i;
200 printf("we_params: type = 0x%x, typestr = %s, is16bit = %d, "
201 "memsize = %d\n", we_type, typestr, we_is16bit, dp8390_memsize);
202 for (i = 0; i < 8; i++)
203 printf(" %d -> 0x%x\n", i,
204 inb(WD_BASEREG + i));
206 #endif
208 return typestr;
212 EtherInit(unsigned char *myadr)
214 const char *typestr;
215 uint8_t x;
216 int i;
217 uint8_t laar_proto;
218 uint8_t msr_proto;
220 dp8390_iobase = WD_BASEREG + WE_NIC_OFFSET;
221 dp8390_membase = WD_BASEMEM;
223 #ifndef _STANDALONE
224 if (mapio()) {
225 printf("no IO access\n");
226 return 0;
228 #endif
230 for (x = 0, i = 0; i < 8; i++)
231 x += inb(WD_BASEREG + WE_PROM + i);
233 if (x != WE_ROM_CHECKSUM_TOTAL)
234 return 0;
236 /* reset the ethernet card */
237 outb(WD_BASEREG + WE_MSR, WE_MSR_RST);
238 delay(100);
239 outb(WD_BASEREG + WE_MSR, inb(WD_BASEREG + WE_MSR) & ~WE_MSR_RST);
240 delay(5000);
242 typestr = we_params();
243 if (!typestr)
244 return 0;
246 printf("Using %s board, port 0x%x, iomem 0x%x, iosiz %d\n",
247 typestr, WD_BASEREG, WD_BASEMEM, dp8390_memsize);
249 /* get ethernet address */
250 for (i = 0; i < 6; i++)
251 eth_myaddr[i] = myadr[i]= inb(WD_BASEREG + WE_PROM + i);
254 * Set upper address bits and 8/16 bit access to shared memory.
256 if (dp8390_is790) {
257 laar_proto = inb(WD_BASEREG + WE_LAAR) & ~WE_LAAR_M16EN;
258 outb(WD_BASEREG + WE_LAAR, laar_proto |
259 (we_is16bit ? WE_LAAR_M16EN : 0));
260 } else if ((we_type & WE_SOFTCONFIG) ||
261 (we_type == WE_TYPE_WD8013EBT)) {
262 laar_proto = (WD_BASEMEM >> 19) & WE_LAAR_ADDRHI;
263 if (we_is16bit)
264 laar_proto |= WE_LAAR_L16EN;
265 outb(WD_BASEREG + WE_LAAR, laar_proto |
266 (we_is16bit ? WE_LAAR_M16EN : 0));
270 * Set address and enable interface shared memory.
272 if (dp8390_is790) {
273 /* XXX MAGIC CONSTANTS XXX */
274 x = inb(WD_BASEREG + 0x04);
275 outb(WD_BASEREG + 0x04, x | 0x80);
276 outb(WD_BASEREG + 0x0b,
277 ((WD_BASEMEM >> 13) & 0x0f) |
278 ((WD_BASEMEM >> 11) & 0x40) |
279 (inb(WD_BASEREG + 0x0b) & 0xb0));
280 outb(WD_BASEREG + 0x04, x);
281 msr_proto = 0x00;
282 dp8390_cr_proto = 0x00;
283 } else {
284 msr_proto = (WD_BASEMEM >> 13) & WE_MSR_ADDR;
285 dp8390_cr_proto = ED_CR_RD2;
288 outb(WD_BASEREG + WE_MSR, msr_proto | WE_MSR_MENB);
289 delay(2);
292 * DCR gets:
294 * FIFO threshold to 8, No auto-init Remote DMA,
295 * byte order=80x86.
297 * 16-bit cards also get word-wide DMA transfers.
299 dp8390_dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (we_is16bit ? ED_DCR_WTS : 0);
301 if (dp8390_config())
302 return 0;
304 #ifdef _STANDALONE
305 strncpy(bi_netif.ifname, "we", sizeof(bi_netif.ifname));
306 bi_netif.bus = BI_BUS_ISA;
307 bi_netif.addr.iobase = WD_BASEREG;
309 BI_ADD(&bi_netif, BTINFO_NETIF, sizeof(bi_netif));
310 #endif
311 return 1;
315 * Stop ethernet board
317 void
318 EtherStop(void) {
319 /* stop dp8390, followed by a board reset */
320 dp8390_stop();
321 outb(WD_BASEREG + WE_MSR, WE_MSR_RST);
322 outb(WD_BASEREG + WE_MSR, 0);