1 /* $NetBSD: if_ae_nubus.c,v 1.40 2008/04/04 09:49:33 hauke Exp $ */
4 * Copyright (C) 1997 Scott Reynolds
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Some parts are derived from code adapted for MacBSD by Brad Parker
34 * Apple NB Ethernet Card
35 * Apple NB Ethernet Card II
36 * Interlan A310 NuBus Ethernet card
37 * Cayman Systems GatorCard
39 * Kinetics EtherPort SE/30
42 #include <sys/cdefs.h>
43 __KERNEL_RCSID(0, "$NetBSD: if_ae_nubus.c,v 1.40 2008/04/04 09:49:33 hauke Exp $");
45 #include <sys/param.h>
46 #include <sys/device.h>
47 #include <sys/errno.h>
48 #include <sys/ioctl.h>
49 #include <sys/malloc.h>
50 #include <sys/socket.h>
51 #include <sys/syslog.h>
52 #include <sys/systm.h>
55 #include <net/if_media.h>
56 #include <net/if_ether.h>
58 #include <machine/bus.h>
59 #include <machine/viareg.h>
61 #include <dev/ic/dp8390reg.h>
62 #include <dev/ic/dp8390var.h>
63 #include <mac68k/nubus/nubus.h>
64 #include <mac68k/dev/if_aevar.h>
65 #include <mac68k/dev/if_aereg.h>
67 static int ae_nubus_match(device_t
, cfdata_t
, void *);
68 static void ae_nubus_attach(device_t
, device_t
, void *);
69 static int ae_nb_card_vendor(bus_space_tag_t
, bus_space_handle_t
,
70 struct nubus_attach_args
*);
71 static int ae_nb_get_enaddr(bus_space_tag_t
, bus_space_handle_t
,
72 struct nubus_attach_args
*, u_int8_t
*);
74 static void ae_nb_watchdog(struct ifnet
*);
77 void ae_nubus_intr(void *);
79 CFATTACH_DECL_NEW(ae_nubus
, sizeof(struct dp8390_softc
),
80 ae_nubus_match
, ae_nubus_attach
, NULL
, NULL
);
83 ae_nubus_match(device_t parent
, cfdata_t cf
, void *aux
)
85 struct nubus_attach_args
*na
= aux
;
86 bus_space_handle_t bsh
;
89 if (bus_space_map(na
->na_tag
, NUBUS_SLOT2PA(na
->slot
), NBMEMSIZE
,
95 if (na
->category
== NUBUS_CATEGORY_NETWORK
&&
96 na
->type
== NUBUS_TYPE_ETHERNET
) {
97 switch (ae_nb_card_vendor(na
->na_tag
, bsh
, na
)) {
98 case DP8390_VENDOR_APPLE
:
99 case DP8390_VENDOR_ASANTE
:
100 case DP8390_VENDOR_FARALLON
:
101 case DP8390_VENDOR_INTERLAN
:
102 case DP8390_VENDOR_KINETICS
:
103 case DP8390_VENDOR_CABLETRON
:
106 case DP8390_VENDOR_DAYNA
:
114 bus_space_unmap(na
->na_tag
, bsh
, NBMEMSIZE
);
120 * Install interface into kernel networking data structures
123 ae_nubus_attach(device_t parent
, device_t self
, void *aux
)
125 struct dp8390_softc
*sc
= device_private(self
);
126 struct nubus_attach_args
*na
= aux
;
128 struct ifnet
*ifp
= &sc
->sc_ec
.ec_if
;
131 bus_space_handle_t bsh
;
133 const char *cardtype
;
137 if (bus_space_map(bst
, NUBUS_SLOT2PA(na
->slot
), NBMEMSIZE
,
139 aprint_error(": can't map memory space\n");
143 sc
->sc_regt
= sc
->sc_buft
= bst
;
144 sc
->sc_flags
= device_cfdata(self
)->cf_flags
;
146 cardtype
= nubus_get_card_name(bst
, bsh
, na
->fmt
);
155 switch (ae_nb_card_vendor(bst
, bsh
, na
)) {
156 case DP8390_VENDOR_APPLE
: /* Apple-compatible cards */
157 case DP8390_VENDOR_ASANTE
:
158 /* Map register offsets */
159 for (i
= 0; i
< 16; i
++) /* reverse order, longword aligned */
160 sc
->sc_reg_map
[i
] = (15 - i
) << 2;
162 sc
->dcr_reg
= (ED_DCR_FT1
| ED_DCR_WTS
| ED_DCR_LS
);
163 if (bus_space_subregion(bst
, bsh
,
164 AE_REG_OFFSET
, AE_REG_SIZE
, &sc
->sc_regh
)) {
165 aprint_error(": failed to map register space\n");
168 if ((sc
->mem_size
= ae_size_card_memory(bst
, bsh
,
169 AE_DATA_OFFSET
)) == 0) {
170 aprint_error(": failed to determine size of RAM.\n");
173 if (bus_space_subregion(bst
, bsh
,
174 AE_DATA_OFFSET
, sc
->mem_size
, &sc
->sc_bufh
)) {
175 aprint_error(": failed to map register space\n");
178 #ifdef AE_OLD_GET_ENADDR
179 /* Get station address from on-board ROM */
180 for (i
= 0; i
< ETHER_ADDR_LEN
; ++i
)
182 bus_space_read_1(bst
, bsh
, (AE_ROM_OFFSET
+ i
* 2));
184 if (ae_nb_get_enaddr(bst
, bsh
, na
, sc
->sc_enaddr
)) {
185 aprint_error(": can't find MAC address\n");
193 case DP8390_VENDOR_DAYNA
:
194 /* Map register offsets */
195 for (i
= 0; i
< 16; i
++) /* normal order, longword aligned */
196 sc
->sc_reg_map
[i
] = i
<< 2;
198 sc
->dcr_reg
= (ED_DCR_FT1
| ED_DCR_WTS
| ED_DCR_LS
);
199 if (bus_space_subregion(bst
, bsh
,
200 DP_REG_OFFSET
, AE_REG_SIZE
, &sc
->sc_regh
)) {
201 aprint_error(": failed to map register space\n");
205 if (bus_space_subregion(bst
, bsh
,
206 DP_DATA_OFFSET
, sc
->mem_size
, &sc
->sc_bufh
)) {
207 aprint_error(": failed to map register space\n");
210 #ifdef AE_OLD_GET_ENADDR
211 /* Get station address from on-board ROM */
212 for (i
= 0; i
< ETHER_ADDR_LEN
; ++i
)
214 bus_space_read_1(bst
, bsh
, (DP_ROM_OFFSET
+ i
* 2));
216 if (ae_nb_get_enaddr(bst
, bsh
, na
, sc
->sc_enaddr
)) {
217 aprint_error(": can't find MAC address\n");
222 aprint_error(": unsupported Dayna hardware\n");
225 case DP8390_VENDOR_FARALLON
:
226 /* Map register offsets */
227 for (i
= 0; i
< 16; i
++) /* reverse order, longword aligned */
228 sc
->sc_reg_map
[i
] = (15 - i
) << 2;
230 sc
->dcr_reg
= (ED_DCR_FT1
| ED_DCR_WTS
| ED_DCR_LS
);
231 if (bus_space_subregion(bst
, bsh
,
232 AE_REG_OFFSET
, AE_REG_SIZE
, &sc
->sc_regh
)) {
233 aprint_error(": failed to map register space\n");
236 if ((sc
->mem_size
= ae_size_card_memory(bst
, bsh
,
237 AE_DATA_OFFSET
)) == 0) {
238 aprint_error(": failed to determine size of RAM.\n");
241 if (bus_space_subregion(bst
, bsh
,
242 AE_DATA_OFFSET
, sc
->mem_size
, &sc
->sc_bufh
)) {
243 aprint_error(": failed to map register space\n");
246 #ifdef AE_OLD_GET_ENADDR
247 /* Get station address from on-board ROM */
248 for (i
= 0; i
< ETHER_ADDR_LEN
; ++i
)
250 bus_space_read_1(bst
, bsh
, (FE_ROM_OFFSET
+ i
));
252 if (ae_nb_get_enaddr(bst
, bsh
, na
, sc
->sc_enaddr
)) {
253 aprint_error(": can't find MAC address\n");
261 case DP8390_VENDOR_INTERLAN
:
262 /* Map register offsets */
263 for (i
= 0; i
< 16; i
++) /* normal order, longword aligned */
264 sc
->sc_reg_map
[i
] = i
<< 2;
266 sc
->dcr_reg
= (ED_DCR_FT1
| ED_DCR_WTS
| ED_DCR_LS
);
267 if (bus_space_subregion(bst
, bsh
,
268 GC_REG_OFFSET
, AE_REG_SIZE
, &sc
->sc_regh
)) {
269 aprint_error(": failed to map register space\n");
272 if ((sc
->mem_size
= ae_size_card_memory(bst
, bsh
,
273 GC_DATA_OFFSET
)) == 0) {
274 aprint_error(": failed to determine size of RAM.\n");
277 if (bus_space_subregion(bst
, bsh
,
278 GC_DATA_OFFSET
, sc
->mem_size
, &sc
->sc_bufh
)) {
279 aprint_error(": failed to map register space\n");
283 /* reset the NIC chip */
284 bus_space_write_1(bst
, bsh
, GC_RESET_OFFSET
, 0);
286 if (ae_nb_get_enaddr(bst
, bsh
, na
, sc
->sc_enaddr
)) {
287 /* Fall back to snarf directly from ROM. Ick. */
288 for (i
= 0; i
< ETHER_ADDR_LEN
; ++i
)
290 bus_space_read_1(bst
, bsh
,
291 (GC_ROM_OFFSET
+ i
* 4));
297 case DP8390_VENDOR_KINETICS
:
298 /* Map register offsets */
299 for (i
= 0; i
< 16; i
++) /* normal order, longword aligned */
300 sc
->sc_reg_map
[i
] = i
<< 2;
302 if (bus_space_subregion(bst
, bsh
,
303 KE_REG_OFFSET
, AE_REG_SIZE
, &sc
->sc_regh
)) {
304 aprint_error(": failed to map register space\n");
307 if ((sc
->mem_size
= ae_size_card_memory(bst
, bsh
,
308 KE_DATA_OFFSET
)) == 0) {
309 aprint_error(": failed to determine size of RAM.\n");
312 if (bus_space_subregion(bst
, bsh
,
313 KE_DATA_OFFSET
, sc
->mem_size
, &sc
->sc_bufh
)) {
314 aprint_error(": failed to map register space\n");
317 if (ae_nb_get_enaddr(bst
, bsh
, na
, sc
->sc_enaddr
)) {
318 aprint_error(": can't find MAC address\n");
325 case DP8390_VENDOR_CABLETRON
:
326 /* Map register offsets */
327 for (i
= 0; i
< 16; i
++)
328 sc
->sc_reg_map
[i
] = i
<< 1 ; /* normal order, word aligned */
329 sc
->dcr_reg
= (ED_DCR_FT1
| ED_DCR_WTS
| ED_DCR_LS
);
330 if (bus_space_subregion(bst
, bsh
,
331 CT_REG_OFFSET
, AE_REG_SIZE
, &sc
->sc_regh
)) {
332 aprint_error(": failed to map register space\n");
335 if ((sc
->mem_size
= ae_size_card_memory(bst
, bsh
,
336 CT_DATA_OFFSET
)) == 0) {
337 aprint_error(": failed to determine size of RAM.\n");
340 if (bus_space_subregion(bst
, bsh
,
341 CT_DATA_OFFSET
, sc
->mem_size
, &sc
->sc_bufh
)) {
342 aprint_error(": failed to map register space\n");
345 if (ae_nb_get_enaddr(bst
, bsh
, na
, sc
->sc_enaddr
)) {
346 aprint_error(": can't find MAC address\n");
356 bus_space_unmap(bst
, bsh
, NBMEMSIZE
);
361 * Override test_mem and write_mbuf functions; other defaults
362 * already work properly.
364 sc
->test_mem
= ae_test_mem
;
365 sc
->write_mbuf
= ae_write_mbuf
;
367 ifp
->if_watchdog
= ae_nb_watchdog
; /* Override watchdog */
369 sc
->sc_media_init
= dp8390_media_init
;
371 /* Interface is always enabled. */
374 aprint_normal(": %s, %dKB memory\n", cardtype
, sc
->mem_size
/ 1024);
376 if (dp8390_config(sc
)) {
377 bus_space_unmap(bst
, bsh
, NBMEMSIZE
);
381 /* make sure interrupts are vectored to us */
382 add_nubus_intr(na
->slot
, ae_nubus_intr
, sc
);
386 ae_nubus_intr(void *arg
)
388 struct dp8390_softc
*sc
= arg
;
390 (void)dp8390_intr(sc
);
394 ae_nb_card_vendor(bus_space_tag_t bst
, bus_space_handle_t bsh
,
395 struct nubus_attach_args
*na
)
400 case NUBUS_DRSW_3COM
:
402 case NUBUS_DRHW_APPLE_SN
:
403 case NUBUS_DRHW_APPLE_SNT
:
404 vendor
= DP8390_VENDOR_UNKNOWN
;
407 vendor
= DP8390_VENDOR_APPLE
;
411 case NUBUS_DRSW_APPLE
:
412 if (na
->drhw
== NUBUS_DRHW_ASANTE_LC
) {
413 vendor
= DP8390_VENDOR_UNKNOWN
;
417 case NUBUS_DRSW_DAYNA2
:
418 case NUBUS_DRSW_TECHWORKS
:
419 case NUBUS_DRSW_TFLLAN
:
420 if (na
->drhw
== NUBUS_DRHW_CABLETRON
) {
421 vendor
= DP8390_VENDOR_CABLETRON
;
423 vendor
= DP8390_VENDOR_APPLE
;
426 case NUBUS_DRSW_ASANTE
:
427 vendor
= DP8390_VENDOR_ASANTE
;
429 case NUBUS_DRSW_FARALLON
:
430 vendor
= DP8390_VENDOR_FARALLON
;
432 case NUBUS_DRSW_GATOR
:
435 case NUBUS_DRHW_INTERLAN
:
436 vendor
= DP8390_VENDOR_INTERLAN
;
438 case NUBUS_DRHW_KINETICS
:
439 if (strncmp(nubus_get_card_name(bst
, bsh
, na
->fmt
),
440 "EtherPort", 9) == 0)
441 vendor
= DP8390_VENDOR_KINETICS
;
443 vendor
= DP8390_VENDOR_DAYNA
;
448 vendor
= DP8390_VENDOR_UNKNOWN
;
454 ae_nb_get_enaddr(bus_space_tag_t bst
, bus_space_handle_t bsh
,
455 struct nubus_attach_args
*na
, u_int8_t
*ep
)
462 * XXX - note hardwired resource IDs here; these are assumed to
463 * be used by all cards, but should be fixed when we find out
464 * more about Ethernet card resources.
466 nubus_get_main_dir(na
->fmt
, &dir
);
467 switch (ae_nb_card_vendor(bst
, bsh
, na
)) {
468 case DP8390_VENDOR_APPLE
:
469 if (na
->drsw
== NUBUS_DRSW_TFLLAN
) { /* TFL LAN E410/E420 */
470 rv
= nubus_find_rsrc(bst
, bsh
, na
->fmt
,
471 &dir
, 0x08, &dirent
);
476 rv
= nubus_find_rsrc(bst
, bsh
, na
->fmt
, &dir
, 0x80, &dirent
);
481 nubus_get_dir_from_rsrc(na
->fmt
, &dirent
, &dir
);
482 if (nubus_find_rsrc(bst
, bsh
, na
->fmt
, &dir
, 0x80, &dirent
) <= 0)
484 if (nubus_get_ind_data(bst
, bsh
,
485 na
->fmt
, &dirent
, ep
, ETHER_ADDR_LEN
) <= 0)
493 ae_nb_watchdog(struct ifnet
*ifp
)
495 struct dp8390_softc
*sc
= ifp
->if_softc
;
498 * This is a kludge! The via code seems to miss slot interrupts
499 * sometimes. This kludges around that by calling the handler
500 * by hand if the watchdog is activated. -- XXX (akb)
502 (*via2itab
[1])((void *)1);
504 log(LOG_ERR
, "%s: device timeout\n", device_xname(sc
->sc_dev
));