if_ed_cbus.c revision 141550
1/*- 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: head/sys/dev/ed/if_ed_cbus.c 141550 2005-02-09 00:06:12Z imp $ 28 */ 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/socket.h> 33#include <sys/kernel.h> 34 35#include <sys/module.h> 36#include <sys/bus.h> 37#include <machine/bus.h> 38#include <sys/rman.h> 39#include <machine/resource.h> 40#include <machine/clock.h> 41#include <machine/md_var.h> 42 43#include <net/ethernet.h> 44#include <net/if.h> 45#include <net/if_arp.h> 46#include <net/if_mib.h> 47 48#include <isa/isavar.h> 49 50#include <dev/ed/if_edvar.h> 51#include <dev/ed/if_edreg.h> 52#include <dev/ed/if_ed98.h> 53 54static int ed98_alloc_port(device_t, int); 55static int ed98_alloc_memory(device_t, int); 56static int ed_pio_testmem(struct ed_softc *, int, int, int); 57static int ed_probe_SIC98(device_t, int, int); 58static int ed_probe_CNET98(device_t, int, int); 59static int ed_probe_CNET98EL(device_t, int, int); 60static int ed_probe_NEC77(device_t, int, int); 61static int ed_probe_NW98X(device_t, int, int); 62static int ed_probe_SB98(device_t, int, int); 63static int ed_probe_EZ98(device_t, int, int); 64static int ed98_probe_Novell(device_t, int, int); 65static int ed98_probe_generic8390(struct ed_softc *); 66static void ed_reset_CNET98(struct ed_softc *, int); 67static void ed_winsel_CNET98(struct ed_softc *, u_short); 68static void ed_get_SB98(struct ed_softc *); 69 70static int ed_cbus_probe(device_t); 71static int ed_cbus_attach(device_t); 72 73static struct isa_pnp_id ed_ids[] = { 74/* TODO - list up PnP boards for PC-98 */ 75 { 0, NULL } 76}; 77 78static int 79ed_cbus_probe(device_t dev) 80{ 81 struct ed_softc *sc = device_get_softc(dev); 82 int flags = device_get_flags(dev); 83 int error = 0; 84 85 sc->type = ED_TYPE98(flags); 86#ifdef ED_DEBUG 87 device_printf(dev, "ed_cbus_probe: sc->type=%x\n", sc->type); 88#endif 89 90 /* Check isapnp ids */ 91 error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); 92#ifdef ED_DEBUG 93 device_printf(dev, "ed_cbus_probe: ISA_PNP_PROBE returns %d\n", error); 94#endif 95 96 /* If the card had a PnP ID that didn't match any we know about */ 97 if (error == ENXIO) { 98 goto end; 99 } 100 101 /* If we had some other problem. */ 102 if (!(error == 0 || error == ENOENT)) { 103 goto end; 104 } 105 106 /* Heuristic probes */ 107#ifdef ED_DEBUG 108 device_printf(dev, "ed_cbus_probe: Heuristic probes start\n"); 109#endif 110 switch (sc->type) { 111 case ED_TYPE98_GENERIC: 112 /* 113 * CAUTION! 114 * sc->type of these boards are overwritten by PC/AT's value. 115 */ 116 117 /* 118 * SMC EtherEZ98 119 */ 120 error = ed_probe_EZ98(dev, 0, flags); 121 if (error == 0) { 122 goto end; 123 } 124 125 ed_release_resources(dev); 126 127 /* 128 * Allied Telesis CenterCom LA-98-T 129 */ 130 error = ed_probe_Novell(dev, 0, flags); 131 if (error == 0) { 132 goto end; 133 } 134 135 break; 136 137 /* 138 * NE2000-like boards probe routine 139 */ 140 case ED_TYPE98_BDN: 141 /* 142 * ELECOM LANEED LD-BDN 143 * PLANET SMART COM 98 EN-2298 144 */ 145 case ED_TYPE98_LGY: 146 /* 147 * MELCO LGY-98, IND-SP, IND-SS 148 * MACNICA NE2098 149 */ 150 case ED_TYPE98_ICM: 151 /* 152 * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET 153 * D-Link DE-298P, DE-298 154 */ 155 case ED_TYPE98_EGY: 156 /* 157 * MELCO EGY-98 158 * Contec C-NET(98)E-A, C-NET(98)L-A 159 */ 160 case ED_TYPE98_108: 161 /* 162 * NEC PC-9801-107,108 163 */ 164 case ED_TYPE98_NC5098: 165 /* 166 * NextCom NC5098 167 */ 168 169 error = ed98_probe_Novell(dev, 0, flags); 170 171 break; 172 173 /* 174 * other boards with special probe routine 175 */ 176 case ED_TYPE98_SIC: 177 /* 178 * Allied Telesis SIC-98 179 */ 180 error = ed_probe_SIC98(dev, 0, flags); 181 182 break; 183 184 case ED_TYPE98_CNET98EL: 185 /* 186 * Contec C-NET(98)E/L 187 */ 188 error = ed_probe_CNET98EL(dev, 0, flags); 189 190 break; 191 192 case ED_TYPE98_CNET98: 193 /* 194 * Contec C-NET(98) 195 */ 196 error = ed_probe_CNET98(dev, 0, flags); 197 198 break; 199 200 case ED_TYPE98_LA98: 201 /* 202 * IO-DATA LA/T-98 203 * NEC PC-9801-77,78 204 */ 205 error = ed_probe_NEC77(dev, 0, flags); 206 207 break; 208 209 case ED_TYPE98_NW98X: 210 /* 211 * Networld EC/EP-98X 212 */ 213 error = ed_probe_NW98X(dev, 0, flags); 214 215 break; 216 217 case ED_TYPE98_SB98: 218 /* 219 * Soliton SB-9801 220 * Fujikura FN-9801 221 */ 222 223 error = ed_probe_SB98(dev, 0, flags); 224 225 break; 226 } 227 228end: 229#ifdef ED_DEBUG 230 device_printf(dev, "ed_cbus_probe: end, error=%d\n", error); 231#endif 232 if (error == 0) 233 error = ed_alloc_irq(dev, 0, 0); 234 235 ed_release_resources(dev); 236 return (error); 237} 238 239static int 240ed_cbus_attach(dev) 241 device_t dev; 242{ 243 struct ed_softc *sc = device_get_softc(dev); 244 int flags = device_get_flags(dev); 245 int error; 246 247 if (sc->port_used > 0) { 248 if (ED_TYPE98(flags) == ED_TYPE98_GENERIC) { 249 ed_alloc_port(dev, sc->port_rid, sc->port_used); 250 } else { 251 ed98_alloc_port(dev, sc->port_rid); 252 } 253 } 254 if (sc->mem_used) 255 ed_alloc_memory(dev, sc->mem_rid, sc->mem_used); 256 257 ed_alloc_irq(dev, sc->irq_rid, 0); 258 259 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, 260 edintr, sc, &sc->irq_handle); 261 if (error) { 262 ed_release_resources(dev); 263 return (error); 264 } 265 266 return ed_attach(dev); 267} 268 269/* 270 * Interrupt conversion table for EtherEZ98 271 */ 272static uint16_t ed_EZ98_intr_val[] = { 273 0, 274 3, 275 5, 276 6, 277 0, 278 9, 279 12, 280 13 281}; 282 283static int 284ed_probe_EZ98(device_t dev, int port_rid, int flags) 285{ 286 struct ed_softc *sc = device_get_softc(dev); 287 int error; 288 static unsigned short *intr_vals[] = {NULL, ed_EZ98_intr_val}; 289 290 error = ed_alloc_port(dev, port_rid, ED_EZ98_IO_PORTS); 291 if (error) { 292 return (error); 293 } 294 295 sc->asic_offset = ED_EZ98_ASIC_OFFSET; 296 sc->nic_offset = ED_EZ98_NIC_OFFSET; 297 298 return ed_probe_WD80x3_generic(dev, flags, intr_vals); 299} 300 301/* 302 * I/O conversion tables 303 */ 304 305/* LGY-98, ICM, C-NET(98)E/L */ 306static bus_addr_t ed98_ioaddr_generic[] = { 307 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 308}; 309 310/* 311 * Definitions for Contec C-NET(98)E/L 312 */ 313#define ED_CNET98EL_ICR 2 /* Interrupt Configuration Register */ 314 315#define ED_CNET98EL_ICR_IRQ3 0x01 316#define ED_CNET98EL_ICR_IRQ5 0x02 317#define ED_CNET98EL_ICR_IRQ6 0x04 318#define ED_CNET98EL_ICR_IRQ12 0x20 319 320#define ED_CNET98EL_IMR 4 /* Interrupt Mask Register */ 321#define ED_CNET98EL_ISR 5 /* Interrupt Status Register */ 322 323/* EGY-98 */ 324static bus_addr_t ed98_ioaddr_egy98[] = { 325 0, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 326 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e 327}; 328 329/* SIC-98 */ 330static bus_addr_t ed98_ioaddr_sic98[] = { 331 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00, 332 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00 333}; 334 335/* LA/T-98, LD-BDN, PC-9801-77, SB-9801 */ 336static bus_addr_t ed98_ioaddr_la98[] = { 337 0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 338 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000, 339 0x0100 /* for NEC 77(see below) */ 340}; 341 342/* 343 * Definitions for NEC PC-9801-77 344 */ 345#define ED_NEC77_IRQ 16 /* Interrupt Configuration Register */ 346 347#define ED_NEC77_IRQ3 0x04 348#define ED_NEC77_IRQ5 0x06 349#define ED_NEC77_IRQ6 0x08 350#define ED_NEC77_IRQ12 0x0a 351#define ED_NEC77_IRQ13 0x02 352 353/* 354 * Definitions for Soliton SB-9801 355 */ 356#define ED_SB98_CFG 1 /* Board configuration */ 357 358#define ED_SB98_CFG_IRQ3 0x00 359#define ED_SB98_CFG_IRQ5 0x04 360#define ED_SB98_CFG_IRQ6 0x08 361#define ED_SB98_CFG_IRQ12 0x0c 362#define ED_SB98_CFG_ALTPORT 0x40 /* use EXTERNAL media */ 363#define ED_SB98_CFG_ENABLE 0xa0 /* enable configuration */ 364 365#define ED_SB98_EEPENA 2 /* EEPROM access enable */ 366 367#define ED_SB98_EEPENA_DISABLE 0x00 368#define ED_SB98_EEPENA_ENABLE 0x01 369 370#define ED_SB98_EEP 3 /* EEPROM access */ 371 372#define ED_SB98_EEP_SDA 0x01 /* Serial Data */ 373#define ED_SB98_EEP_SCL 0x02 /* Serial Clock */ 374#define ED_SB98_EEP_READ 0x01 /* Read Command */ 375 376#define ED_SB98_EEP_DELAY 300 377 378#define ED_SB98_ADDRESS 0x01 /* Station Address(1-6) */ 379 380#define ED_SB98_POLARITY 4 /* Polarity */ 381 382/* PC-9801-108 */ 383static bus_addr_t ed98_ioaddr_nec108[] = { 384 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 385 0x1000, 0x1002, 0x1004, 0x1006, 0x1008, 0x100a, 0x100c, 0x100e 386}; 387 388/* C-NET(98) */ 389static bus_addr_t ed98_ioaddr_cnet98[] = { 390 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 391 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e 392}; 393 394/* 395 * Definitions for Contec C-NET(98) 396 */ 397#define ED_CNET98_MAP_REG0L 0 /* MAPPING register0 Low */ 398#define ED_CNET98_MAP_REG1L 1 /* MAPPING register1 Low */ 399#define ED_CNET98_MAP_REG2L 2 /* MAPPING register2 Low */ 400#define ED_CNET98_MAP_REG3L 3 /* MAPPING register3 Low */ 401#define ED_CNET98_MAP_REG0H 4 /* MAPPING register0 Hi */ 402#define ED_CNET98_MAP_REG1H 5 /* MAPPING register1 Hi */ 403#define ED_CNET98_MAP_REG2H 6 /* MAPPING register2 Hi */ 404#define ED_CNET98_MAP_REG3H 7 /* MAPPING register3 Hi */ 405#define ED_CNET98_WIN_REG 8 /* Window register */ 406#define ED_CNET98_INT_LEV 9 /* Init level register */ 407 408#define ED_CNET98_INT_IRQ3 0x01 /* INT 0 */ 409#define ED_CNET98_INT_IRQ5 0x02 /* INT 1 */ 410#define ED_CNET98_INT_IRQ6 0x04 /* INT 2 */ 411#define ED_CNET98_INT_IRQ9 0x08 /* INT 3 */ 412#define ED_CNET98_INT_IRQ12 0x20 /* INT 5 */ 413#define ED_CNET98_INT_IRQ13 0x40 /* INT 6 */ 414 415#define ED_CNET98_INT_REQ 10 /* Init request register */ 416#define ED_CNET98_INT_MASK 11 /* Init mask register */ 417#define ED_CNET98_INT_STAT 12 /* Init status register */ 418#define ED_CNET98_INT_CLR 12 /* Init clear register */ 419#define ED_CNET98_RESERVE1 13 420#define ED_CNET98_RESERVE2 14 421#define ED_CNET98_RESERVE3 15 422 423/* EC/EP-98X, NC5098 */ 424static bus_addr_t ed98_ioaddr_nw98x[] = { 425 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 426 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, 427 0x1000 /* for EC/EP-98X(see below) */ 428}; 429 430/* 431 * Definitions for Networld EC/EP-98X 432 */ 433#define ED_NW98X_IRQ 16 /* Interrupt Configuration Register */ 434 435#define ED_NW98X_IRQ3 0x04 436#define ED_NW98X_IRQ5 0x06 437#define ED_NW98X_IRQ6 0x08 438#define ED_NW98X_IRQ12 0x0a 439#define ED_NW98X_IRQ13 0x02 440 441/* NC5098 ASIC */ 442static bus_addr_t ed98_asic_nc5098[] = { 443/* DATA ENADDR RESET */ 444 0x0000, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x4000, 445 0, 0, 0, 0, 0, 0, 0, 0 446}; 447 448/* 449 * Definitions for NextCom NC5098 450 */ 451#define ED_NC5098_ENADDR 1 /* Station Address(1-6) */ 452 453/* 454 * Allocate a port resource with the given resource id. 455 */ 456static int 457ed98_alloc_port(device_t dev, int rid) 458{ 459 struct ed_softc *sc = device_get_softc(dev); 460 struct resource *res; 461 int error; 462 bus_addr_t *io_nic, *io_asic, adj; 463 static bus_addr_t io_res[ED_NOVELL_IO_PORTS + 1]; 464 int i, n; 465 int offset, reset, data; 466 467 /* Set i/o table for resource manager */ 468 io_nic = io_asic = ed98_ioaddr_generic; 469 offset = ED_NOVELL_ASIC_OFFSET; 470 reset = ED_NOVELL_RESET; 471 data = ED_NOVELL_DATA; 472 n = ED_NOVELL_IO_PORTS; 473 474 switch (sc->type) { 475 case ED_TYPE98_LGY: 476 io_asic = ed98_ioaddr_egy98; /* XXX - Yes, we use egy98 */ 477 offset = 0x0200; 478 reset = 8; 479 break; 480 481 case ED_TYPE98_EGY: 482 io_nic = io_asic = ed98_ioaddr_egy98; 483 offset = 0x0200; 484 reset = 8; 485 break; 486 487 case ED_TYPE98_ICM: 488 offset = 0x0100; 489 break; 490 491 case ED_TYPE98_BDN: 492 io_nic = io_asic = ed98_ioaddr_la98; 493 offset = 0x0100; 494 reset = 0x0c; 495 break; 496 497 case ED_TYPE98_SIC: 498 io_nic = io_asic = ed98_ioaddr_sic98; 499 offset = 0x2000; 500 n = 16+1; 501 break; 502 503 case ED_TYPE98_108: 504 io_nic = io_asic = ed98_ioaddr_nec108; 505 offset = 0x0888; /* XXX - overwritten after */ 506 reset = 1; 507 n = 16; /* XXX - does not set ASIC i/o here */ 508 break; 509 510 case ED_TYPE98_LA98: 511 io_nic = io_asic = ed98_ioaddr_la98; 512 offset = 0x0100; 513 break; 514 515 case ED_TYPE98_CNET98EL: 516 offset = 0x0400; 517 data = 0x0e; 518 break; 519 520 case ED_TYPE98_CNET98: 521 /* XXX - Yes, we use generic i/o here */ 522 offset = 0x0400; 523 break; 524 525 case ED_TYPE98_NW98X: 526 io_nic = io_asic = ed98_ioaddr_nw98x; 527 offset = 0x1000; 528 break; 529 530 case ED_TYPE98_SB98: 531 io_nic = io_asic = ed98_ioaddr_la98; 532 offset = 0x0400; 533 reset = 7; 534 break; 535 536 case ED_TYPE98_NC5098: 537 io_nic = ed98_ioaddr_nw98x; 538 io_asic = ed98_asic_nc5098; 539 offset = 0x2000; 540 reset = 7; 541 n = 16+8; /* XXX */ 542 break; 543 } 544 545 bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET); 546 for (i = ED_NOVELL_ASIC_OFFSET; i < ED_NOVELL_IO_PORTS; i++) { 547 io_res[i] = io_asic[i - ED_NOVELL_ASIC_OFFSET] + offset; 548 } 549 550 res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, 551 io_res, n, RF_ACTIVE); 552 if (!res) { 553 return (ENOENT); 554 } 555 556 sc->port_rid = rid; 557 sc->port_res = res; 558 sc->port_used = n; 559 560 /* Re-map i/o table if needed */ 561 switch (sc->type) { 562 case ED_TYPE98_LA98: 563 case ED_TYPE98_NW98X: 564 io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 565 n++; 566 break; 567 568 case ED_TYPE98_108: 569 adj = (rman_get_start(res) & 0xf000) / 2; 570 offset = (offset | adj) - rman_get_start(res); 571 572 for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++) { 573 io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 574 } 575 break; 576 577 case ED_TYPE98_CNET98: 578 io_nic = io_asic = ed98_ioaddr_cnet98; 579 offset = 1; 580 581 bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET); 582 for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++) { 583 io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 584 } 585 break; 586 587 case ED_TYPE98_NC5098: 588 n = ED_NOVELL_IO_PORTS; 589 break; 590 } 591 592 if (reset != ED_NOVELL_RESET) { 593 io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_RESET] = 594 io_res[ED_NOVELL_ASIC_OFFSET + reset]; 595 } 596 if (data != ED_NOVELL_DATA) { 597 io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA] = 598 io_res[ED_NOVELL_ASIC_OFFSET + data]; 599#if 0 600 io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA + 1] = 601 io_res[ED_NOVELL_ASIC_OFFSET + data + 1]; 602#endif 603 } 604 605 error = isa_load_resourcev(res, io_res, n); 606 if (error != 0) { 607 return (ENOENT); 608 } 609#ifdef ED_DEBUG 610 device_printf(dev, "ed98_alloc_port: i/o ports = %d\n", n); 611 for (i = 0; i < n; i++) { 612 printf("%x,", io_res[i]); 613 } 614 printf("\n"); 615#endif 616 return (0); 617} 618 619static int 620ed98_alloc_memory(dev, rid) 621 device_t dev; 622 int rid; 623{ 624 struct ed_softc *sc = device_get_softc(dev); 625 int error; 626 u_long conf_maddr, conf_msize; 627 628 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 629 &conf_maddr, &conf_msize); 630 if (error) { 631 return (error); 632 } 633 634 if ((conf_maddr == 0) || (conf_msize == 0)) { 635 return (ENXIO); 636 } 637 638 error = ed_alloc_memory(dev, rid, (int) conf_msize); 639 if (error) { 640 return (error); 641 } 642 643 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); 644 sc->mem_size = conf_msize; 645 646 return (0); 647} 648 649/* 650 * Generic probe routine for testing for the existance of a DS8390. 651 * Must be called after the NIC has just been reset. This routine 652 * works by looking at certain register values that are guaranteed 653 * to be initialized a certain way after power-up or reset. Seems 654 * not to currently work on the 83C690. 655 * 656 * Specifically: 657 * 658 * Register reset bits set bits 659 * Command Register (CR) TXP, STA RD2, STP 660 * Interrupt Status (ISR) RST 661 * Interrupt Mask (IMR) All bits 662 * Data Control (DCR) LAS 663 * Transmit Config. (TCR) LB1, LB0 664 * 665 * XXX - We only check the CR register. 666 * 667 * Return 1 if 8390 was found, 0 if not. 668 */ 669 670static int 671ed98_probe_generic8390(struct ed_softc *sc) 672{ 673 u_char tmp = ed_nic_inb(sc, ED_P0_CR); 674#ifdef DIAGNOSTIC 675 printf("ed?: inb(ED_P0_CR)=%x\n", tmp); 676#endif 677 if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) != 678 (ED_CR_RD2 | ED_CR_STP)) { 679 return (0); 680 } 681 682 (void) ed_nic_inb(sc, ED_P0_ISR); 683 684 return (1); 685} 686 687static int 688ed98_probe_Novell(device_t dev, int port_rid, int flags) 689{ 690 struct ed_softc *sc = device_get_softc(dev); 691 int error; 692 int n; 693 u_char romdata[ETHER_ADDR_LEN * 2], tmp; 694 695#ifdef ED_DEBUG 696 device_printf(dev, "ed98_probe_Novell: start\n"); 697#endif 698 error = ed98_alloc_port(dev, port_rid); 699 if (error) { 700 return (error); 701 } 702 703 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 704 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 705 706 /* Reset the board */ 707#ifdef ED_DEBUG 708 device_printf(dev, "ed98_probe_Novell: reset\n"); 709#endif 710 switch (sc->type) { 711#if 1 /* XXX - I'm not sure this is really necessary... */ 712 case ED_TYPE98_BDN: 713 tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 714 ed_asic_outb(sc, ED_NOVELL_RESET, (tmp & 0xf0) | 0x08); 715 ed_nic_outb(sc, 0x04, tmp); 716 (void) ed_asic_inb(sc, 0x08); 717 ed_asic_outb(sc, 0x08, tmp); 718 ed_asic_outb(sc, 0x08, tmp & 0x7f); 719 break; 720#endif 721 case ED_TYPE98_NC5098: 722 ed_asic_outb(sc, ED_NOVELL_RESET, 0x00); 723 DELAY(5000); 724 ed_asic_outb(sc, ED_NOVELL_RESET, 0x01); 725 break; 726 727 default: 728 tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 729 730 /* 731 * I don't know if this is necessary; probably cruft leftover from 732 * Clarkson packet driver code. Doesn't do a thing on the boards I've 733 * tested. -DG [note that an outb(0x84, 0) seems to work here, and is 734 * non-invasive...but some boards don't seem to reset and I don't have 735 * complete documentation on what the 'right' thing to do is...so we 736 * do the invasive thing for now. Yuck.] 737 */ 738 ed_asic_outb(sc, ED_NOVELL_RESET, tmp); 739 break; 740 } 741 DELAY(5000); 742 743 /* 744 * This is needed because some NE clones apparently don't reset the 745 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 746 * - this makes the probe invasive! ...Done against my better 747 * judgement. -DLG 748 */ 749 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 750 DELAY(5000); 751 752 /* Make sure that we really have an 8390 based board */ 753 if (!ed98_probe_generic8390(sc)) { 754 return (ENXIO); 755 } 756 757 /* Test memory via PIO */ 758#ifdef ED_DEBUG 759 device_printf(dev, "ed98_probe_Novell: test memory\n"); 760#endif 761 sc->cr_proto = ED_CR_RD2; 762 if (!ed_pio_testmem(sc, 8192, 0, flags) 763 && !ed_pio_testmem(sc, 16384, 1, flags)) { 764 return (ENXIO); 765 } 766 767 /* Setup the board type */ 768#ifdef ED_DEBUG 769 device_printf(dev, "ed98_probe_Novell: board type\n"); 770#endif 771 switch (sc->type) { 772 case ED_TYPE98_BDN: 773 sc->type_str = "LD-BDN"; 774 break; 775 case ED_TYPE98_EGY: 776 sc->type_str = "EGY-98"; 777 break; 778 case ED_TYPE98_LGY: 779 sc->type_str = "LGY-98"; 780 break; 781 case ED_TYPE98_ICM: 782 sc->type_str = "ICM"; 783 break; 784 case ED_TYPE98_108: 785 sc->type_str = "PC-9801-108"; 786 break; 787 case ED_TYPE98_LA98: 788 sc->type_str = "LA-98"; 789 break; 790 case ED_TYPE98_NW98X: 791 sc->type_str = "NW98X"; 792 break; 793 case ED_TYPE98_NC5098: 794 sc->type_str = "NC5098"; 795 break; 796 default: 797 sc->type_str = NULL; 798 break; 799 } 800 801 /* Get station address */ 802 switch (sc->type) { 803 case ED_TYPE98_NC5098: 804 for (n = 0; n < ETHER_ADDR_LEN; n++) { 805 sc->arpcom.ac_enaddr[n] = 806 ed_asic_inb(sc, ED_NC5098_ENADDR + n); 807 } 808 break; 809 810 default: 811 ed_pio_readmem(sc, 0, romdata, sizeof(romdata)); 812 for (n = 0; n < ETHER_ADDR_LEN; n++) { 813 sc->arpcom.ac_enaddr[n] = 814 romdata[n * (sc->isa16bit + 1)]; 815 } 816 break; 817 } 818 819 /* clear any pending interrupts that might have occurred above */ 820 ed_nic_outb(sc, ED_P0_ISR, 0xff); 821 822 return (0); 823} 824 825/* 826 * Probe and vendor-specific initialization routine for SIC-98 boards 827 */ 828static int 829ed_probe_SIC98(device_t dev, int port_rid, int flags) 830{ 831 struct ed_softc *sc = device_get_softc(dev); 832 int error; 833 int i; 834 u_char sum; 835 836 /* 837 * Setup card RAM and I/O address 838 * Kernel Virtual to segment C0000-DFFFF???? 839 */ 840 error = ed98_alloc_port(dev, port_rid); 841 if (error) { 842 return (error); 843 } 844 845 sc->asic_offset = ED_SIC_ASIC_OFFSET; 846 sc->nic_offset = ED_SIC_NIC_OFFSET; 847 848 error = ed98_alloc_memory(dev, 0); 849 if (error) { 850 return (error); 851 } 852 853 /* Reset card to force it into a known state. */ 854 ed_asic_outb(sc, 0, 0x00); 855 DELAY(100); 856 if (ED_TYPE98SUB(flags) == 0) { 857 /* SIC-98/SIU-98 */ 858 ed_asic_outb(sc, 0, 0x94); 859 DELAY(100); 860 ed_asic_outb(sc, 0, 0x94); 861 } else { 862 /* SIU-98-D */ 863 ed_asic_outb(sc, 0, 0x80); 864 DELAY(100); 865 ed_asic_outb(sc, 0, 0x94); 866 DELAY(100); 867 ed_asic_outb(sc, 0, 0x9e); 868 } 869 DELAY(100); 870 871 /* 872 * Here we check the card ROM, if the checksum passes, and the 873 * type code and ethernet address check out, then we know we have 874 * an SIC card. 875 */ 876 sum = sc->mem_start[6 * 2]; 877 for (i = 0; i < ETHER_ADDR_LEN; i++) { 878 sum ^= (sc->arpcom.ac_enaddr[i] = sc->mem_start[i * 2]); 879 } 880#ifdef ED_DEBUG 881 device_printf(dev, "ed_probe_sic98: got address %6D\n", 882 sc->arpcom.ac_enaddr, ":"); 883#endif 884 if (sum != 0) { 885 return (ENXIO); 886 } 887 if ((sc->arpcom.ac_enaddr[0] | sc->arpcom.ac_enaddr[1] | 888 sc->arpcom.ac_enaddr[2]) == 0) { 889 return (ENXIO); 890 } 891 892 sc->vendor = ED_VENDOR_SIC; 893 sc->type_str = "SIC98"; 894 sc->isa16bit = 1; 895 sc->cr_proto = 0; 896 897 /* 898 * SIC RAM page 0x0000-0x3fff(or 0x7fff) 899 */ 900 if (ED_TYPE98SUB(flags) == 0) { 901 ed_asic_outb(sc, 0, 0x90); 902 } else { 903 ed_asic_outb(sc, 0, 0x8e); 904 } 905 DELAY(100); 906 907 error = ed_clear_memory(dev); 908 if (error) 909 return (error); 910 911 sc->mem_shared = 1; 912 sc->mem_end = sc->mem_start + sc->mem_size; 913 914 /* 915 * allocate one xmit buffer if < 16k, two buffers otherwise 916 */ 917 if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { 918 sc->txb_cnt = 1; 919 } else { 920 sc->txb_cnt = 2; 921 } 922 sc->tx_page_start = 0; 923 924 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt; 925 sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 926 927 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 928 929 return (0); 930} 931 932/* 933 * Contec C-NET(98) series support routines 934 */ 935static void 936ed_reset_CNET98(struct ed_softc *sc, int flags) 937{ 938 u_int init_addr = ED_CNET98_INIT; 939 u_char tmp; 940 941 /* Choose initial register address */ 942 if (ED_TYPE98SUB(flags) != 0) { 943 init_addr = ED_CNET98_INIT2; 944 } 945#ifdef ED_DEBUG 946 printf("ed?: initial register=%x\n", init_addr); 947#endif 948 /* 949 * Reset the board to force it into a known state. 950 */ 951 outb(init_addr, 0x00); /* request */ 952 DELAY(5000); 953 outb(init_addr, 0x01); /* cancel */ 954 DELAY(5000); 955 956 /* 957 * Set I/O address(A15-12) and cpu type 958 * 959 * AAAAIXXC(8bit) 960 * AAAA: A15-A12, I: I/O enable, XX: reserved, C: CPU type 961 * 962 * CPU type is 1:80286 or higher, 0:not. 963 * But FreeBSD runs under i386 or higher, thus it must be 1. 964 */ 965 tmp = (rman_get_start(sc->port_res) & 0xf000) >> 8; 966 tmp |= (0x08 | 0x01); 967#ifdef ED_DEBUG 968 printf("ed?: outb(%x, %x)\n", init_addr + 2, tmp); 969#endif 970 outb(init_addr + 2, tmp); 971 DELAY(5000); 972 973 /* 974 * This is needed because some NE clones apparently don't reset the 975 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 976 * - this makes the probe invasive! ...Done against my better 977 * judgement. -DLG 978 */ 979 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 980 DELAY(5000); 981} 982 983static void 984ed_winsel_CNET98(struct ed_softc *sc, u_short bank) 985{ 986 u_char mem = (rman_get_start(sc->mem_res) >> 12) & 0xff; 987 988 /* 989 * Disable window memory 990 * bit7 is 0:disable 991 */ 992 ed_asic_outb(sc, ED_CNET98_WIN_REG, mem & 0x7f); 993 DELAY(10); 994 995 /* 996 * Select window address 997 * FreeBSD address 0xf00xxxxx 998 */ 999 ed_asic_outb(sc, ED_CNET98_MAP_REG0L, bank & 0xff); 1000 DELAY(10); 1001 ed_asic_outb(sc, ED_CNET98_MAP_REG0H, (bank >> 8) & 0xff); 1002 DELAY(10); 1003 ed_asic_outb(sc, ED_CNET98_MAP_REG1L, 0x00); 1004 DELAY(10); 1005 ed_asic_outb(sc, ED_CNET98_MAP_REG1H, 0x41); 1006 DELAY(10); 1007 ed_asic_outb(sc, ED_CNET98_MAP_REG2L, 0x00); 1008 DELAY(10); 1009 ed_asic_outb(sc, ED_CNET98_MAP_REG2H, 0x42); 1010 DELAY(10); 1011 ed_asic_outb(sc, ED_CNET98_MAP_REG3L, 0x00); 1012 DELAY(10); 1013 ed_asic_outb(sc, ED_CNET98_MAP_REG3H, 0x43); 1014 DELAY(10); 1015 1016 /* 1017 * Enable window memory(16Kbyte) 1018 * bit7 is 1:enable 1019 */ 1020#ifdef ED_DEBUG 1021 printf("ed?: window start address=%x\n", mem); 1022#endif 1023 ed_asic_outb(sc, ED_CNET98_WIN_REG, mem); 1024 DELAY(10); 1025} 1026 1027/* 1028 * Probe and vendor-specific initialization routine for C-NET(98) boards 1029 */ 1030static int 1031ed_probe_CNET98(device_t dev, int port_rid, int flags) 1032{ 1033 struct ed_softc *sc = device_get_softc(dev); 1034 int error; 1035 u_char tmp; 1036 u_long conf_irq, junk; 1037#ifdef DIAGNOSTIC 1038 u_char tmp_s; 1039#endif 1040 1041 error = ed98_alloc_port(dev, port_rid); 1042 if (error) { 1043 return (error); 1044 } 1045 1046 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1047 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1048 1049 error = ed98_alloc_memory(dev, 0); 1050 if (error) { 1051 return (error); 1052 } 1053 1054 /* Check I/O address. 0x[a-f]3d0 are allowed. */ 1055 if (((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) 1056 || ((rman_get_start(sc->port_res) & 0xf000) < (u_short) 0xa000)) { 1057#ifdef DIAGNOSTIC 1058 device_printf(dev, "Invalid i/o port configuration (0x%lx) " 1059 "must be %s for %s\n", rman_get_start(sc->port_res), 1060 "0x[a-f]3d0", "CNET98"); 1061#endif 1062 return (ENXIO); 1063 } 1064 1065#ifdef DIAGNOSTIC 1066 /* Check window area address */ 1067 tmp_s = rman_get_start(sc->mem_res) >> 12; 1068 if (tmp_s < 0x80) { 1069 device_printf(dev, "Please change window address(0x%lx)\n", 1070 rman_get_start(sc->mem_res)); 1071 return (ENXIO); 1072 } 1073 1074 tmp_s &= 0x0f; 1075 tmp = rman_get_start(sc->port_res) >> 12; 1076 if ((tmp_s <= tmp) && (tmp < (tmp_s + 4))) { 1077 device_printf(dev, "Please change iobase address(0x%lx) " 1078 "or window address(0x%lx)\n", 1079 rman_get_start(sc->port_res), 1080 rman_get_start(sc->mem_res)); 1081 return (ENXIO); 1082 } 1083#endif 1084 /* Reset the board */ 1085 ed_reset_CNET98(sc, flags); 1086 1087 /* 1088 * This is needed because some NE clones apparently don't reset the 1089 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1090 * - this makes the probe invasive! ...Done against my better 1091 * judgement. -DLG 1092 */ 1093 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1094 DELAY(5000); 1095 1096 /* Make sure that we really have an 8390 based board */ 1097 if (!ed98_probe_generic8390(sc)) { 1098 return (ENXIO); 1099 } 1100 1101 /* 1102 * Set window ethernet address area 1103 * board memory base 0x480000 data 256byte 1104 */ 1105 ed_winsel_CNET98(sc, 0x4800); 1106 1107 /* 1108 * Get station address from on-board ROM 1109 */ 1110 bcopy(sc->mem_start, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 1111 1112 sc->vendor = ED_VENDOR_MISC; 1113 sc->type_str = "CNET98"; 1114 sc->isa16bit = 0; 1115 sc->cr_proto = ED_CR_RD2; 1116 1117 /* 1118 * Set window buffer memory area 1119 * board memory base 0x400000 data 16kbyte 1120 */ 1121 ed_winsel_CNET98(sc, 0x4000); 1122 1123 error = ed_clear_memory(dev); 1124 if (error) 1125 return (error); 1126 1127 sc->mem_shared = 1; 1128 sc->mem_end = sc->mem_start + sc->mem_size; 1129 1130 sc->txb_cnt = 1; /* XXX */ 1131 sc->tx_page_start = 0; 1132 1133 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE; 1134 sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 1135 1136 sc->mem_ring = sc->mem_start + ED_PAGE_SIZE * ED_TXBUF_SIZE; 1137 1138 /* 1139 * Set interrupt level 1140 */ 1141 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1142 &conf_irq, &junk); 1143 if (error) 1144 return (error); 1145 1146 switch (conf_irq) { 1147 case 3: 1148 tmp = ED_CNET98_INT_IRQ3; 1149 break; 1150 case 5: 1151 tmp = ED_CNET98_INT_IRQ5; 1152 break; 1153 case 6: 1154 tmp = ED_CNET98_INT_IRQ6; 1155 break; 1156 case 9: 1157 tmp = ED_CNET98_INT_IRQ9; 1158 break; 1159 case 12: 1160 tmp = ED_CNET98_INT_IRQ12; 1161 break; 1162 case 13: 1163 tmp = ED_CNET98_INT_IRQ13; 1164 break; 1165 default: 1166 device_printf(dev, "Invalid irq configuration (%ld) must be " 1167 "%s for %s\n", conf_irq, "3,5,6,9,12,13", "CNET98"); 1168 return (ENXIO); 1169 } 1170 ed_asic_outb(sc, ED_CNET98_INT_LEV, tmp); 1171 DELAY(1000); 1172 /* 1173 * Set interrupt mask. 1174 * bit7:1 all interrupt mask 1175 * bit1:1 timer interrupt mask 1176 * bit0:0 NS controler interrupt enable 1177 */ 1178 ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e); 1179 DELAY(1000); 1180 1181 return (0); 1182} 1183 1184/* 1185 * Probe and vendor-specific initialization routine for C-NET(98)E/L boards 1186 */ 1187static int 1188ed_probe_CNET98EL(device_t dev, int port_rid, int flags) 1189{ 1190 struct ed_softc *sc = device_get_softc(dev); 1191 int error; 1192 int i; 1193 u_char romdata[ETHER_ADDR_LEN * 2], tmp; 1194 u_long conf_irq, junk; 1195 1196 error = ed98_alloc_port(dev, port_rid); 1197 if (error) { 1198 return (error); 1199 } 1200 1201 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1202 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1203 1204 /* Check I/O address. 0x[0-f]3d0 are allowed. */ 1205 if ((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) { 1206#ifdef DIAGNOSTIC 1207 device_printf(dev, "Invalid i/o port configuration (0x%lx) " 1208 "must be %s for %s\n", rman_get_start(sc->port_res), 1209 "0x?3d0", "CNET98E/L"); 1210#endif 1211 return (ENXIO); 1212 } 1213 1214 /* Reset the board */ 1215 ed_reset_CNET98(sc, flags); 1216 1217 /* 1218 * This is needed because some NE clones apparently don't reset the 1219 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1220 * - this makes the probe invasive! ...Done against my better 1221 * judgement. -DLG 1222 */ 1223 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1224 DELAY(5000); 1225 1226 /* Make sure that we really have an 8390 based board */ 1227 if (!ed98_probe_generic8390(sc)) { 1228 return (ENXIO); 1229 } 1230 1231 /* Test memory via PIO */ 1232 sc->cr_proto = ED_CR_RD2; 1233 if (!ed_pio_testmem(sc, ED_CNET98EL_PAGE_OFFSET, 1, flags)) { 1234 return (ENXIO); 1235 } 1236 1237 /* This looks like a C-NET(98)E/L board. */ 1238 sc->type_str = "CNET98E/L"; 1239 1240 /* 1241 * Set IRQ. C-NET(98)E/L only allows a choice of irq 3,5,6. 1242 */ 1243 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1244 &conf_irq, &junk); 1245 if (error) { 1246 return (error); 1247 } 1248 1249 switch (conf_irq) { 1250 case 3: 1251 tmp = ED_CNET98EL_ICR_IRQ3; 1252 break; 1253 case 5: 1254 tmp = ED_CNET98EL_ICR_IRQ5; 1255 break; 1256 case 6: 1257 tmp = ED_CNET98EL_ICR_IRQ6; 1258 break; 1259#if 0 1260 case 12: 1261 tmp = ED_CNET98EL_ICR_IRQ12; 1262 break; 1263#endif 1264 default: 1265 device_printf(dev, "Invalid irq configuration (%ld) must be " 1266 "%s for %s\n", conf_irq, "3,5,6", "CNET98E/L"); 1267 return (ENXIO); 1268 } 1269 ed_asic_outb(sc, ED_CNET98EL_ICR, tmp); 1270 ed_asic_outb(sc, ED_CNET98EL_IMR, 0x7e); 1271 1272 /* Get station address from on-board ROM */ 1273 ed_pio_readmem(sc, 16384, romdata, sizeof(romdata)); 1274 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1275 sc->arpcom.ac_enaddr[i] = romdata[i * 2]; 1276 } 1277 1278 /* clear any pending interrupts that might have occurred above */ 1279 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1280 1281 return (0); 1282} 1283 1284/* 1285 * Probe and vendor-specific initialization routine for PC-9801-77 boards 1286 */ 1287static int 1288ed_probe_NEC77(device_t dev, int port_rid, int flags) 1289{ 1290 struct ed_softc *sc = device_get_softc(dev); 1291 int error; 1292 u_char tmp; 1293 u_long conf_irq, junk; 1294 1295 error = ed98_probe_Novell(dev, port_rid, flags); 1296 if (error) { 1297 return (error); 1298 } 1299 1300 /* LA/T-98 does not need IRQ setting. */ 1301 if (ED_TYPE98SUB(flags) == 0) { 1302 return (0); 1303 } 1304 1305 /* 1306 * Set IRQ. PC-9801-77 only allows a choice of irq 3,5,6,12,13. 1307 */ 1308 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1309 &conf_irq, &junk); 1310 if (error) { 1311 return (error); 1312 } 1313 1314 switch (conf_irq) { 1315 case 3: 1316 tmp = ED_NEC77_IRQ3; 1317 break; 1318 case 5: 1319 tmp = ED_NEC77_IRQ5; 1320 break; 1321 case 6: 1322 tmp = ED_NEC77_IRQ6; 1323 break; 1324 case 12: 1325 tmp = ED_NEC77_IRQ12; 1326 break; 1327 case 13: 1328 tmp = ED_NEC77_IRQ13; 1329 break; 1330 default: 1331 device_printf(dev, "Invalid irq configuration (%ld) must be " 1332 "%s for %s\n", conf_irq, "3,5,6,12,13", "PC-9801-77"); 1333 return (ENXIO); 1334 } 1335 ed_asic_outb(sc, ED_NEC77_IRQ, tmp); 1336 1337 return (0); 1338} 1339 1340/* 1341 * Probe and vendor-specific initialization routine for EC/EP-98X boards 1342 */ 1343static int 1344ed_probe_NW98X(device_t dev, int port_rid, int flags) 1345{ 1346 struct ed_softc *sc = device_get_softc(dev); 1347 int error; 1348 u_char tmp; 1349 u_long conf_irq, junk; 1350 1351 error = ed98_probe_Novell(dev, port_rid, flags); 1352 if (error) { 1353 return (error); 1354 } 1355 1356 /* Networld 98X3 does not need IRQ setting. */ 1357 if (ED_TYPE98SUB(flags) == 0) { 1358 return (0); 1359 } 1360 1361 /* 1362 * Set IRQ. EC/EP-98X only allows a choice of irq 3,5,6,12,13. 1363 */ 1364 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1365 &conf_irq, &junk); 1366 if (error) { 1367 return (error); 1368 } 1369 1370 switch (conf_irq) { 1371 case 3: 1372 tmp = ED_NW98X_IRQ3; 1373 break; 1374 case 5: 1375 tmp = ED_NW98X_IRQ5; 1376 break; 1377 case 6: 1378 tmp = ED_NW98X_IRQ6; 1379 break; 1380 case 12: 1381 tmp = ED_NW98X_IRQ12; 1382 break; 1383 case 13: 1384 tmp = ED_NW98X_IRQ13; 1385 break; 1386 default: 1387 device_printf(dev, "Invalid irq configuration (%ld) must be " 1388 "%s for %s\n", conf_irq, "3,5,6,12,13", "EC/EP-98X"); 1389 return (ENXIO); 1390 } 1391 ed_asic_outb(sc, ED_NW98X_IRQ, tmp); 1392 1393 return (0); 1394} 1395 1396/* 1397 * Read SB-9801 station address from Serial Two-Wire EEPROM 1398 */ 1399static void 1400ed_get_SB98(struct ed_softc *sc) 1401{ 1402 int i, j; 1403 u_char mask, val; 1404 1405 /* enable EEPROM acceess */ 1406 ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_ENABLE); 1407 1408 /* output start command */ 1409 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1410 DELAY(ED_SB98_EEP_DELAY); 1411 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1412 DELAY(ED_SB98_EEP_DELAY); 1413 1414 /* output address (7bit) */ 1415 for (mask = 0x40; mask != 0; mask >>= 1) { 1416 val = 0; 1417 if (ED_SB98_ADDRESS & mask) 1418 val = ED_SB98_EEP_SDA; 1419 ed_asic_outb(sc, ED_SB98_EEP, val); 1420 DELAY(ED_SB98_EEP_DELAY); 1421 ed_asic_outb(sc, ED_SB98_EEP, val | ED_SB98_EEP_SCL); 1422 DELAY(ED_SB98_EEP_DELAY); 1423 } 1424 1425 /* output READ command */ 1426 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ); 1427 DELAY(ED_SB98_EEP_DELAY); 1428 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ | ED_SB98_EEP_SCL); 1429 DELAY(ED_SB98_EEP_DELAY); 1430 1431 /* read station address */ 1432 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1433 /* output ACK */ 1434 ed_asic_outb(sc, ED_SB98_EEP, 0); 1435 DELAY(ED_SB98_EEP_DELAY); 1436 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1437 DELAY(ED_SB98_EEP_DELAY); 1438 1439 val = 0; 1440 for (j = 0; j < 8; j++) { 1441 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA); 1442 DELAY(ED_SB98_EEP_DELAY); 1443 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1444 DELAY(ED_SB98_EEP_DELAY); 1445 val <<= 1; 1446 val |= (ed_asic_inb(sc, ED_SB98_EEP) & ED_SB98_EEP_SDA); 1447 DELAY(ED_SB98_EEP_DELAY); 1448 } 1449 sc->arpcom.ac_enaddr[i] = val; 1450 } 1451 1452 /* output Last ACK */ 1453 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA); 1454 DELAY(ED_SB98_EEP_DELAY); 1455 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1456 DELAY(ED_SB98_EEP_DELAY); 1457 1458 /* output stop command */ 1459 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1460 DELAY(ED_SB98_EEP_DELAY); 1461 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1462 DELAY(ED_SB98_EEP_DELAY); 1463 1464 /* disable EEPROM access */ 1465 ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_DISABLE); 1466} 1467 1468/* 1469 * Probe and vendor-specific initialization routine for SB-9801 boards 1470 */ 1471static int 1472ed_probe_SB98(device_t dev, int port_rid, int flags) 1473{ 1474 struct ed_softc *sc = device_get_softc(dev); 1475 int error; 1476 u_char tmp; 1477 u_long conf_irq, junk; 1478 1479 error = ed98_alloc_port(dev, port_rid); 1480 if (error) { 1481 return (error); 1482 } 1483 1484 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1485 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1486 1487 /* Check I/O address. 00d[02468ace] are allowed. */ 1488 if ((rman_get_start(sc->port_res) & ~0x000e) != 0x00d0) { 1489#ifdef DIAGNOSTIC 1490 device_printf(dev, "Invalid i/o port configuration (0x%lx) " 1491 "must be %s for %s\n", rman_get_start(sc->port_res), 1492 "0xd?", "SB9801"); 1493#endif 1494 return (ENXIO); 1495 } 1496 1497 /* Write I/O port address and read 4 times */ 1498 outb(ED_SB98_IO_INHIBIT, rman_get_start(sc->port_res) & 0xff); 1499 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1500 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1501 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1502 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1503 1504 /* 1505 * Check IRQ. Soliton SB-9801 only allows a choice of 1506 * irq 3,5,6,12 1507 */ 1508 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1509 &conf_irq, &junk); 1510 if (error) { 1511 return (error); 1512 } 1513 1514 switch (conf_irq) { 1515 case 3: 1516 tmp = ED_SB98_CFG_IRQ3; 1517 break; 1518 case 5: 1519 tmp = ED_SB98_CFG_IRQ5; 1520 break; 1521 case 6: 1522 tmp = ED_SB98_CFG_IRQ6; 1523 break; 1524 case 12: 1525 tmp = ED_SB98_CFG_IRQ12; 1526 break; 1527 default: 1528 device_printf(dev, "Invalid irq configuration (%ld) must be " 1529 "%s for %s\n", conf_irq, "3,5,6,12", "SB9801"); 1530 return (ENXIO); 1531 } 1532 1533 if (flags & ED_FLAGS_DISABLE_TRANCEIVER) { 1534 tmp |= ED_SB98_CFG_ALTPORT; 1535 } 1536 ed_asic_outb(sc, ED_SB98_CFG, ED_SB98_CFG_ENABLE | tmp); 1537 ed_asic_outb(sc, ED_SB98_POLARITY, 0x01); 1538 1539 /* Reset the board. */ 1540 ed_asic_outb(sc, ED_NOVELL_RESET, 0x7a); 1541 DELAY(300); 1542 ed_asic_outb(sc, ED_NOVELL_RESET, 0x79); 1543 DELAY(300); 1544 1545 /* 1546 * This is needed because some NE clones apparently don't reset the 1547 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1548 * - this makes the probe invasive! ...Done against my better 1549 * judgement. -DLG 1550 */ 1551 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1552 DELAY(5000); 1553 1554 /* Make sure that we really have an 8390 based board */ 1555 if (!ed98_probe_generic8390(sc)) { 1556 return (ENXIO); 1557 } 1558 1559 /* Test memory via PIO */ 1560 sc->cr_proto = ED_CR_RD2; 1561 if (!ed_pio_testmem(sc, 16384, 1, flags)) { 1562 return (ENXIO); 1563 } 1564 1565 /* This looks like an SB9801 board. */ 1566 sc->type_str = "SB9801"; 1567 1568 /* Get station address */ 1569 ed_get_SB98(sc); 1570 1571 /* clear any pending interrupts that might have occurred above */ 1572 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1573 1574 return (0); 1575} 1576 1577/* 1578 * Test the ability to read and write to the NIC memory. 1579 */ 1580static int 1581ed_pio_testmem(struct ed_softc *sc, int page_offset, int isa16bit, int flags) 1582{ 1583 u_long memsize; 1584 static char test_pattern[32] = "THIS is A memory TEST pattern"; 1585 char test_buffer[32]; 1586#ifdef DIAGNOSTIC 1587 int page_end; 1588#endif 1589 1590 sc->vendor = ED_VENDOR_NOVELL; 1591 sc->mem_shared = 0; 1592 sc->isa16bit = isa16bit; 1593 1594 /* 8k of memory plus an additional 8k if 16bit */ 1595 memsize = (isa16bit ? 16384 : 8192); 1596 1597 /* 1598 * This prevents packets from being stored in the NIC memory when the 1599 * readmem routine turns on the start bit in the CR. 1600 */ 1601 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); 1602 1603 /* Initialize DCR for byte/word operations */ 1604 if (isa16bit) 1605 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 1606 else 1607 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 1608 ed_nic_outb(sc, ED_P0_PSTART, page_offset / ED_PAGE_SIZE); 1609 ed_nic_outb(sc, ED_P0_PSTOP, (page_offset + memsize) / ED_PAGE_SIZE); 1610#ifdef ED_DEBUG 1611 printf("ed?: ed_pio_testmem: page start=%x, end=%lx", 1612 page_offset, page_offset + memsize); 1613#endif 1614 1615 /* 1616 * Write a test pattern. If this fails, then we don't know 1617 * what this board is. 1618 */ 1619 ed_pio_writemem(sc, test_pattern, page_offset, sizeof(test_pattern)); 1620 ed_pio_readmem(sc, page_offset, test_buffer, sizeof(test_pattern)); 1621 1622 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) { 1623#ifdef ED_DEBUG 1624 printf("ed?: ed_pio_testmem: bcmp(page %x) NG", 1625 page_offset); 1626#endif 1627 return (0); 1628 } 1629 1630#ifdef DIAGNOSTIC 1631 /* Check the bottom. */ 1632 page_end = page_offset + memsize - ED_PAGE_SIZE; 1633 ed_pio_writemem(sc, test_pattern, page_end, sizeof(test_pattern)); 1634 ed_pio_readmem(sc, page_end, test_buffer, sizeof(test_pattern)); 1635 1636 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) { 1637#ifdef ED_DEBUG 1638 printf("ed?: ed_pio_testmem: bcmp(page %x) NG", 1639 page_end); 1640#endif 1641 return (0); 1642 } 1643#endif 1644 sc->mem_size = memsize; 1645 sc->mem_start = (char *) page_offset; 1646 sc->mem_end = sc->mem_start + memsize; 1647 sc->tx_page_start = page_offset / ED_PAGE_SIZE; 1648 1649 /* 1650 * Use one xmit buffer if < 16k, two buffers otherwise (if not told 1651 * otherwise). 1652 */ 1653 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { 1654 sc->txb_cnt = 1; 1655 } else { 1656 sc->txb_cnt = 2; 1657 } 1658 1659 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 1660 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 1661 1662 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 1663 1664 return (1); 1665} 1666 1667static device_method_t ed_cbus_methods[] = { 1668 /* Device interface */ 1669 DEVMETHOD(device_probe, ed_cbus_probe), 1670 DEVMETHOD(device_attach, ed_cbus_attach), 1671 DEVMETHOD(device_attach, ed_detach), 1672 1673 { 0, 0 } 1674}; 1675 1676static driver_t ed_cbus_driver = { 1677 "ed", 1678 ed_cbus_methods, 1679 sizeof(struct ed_softc) 1680}; 1681 1682DRIVER_MODULE(ed, isa, ed_cbus_driver, ed_devclass, 0, 0); 1683MODULE_DEPEND(ed, isa, 1, 1, 1); 1684MODULE_DEPEND(ed, ether, 1, 1, 1); 1685