1 /* $NetBSD: if_ix.c,v 1.27 2007/10/19 12:00:18 ad 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.27 2007/10/19 12:00:18 ad 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 sc->sc_dev.dv_xname, 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 sc->sc_dev.dv_xname, 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 sc->sc_dev.dv_xname)); 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 sc->sc_dev.dv_xname)); 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 printf("%s: unsupported memory config, using PIO to access %d bytes of memory\n", sc->sc_dev.dv_xname, 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 sc->sc_dev.dv_xname)); 1010 } 1011 } 1012 1013 CFATTACH_DECL(ix, sizeof(struct ix_softc), 1014 ix_match, ix_attach, NULL, NULL); 1015