1 /* $NetBSD: if_cs_isa.c,v 1.24 2009/09/22 14:55:19 tsutsui Exp $ */
5 * Digital Equipment Corporation. All rights reserved.
7 * This software is furnished under license and may be used and
8 * copied only in accordance with the following terms and conditions.
9 * Subject to these conditions, you may download, copy, install,
10 * use, modify and distribute this software in source and/or binary
11 * form. No title or ownership is transferred hereby.
13 * 1) Any source code used, modified or distributed must reproduce
14 * and retain this copyright notice and list of conditions as
15 * they appear in the source file.
17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Digital Equipment Corporation. Neither the "Digital Equipment
19 * Corporation" name nor any trademark or logo of Digital Equipment
20 * Corporation may be used to endorse or promote products derived
21 * from this software without the prior written permission of
22 * Digital Equipment Corporation.
24 * 3) This software is provided "AS-IS" and any express or implied
25 * warranties, including but not limited to, any implied warranties
26 * of merchantability, fitness for a particular purpose, or
27 * non-infringement are disclaimed. In no event shall DIGITAL be
28 * liable for any damages whatsoever, and in particular, DIGITAL
29 * shall not be liable for special, indirect, consequential, or
30 * incidental damages or damages for lost profits, loss of
31 * revenue or loss of use, whether such damages arise in contract,
32 * negligence, tort, under statute, in equity, at law or otherwise,
33 * even if advised of the possibility of such damage.
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: if_cs_isa.c,v 1.24 2009/09/22 14:55:19 tsutsui Exp $");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/socket.h>
42 #include <sys/device.h>
50 #include <net/if_ether.h>
51 #include <net/if_media.h>
56 #include <dev/isa/isareg.h>
57 #include <dev/isa/isavar.h>
58 #include <dev/isa/isadmavar.h>
60 #include <dev/ic/cs89x0reg.h>
61 #include <dev/ic/cs89x0var.h>
62 #include <dev/isa/cs89x0isavar.h>
64 static int cs_isa_probe(device_t
, cfdata_t
, void *);
65 static void cs_isa_attach(device_t
, device_t
, void *);
67 CFATTACH_DECL_NEW(cs_isa
, sizeof(struct cs_softc_isa
),
68 cs_isa_probe
, cs_isa_attach
, NULL
, NULL
);
71 cs_isa_probe(device_t parent
, cfdata_t cf
, void *aux
)
73 struct isa_attach_args
*ia
= aux
;
74 bus_space_tag_t iot
= ia
->ia_iot
;
75 bus_space_tag_t memt
= ia
->ia_memt
;
76 bus_space_handle_t ioh
, memh
;
78 int rv
= 0, have_io
= 0, have_mem
= 0;
79 u_int16_t isa_cfg
, isa_membase
;
87 if (ISA_DIRECT_CONFIG(ia
))
91 * Disallow wildcarded I/O base.
93 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
96 if (ia
->ia_niomem
> 0)
97 maddr
= ia
->ia_iomem
[0].ir_addr
;
99 maddr
= ISA_UNKNOWN_IOMEM
;
104 if (bus_space_map(ia
->ia_iot
, ia
->ia_io
[0].ir_addr
, CS8900_IOSIZE
,
109 memset(&sc
, 0, sizeof sc
);
112 /* Verify that it's a Crystal product. */
113 if (CS_READ_PACKET_PAGE_IO(&sc
, PKTPG_EISA_NUM
) !=
118 * Verify that it's a supported chip.
120 switch (CS_READ_PACKET_PAGE_IO(&sc
, PKTPG_PRODUCT_ID
) &
125 case PROD_ID_CS8920M
:
129 /* invalid product ID */
134 * If the IRQ or memory address were not specified, read the
135 * ISA_CFG EEPROM location.
137 if (maddr
== ISA_UNKNOWN_IOMEM
||
138 ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
) {
139 if (cs_verify_eeprom(&sc
) == CS_ERROR
) {
140 printf("cs_isa_probe: EEPROM bad or missing\n");
143 if (cs_read_eeprom(&sc
, EEPROM_ISA_CFG
, &isa_cfg
)
145 printf("cs_isa_probe: unable to read ISA_CFG\n");
151 * If the IRQ wasn't specified, get it from the EEPROM.
153 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
) {
154 irq
= isa_cfg
& ISA_CFG_IRQ_MASK
;
160 irq
= ia
->ia_irq
[0].ir_irq
;
163 * If the memory address wasn't specified, get it from the EEPROM.
165 if (maddr
== ISA_UNKNOWN_IOMEM
) {
166 if ((isa_cfg
& ISA_CFG_MEM_MODE
) == 0) {
167 /* EEPROM says don't use memory mode. */
170 if (cs_read_eeprom(&sc
, EEPROM_MEM_BASE
, &isa_membase
)
172 printf("cs_isa_probe: unable to read MEM_BASE\n");
176 isa_membase
&= MEM_BASE_MASK
;
177 maddr
= (int)isa_membase
<< 8;
181 * We now have a valid mem address; attempt to map it.
183 if (bus_space_map(ia
->ia_memt
, maddr
, CS8900_MEMSIZE
, 0, &memh
)) {
184 /* Can't map it; fall back on i/o-only mode. */
185 printf("cs_isa_probe: unable to map memory space\n");
186 maddr
= ISA_UNKNOWN_IOMEM
;
191 ia
->ia_io
[0].ir_size
= CS8900_IOSIZE
;
193 if (maddr
== ISA_UNKNOWN_IOMEM
)
197 ia
->ia_iomem
[0].ir_addr
= maddr
;
198 ia
->ia_iomem
[0].ir_size
= CS8900_MEMSIZE
;
202 ia
->ia_irq
[0].ir_irq
= irq
;
208 bus_space_unmap(iot
, ioh
, CS8900_IOSIZE
);
210 bus_space_unmap(memt
, memh
, CS8900_MEMSIZE
);
216 cs_isa_attach(device_t parent
, device_t self
, void *aux
)
218 struct cs_softc_isa
*isc
= device_private(self
);
219 struct cs_softc
*sc
= &isc
->sc_cs
;
220 struct isa_attach_args
*ia
= aux
;
223 isc
->sc_ic
= ia
->ia_ic
;
224 sc
->sc_iot
= ia
->ia_iot
;
225 sc
->sc_memt
= ia
->ia_memt
;
228 isc
->sc_drq
= ia
->ia_drq
[0].ir_drq
;
232 sc
->sc_irq
= ia
->ia_irq
[0].ir_irq
;
239 if (bus_space_map(sc
->sc_iot
, ia
->ia_io
[0].ir_addr
, CS8900_IOSIZE
,
241 aprint_error_dev(self
, "unable to map i/o space\n");
248 if (CS8900_IRQ_ISVALID(sc
->sc_irq
) == 0) {
249 aprint_error_dev(self
, "invalid IRQ %d\n", sc
->sc_irq
);
254 * Map the memory space if it was specified. If we can do this,
255 * we set ourselves up to use memory mode forever. Otherwise,
256 * we fall back on I/O mode.
258 if (ia
->ia_iomem
[0].ir_addr
!= ISA_UNKNOWN_IOMEM
&&
259 ia
->ia_iomem
[0].ir_size
== CS8900_MEMSIZE
&&
260 CS8900_MEMBASE_ISVALID(ia
->ia_iomem
[0].ir_addr
)) {
261 if (bus_space_map(sc
->sc_memt
, ia
->ia_iomem
[0].ir_addr
,
262 CS8900_MEMSIZE
, 0, &sc
->sc_memh
)) {
263 aprint_error_dev(self
, "unable to map memory space\n");
265 sc
->sc_cfgflags
|= CFGFLG_MEM_MODE
;
266 sc
->sc_pktpgaddr
= ia
->ia_iomem
[0].ir_addr
;
270 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, sc
->sc_irq
, IST_EDGE
,
271 IPL_NET
, cs_intr
, sc
);
272 if (sc
->sc_ih
== NULL
) {
273 aprint_error_dev(self
, "unable to establish interrupt\n");
277 sc
->sc_dma_chipinit
= cs_isa_dma_chipinit
;
278 sc
->sc_dma_attach
= cs_isa_dma_attach
;
279 sc
->sc_dma_process_rx
= cs_process_rx_dma
;
281 cs_attach(sc
, NULL
, NULL
, 0, 0);