1 /* $NetBSD: if_tlp_eisa.c,v 1.22 2009/04/17 10:20:32 cegger Exp $ */
4 * Copyright (c) 1999, 2000 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 * EISA bus front-end for the Digital Semiconductor ``Tulip'' (21x4x)
35 * Ethernet controller family driver.
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: if_tlp_eisa.c,v 1.22 2009/04/17 10:20:32 cegger Exp $");
44 #include <sys/param.h>
45 #include <sys/systm.h>
47 #include <sys/malloc.h>
48 #include <sys/kernel.h>
49 #include <sys/socket.h>
50 #include <sys/ioctl.h>
51 #include <sys/errno.h>
52 #include <sys/device.h>
54 #include <machine/endian.h>
57 #include <net/if_dl.h>
58 #include <net/if_media.h>
59 #include <net/if_ether.h>
66 #include <netinet/in.h>
67 #include <netinet/if_inarp.h>
74 #include <dev/mii/miivar.h>
75 #include <dev/mii/mii_bitbang.h>
77 #include <dev/ic/tulipreg.h>
78 #include <dev/ic/tulipvar.h>
80 #include <dev/eisa/eisareg.h>
81 #include <dev/eisa/eisavar.h>
82 #include <dev/eisa/eisadevs.h>
84 #include <dev/pci/pcireg.h>
87 * DE425 configuration registers; literal offsets from CSR base.
88 * This is effectively the 21040 PCI configuration space interleaved
89 * into the CSR space (CSRs are space 16 bytes on the DE425).
91 * What a cool address decoder hack they must have on that board...
93 #define DE425_CFID 0x08 /* Configuration ID */
94 #define DE425_CFCS 0x0c /* Configuration Command-Status */
95 #define DE425_CFRV 0x18 /* Configuration Revision */
96 #define DE425_CFLT 0x1c /* Configuration Latency Timer */
97 #define DE425_CBIO 0x28 /* Configuration Base I/O Address */
98 #define DE425_CFDA 0x2c /* Configuration Driver Area */
99 #define DE425_ENETROM 0xc90 /* Offset in I/O space for ENETROM */
100 #define DE425_CFG0 0xc88 /* IRQ Configuration Register */
102 struct tulip_eisa_softc
{
103 struct tulip_softc sc_tulip
; /* real Tulip softc */
105 /* EISA-specific goo. */
106 void *sc_ih
; /* interrupt handle */
109 static int tlp_eisa_match(device_t
, cfdata_t
, void *);
110 static void tlp_eisa_attach(device_t
, device_t
, void *);
112 CFATTACH_DECL_NEW(tlp_eisa
, sizeof(struct tulip_eisa_softc
),
113 tlp_eisa_match
, tlp_eisa_attach
, NULL
, NULL
);
115 static const int tlp_eisa_irqs
[] = { 5, 9, 10, 11 };
117 static const struct tulip_eisa_product
{
118 const char *tep_eisaid
; /* EISA ID */
119 const char *tep_name
; /* device name */
120 tulip_chip_t tep_chip
; /* base Tulip chip type */
121 } tlp_eisa_products
[] = {
122 { "DEC4250", "DEC DE425",
126 TULIP_CHIP_INVALID
},
129 static const struct tulip_eisa_product
*
130 tlp_eisa_lookup(const struct eisa_attach_args
*ea
)
132 const struct tulip_eisa_product
*tep
;
134 for (tep
= tlp_eisa_products
;
135 tep
->tep_chip
!= TULIP_CHIP_INVALID
; tep
++)
136 if (strcmp(ea
->ea_idstring
, tep
->tep_eisaid
) == 0)
142 tlp_eisa_match(device_t parent
, cfdata_t match
,
145 struct eisa_attach_args
*ea
= aux
;
147 if (tlp_eisa_lookup(ea
) != NULL
)
154 tlp_eisa_attach(device_t parent
, device_t self
, void *aux
)
156 static const u_int8_t testpat
[] =
157 { 0xff, 0, 0x55, 0xaa, 0xff, 0, 0x55, 0xaa };
158 struct tulip_eisa_softc
*esc
= device_private(self
);
159 struct tulip_softc
*sc
= &esc
->sc_tulip
;
160 struct eisa_attach_args
*ea
= aux
;
161 eisa_chipset_tag_t ec
= ea
->ea_ec
;
162 eisa_intr_handle_t ih
;
163 bus_space_tag_t iot
= ea
->ea_iot
;
164 bus_space_handle_t ioh
;
166 const struct tulip_eisa_product
*tep
;
167 u_int8_t enaddr
[ETHER_ADDR_LEN
], tmpbuf
[sizeof(testpat
)];
174 if (bus_space_map(iot
, EISA_SLOT_ADDR(ea
->ea_slot
),
175 EISA_SLOT_SIZE
, 0, &ioh
)) {
176 printf(": unable to map I/O space\n");
184 tep
= tlp_eisa_lookup(ea
);
187 panic("tlp_eisa_attach: impossible");
189 sc
->sc_chip
= tep
->tep_chip
;
192 * DE425's registers are 16 bytes long; the PCI configuration
193 * space registers are interleaved in the I/O space.
198 * No power management hooks.
200 sc
->sc_flags
|= TULIPF_ENABLED
;
203 * CBIO must map the EISA slot, and I/O access and Bus Mastering
206 bus_space_write_4(iot
, ioh
, DE425_CBIO
, EISA_SLOT_ADDR(ea
->ea_slot
));
207 bus_space_write_4(iot
, ioh
, DE425_CFCS
,
208 bus_space_read_4(iot
, ioh
, DE425_CFCS
) |
209 PCI_COMMAND_IO_ENABLE
| PCI_COMMAND_MASTER_ENABLE
);
214 sc
->sc_rev
= bus_space_read_4(iot
, ioh
, DE425_CFRV
) & 0xff;
216 printf(": %s Ethernet, pass %d.%d\n",
217 tep
->tep_name
, (sc
->sc_rev
>> 4) & 0xf, sc
->sc_rev
& 0xf);
219 sc
->sc_dmat
= ea
->ea_dmat
;
222 * EISA doesn't have a cache line register.
224 sc
->sc_cacheline
= 0;
227 * Find the beginning of the Ethernet Address ROM.
229 for (i
= 0, cnt
= 0; i
< sizeof(testpat
) && cnt
< 32; cnt
++) {
230 tmpbuf
[i
] = bus_space_read_1(iot
, ioh
, DE425_ENETROM
);
231 if (tmpbuf
[i
] == testpat
[i
])
238 * ...and now read the contents of the Ethernet Address ROM.
240 sc
->sc_srom
= malloc(32, M_DEVBUF
, M_WAITOK
|M_ZERO
);
241 for (i
= 0; i
< 32; i
++)
242 sc
->sc_srom
[i
] = bus_space_read_1(iot
, ioh
, DE425_ENETROM
);
245 * None of the DE425 boards have the new-style SROMs.
247 if (tlp_parse_old_srom(sc
, enaddr
) == 0) {
248 aprint_error_dev(self
, "unable to decode old-style SROM\n");
253 * All DE425 boards use the 21040 media switch.
255 sc
->sc_mediasw
= &tlp_21040_mediasw
;
258 * Figure out which IRQ we want to use, and determine of it's
259 * edge- or level-triggered.
261 val
= bus_space_read_4(iot
, ioh
, DE425_CFG0
);
262 irq
= tlp_eisa_irqs
[(val
>> 1) & 0x03];
265 * Map and establish our interrupt.
267 if (eisa_intr_map(ec
, irq
, &ih
)) {
268 aprint_error_dev(self
, "unable to map interrupt (%u)\n",
272 intrstr
= eisa_intr_string(ec
, ih
);
273 esc
->sc_ih
= eisa_intr_establish(ec
, ih
,
274 (val
& 0x01) ? IST_EDGE
: IST_LEVEL
, IPL_NET
, tlp_intr
, sc
);
275 if (esc
->sc_ih
== NULL
) {
276 aprint_error_dev(self
, "unable to establish interrupt");
278 aprint_error(" at %s", intrstr
);
283 aprint_normal_dev(self
, "interrupting at %s\n", intrstr
);
286 * Finish off the attach.
288 tlp_attach(sc
, enaddr
);