if_ix.c revision 1.9 1 /* $NetBSD: if_ix.c,v 1.9 2001/03/10 20:04:30 jdolecek Exp $ */
2
3 /*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Rafal K. Boni.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/mbuf.h>
42 #include <sys/errno.h>
43 #include <sys/device.h>
44 #include <sys/protosw.h>
45 #include <sys/socket.h>
46
47 #include <net/if.h>
48 #include <net/if_dl.h>
49 #include <net/if_types.h>
50 #include <net/if_media.h>
51 #include <net/if_ether.h>
52
53 #include <machine/cpu.h>
54 #include <machine/bus.h>
55 #include <machine/intr.h>
56
57 #include <dev/isa/isareg.h>
58 #include <dev/isa/isavar.h>
59
60 #include <dev/ic/i82586reg.h>
61 #include <dev/ic/i82586var.h>
62 #include <dev/isa/if_ixreg.h>
63
64 #ifdef IX_DEBUG
65 #define DPRINTF(x) printf x
66 #else
67 #define DPRINTF(x)
68 #endif
69
70 int ix_media[] = {
71 IFM_ETHER | IFM_10_5,
72 IFM_ETHER | IFM_10_2,
73 IFM_ETHER | IFM_10_T,
74 };
75 #define NIX_MEDIA (sizeof(ix_media) / sizeof(ix_media[0]))
76
77 struct ix_softc {
78 struct ie_softc sc_ie;
79
80 bus_space_tag_t sc_regt; /* space tag for registers */
81 bus_space_handle_t sc_regh; /* space handle for registers */
82
83 u_int8_t use_pio; /* use PIO rather than shared mem */
84 u_int16_t irq_encoded; /* encoded IRQ */
85 void *sc_ih; /* interrupt handle */
86 };
87
88 static void ix_reset __P((struct ie_softc *, int));
89 static void ix_atten __P((struct ie_softc *, int));
90 static int ix_intrhook __P((struct ie_softc *, int));
91
92 static void ix_copyin __P((struct ie_softc *, void *, int, size_t));
93 static void ix_copyout __P((struct ie_softc *, const void *, int, size_t));
94
95 static void ix_bus_barrier __P((struct ie_softc *, int, int, int));
96
97 static u_int16_t ix_read_16 __P((struct ie_softc *, int));
98 static void ix_write_16 __P((struct ie_softc *, int, u_int16_t));
99 static void ix_write_24 __P((struct ie_softc *, int, int));
100 static void ix_zeromem __P((struct ie_softc *, int, int));
101
102 static void ix_mediastatus __P((struct ie_softc *, struct ifmediareq *));
103
104 static u_int16_t ix_read_eeprom __P((bus_space_tag_t, bus_space_handle_t, int));
105 static void ix_eeprom_outbits __P((bus_space_tag_t, bus_space_handle_t, int, int));
106 static int ix_eeprom_inbits __P((bus_space_tag_t, bus_space_handle_t));
107 static void ix_eeprom_clock __P((bus_space_tag_t, bus_space_handle_t, int));
108
109 int ix_match __P((struct device *, struct cfdata *, void *));
110 void ix_attach __P((struct device *, struct device *, void *));
111
112 /*
113 * EtherExpress/16 support routines
114 */
115 static void
116 ix_reset(sc, why)
117 struct ie_softc *sc;
118 int why;
119 {
120 struct ix_softc* isc = (struct ix_softc *) sc;
121
122 switch (why) {
123 case CHIP_PROBE:
124 bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_ECTRL,
125 IX_RESET_586);
126 delay(100);
127 bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_ECTRL, 0);
128 delay(100);
129 break;
130
131 case CARD_RESET:
132 break;
133 }
134 }
135
136 static void
137 ix_atten(sc, why)
138 struct ie_softc *sc;
139 int why;
140 {
141 struct ix_softc* isc = (struct ix_softc *) sc;
142 bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_ATTN, 0);
143 }
144
145 static u_int16_t
146 ix_read_eeprom(iot, ioh, location)
147 bus_space_tag_t iot;
148 bus_space_handle_t ioh;
149 int location;
150 {
151 int ectrl, edata;
152
153 ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
154 ectrl &= IX_ECTRL_MASK;
155 ectrl |= IX_ECTRL_EECS;
156 bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
157
158 ix_eeprom_outbits(iot, ioh, IX_EEPROM_READ, IX_EEPROM_OPSIZE1);
159 ix_eeprom_outbits(iot, ioh, location, IX_EEPROM_ADDR_SIZE);
160 edata = ix_eeprom_inbits(iot, ioh);
161 ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
162 ectrl &= ~(IX_RESET_ASIC | IX_ECTRL_EEDI | IX_ECTRL_EECS);
163 bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
164 ix_eeprom_clock(iot, ioh, 1);
165 ix_eeprom_clock(iot, ioh, 0);
166 return (edata);
167 }
168
169 static void
170 ix_eeprom_outbits(iot, ioh, edata, count)
171 bus_space_tag_t iot;
172 bus_space_handle_t ioh;
173 int edata, count;
174 {
175 int ectrl, i;
176
177 ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
178 ectrl &= ~IX_RESET_ASIC;
179 for (i = count - 1; i >= 0; i--) {
180 ectrl &= ~IX_ECTRL_EEDI;
181 if (edata & (1 << i)) {
182 ectrl |= IX_ECTRL_EEDI;
183 }
184 bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
185 delay(1); /* eeprom data must be setup for 0.4 uSec */
186 ix_eeprom_clock(iot, ioh, 1);
187 ix_eeprom_clock(iot, ioh, 0);
188 }
189 ectrl &= ~IX_ECTRL_EEDI;
190 bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
191 delay(1); /* eeprom data must be held for 0.4 uSec */
192 }
193
194 static int
195 ix_eeprom_inbits(iot, ioh)
196 bus_space_tag_t iot;
197 bus_space_handle_t ioh;
198 {
199 int ectrl, edata, i;
200
201 ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
202 ectrl &= ~IX_RESET_ASIC;
203 for (edata = 0, i = 0; i < 16; i++) {
204 edata = edata << 1;
205 ix_eeprom_clock(iot, ioh, 1);
206 ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
207 if (ectrl & IX_ECTRL_EEDO) {
208 edata |= 1;
209 }
210 ix_eeprom_clock(iot, ioh, 0);
211 }
212 return (edata);
213 }
214
215 static void
216 ix_eeprom_clock(iot, ioh, state)
217 bus_space_tag_t iot;
218 bus_space_handle_t ioh;
219 int state;
220 {
221 int ectrl;
222
223 ectrl = bus_space_read_1(iot, ioh, IX_ECTRL);
224 ectrl &= ~(IX_RESET_ASIC | IX_ECTRL_EESK);
225 if (state) {
226 ectrl |= IX_ECTRL_EESK;
227 }
228 bus_space_write_1(iot, ioh, IX_ECTRL, ectrl);
229 delay(9); /* EESK must be stable for 8.38 uSec */
230 }
231
232 static int
233 ix_intrhook(sc, where)
234 struct ie_softc *sc;
235 int where;
236 {
237 struct ix_softc* isc = (struct ix_softc *) sc;
238
239 switch (where) {
240 case INTR_ENTER:
241 /* entering ISR: disable card interrupts */
242 bus_space_write_1(isc->sc_regt, isc->sc_regh,
243 IX_IRQ, isc->irq_encoded);
244 break;
245
246 case INTR_EXIT:
247 /* exiting ISR: re-enable card interrupts */
248 bus_space_write_1(isc->sc_regt, isc->sc_regh, IX_IRQ,
249 isc->irq_encoded | IX_IRQ_ENABLE);
250 break;
251 }
252
253 return 1;
254 }
255
256
257 static void
258 ix_copyin (sc, dst, offset, size)
259 struct ie_softc *sc;
260 void *dst;
261 int offset;
262 size_t size;
263 {
264 int i, dribble;
265 u_int8_t* bptr = dst;
266 u_int16_t* wptr = dst;
267 struct ix_softc* isc = (struct ix_softc *) sc;
268
269 if (isc->use_pio) {
270 /* Reset read pointer to the specified offset */
271 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
272 BUS_SPACE_BARRIER_READ);
273 bus_space_write_2(sc->bt, sc->bh, IX_READPTR, offset);
274 bus_space_barrier(sc->bt, sc->bh, IX_READPTR, 2,
275 BUS_SPACE_BARRIER_WRITE);
276 } else {
277 bus_space_barrier(sc->bt, sc->bh, offset, size,
278 BUS_SPACE_BARRIER_READ);
279 }
280
281 if (offset % 2) {
282 if (isc->use_pio)
283 *bptr = bus_space_read_1(sc->bt, sc->bh, IX_DATAPORT);
284 else
285 *bptr = bus_space_read_1(sc->bt, sc->bh, offset);
286 offset++; bptr++; size--;
287 }
288
289 dribble = size % 2;
290 wptr = (u_int16_t*) bptr;
291
292 if (isc->use_pio) {
293 for(i = 0; i < size / 2; i++) {
294 *wptr = bus_space_read_2(sc->bt, sc->bh, IX_DATAPORT);
295 wptr++;
296 }
297 } else {
298 bus_space_read_region_2(sc->bt, sc->bh, offset,
299 (u_int16_t *) bptr, size / 2);
300 }
301
302 if (dribble) {
303 bptr += size - 1;
304 offset += size - 1;
305
306 if (isc->use_pio)
307 *bptr = bus_space_read_1(sc->bt, sc->bh, IX_DATAPORT);
308 else
309 *bptr = bus_space_read_1(sc->bt, sc->bh, offset);
310 }
311 }
312
313 static void
314 ix_copyout (sc, src, offset, size)
315 struct ie_softc *sc;
316 const void *src;
317 int offset;
318 size_t size;
319 {
320 int i, dribble;
321 int osize = size;
322 int ooffset = offset;
323 const u_int8_t* bptr = src;
324 const u_int16_t* wptr = src;
325 struct ix_softc* isc = (struct ix_softc *) sc;
326
327 if (isc->use_pio) {
328 /* Reset write pointer to the specified offset */
329 bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
330 bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
331 BUS_SPACE_BARRIER_WRITE);
332 }
333
334 if (offset % 2) {
335 if (isc->use_pio)
336 bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, *bptr);
337 else
338 bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
339 offset++; bptr++; size--;
340 }
341
342 dribble = size % 2;
343 wptr = (u_int16_t*) bptr;
344
345 if (isc->use_pio) {
346 for(i = 0; i < size / 2; i++) {
347 bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT, *wptr);
348 wptr++;
349 }
350 } else {
351 bus_space_write_region_2(sc->bt, sc->bh, offset,
352 (u_int16_t *)bptr, size / 2);
353 }
354
355 if (dribble) {
356 bptr += size - 1;
357 offset += size - 1;
358
359 if (isc->use_pio)
360 bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, *bptr);
361 else
362 bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
363 }
364
365 if (isc->use_pio)
366 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
367 BUS_SPACE_BARRIER_WRITE);
368 else
369 bus_space_barrier(sc->bt, sc->bh, ooffset, osize,
370 BUS_SPACE_BARRIER_WRITE);
371 }
372
373 static void
374 ix_bus_barrier(sc, offset, length, flags)
375 struct ie_softc *sc;
376 int offset, length, flags;
377 {
378 struct ix_softc* isc = (struct ix_softc *) sc;
379
380 if (isc->use_pio)
381 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2, flags);
382 else
383 bus_space_barrier(sc->bt, sc->bh, offset, length, flags);
384 }
385
386 static u_int16_t
387 ix_read_16 (sc, offset)
388 struct ie_softc *sc;
389 int offset;
390 {
391 struct ix_softc* isc = (struct ix_softc *) sc;
392
393 if (isc->use_pio) {
394 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
395 BUS_SPACE_BARRIER_READ);
396
397 /* Reset read pointer to the specified offset */
398 bus_space_write_2(sc->bt, sc->bh, IX_READPTR, offset);
399 bus_space_barrier(sc->bt, sc->bh, IX_READPTR, 2,
400 BUS_SPACE_BARRIER_WRITE);
401
402 return bus_space_read_2(sc->bt, sc->bh, IX_DATAPORT);
403 } else {
404 bus_space_barrier(sc->bt, sc->bh, offset, 2,
405 BUS_SPACE_BARRIER_READ);
406 return bus_space_read_2(sc->bt, sc->bh, offset);
407 }
408 }
409
410 static void
411 ix_write_16 (sc, offset, value)
412 struct ie_softc *sc;
413 int offset;
414 u_int16_t value;
415 {
416 struct ix_softc* isc = (struct ix_softc *) sc;
417
418 if (isc->use_pio) {
419 /* Reset write pointer to the specified offset */
420 bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
421 bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
422 BUS_SPACE_BARRIER_WRITE);
423
424 bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT, value);
425 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
426 BUS_SPACE_BARRIER_WRITE);
427 } else {
428 bus_space_write_2(sc->bt, sc->bh, offset, value);
429 bus_space_barrier(sc->bt, sc->bh, offset, 2,
430 BUS_SPACE_BARRIER_WRITE);
431 }
432 }
433
434 static void
435 ix_write_24 (sc, offset, addr)
436 struct ie_softc *sc;
437 int offset, addr;
438 {
439 char* ptr;
440 struct ix_softc* isc = (struct ix_softc *) sc;
441 int val = addr + (u_long) sc->sc_maddr - (u_long) sc->sc_iobase;
442
443 if (isc->use_pio) {
444 /* Reset write pointer to the specified offset */
445 bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
446 bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
447 BUS_SPACE_BARRIER_WRITE);
448
449 ptr = (char*) &val;
450 bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT,
451 *((u_int16_t *)ptr));
452 bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT,
453 *((u_int16_t *)(ptr + 2)));
454 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
455 BUS_SPACE_BARRIER_WRITE);
456 } else {
457 bus_space_write_4(sc->bt, sc->bh, offset, val);
458 bus_space_barrier(sc->bt, sc->bh, offset, 4,
459 BUS_SPACE_BARRIER_WRITE);
460 }
461 }
462
463 static void
464 ix_zeromem(sc, offset, count)
465 struct ie_softc *sc;
466 int offset, count;
467 {
468 int i;
469 int dribble;
470 struct ix_softc* isc = (struct ix_softc *) sc;
471
472 if (isc->use_pio) {
473 /* Reset write pointer to the specified offset */
474 bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR, offset);
475 bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
476 BUS_SPACE_BARRIER_WRITE);
477
478 if (offset % 2) {
479 bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, 0);
480 count--;
481 }
482
483 dribble = count % 2;
484 for(i = 0; i < count / 2; i++)
485 bus_space_write_2(sc->bt, sc->bh, IX_DATAPORT, 0);
486
487 if (dribble)
488 bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, 0);
489
490 bus_space_barrier(sc->bt, sc->bh, IX_DATAPORT, 2,
491 BUS_SPACE_BARRIER_WRITE);
492 } else {
493 bus_space_set_region_1(sc->bt, sc->bh, offset, 0, count);
494 bus_space_barrier(sc->bt, sc->bh, offset, count,
495 BUS_SPACE_BARRIER_WRITE);
496 }
497 }
498
499 static void
500 ix_mediastatus(sc, ifmr)
501 struct ie_softc *sc;
502 struct ifmediareq *ifmr;
503 {
504 struct ifmedia *ifm = &sc->sc_media;
505
506 /*
507 * The currently selected media is always the active media.
508 */
509 ifmr->ifm_active = ifm->ifm_cur->ifm_media;
510 }
511
512 int
513 ix_match(parent, cf, aux)
514 struct device *parent;
515 struct cfdata *cf;
516 void *aux;
517 {
518 int i;
519 int rv = 0;
520 bus_addr_t maddr;
521 bus_size_t msize;
522 u_short checksum = 0;
523 bus_space_handle_t ioh;
524 bus_space_tag_t iot;
525 u_int8_t val, bart_config;
526 u_short pg, adjust, decode, edecode;
527 u_short board_id, id_var1, id_var2, irq, irq_encoded;
528 struct isa_attach_args * const ia = aux;
529 short irq_translate[] = {0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0};
530
531 iot = ia->ia_iot;
532
533 if (bus_space_map(iot, ia->ia_iobase,
534 IX_IOSIZE, 0, &ioh) != 0) {
535 DPRINTF(("Can't map io space at 0x%x\n", ia->ia_iobase));
536 return (0);
537 }
538
539 /* XXX: reset any ee16 at the current iobase */
540 bus_space_write_1(iot, ioh, IX_ECTRL, IX_RESET_ASIC);
541 bus_space_write_1(iot, ioh, IX_ECTRL, 0);
542 delay(240);
543
544 /* now look for ee16. */
545 board_id = id_var1 = id_var2 = 0;
546 for (i = 0; i < 4 ; i++) {
547 id_var1 = bus_space_read_1(iot, ioh, IX_ID_PORT);
548 id_var2 = ((id_var1 & 0x03) << 2);
549 board_id |= (( id_var1 >> 4) << id_var2);
550 }
551
552 if (board_id != IX_ID) {
553 DPRINTF(("BART ID mismatch (got 0x%04x, expected 0x%04x)\n",
554 board_id, IX_ID));
555 goto out;
556 }
557
558 /*
559 * The shared RAM size and location of the EE16 is encoded into
560 * EEPROM location 6. The location of the first set bit tells us
561 * the memory address (0xc0000 + (0x4000 * FSB)), where FSB is the
562 * number of the first set bit. The zeroes are then shifted out,
563 * and the results is the memory size (1 = 16k, 3 = 32k, 7 = 48k,
564 * 0x0f = 64k).
565 *
566 * Examples:
567 * 0x3c -> 64k@0xc8000, 0x70 -> 48k@0xd0000, 0xc0 -> 32k@0xd8000
568 * 0x80 -> 16k@0xdc000.
569 *
570 * Side note: this comes from reading the old driver rather than
571 * from a more definitive source, so it could be out-of-whack
572 * with what the card can do...
573 */
574
575 val = ix_read_eeprom(iot, ioh, 6) & 0xff;
576 for(pg = 0; pg < 8; pg++) {
577 if (val & 1)
578 break;
579 val = val >> 1;
580 }
581
582 if (pg == 8) {
583 DPRINTF(("Invalid or unsupported memory config\n"));
584 goto out;
585 }
586
587 maddr = 0xc0000 + (pg * 0x4000);
588
589 switch (val) {
590 case 0x00:
591 msize = 0;
592 break;
593
594 case 0x01:
595 msize = 16 * 1024;
596 break;
597
598 case 0x03:
599 msize = 32 * 1024;
600 break;
601
602 case 0x07:
603 msize = 48 * 1024;
604 break;
605
606 case 0x0f:
607 msize = 64 * 1024;
608 break;
609
610 default:
611 DPRINTF(("invalid memory size %02x\n", val));
612 goto out;
613 }
614
615 if (ia->ia_maddr == ISACF_IOMEM_DEFAULT)
616 ia->ia_maddr = maddr;
617 else if (ia->ia_maddr != maddr) {
618 DPRINTF((
619 "ix_match: memaddr of board @ 0x%x doesn't match config\n",
620 ia->ia_iobase));
621 goto out;
622 }
623
624 if (ia->ia_msize == ISACF_IOSIZ_DEFAULT)
625 ia->ia_msize = msize;
626 else if (ia->ia_msize != msize) {
627 DPRINTF((
628 "ix_match: memsize of board @ 0x%x doesn't match config\n",
629 ia->ia_iobase));
630 goto out;
631 }
632
633 /* need to put the 586 in RESET, and leave it */
634 bus_space_write_1(iot, ioh, IX_ECTRL, IX_RESET_586);
635
636 /* read the eeprom and checksum it, should == IX_ID */
637 for(i = 0; i < 0x40; i++)
638 checksum += ix_read_eeprom(iot, ioh, i);
639
640 if (checksum != IX_ID) {
641 DPRINTF(("checksum mismatch (got 0x%04x, expected 0x%04x\n",
642 checksum, IX_ID));
643 goto out;
644 }
645
646 /*
647 * Only do the following bit if using memory-mapped access. For
648 * boards with no mapped memory, we use PIO. We also use PIO for
649 * boards with 16K of mapped memory, as those setups don't seem
650 * to work otherwise.
651 */
652 if (msize != 0 && msize != 16384) {
653 /* Set board up with memory-mapping info */
654 adjust = IX_MCTRL_FMCS16 | (pg & 0x3) << 2;
655 decode = ((1 << (ia->ia_msize / 16384)) - 1) << pg;
656 edecode = ((~decode >> 4) & 0xF0) | (decode >> 8);
657
658 bus_space_write_1(iot, ioh, IX_MEMDEC, decode & 0xFF);
659 bus_space_write_1(iot, ioh, IX_MCTRL, adjust);
660 bus_space_write_1(iot, ioh, IX_MPCTRL, (~decode & 0xFF));
661
662 /* XXX disable Exxx */
663 bus_space_write_1(iot, ioh, IX_MECTRL, edecode);
664 }
665
666 /*
667 * Get the encoded interrupt number from the EEPROM, check it
668 * against the passed in IRQ. Issue a warning if they do not
669 * match, and fail the probe. If irq is 'IRQUNK' then we
670 * use the EEPROM irq, and continue.
671 */
672 irq_encoded = ix_read_eeprom(iot, ioh, IX_EEPROM_CONFIG1);
673 irq_encoded = (irq_encoded & IX_EEPROM_IRQ) >> IX_EEPROM_IRQ_SHIFT;
674 irq = irq_translate[irq_encoded];
675 if (ia->ia_irq == ISACF_IRQ_DEFAULT)
676 ia->ia_irq = irq;
677 else if (irq != ia->ia_irq) {
678 DPRINTF(("board IRQ %d does not match config\n", irq));
679 goto out;
680 }
681
682 /* disable the board interrupts */
683 bus_space_write_1(iot, ioh, IX_IRQ, irq_encoded);
684
685 bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
686 bart_config |= IX_BART_LOOPBACK;
687 bart_config |= IX_BART_MCS16_TEST; /* inb doesn't get bit! */
688 bus_space_write_1(iot, ioh, IX_CONFIG, bart_config);
689 bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
690
691 bus_space_write_1(iot, ioh, IX_ECTRL, 0);
692 delay(100);
693
694 rv = 1;
695 ia->ia_iosize = IX_IOSIZE;
696 DPRINTF(("ix_match: found board @ 0x%x\n", ia->ia_iobase));
697
698 out:
699 bus_space_unmap(iot, ioh, IX_IOSIZE);
700 return (rv);
701 }
702
703 void
704 ix_attach(parent, self, aux)
705 struct device *parent;
706 struct device *self;
707 void *aux;
708 {
709 struct ix_softc *isc = (void *)self;
710 struct ie_softc *sc = &isc->sc_ie;
711 struct isa_attach_args *ia = aux;
712
713 int media;
714 int i, memsize;
715 u_int8_t bart_config;
716 bus_space_tag_t iot;
717 u_int8_t bpat, bval;
718 u_int16_t wpat, wval;
719 bus_space_handle_t ioh, memh;
720 u_short irq_encoded;
721 u_int8_t ethaddr[ETHER_ADDR_LEN];
722
723 iot = ia->ia_iot;
724
725 /*
726 * Shared memory access seems to fail on 16K mapped boards, so
727 * disable shared memory access if the board is in 16K mode. If
728 * no memory is mapped, we have no choice but to use PIO
729 */
730 isc->use_pio = (ia->ia_msize <= (16 * 1024));
731
732 if (bus_space_map(iot, ia->ia_iobase,
733 ia->ia_iosize, 0, &ioh) != 0) {
734
735 DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
736 sc->sc_dev.dv_xname, ia->ia_iobase,
737 ia->ia_iobase + ia->ia_iosize - 1));
738 return;
739 }
740
741 /* We map memory even if using PIO so something else doesn't grab it */
742 if (ia->ia_msize) {
743 if (bus_space_map(ia->ia_memt, ia->ia_maddr,
744 ia->ia_msize, 0, &memh) != 0) {
745 DPRINTF(("\n%s: can't map iomem space 0x%x-0x%x\n",
746 sc->sc_dev.dv_xname, ia->ia_maddr,
747 ia->ia_maddr + ia->ia_msize - 1));
748 bus_space_unmap(iot, ioh, ia->ia_iosize);
749 return;
750 }
751 }
752
753 isc->sc_regt = iot;
754 isc->sc_regh = ioh;
755
756 /*
757 * Get the hardware ethernet address from the EEPROM and
758 * save it in the softc for use by the 586 setup code.
759 */
760 wval = ix_read_eeprom(iot, ioh, IX_EEPROM_ENET_HIGH);
761 ethaddr[1] = wval & 0xFF;
762 ethaddr[0] = wval >> 8;
763 wval = ix_read_eeprom(iot, ioh, IX_EEPROM_ENET_MID);
764 ethaddr[3] = wval & 0xFF;
765 ethaddr[2] = wval >> 8;
766 wval = ix_read_eeprom(iot, ioh, IX_EEPROM_ENET_LOW);
767 ethaddr[5] = wval & 0xFF;
768 ethaddr[4] = wval >> 8;
769
770 sc->hwinit = NULL;
771 sc->hwreset = ix_reset;
772 sc->chan_attn = ix_atten;
773 sc->intrhook = ix_intrhook;
774
775 sc->memcopyin = ix_copyin;
776 sc->memcopyout = ix_copyout;
777
778 /* If using PIO, make sure to setup single-byte read/write functions */
779 if (isc->use_pio) {
780 sc->ie_bus_barrier = ix_bus_barrier;
781 } else {
782 sc->ie_bus_barrier = NULL;
783 }
784
785 sc->ie_bus_read16 = ix_read_16;
786 sc->ie_bus_write16 = ix_write_16;
787 sc->ie_bus_write24 = ix_write_24;
788
789 sc->do_xmitnopchain = 0;
790
791 sc->sc_mediachange = NULL;
792 sc->sc_mediastatus = ix_mediastatus;
793
794 if (isc->use_pio) {
795 sc->bt = iot;
796 sc->bh = ioh;
797
798 /*
799 * If using PIO, the memory size is bounded by on-card memory,
800 * not by how much is mapped into the memory-mapped region, so
801 * determine how much total memory we have to play with here.
802 */
803 for(memsize = 64 * 1024; memsize; memsize -= 16 * 1024) {
804 /* warm up shared memory, the zero it all out */
805 ix_zeromem(sc, 0, 32);
806 ix_zeromem(sc, 0, memsize);
807
808 /* Reset write pointer to the start of RAM */
809 bus_space_write_2(iot, ioh, IX_WRITEPTR, 0);
810 bus_space_barrier(iot, ioh, IX_WRITEPTR, 2,
811 BUS_SPACE_BARRIER_WRITE);
812
813 /* write test pattern */
814 for(i = 0; i < memsize; i += 2) {
815 bus_space_write_2(iot, ioh, IX_DATAPORT, wpat);
816 wpat += 3;
817 }
818
819 /* Flush all reads & writes to data port */
820 bus_space_barrier(iot, ioh, IX_DATAPORT, 2,
821 BUS_SPACE_BARRIER_READ |
822 BUS_SPACE_BARRIER_WRITE);
823
824 /* Reset read pointer to beginning of card RAM */
825 bus_space_write_2(iot, ioh, IX_READPTR, 0);
826 bus_space_barrier(iot, ioh, IX_READPTR, 2,
827 BUS_SPACE_BARRIER_WRITE);
828
829 /* read and verify test pattern */
830 for(i = 0, wpat = 1; i < memsize; i += 2) {
831 wval = bus_space_read_2(iot, ioh, IX_DATAPORT);
832
833 if (wval != wpat)
834 break;
835
836 wpat += 3;
837 }
838
839 /* If we failed, try next size down */
840 if (i != memsize)
841 continue;
842
843 /* Now try it all with byte reads/writes */
844 ix_zeromem(sc, 0, 32);
845 ix_zeromem(sc, 0, memsize);
846
847 /* Reset write pointer to start of card RAM */
848 bus_space_write_2(iot, ioh, IX_WRITEPTR, 0);
849 bus_space_barrier(iot, ioh, IX_WRITEPTR, 2,
850 BUS_SPACE_BARRIER_WRITE);
851
852 /* write out test pattern */
853 for(i = 0, bpat = 1; i < memsize; i++) {
854 bus_space_write_1(iot, ioh, IX_DATAPORT, bpat);
855 bpat += 3;
856 }
857
858 /* Flush all reads & writes to data port */
859 bus_space_barrier(iot, ioh, IX_DATAPORT, 2,
860 BUS_SPACE_BARRIER_READ |
861 BUS_SPACE_BARRIER_WRITE);
862
863 /* Reset read pointer to beginning of card RAM */
864 bus_space_write_2(iot, ioh, IX_READPTR, 0);
865 bus_space_barrier(iot, ioh, IX_READPTR, 2,
866 BUS_SPACE_BARRIER_WRITE);
867
868 /* read and verify test pattern */
869 for(i = 0, bpat = 1; i < memsize; i++) {
870 bval = bus_space_read_1(iot, ioh, IX_DATAPORT);
871
872 if (bval != bpat)
873 bpat += 3;
874 }
875
876 /* If we got through all of memory, we're done! */
877 if (i == memsize)
878 break;
879 }
880
881 /* Memory tests failed, punt... */
882 if (memsize == 0) {
883 DPRINTF(("\n%s: can't determine size of on-card RAM\n",
884 sc->sc_dev.dv_xname));
885 bus_space_unmap(iot, ioh, ia->ia_iosize);
886 return;
887 }
888
889 sc->bt = iot;
890 sc->bh = ioh;
891
892 sc->sc_msize = memsize;
893 sc->sc_maddr = (void*) 0;
894 } else {
895 sc->bt = ia->ia_memt;
896 sc->bh = memh;
897
898 sc->sc_msize = ia->ia_msize;
899 sc->sc_maddr = (void *)memh;
900 }
901
902 /* Map i/o space. */
903 sc->sc_iobase = (char *)sc->sc_maddr + sc->sc_msize - (1 << 24);
904
905 /* set up pointers to important on-card control structures */
906 sc->iscp = 0;
907 sc->scb = IE_ISCP_SZ;
908 sc->scp = sc->sc_msize + IE_SCP_ADDR - (1 << 24);
909
910 sc->buf_area = sc->scb + IE_SCB_SZ;
911 sc->buf_area_sz = sc->sc_msize - IE_ISCP_SZ - IE_SCB_SZ - IE_SCP_SZ;
912
913 /* zero card memory */
914 ix_zeromem(sc, 0, 32);
915 ix_zeromem(sc, 0, sc->sc_msize);
916
917 /* set card to 16-bit bus mode */
918 if (isc->use_pio) {
919 bus_space_write_2(sc->bt, sc->bh, IX_WRITEPTR,
920 IE_SCP_BUS_USE((u_long)sc->scp));
921 bus_space_barrier(sc->bt, sc->bh, IX_WRITEPTR, 2,
922 BUS_SPACE_BARRIER_WRITE);
923
924 bus_space_write_1(sc->bt, sc->bh, IX_DATAPORT, 0);
925 } else {
926 bus_space_write_1(sc->bt, sc->bh,
927 IE_SCP_BUS_USE((u_long)sc->scp), 0);
928 }
929
930 /* set up pointers to key structures */
931 ix_write_24(sc, IE_SCP_ISCP((u_long)sc->scp), (u_long) sc->iscp);
932 ix_write_16(sc, IE_ISCP_SCB((u_long)sc->iscp), (u_long) sc->scb);
933 ix_write_24(sc, IE_ISCP_BASE((u_long)sc->iscp), (u_long) sc->iscp);
934
935 /* flush setup of pointers, check if chip answers */
936 if (isc->use_pio) {
937 bus_space_barrier(sc->bt, sc->bh, 0, IX_IOSIZE,
938 BUS_SPACE_BARRIER_WRITE);
939 } else {
940 bus_space_barrier(sc->bt, sc->bh, 0, sc->sc_msize,
941 BUS_SPACE_BARRIER_WRITE);
942 }
943
944 if (!i82586_proberam(sc)) {
945 DPRINTF(("\n%s: Can't talk to i82586!\n",
946 sc->sc_dev.dv_xname));
947 bus_space_unmap(iot, ioh, ia->ia_iosize);
948
949 if (ia->ia_msize)
950 bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
951 return;
952 }
953
954 /* Figure out which media is being used... */
955 if (ix_read_eeprom(iot, ioh, IX_EEPROM_CONFIG1) &
956 IX_EEPROM_MEDIA_EXT) {
957 if (ix_read_eeprom(iot, ioh, IX_EEPROM_MEDIA) &
958 IX_EEPROM_MEDIA_TP)
959 media = IFM_ETHER | IFM_10_T;
960 else
961 media = IFM_ETHER | IFM_10_2;
962 } else
963 media = IFM_ETHER | IFM_10_5;
964
965 /* Take the card out of lookback */
966 bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
967 bart_config &= ~IX_BART_LOOPBACK;
968 bart_config |= IX_BART_MCS16_TEST; /* inb doesn't get bit! */
969 bus_space_write_1(iot, ioh, IX_CONFIG, bart_config);
970 bart_config = bus_space_read_1(iot, ioh, IX_CONFIG);
971
972 irq_encoded = ix_read_eeprom(iot, ioh,
973 IX_EEPROM_CONFIG1);
974 irq_encoded = (irq_encoded & IX_EEPROM_IRQ) >> IX_EEPROM_IRQ_SHIFT;
975
976 /* Enable interrupts */
977 bus_space_write_1(iot, ioh, IX_IRQ,
978 irq_encoded | IX_IRQ_ENABLE);
979
980 /* Flush all writes to registers */
981 bus_space_barrier(iot, ioh, 0, ia->ia_iosize, BUS_SPACE_BARRIER_WRITE);
982
983 isc->irq_encoded = irq_encoded;
984
985 i82586_attach(sc, "EtherExpress/16", ethaddr,
986 ix_media, NIX_MEDIA, media);
987
988 if (isc->use_pio)
989 printf("%s: unsupported memory config, using PIO to access %d bytes of memory\n", sc->sc_dev.dv_xname, sc->sc_msize);
990
991 isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
992 IPL_NET, i82586_intr, sc);
993 if (isc->sc_ih == NULL)
994 DPRINTF(("\n%s: can't establish interrupt\n",
995 sc->sc_dev.dv_xname));
996 }
997
998 struct cfattach ix_ca = {
999 sizeof(struct ix_softc), ix_match, ix_attach
1000 };
1001