1 /* $NetBSD: if_ix.c,v 1.32 2009/05/12 08:44:19 cegger Exp $ */
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: if_ix.c,v 1.32 2009/05/12 08:44:19 cegger Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
38 #include <sys/errno.h>
39 #include <sys/device.h>
40 #include <sys/protosw.h>
41 #include <sys/socket.h>
44 #include <net/if_dl.h>
45 #include <net/if_types.h>
46 #include <net/if_media.h>
47 #include <net/if_ether.h>
53 #include <dev/isa/isareg.h>
54 #include <dev/isa/isavar.h>
56 #include <dev/ic/i82586reg.h>
57 #include <dev/ic/i82586var.h>
58 #include <dev/isa/if_ixreg.h>
61 #define DPRINTF(x) printf x
71 #define NIX_MEDIA (sizeof(ix_media) / sizeof(ix_media[0]))
74 struct ie_softc sc_ie
;
76 bus_space_tag_t sc_regt
; /* space tag for registers */
77 bus_space_handle_t sc_regh
; /* space handle for registers */
79 u_int8_t use_pio
; /* use PIO rather than shared mem */
80 u_int16_t irq_encoded
; /* encoded IRQ */
81 void *sc_ih
; /* interrupt handle */
84 static void ix_reset(struct ie_softc
*, int);
85 static void ix_atten(struct ie_softc
*, int);
86 static int ix_intrhook(struct ie_softc
*, int);
88 static void ix_copyin(struct ie_softc
*, void *, int, size_t);
89 static void ix_copyout(struct ie_softc
*, const void *, int, size_t);
91 static void ix_bus_barrier(struct ie_softc
*, int, int, int);
93 static u_int16_t
ix_read_16(struct ie_softc
*, int);
94 static void ix_write_16(struct ie_softc
*, int, u_int16_t
);
95 static void ix_write_24(struct ie_softc
*, int, int);
96 static void ix_zeromem (struct ie_softc
*, int, int);
98 static void ix_mediastatus(struct ie_softc
*, struct ifmediareq
*);
100 static u_int16_t
ix_read_eeprom(bus_space_tag_t
, bus_space_handle_t
, int);
101 static void ix_eeprom_outbits(bus_space_tag_t
, bus_space_handle_t
, int, int);
102 static int ix_eeprom_inbits (bus_space_tag_t
, bus_space_handle_t
);
103 static void ix_eeprom_clock (bus_space_tag_t
, bus_space_handle_t
, int);
105 int ix_match(device_t
, cfdata_t
, void *);
106 void ix_attach(device_t
, device_t
, void *);
109 * EtherExpress/16 support routines
112 ix_reset(struct ie_softc
*sc
, int why
)
114 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
118 bus_space_write_1(isc
->sc_regt
, isc
->sc_regh
, IX_ECTRL
,
121 bus_space_write_1(isc
->sc_regt
, isc
->sc_regh
, IX_ECTRL
, 0);
131 ix_atten(struct ie_softc
*sc
, int why
)
133 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
134 bus_space_write_1(isc
->sc_regt
, isc
->sc_regh
, IX_ATTN
, 0);
138 ix_read_eeprom(bus_space_tag_t iot
, bus_space_handle_t ioh
, int location
)
142 ectrl
= bus_space_read_1(iot
, ioh
, IX_ECTRL
);
143 ectrl
&= IX_ECTRL_MASK
;
144 ectrl
|= IX_ECTRL_EECS
;
145 bus_space_write_1(iot
, ioh
, IX_ECTRL
, ectrl
);
147 ix_eeprom_outbits(iot
, ioh
, IX_EEPROM_READ
, IX_EEPROM_OPSIZE1
);
148 ix_eeprom_outbits(iot
, ioh
, location
, IX_EEPROM_ADDR_SIZE
);
149 edata
= ix_eeprom_inbits(iot
, ioh
);
150 ectrl
= bus_space_read_1(iot
, ioh
, IX_ECTRL
);
151 ectrl
&= ~(IX_RESET_ASIC
| IX_ECTRL_EEDI
| IX_ECTRL_EECS
);
152 bus_space_write_1(iot
, ioh
, IX_ECTRL
, ectrl
);
153 ix_eeprom_clock(iot
, ioh
, 1);
154 ix_eeprom_clock(iot
, ioh
, 0);
159 ix_eeprom_outbits(bus_space_tag_t iot
, bus_space_handle_t ioh
, int edata
, int count
)
163 ectrl
= bus_space_read_1(iot
, ioh
, IX_ECTRL
);
164 ectrl
&= ~IX_RESET_ASIC
;
165 for (i
= count
- 1; i
>= 0; i
--) {
166 ectrl
&= ~IX_ECTRL_EEDI
;
167 if (edata
& (1 << i
)) {
168 ectrl
|= IX_ECTRL_EEDI
;
170 bus_space_write_1(iot
, ioh
, IX_ECTRL
, ectrl
);
171 delay(1); /* eeprom data must be setup for 0.4 uSec */
172 ix_eeprom_clock(iot
, ioh
, 1);
173 ix_eeprom_clock(iot
, ioh
, 0);
175 ectrl
&= ~IX_ECTRL_EEDI
;
176 bus_space_write_1(iot
, ioh
, IX_ECTRL
, ectrl
);
177 delay(1); /* eeprom data must be held for 0.4 uSec */
181 ix_eeprom_inbits(bus_space_tag_t iot
, bus_space_handle_t ioh
)
185 ectrl
= bus_space_read_1(iot
, ioh
, IX_ECTRL
);
186 ectrl
&= ~IX_RESET_ASIC
;
187 for (edata
= 0, i
= 0; i
< 16; i
++) {
189 ix_eeprom_clock(iot
, ioh
, 1);
190 ectrl
= bus_space_read_1(iot
, ioh
, IX_ECTRL
);
191 if (ectrl
& IX_ECTRL_EEDO
) {
194 ix_eeprom_clock(iot
, ioh
, 0);
200 ix_eeprom_clock(bus_space_tag_t iot
, bus_space_handle_t ioh
, int state
)
204 ectrl
= bus_space_read_1(iot
, ioh
, IX_ECTRL
);
205 ectrl
&= ~(IX_RESET_ASIC
| IX_ECTRL_EESK
);
207 ectrl
|= IX_ECTRL_EESK
;
209 bus_space_write_1(iot
, ioh
, IX_ECTRL
, ectrl
);
210 delay(9); /* EESK must be stable for 8.38 uSec */
214 ix_intrhook(struct ie_softc
*sc
, int where
)
216 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
220 /* entering ISR: disable card interrupts */
221 bus_space_write_1(isc
->sc_regt
, isc
->sc_regh
,
222 IX_IRQ
, isc
->irq_encoded
);
226 /* exiting ISR: re-enable card interrupts */
227 bus_space_write_1(isc
->sc_regt
, isc
->sc_regh
, IX_IRQ
,
228 isc
->irq_encoded
| IX_IRQ_ENABLE
);
237 ix_copyin (struct ie_softc
*sc
, void *dst
, int offset
, size_t size
)
240 u_int8_t
* bptr
= dst
;
241 u_int16_t
* wptr
= dst
;
242 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
245 /* Reset read pointer to the specified offset */
246 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2,
247 BUS_SPACE_BARRIER_READ
);
248 bus_space_write_2(sc
->bt
, sc
->bh
, IX_READPTR
, offset
);
249 bus_space_barrier(sc
->bt
, sc
->bh
, IX_READPTR
, 2,
250 BUS_SPACE_BARRIER_WRITE
);
252 bus_space_barrier(sc
->bt
, sc
->bh
, offset
, size
,
253 BUS_SPACE_BARRIER_READ
);
258 *bptr
= bus_space_read_1(sc
->bt
, sc
->bh
, IX_DATAPORT
);
260 *bptr
= bus_space_read_1(sc
->bt
, sc
->bh
, offset
);
261 offset
++; bptr
++; size
--;
265 wptr
= (u_int16_t
*) bptr
;
268 for(i
= 0; i
< size
/ 2; i
++) {
269 *wptr
= bus_space_read_2(sc
->bt
, sc
->bh
, IX_DATAPORT
);
273 bus_space_read_region_2(sc
->bt
, sc
->bh
, offset
,
274 (u_int16_t
*) bptr
, size
/ 2);
282 *bptr
= bus_space_read_1(sc
->bt
, sc
->bh
, IX_DATAPORT
);
284 *bptr
= bus_space_read_1(sc
->bt
, sc
->bh
, offset
);
289 ix_copyout (struct ie_softc
*sc
, const void *src
, int offset
, size_t size
)
293 int ooffset
= offset
;
294 const u_int8_t
* bptr
= src
;
295 const u_int16_t
* wptr
= src
;
296 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
299 /* Reset write pointer to the specified offset */
300 bus_space_write_2(sc
->bt
, sc
->bh
, IX_WRITEPTR
, offset
);
301 bus_space_barrier(sc
->bt
, sc
->bh
, IX_WRITEPTR
, 2,
302 BUS_SPACE_BARRIER_WRITE
);
307 bus_space_write_1(sc
->bt
, sc
->bh
, IX_DATAPORT
, *bptr
);
309 bus_space_write_1(sc
->bt
, sc
->bh
, offset
, *bptr
);
310 offset
++; bptr
++; size
--;
314 wptr
= (const u_int16_t
*) bptr
;
317 for(i
= 0; i
< size
/ 2; i
++) {
318 bus_space_write_2(sc
->bt
, sc
->bh
, IX_DATAPORT
, *wptr
);
322 bus_space_write_region_2(sc
->bt
, sc
->bh
, offset
,
323 (const u_int16_t
*)bptr
, size
/ 2);
331 bus_space_write_1(sc
->bt
, sc
->bh
, IX_DATAPORT
, *bptr
);
333 bus_space_write_1(sc
->bt
, sc
->bh
, offset
, *bptr
);
337 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2,
338 BUS_SPACE_BARRIER_WRITE
);
340 bus_space_barrier(sc
->bt
, sc
->bh
, ooffset
, osize
,
341 BUS_SPACE_BARRIER_WRITE
);
345 ix_bus_barrier(struct ie_softc
*sc
, int offset
, int length
, int flags
)
347 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
350 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2, flags
);
352 bus_space_barrier(sc
->bt
, sc
->bh
, offset
, length
, flags
);
356 ix_read_16 (struct ie_softc
*sc
, int offset
)
358 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
361 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2,
362 BUS_SPACE_BARRIER_READ
);
364 /* Reset read pointer to the specified offset */
365 bus_space_write_2(sc
->bt
, sc
->bh
, IX_READPTR
, offset
);
366 bus_space_barrier(sc
->bt
, sc
->bh
, IX_READPTR
, 2,
367 BUS_SPACE_BARRIER_WRITE
);
369 return bus_space_read_2(sc
->bt
, sc
->bh
, IX_DATAPORT
);
371 bus_space_barrier(sc
->bt
, sc
->bh
, offset
, 2,
372 BUS_SPACE_BARRIER_READ
);
373 return bus_space_read_2(sc
->bt
, sc
->bh
, offset
);
378 ix_write_16 (struct ie_softc
*sc
, int offset
, u_int16_t value
)
380 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
383 /* Reset write pointer to the specified offset */
384 bus_space_write_2(sc
->bt
, sc
->bh
, IX_WRITEPTR
, offset
);
385 bus_space_barrier(sc
->bt
, sc
->bh
, IX_WRITEPTR
, 2,
386 BUS_SPACE_BARRIER_WRITE
);
388 bus_space_write_2(sc
->bt
, sc
->bh
, IX_DATAPORT
, value
);
389 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2,
390 BUS_SPACE_BARRIER_WRITE
);
392 bus_space_write_2(sc
->bt
, sc
->bh
, offset
, value
);
393 bus_space_barrier(sc
->bt
, sc
->bh
, offset
, 2,
394 BUS_SPACE_BARRIER_WRITE
);
399 ix_write_24 (struct ie_softc
*sc
, int offset
, int addr
)
402 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
403 int val
= addr
+ (u_long
) sc
->sc_maddr
- (u_long
) sc
->sc_iobase
;
406 /* Reset write pointer to the specified offset */
407 bus_space_write_2(sc
->bt
, sc
->bh
, IX_WRITEPTR
, offset
);
408 bus_space_barrier(sc
->bt
, sc
->bh
, IX_WRITEPTR
, 2,
409 BUS_SPACE_BARRIER_WRITE
);
412 bus_space_write_2(sc
->bt
, sc
->bh
, IX_DATAPORT
,
413 *((u_int16_t
*)ptr
));
414 bus_space_write_2(sc
->bt
, sc
->bh
, IX_DATAPORT
,
415 *((u_int16_t
*)(ptr
+ 2)));
416 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2,
417 BUS_SPACE_BARRIER_WRITE
);
419 bus_space_write_4(sc
->bt
, sc
->bh
, offset
, val
);
420 bus_space_barrier(sc
->bt
, sc
->bh
, offset
, 4,
421 BUS_SPACE_BARRIER_WRITE
);
426 ix_zeromem(struct ie_softc
*sc
, int offset
, int count
)
430 struct ix_softc
* isc
= (struct ix_softc
*) sc
;
433 /* Reset write pointer to the specified offset */
434 bus_space_write_2(sc
->bt
, sc
->bh
, IX_WRITEPTR
, offset
);
435 bus_space_barrier(sc
->bt
, sc
->bh
, IX_WRITEPTR
, 2,
436 BUS_SPACE_BARRIER_WRITE
);
439 bus_space_write_1(sc
->bt
, sc
->bh
, IX_DATAPORT
, 0);
444 for(i
= 0; i
< count
/ 2; i
++)
445 bus_space_write_2(sc
->bt
, sc
->bh
, IX_DATAPORT
, 0);
448 bus_space_write_1(sc
->bt
, sc
->bh
, IX_DATAPORT
, 0);
450 bus_space_barrier(sc
->bt
, sc
->bh
, IX_DATAPORT
, 2,
451 BUS_SPACE_BARRIER_WRITE
);
453 bus_space_set_region_1(sc
->bt
, sc
->bh
, offset
, 0, count
);
454 bus_space_barrier(sc
->bt
, sc
->bh
, offset
, count
,
455 BUS_SPACE_BARRIER_WRITE
);
460 ix_mediastatus(struct ie_softc
*sc
, struct ifmediareq
*ifmr
)
462 struct ifmedia
*ifm
= &sc
->sc_media
;
465 * The currently selected media is always the active media.
467 ifmr
->ifm_active
= ifm
->ifm_cur
->ifm_media
;
471 ix_match(device_t parent
, cfdata_t cf
, void *aux
)
477 u_short checksum
= 0;
478 bus_space_handle_t ioh
;
480 u_int8_t val
, bart_config
;
481 u_short pg
, adjust
, decode
, edecode
;
482 u_short board_id
, id_var1
, id_var2
, irq
, irq_encoded
;
483 struct isa_attach_args
* const ia
= aux
;
484 short irq_translate
[] = {0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0};
488 if (ia
->ia_niomem
< 1)
493 if (ISA_DIRECT_CONFIG(ia
))
498 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
)
501 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
,
502 IX_IOSIZE
, 0, &ioh
) != 0) {
503 DPRINTF(("Can't map io space at 0x%x\n", ia
->ia_iobase
));
507 /* XXX: reset any ee16 at the current iobase */
508 bus_space_write_1(iot
, ioh
, IX_ECTRL
, IX_RESET_ASIC
);
509 bus_space_write_1(iot
, ioh
, IX_ECTRL
, 0);
512 /* now look for ee16. */
513 board_id
= id_var1
= id_var2
= 0;
514 for (i
= 0; i
< 4 ; i
++) {
515 id_var1
= bus_space_read_1(iot
, ioh
, IX_ID_PORT
);
516 id_var2
= ((id_var1
& 0x03) << 2);
517 board_id
|= (( id_var1
>> 4) << id_var2
);
520 if (board_id
!= IX_ID
) {
521 DPRINTF(("BART ID mismatch (got 0x%04x, expected 0x%04x)\n",
527 * The shared RAM size and location of the EE16 is encoded into
528 * EEPROM location 6. The location of the first set bit tells us
529 * the memory address (0xc0000 + (0x4000 * FSB)), where FSB is the
530 * number of the first set bit. The zeroes are then shifted out,
531 * and the results is the memory size (1 = 16k, 3 = 32k, 7 = 48k,
535 * 0x3c -> 64k@0xc8000, 0x70 -> 48k@0xd0000, 0xc0 -> 32k@0xd8000
536 * 0x80 -> 16k@0xdc000.
538 * Side note: this comes from reading the old driver rather than
539 * from a more definitive source, so it could be out-of-whack
540 * with what the card can do...
543 val
= ix_read_eeprom(iot
, ioh
, 6) & 0xff;
544 for (pg
= 0; pg
< 8; pg
++) {
550 maddr
= 0xc0000 + (pg
* 0x4000);
575 DPRINTF(("invalid memory size %02x\n", val
));
579 if (ia
->ia_iomem
[0].ir_addr
!= ISA_UNKNOWN_IOMEM
&&
580 ia
->ia_iomem
[0].ir_addr
!= maddr
) {
582 "ix_match: memaddr of board @ 0x%x doesn't match config\n",
587 if (ia
->ia_iomem
[0].ir_size
!= ISA_UNKNOWN_IOSIZ
&&
588 ia
->ia_iomem
[0].ir_size
!= msiz
) {
590 "ix_match: memsize of board @ 0x%x doesn't match config\n",
595 /* need to put the 586 in RESET, and leave it */
596 bus_space_write_1(iot
, ioh
, IX_ECTRL
, IX_RESET_586
);
598 /* read the eeprom and checksum it, should == IX_ID */
599 for(i
= 0; i
< 0x40; i
++)
600 checksum
+= ix_read_eeprom(iot
, ioh
, i
);
602 if (checksum
!= IX_ID
) {
603 DPRINTF(("checksum mismatch (got 0x%04x, expected 0x%04x\n",
609 * Only do the following bit if using memory-mapped access. For
610 * boards with no mapped memory, we use PIO. We also use PIO for
611 * boards with 16K of mapped memory, as those setups don't seem
614 if (msiz
!= 0 && msiz
!= 16384) {
615 /* Set board up with memory-mapping info */
616 adjust
= IX_MCTRL_FMCS16
| (pg
& 0x3) << 2;
617 decode
= ((1 << (ia
->ia_iomem
[0].ir_size
/ 16384)) - 1) << pg
;
618 edecode
= ((~decode
>> 4) & 0xF0) | (decode
>> 8);
620 bus_space_write_1(iot
, ioh
, IX_MEMDEC
, decode
& 0xFF);
621 bus_space_write_1(iot
, ioh
, IX_MCTRL
, adjust
);
622 bus_space_write_1(iot
, ioh
, IX_MPCTRL
, (~decode
& 0xFF));
624 /* XXX disable Exxx */
625 bus_space_write_1(iot
, ioh
, IX_MECTRL
, edecode
);
629 * Get the encoded interrupt number from the EEPROM, check it
630 * against the passed in IRQ. Issue a warning if they do not
631 * match, and fail the probe. If irq is 'ISA_UNKNOWN_IRQ' then we
632 * use the EEPROM irq, and continue.
634 irq_encoded
= ix_read_eeprom(iot
, ioh
, IX_EEPROM_CONFIG1
);
635 irq_encoded
= (irq_encoded
& IX_EEPROM_IRQ
) >> IX_EEPROM_IRQ_SHIFT
;
636 irq
= irq_translate
[irq_encoded
];
637 if (ia
->ia_irq
[0].ir_irq
!= ISA_UNKNOWN_IRQ
&&
638 irq
!= ia
->ia_irq
[0].ir_irq
) {
639 DPRINTF(("board IRQ %d does not match config\n", irq
));
643 /* disable the board interrupts */
644 bus_space_write_1(iot
, ioh
, IX_IRQ
, irq_encoded
);
646 bart_config
= bus_space_read_1(iot
, ioh
, IX_CONFIG
);
647 bart_config
|= IX_BART_LOOPBACK
;
648 bart_config
|= IX_BART_MCS16_TEST
; /* inb doesn't get bit! */
649 bus_space_write_1(iot
, ioh
, IX_CONFIG
, bart_config
);
650 bart_config
= bus_space_read_1(iot
, ioh
, IX_CONFIG
);
652 bus_space_write_1(iot
, ioh
, IX_ECTRL
, 0);
658 ia
->ia_io
[0].ir_size
= IX_IOSIZE
;
661 ia
->ia_iomem
[0].ir_addr
= maddr
;
662 ia
->ia_iomem
[0].ir_size
= msiz
;
665 ia
->ia_irq
[0].ir_irq
= irq
;
667 DPRINTF(("ix_match: found board @ 0x%x\n", ia
->ia_iobase
));
670 bus_space_unmap(iot
, ioh
, IX_IOSIZE
);
675 ix_attach(device_t parent
, device_t self
, void *aux
)
677 struct ix_softc
*isc
= (void *)self
;
678 struct ie_softc
*sc
= &isc
->sc_ie
;
679 struct isa_attach_args
*ia
= aux
;
683 u_int8_t bart_config
;
686 u_int16_t wpat
, wval
;
687 bus_space_handle_t ioh
, memh
;
689 u_int8_t ethaddr
[ETHER_ADDR_LEN
];
694 * Shared memory access seems to fail on 16K mapped boards, so
695 * disable shared memory access if the board is in 16K mode. If
696 * no memory is mapped, we have no choice but to use PIO
698 isc
->use_pio
= (ia
->ia_iomem
[0].ir_size
<= (16 * 1024));
700 if (bus_space_map(iot
, ia
->ia_io
[0].ir_addr
,
701 ia
->ia_io
[0].ir_size
, 0, &ioh
) != 0) {
703 DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
704 device_xname(&sc
->sc_dev
), ia
->ia_
[0].ir_addr
,
705 ia
->ia_io
[0].ir_addr
+ ia
->ia_io
[0].ir_size
- 1));
709 /* We map memory even if using PIO so something else doesn't grab it */
710 if (ia
->ia_iomem
[0].ir_size
) {
711 if (bus_space_map(ia
->ia_memt
, ia
->ia_iomem
[0].ir_addr
,
712 ia
->ia_iomem
[0].ir_size
, 0, &memh
) != 0) {
713 DPRINTF(("\n%s: can't map iomem space 0x%x-0x%x\n",
714 device_xname(&sc
->sc_dev
), ia
->ia_iomem
[0].ir_addr
,
715 ia
->ia_iomem
[0].ir_addr
+ ia
->ia_iomem
[0].ir_size
- 1));
716 bus_space_unmap(iot
, ioh
, ia
->ia_io
[0].ir_size
);
725 * Get the hardware ethernet address from the EEPROM and
726 * save it in the softc for use by the 586 setup code.
728 wval
= ix_read_eeprom(iot
, ioh
, IX_EEPROM_ENET_HIGH
);
729 ethaddr
[1] = wval
& 0xFF;
730 ethaddr
[0] = wval
>> 8;
731 wval
= ix_read_eeprom(iot
, ioh
, IX_EEPROM_ENET_MID
);
732 ethaddr
[3] = wval
& 0xFF;
733 ethaddr
[2] = wval
>> 8;
734 wval
= ix_read_eeprom(iot
, ioh
, IX_EEPROM_ENET_LOW
);
735 ethaddr
[5] = wval
& 0xFF;
736 ethaddr
[4] = wval
>> 8;
739 sc
->hwreset
= ix_reset
;
740 sc
->chan_attn
= ix_atten
;
741 sc
->intrhook
= ix_intrhook
;
743 sc
->memcopyin
= ix_copyin
;
744 sc
->memcopyout
= ix_copyout
;
746 /* If using PIO, make sure to setup single-byte read/write functions */
748 sc
->ie_bus_barrier
= ix_bus_barrier
;
750 sc
->ie_bus_barrier
= NULL
;
753 sc
->ie_bus_read16
= ix_read_16
;
754 sc
->ie_bus_write16
= ix_write_16
;
755 sc
->ie_bus_write24
= ix_write_24
;
757 sc
->do_xmitnopchain
= 0;
759 sc
->sc_mediachange
= NULL
;
760 sc
->sc_mediastatus
= ix_mediastatus
;
767 * If using PIO, the memory size is bounded by on-card memory,
768 * not by how much is mapped into the memory-mapped region, so
769 * determine how much total memory we have to play with here.
771 for(memsize
= 64 * 1024; memsize
; memsize
-= 16 * 1024) {
772 /* warm up shared memory, the zero it all out */
773 ix_zeromem(sc
, 0, 32);
774 ix_zeromem(sc
, 0, memsize
);
776 /* Reset write pointer to the start of RAM */
777 bus_space_write_2(iot
, ioh
, IX_WRITEPTR
, 0);
778 bus_space_barrier(iot
, ioh
, IX_WRITEPTR
, 2,
779 BUS_SPACE_BARRIER_WRITE
);
781 /* write test pattern */
782 for(i
= 0, wpat
= 1; i
< memsize
; i
+= 2) {
783 bus_space_write_2(iot
, ioh
, IX_DATAPORT
, wpat
);
787 /* Flush all reads & writes to data port */
788 bus_space_barrier(iot
, ioh
, IX_DATAPORT
, 2,
789 BUS_SPACE_BARRIER_READ
|
790 BUS_SPACE_BARRIER_WRITE
);
792 /* Reset read pointer to beginning of card RAM */
793 bus_space_write_2(iot
, ioh
, IX_READPTR
, 0);
794 bus_space_barrier(iot
, ioh
, IX_READPTR
, 2,
795 BUS_SPACE_BARRIER_WRITE
);
797 /* read and verify test pattern */
798 for(i
= 0, wpat
= 1; i
< memsize
; i
+= 2) {
799 wval
= bus_space_read_2(iot
, ioh
, IX_DATAPORT
);
807 /* If we failed, try next size down */
811 /* Now try it all with byte reads/writes */
812 ix_zeromem(sc
, 0, 32);
813 ix_zeromem(sc
, 0, memsize
);
815 /* Reset write pointer to start of card RAM */
816 bus_space_write_2(iot
, ioh
, IX_WRITEPTR
, 0);
817 bus_space_barrier(iot
, ioh
, IX_WRITEPTR
, 2,
818 BUS_SPACE_BARRIER_WRITE
);
820 /* write out test pattern */
821 for(i
= 0, bpat
= 1; i
< memsize
; i
++) {
822 bus_space_write_1(iot
, ioh
, IX_DATAPORT
, bpat
);
826 /* Flush all reads & writes to data port */
827 bus_space_barrier(iot
, ioh
, IX_DATAPORT
, 2,
828 BUS_SPACE_BARRIER_READ
|
829 BUS_SPACE_BARRIER_WRITE
);
831 /* Reset read pointer to beginning of card RAM */
832 bus_space_write_2(iot
, ioh
, IX_READPTR
, 0);
833 bus_space_barrier(iot
, ioh
, IX_READPTR
, 2,
834 BUS_SPACE_BARRIER_WRITE
);
836 /* read and verify test pattern */
837 for(i
= 0, bpat
= 1; i
< memsize
; i
++) {
838 bval
= bus_space_read_1(iot
, ioh
, IX_DATAPORT
);
844 /* If we got through all of memory, we're done! */
849 /* Memory tests failed, punt... */
851 DPRINTF(("\n%s: can't determine size of on-card RAM\n",
852 device_xname(&sc
->sc_dev
)));
853 bus_space_unmap(iot
, ioh
, ia
->ia_io
[0].ir_size
);
860 sc
->sc_msize
= memsize
;
861 sc
->sc_maddr
= (void*) 0;
863 sc
->bt
= ia
->ia_memt
;
866 sc
->sc_msize
= ia
->ia_iomem
[0].ir_size
;
867 sc
->sc_maddr
= (void *)memh
;
871 sc
->sc_iobase
= (char *)sc
->sc_maddr
+ sc
->sc_msize
- (1 << 24);
873 /* set up pointers to important on-card control structures */
875 sc
->scb
= IE_ISCP_SZ
;
876 sc
->scp
= sc
->sc_msize
+ IE_SCP_ADDR
- (1 << 24);
878 sc
->buf_area
= sc
->scb
+ IE_SCB_SZ
;
879 sc
->buf_area_sz
= sc
->sc_msize
- IE_ISCP_SZ
- IE_SCB_SZ
- IE_SCP_SZ
;
881 /* zero card memory */
882 ix_zeromem(sc
, 0, 32);
883 ix_zeromem(sc
, 0, sc
->sc_msize
);
885 /* set card to 16-bit bus mode */
887 bus_space_write_2(sc
->bt
, sc
->bh
, IX_WRITEPTR
,
888 IE_SCP_BUS_USE((u_long
)sc
->scp
));
889 bus_space_barrier(sc
->bt
, sc
->bh
, IX_WRITEPTR
, 2,
890 BUS_SPACE_BARRIER_WRITE
);
892 bus_space_write_1(sc
->bt
, sc
->bh
, IX_DATAPORT
,
895 bus_space_write_1(sc
->bt
, sc
->bh
,
896 IE_SCP_BUS_USE((u_long
)sc
->scp
),
900 /* set up pointers to key structures */
901 ix_write_24(sc
, IE_SCP_ISCP((u_long
)sc
->scp
), (u_long
) sc
->iscp
);
902 ix_write_16(sc
, IE_ISCP_SCB((u_long
)sc
->iscp
), (u_long
) sc
->scb
);
903 ix_write_24(sc
, IE_ISCP_BASE((u_long
)sc
->iscp
), (u_long
) sc
->iscp
);
905 /* flush setup of pointers, check if chip answers */
907 bus_space_barrier(sc
->bt
, sc
->bh
, 0, IX_IOSIZE
,
908 BUS_SPACE_BARRIER_WRITE
);
910 bus_space_barrier(sc
->bt
, sc
->bh
, 0, sc
->sc_msize
,
911 BUS_SPACE_BARRIER_WRITE
);
914 if (!i82586_proberam(sc
)) {
915 DPRINTF(("\n%s: Can't talk to i82586!\n",
916 device_xname(&sc
->sc_dev
)));
917 bus_space_unmap(iot
, ioh
, ia
->ia_io
[0].ir_size
);
919 if (ia
->ia_iomem
[0].ir_size
)
920 bus_space_unmap(ia
->ia_memt
, memh
, ia
->ia_iomem
[0].ir_size
);
924 /* Figure out which media is being used... */
925 if (ix_read_eeprom(iot
, ioh
, IX_EEPROM_CONFIG1
) &
926 IX_EEPROM_MEDIA_EXT
) {
927 if (ix_read_eeprom(iot
, ioh
, IX_EEPROM_MEDIA
) &
929 media
= IFM_ETHER
| IFM_10_T
;
931 media
= IFM_ETHER
| IFM_10_2
;
933 media
= IFM_ETHER
| IFM_10_5
;
935 /* Take the card out of lookback */
936 bart_config
= bus_space_read_1(iot
, ioh
, IX_CONFIG
);
937 bart_config
&= ~IX_BART_LOOPBACK
;
938 bart_config
|= IX_BART_MCS16_TEST
; /* inb doesn't get bit! */
939 bus_space_write_1(iot
, ioh
, IX_CONFIG
, bart_config
);
940 bart_config
= bus_space_read_1(iot
, ioh
, IX_CONFIG
);
942 irq_encoded
= ix_read_eeprom(iot
, ioh
,
944 irq_encoded
= (irq_encoded
& IX_EEPROM_IRQ
) >> IX_EEPROM_IRQ_SHIFT
;
946 /* Enable interrupts */
947 bus_space_write_1(iot
, ioh
, IX_IRQ
,
948 irq_encoded
| IX_IRQ_ENABLE
);
950 /* Flush all writes to registers */
951 bus_space_barrier(iot
, ioh
, 0, ia
->ia_io
[0].ir_size
,
952 BUS_SPACE_BARRIER_WRITE
);
954 isc
->irq_encoded
= irq_encoded
;
956 i82586_attach(sc
, "EtherExpress/16", ethaddr
,
957 ix_media
, NIX_MEDIA
, media
);
960 aprint_error_dev(&sc
->sc_dev
, "unsupported memory config, using PIO to access %d bytes of memory\n", sc
->sc_msize
);
962 isc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
963 IST_EDGE
, IPL_NET
, i82586_intr
, sc
);
964 if (isc
->sc_ih
== NULL
) {
965 DPRINTF(("\n%s: can't establish interrupt\n",
966 device_xname(&sc
->sc_dev
)));
970 CFATTACH_DECL(ix
, sizeof(struct ix_softc
),
971 ix_match
, ix_attach
, NULL
, NULL
);