1 /* $NetBSD: if_tr_isa.c,v 1.22 2009/05/12 08:44:19 cegger Exp $ */
3 /* XXXJRT changes isa_attach_args too early!! */
6 * Copyright (c) 1999 The NetBSD Foundation, Inc.
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Onno van der Linden.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: if_tr_isa.c,v 1.22 2009/05/12 08:44:19 cegger Exp $");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/socket.h>
42 #include <sys/device.h>
45 #include <net/if_ether.h>
46 #include <net/if_media.h>
52 #include <dev/isa/isavar.h>
54 #include <dev/ic/tropicreg.h>
55 #include <dev/ic/tropicvar.h>
58 int tr_isa_probe(device_t
, cfdata_t
, void *);
59 int trtcm_isa_probe(device_t
, cfdata_t
, void *);
60 int tribm_isa_probe(device_t
, cfdata_t
, void *);
61 void tr_isa_attach(device_t
, device_t
, void *);
62 int tr_isa_map_io(struct isa_attach_args
*, bus_space_handle_t
*,
63 bus_space_handle_t
*);
64 void tr_isa_unmap_io(struct isa_attach_args
*, bus_space_handle_t
,
66 int trtcm_isa_mediachange(struct tr_softc
*);
67 void trtcm_isa_mediastatus(struct tr_softc
*, struct ifmediareq
*);
69 void tr_isa_dumpaip(bus_space_tag_t
, bus_space_handle_t
);
73 * List of manufacturer specific probe routines. Order is important.
75 int (*tr_isa_probe_list
[])(device_t
, cfdata_t
, void *) = {
81 CFATTACH_DECL(tr_isa
, sizeof(struct tr_softc
),
82 tr_isa_probe
, tr_isa_attach
, NULL
, NULL
);
85 tr_isa_map_io(struct isa_attach_args
*ia
, bus_space_handle_t
*pioh
, bus_space_handle_t
*mmioh
)
90 if (bus_space_map(ia
->ia_iot
, ia
->ia_io
[0].ir_addr
,
91 ia
->ia_io
[0].ir_size
, 0, pioh
)) {
92 printf("tr_isa_map_io: can't map PIO ports\n");
96 /* Read adapter switches and calculate addresses of MMIO. */
97 s
= bus_space_read_1(ia
->ia_iot
, *pioh
, TR_SWITCH
);
99 if ((s
& 0xfc) < ((TR_MMIO_MINADDR
- TR_MMIO_OFFSET
) >> 11) ||
100 (s
& 0xfc) > ((TR_MMIO_MAXADDR
- TR_MMIO_OFFSET
) >> 11)) {
101 bus_space_unmap(ia
->ia_iot
, *pioh
, ia
->ia_io
[0].ir_size
);
105 mmio
= ((s
& 0xfc) << 11) + TR_MMIO_OFFSET
;
106 if (bus_space_map(ia
->ia_memt
, mmio
, TR_MMIO_SIZE
, 0, mmioh
)) {
107 printf("tr_isa_map_io: can't map MMIO region 0x%05lx/%d\n",
108 (u_long
)mmio
, TR_MMIO_SIZE
);
109 bus_space_unmap(ia
->ia_iot
, *pioh
, ia
->ia_io
[0].ir_size
);
116 tr_isa_unmap_io(struct isa_attach_args
*ia
, bus_space_handle_t pioh
, bus_space_handle_t mmioh
)
118 bus_space_unmap(ia
->ia_memt
, mmioh
, TR_MMIO_SIZE
);
119 bus_space_unmap(ia
->ia_iot
, pioh
, ia
->ia_io
[0].ir_size
);
122 static u_char tr_isa_id
[] = {
123 5, 0, 4, 9, 4, 3, 4, 15, 3, 6, 3, 1, 3, 1, 3, 0, 3, 9, 3, 9, 3, 0, 2, 0
127 * XXX handle multiple IBM TR cards (sram mapping !!)
131 tr_isa_probe(device_t parent
, cfdata_t match
, void *aux
)
133 struct isa_attach_args
*ia
= aux
;
136 bus_space_handle_t sramh
, pioh
, mmioh
;
142 if (ia
->ia_niomem
< 1)
147 if (ISA_DIRECT_CONFIG(ia
))
150 for (i
= 0; tr_isa_probe_list
[i
] != 0; i
++) {
151 probecode
= tr_isa_probe_list
[i
](parent
, match
, aux
);
153 return 0; /* Fail instantly. */
155 break; /* We have a match. */
157 if (tr_isa_probe_list
[i
] == 0)
158 return 0; /* Nothing matched. */
159 if (tr_isa_map_io(ia
, &pioh
, &mmioh
))
161 tr_id
= TR_ID_OFFSET
;
163 for (i
= 0; i
< sizeof(tr_isa_id
); i
++) {
164 if (bus_space_read_1(ia
->ia_memt
, mmioh
, tr_id
) !=
170 tr_isa_dumpaip(ia
->ia_memt
, mmioh
);
172 tr_isa_unmap_io(ia
, pioh
, mmioh
);
176 if (bus_space_map(ia
->ia_memt
, ia
->ia_iomem
[0].ir_addr
,
177 ia
->ia_iomem
[0].ir_size
, 0, &sramh
)) {
178 printf("tr_isa_probe: can't map shared ram\n");
181 bus_space_unmap(ia
->ia_memt
, sramh
, ia
->ia_iomem
[0].ir_size
);
192 int trtcm_setspeed(struct tr_softc
*, int);
195 tr_isa_attach(device_t parent
, device_t self
, void *aux
)
197 struct tr_softc
*sc
= (void *) self
;
198 struct isa_attach_args
*ia
= aux
;
202 sc
->sc_piot
= ia
->ia_iot
;
203 sc
->sc_memt
= ia
->ia_memt
;
204 if (tr_isa_map_io(ia
, &sc
->sc_pioh
, &sc
->sc_mmioh
)) {
205 printf("tr_isa_attach: IO space vanished\n");
208 if (bus_space_map(sc
->sc_memt
, ia
->ia_iomem
[0].ir_addr
,
209 ia
->ia_iomem
[0].ir_size
, 0, &sc
->sc_sramh
)) {
210 printf("tr_isa_attach: shared ram space vanished\n");
214 sc
->sc_aca
= TR_ACA_OFFSET
;
215 sc
->sc_memwinsz
= ia
->ia_iomem
[0].ir_size
;
216 sc
->sc_maddr
= ia
->ia_iomem
[0].ir_addr
;
218 * Determine total RAM on adapter and decide how much to use.
219 * XXX Since we don't use RAM paging, use sc_memwinsz for now.
221 sc
->sc_memsize
= sc
->sc_memwinsz
;
222 sc
->sc_memreserved
= 0;
224 if (tr_reset(sc
) != 0)
227 if (ia
->ia_aux
!= NULL
) {
228 sc
->sc_mediastatus
= trtcm_isa_mediastatus
;
229 sc
->sc_mediachange
= trtcm_isa_mediachange
;
232 sc
->sc_mediastatus
= NULL
;
233 sc
->sc_mediachange
= NULL
;
236 if (tr_attach(sc
) != 0)
240 * XXX 3Com 619 can use LEVEL intr
242 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
243 IST_EDGE
, IPL_NET
, tr_intr
, sc
);
248 * Dump the adapters AIP
251 tr_isa_dumpaip(bus_space_tag_t memt
, bus_space_handle_t mmioh
)
253 unsigned int off
, val
;
254 printf("AIP contents:");
255 for (off
=0; off
< 256; off
++) {
256 val
= bus_space_read_1(memt
, mmioh
, TR_MAC_OFFSET
+ off
);
259 printf("%02x ", val
);