Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / prep / pnpbus / if_we_pnpbus.c
blob2284d51be47941aaec57b08978fa25aff843eb24
1 /* $NetBSD: if_we_pnpbus.c,v 1.4 2008/04/28 20:23:33 martin 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/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: if_we_pnpbus.c,v 1.4 2008/04/28 20:23:33 martin Exp $");
54 #include <sys/types.h>
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/device.h>
58 #include <sys/socket.h>
59 #include <sys/mbuf.h>
60 #include <sys/syslog.h>
61 #include <sys/bswap.h>
63 #include <net/if.h>
64 #include <net/if_dl.h>
65 #include <net/if_types.h>
66 #include <net/if_media.h>
68 #include <net/if_ether.h>
70 #include <machine/bus.h>
71 #include <machine/intr.h>
72 #include <machine/isa_machdep.h>
73 #include <machine/residual.h>
75 #include <dev/ic/dp8390reg.h>
76 #include <dev/ic/dp8390var.h>
77 #include <dev/ic/wereg.h>
78 #include <dev/ic/wevar.h>
80 #include <prep/pnpbus/pnpbusvar.h>
82 int we_pnpbus_probe(struct device *, struct cfdata *, void *);
83 void we_pnpbus_attach(struct device *, struct device *, void *);
85 CFATTACH_DECL(we_pnpbus, sizeof(struct we_softc),
86 we_pnpbus_probe, we_pnpbus_attach, NULL, NULL);
88 extern struct cfdriver we_cd;
90 static const char *we_params(bus_space_tag_t, bus_space_handle_t,
91 u_int8_t *, bus_size_t *, u_int8_t *, int *);
93 #define WE_DEFAULT_IOMEM 0xe4000
96 * Delay needed when switching 16-bit access to shared memory.
98 #define WE_DELAY(wsc) delay(3)
101 * Enable card RAM, and 16-bit access.
103 #define WE_MEM_ENABLE(wsc) \
104 do { \
105 if ((wsc)->sc_16bitp) \
106 bus_space_write_1((wsc)->sc_asict, (wsc)->sc_asich, \
107 WE_LAAR, (wsc)->sc_laar_proto | WE_LAAR_M16EN); \
108 bus_space_write_1((wsc)->sc_asict, (wsc)->sc_asich, \
109 WE_MSR, wsc->sc_msr_proto | WE_MSR_MENB); \
110 WE_DELAY((wsc)); \
111 } while (0)
114 * Disable card RAM, and 16-bit access.
116 #define WE_MEM_DISABLE(wsc) \
117 do { \
118 bus_space_write_1((wsc)->sc_asict, (wsc)->sc_asich, \
119 WE_MSR, (wsc)->sc_msr_proto); \
120 if ((wsc)->sc_16bitp) \
121 bus_space_write_1((wsc)->sc_asict, (wsc)->sc_asich, \
122 WE_LAAR, (wsc)->sc_laar_proto); \
123 WE_DELAY((wsc)); \
124 } while (0)
127 we_pnpbus_probe(struct device *parent, struct cfdata *cf, void *aux)
129 struct pnpbus_dev_attach_args *pna = aux;
130 int ret = 0;
132 if (strcmp(pna->pna_devid, "IBM2001") == 0)
133 ret = 1;
135 if (strcmp(pna->pna_devid, "IBM0010") == 0)
136 ret = 1;
138 if (ret)
139 pnpbus_scan(pna, pna->pna_ppc_dev);
141 return ret;
144 void
145 we_pnpbus_attach(struct device *parent, struct device *self, void *aux)
147 struct we_softc *wsc = (struct we_softc *)self;
148 struct dp8390_softc *sc = &wsc->sc_dp8390;
149 struct pnpbus_dev_attach_args *pna = aux;
150 struct pnpbus_irq *irq;
151 bus_space_tag_t nict, asict, memt;
152 bus_space_handle_t nich, asich, memh;
153 bus_size_t memsize = 0x4000;
154 const char *typestr;
155 int memfound = 0, i, irqnum;
157 nict = asict = pna->pna_iot;
158 memt = pna->pna_memt;
160 aprint_normal("\n");
162 if (pnpbus_io_map(&pna->pna_res, 0, &asict, &asich)) {
163 aprint_error("%s: can't map nic i/o space\n",
164 device_xname(self));
165 return;
168 if (bus_space_subregion(asict, asich, WE_NIC_OFFSET, WE_NIC_NPORTS,
169 &nich)) {
170 aprint_error("%s: can't subregion i/o space\n",
171 device_xname(self));
172 return;
175 typestr = we_params(asict, asich, &wsc->sc_type, &memsize,
176 &wsc->sc_flags, &sc->is790);
177 if (typestr == NULL) {
178 aprint_error("%s: where did the card go?\n",
179 device_xname(self));
180 return;
184 * Map memory space. See if any was allocated via PNP, if not, use
185 * the default.
187 if (pnpbus_iomem_map(&pna->pna_res, 0, &memt, &memh) == 0)
188 memfound = 1;
189 else if (bus_space_map(memt, WE_DEFAULT_IOMEM, memsize, 0, &memh)) {
190 aprint_error("%s: can't map shared memory\n",
191 device_xname(self));
192 return;
195 wsc->sc_asict = asict;
196 wsc->sc_asich = asich;
198 sc->sc_regt = nict;
199 sc->sc_regh = nich;
201 sc->sc_buft = memt;
202 sc->sc_bufh = memh;
204 if (memfound)
205 pnpbus_getiomem(&pna->pna_res, 0, &wsc->sc_maddr,
206 &sc->mem_size);
207 else {
208 wsc->sc_maddr = WE_DEFAULT_IOMEM;
209 sc->mem_size = memsize;
212 /* Interface is always enabled. */
213 sc->sc_enabled = 1;
215 if (we_config(self, wsc, typestr))
216 return;
219 * Enable the configured interrupt.
221 #if 0
222 if (sc->is790)
223 bus_space_write_1(asict, asich, WE790_ICR,
224 bus_space_read_1(asict, asich, WE790_ICR) |
225 WE790_ICR_EIL);
226 else if (wsc->sc_type & WE_SOFTCONFIG)
227 bus_space_write_1(asict, asich, WE_IRR,
228 bus_space_read_1(asict, asich, WE_IRR) | WE_IRR_IEN);
229 #endif
232 * Establish interrupt handler.
233 * Loop through all probed IRQs until one looks sane.
235 for (i = 0, irq = SIMPLEQ_FIRST(&pna->pna_res.irq);
236 i < pna->pna_res.numirq; i++, irq = SIMPLEQ_NEXT(irq, next)) {
237 irqnum = ffs(irq->mask) - 1;
238 /* some cards think they are level. force them to edge */
239 if (irq->flags & 0x0c)
240 irq->flags = 0x01;
241 if (!LEGAL_IRQ(irqnum))
242 continue;
243 if (irqnum < 2)
244 continue;
245 break;
247 wsc->sc_ih = pnpbus_intr_establish(i, IPL_NET, IST_PNP, dp8390_intr, sc,
248 &pna->pna_res);
249 if (wsc->sc_ih == NULL)
250 aprint_error("%s: can't establish interrupt\n",
251 device_xname(self));
254 static const char *
255 we_params(bus_space_tag_t asict, bus_space_handle_t asich, u_int8_t *typep, bus_size_t *memsizep, u_int8_t *flagp, int *is790p)
257 const char *typestr;
258 bus_size_t memsize;
259 int is16bit, is790;
260 u_int8_t type;
262 memsize = 8192;
263 is16bit = is790 = 0;
265 type = bus_space_read_1(asict, asich, WE_CARD_ID);
266 switch (type) {
267 case WE_TYPE_WD8003S:
268 typestr = "WD8003S";
269 break;
270 case WE_TYPE_WD8003E:
271 typestr = "WD8003E";
272 break;
273 case WE_TYPE_WD8003EB:
274 typestr = "WD8003EB";
275 break;
276 case WE_TYPE_WD8003W:
277 typestr = "WD8003W";
278 break;
279 case WE_TYPE_WD8013EBT:
280 typestr = "WD8013EBT";
281 memsize = 16384;
282 is16bit = 1;
283 break;
284 case WE_TYPE_WD8013W:
285 typestr = "WD8013W";
286 memsize = 16384;
287 is16bit = 1;
288 break;
289 case WE_TYPE_WD8013EP: /* also WD8003EP */
290 if (bus_space_read_1(asict, asich, WE_ICR) & WE_ICR_16BIT) {
291 is16bit = 1;
292 memsize = 16384;
293 typestr = "WD8013EP";
294 } else
295 typestr = "WD8003EP";
296 break;
297 case WE_TYPE_WD8013WC:
298 typestr = "WD8013WC";
299 memsize = 16384;
300 is16bit = 1;
301 break;
302 case WE_TYPE_WD8013EBP:
303 typestr = "WD8013EBP";
304 memsize = 16384;
305 is16bit = 1;
306 break;
307 case WE_TYPE_WD8013EPC:
308 typestr = "WD8013EPC";
309 memsize = 16384;
310 is16bit = 1;
311 break;
312 case WE_TYPE_SMC8216C:
313 case WE_TYPE_SMC8216T:
315 u_int8_t hwr;
317 typestr = (type == WE_TYPE_SMC8216C) ?
318 "SMC8216/SMC8216C" : "SMC8216T";
320 hwr = bus_space_read_1(asict, asich, WE790_HWR);
321 bus_space_write_1(asict, asich, WE790_HWR,
322 hwr | WE790_HWR_SWH);
323 switch (bus_space_read_1(asict, asich, WE790_RAR) &
324 WE790_RAR_SZ64) {
325 case WE790_RAR_SZ64:
326 memsize = 65536;
327 break;
328 case WE790_RAR_SZ32:
329 memsize = 32768;
330 break;
331 case WE790_RAR_SZ16:
332 memsize = 16384;
333 break;
334 case WE790_RAR_SZ8:
335 /* 8216 has 16K shared mem -- 8416 has 8K */
336 typestr = (type == WE_TYPE_SMC8216C) ?
337 "SMC8416C/SMC8416BT" : "SMC8416T";
338 memsize = 8192;
339 break;
341 bus_space_write_1(asict, asich, WE790_HWR, hwr);
343 is16bit = 1;
344 is790 = 1;
345 break;
347 #ifdef TOSH_ETHER
348 case WE_TYPE_TOSHIBA1:
349 typestr = "Toshiba1";
350 memsize = 32768;
351 is16bit = 1;
352 break;
353 case WE_TYPE_TOSHIBA4:
354 typestr = "Toshiba4";
355 memsize = 32768;
356 is16bit = 1;
357 break;
358 #endif
359 default:
360 /* Not one we recognize. */
361 return (NULL);
365 * Make some adjustments to initial values depending on what is
366 * found in the ICR.
368 if (is16bit && (type != WE_TYPE_WD8013EBT) &&
369 #ifdef TOSH_ETHER
370 (type != WE_TYPE_TOSHIBA1 && type != WE_TYPE_TOSHIBA4) &&
371 #endif
372 (bus_space_read_1(asict, asich, WE_ICR) & WE_ICR_16BIT) == 0) {
373 is16bit = 0;
374 memsize = 8192;
377 #ifdef WE_DEBUG
379 int i;
381 aprint_debug("we_params: type = 0x%x, typestr = %s,"
382 " is16bit = %d, memsize = %d\n", type, typestr, is16bit,
383 memsize);
384 for (i = 0; i < 8; i++)
385 aprint_debug(" %d -> 0x%x\n", i,
386 bus_space_read_1(asict, asich, i));
388 #endif
390 if (typep != NULL)
391 *typep = type;
392 if (memsizep != NULL)
393 *memsizep = memsize;
394 if (flagp != NULL && is16bit)
395 *flagp |= WE_16BIT_ENABLE;
396 if (is790p != NULL)
397 *is790p = is790;
398 return (typestr);