1 /* $NetBSD: if_we_pnpbus.c,v 1.4 2008/04/28 20:23:33 martin Exp $ */
4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
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
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
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>
60 #include <sys/syslog.h>
61 #include <sys/bswap.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) \
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); \
114 * Disable card RAM, and 16-bit access.
116 #define WE_MEM_DISABLE(wsc) \
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); \
127 we_pnpbus_probe(struct device
*parent
, struct cfdata
*cf
, void *aux
)
129 struct pnpbus_dev_attach_args
*pna
= aux
;
132 if (strcmp(pna
->pna_devid
, "IBM2001") == 0)
135 if (strcmp(pna
->pna_devid
, "IBM0010") == 0)
139 pnpbus_scan(pna
, pna
->pna_ppc_dev
);
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;
155 int memfound
= 0, i
, irqnum
;
157 nict
= asict
= pna
->pna_iot
;
158 memt
= pna
->pna_memt
;
162 if (pnpbus_io_map(&pna
->pna_res
, 0, &asict
, &asich
)) {
163 aprint_error("%s: can't map nic i/o space\n",
168 if (bus_space_subregion(asict
, asich
, WE_NIC_OFFSET
, WE_NIC_NPORTS
,
170 aprint_error("%s: can't subregion i/o space\n",
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",
184 * Map memory space. See if any was allocated via PNP, if not, use
187 if (pnpbus_iomem_map(&pna
->pna_res
, 0, &memt
, &memh
) == 0)
189 else if (bus_space_map(memt
, WE_DEFAULT_IOMEM
, memsize
, 0, &memh
)) {
190 aprint_error("%s: can't map shared memory\n",
195 wsc
->sc_asict
= asict
;
196 wsc
->sc_asich
= asich
;
205 pnpbus_getiomem(&pna
->pna_res
, 0, &wsc
->sc_maddr
,
208 wsc
->sc_maddr
= WE_DEFAULT_IOMEM
;
209 sc
->mem_size
= memsize
;
212 /* Interface is always enabled. */
215 if (we_config(self
, wsc
, typestr
))
219 * Enable the configured interrupt.
223 bus_space_write_1(asict
, asich
, WE790_ICR
,
224 bus_space_read_1(asict
, asich
, WE790_ICR
) |
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
);
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)
241 if (!LEGAL_IRQ(irqnum
))
247 wsc
->sc_ih
= pnpbus_intr_establish(i
, IPL_NET
, IST_PNP
, dp8390_intr
, sc
,
249 if (wsc
->sc_ih
== NULL
)
250 aprint_error("%s: can't establish interrupt\n",
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
)
265 type
= bus_space_read_1(asict
, asich
, WE_CARD_ID
);
267 case WE_TYPE_WD8003S
:
270 case WE_TYPE_WD8003E
:
273 case WE_TYPE_WD8003EB
:
274 typestr
= "WD8003EB";
276 case WE_TYPE_WD8003W
:
279 case WE_TYPE_WD8013EBT
:
280 typestr
= "WD8013EBT";
284 case WE_TYPE_WD8013W
:
289 case WE_TYPE_WD8013EP
: /* also WD8003EP */
290 if (bus_space_read_1(asict
, asich
, WE_ICR
) & WE_ICR_16BIT
) {
293 typestr
= "WD8013EP";
295 typestr
= "WD8003EP";
297 case WE_TYPE_WD8013WC
:
298 typestr
= "WD8013WC";
302 case WE_TYPE_WD8013EBP
:
303 typestr
= "WD8013EBP";
307 case WE_TYPE_WD8013EPC
:
308 typestr
= "WD8013EPC";
312 case WE_TYPE_SMC8216C
:
313 case WE_TYPE_SMC8216T
:
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
) &
335 /* 8216 has 16K shared mem -- 8416 has 8K */
336 typestr
= (type
== WE_TYPE_SMC8216C
) ?
337 "SMC8416C/SMC8416BT" : "SMC8416T";
341 bus_space_write_1(asict
, asich
, WE790_HWR
, hwr
);
348 case WE_TYPE_TOSHIBA1
:
349 typestr
= "Toshiba1";
353 case WE_TYPE_TOSHIBA4
:
354 typestr
= "Toshiba4";
360 /* Not one we recognize. */
365 * Make some adjustments to initial values depending on what is
368 if (is16bit
&& (type
!= WE_TYPE_WD8013EBT
) &&
370 (type
!= WE_TYPE_TOSHIBA1
&& type
!= WE_TYPE_TOSHIBA4
) &&
372 (bus_space_read_1(asict
, asich
, WE_ICR
) & WE_ICR_16BIT
) == 0) {
381 aprint_debug("we_params: type = 0x%x, typestr = %s,"
382 " is16bit = %d, memsize = %d\n", type
, typestr
, is16bit
,
384 for (i
= 0; i
< 8; i
++)
385 aprint_debug(" %d -> 0x%x\n", i
,
386 bus_space_read_1(asict
, asich
, i
));
392 if (memsizep
!= NULL
)
394 if (flagp
!= NULL
&& is16bit
)
395 *flagp
|= WE_16BIT_ENABLE
;