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