if_ed_cbus.c revision 191234
1112125Ssam/*- 2112125Ssam * Copyright (c) 1995, David Greenman 3139749Simp * All rights reserved. 4112125Ssam * 5112125Ssam * Redistribution and use in source and binary forms, with or without 6112125Ssam * modification, are permitted provided that the following conditions 7112125Ssam * are met: 8112125Ssam * 1. Redistributions of source code must retain the above copyright 9112125Ssam * notice unmodified, this list of conditions, and the following 10112125Ssam * disclaimer. 11112125Ssam * 2. Redistributions in binary form must reproduce the above copyright 12112125Ssam * notice, this list of conditions and the following disclaimer in the 13112125Ssam * documentation and/or other materials provided with the distribution. 14112125Ssam * 15112125Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16112125Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17112125Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18112125Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19112125Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20112125Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21112125Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22112125Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23112125Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24112125Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25112125Ssam * SUCH DAMAGE. 26112125Ssam * 27112125Ssam * $FreeBSD: head/sys/dev/ed/if_ed_cbus.c 191234 2009-04-18 03:10:28Z imp $ 28112125Ssam */ 29112125Ssam 30112125Ssam#include <sys/param.h> 31112125Ssam#include <sys/systm.h> 32112125Ssam#include <sys/socket.h> 33112125Ssam#include <sys/kernel.h> 34119418Sobrien 35119418Sobrien#include <sys/module.h> 36119418Sobrien#include <sys/bus.h> 37112125Ssam#include <machine/bus.h> 38112125Ssam#include <sys/rman.h> 39112125Ssam#include <machine/resource.h> 40112125Ssam 41112125Ssam#include <net/ethernet.h> 42112125Ssam#include <net/if.h> 43112125Ssam#include <net/if_arp.h> 44112125Ssam#include <net/if_media.h> 45112125Ssam#include <net/if_mib.h> 46112125Ssam 47112125Ssam#include <isa/isavar.h> 48112125Ssam 49112125Ssam#include <dev/ed/if_edvar.h> 50112125Ssam#include <dev/ed/if_edreg.h> 51112125Ssam#include <dev/ed/if_ed98.h> 52112125Ssam 53112125Ssamstatic int ed98_alloc_port(device_t, int); 54112125Ssamstatic int ed98_alloc_memory(device_t, int); 55112125Ssamstatic int ed_pio_testmem(struct ed_softc *, int, int, int); 56112125Ssamstatic int ed_probe_CNET98(device_t, int, int); 57112125Ssamstatic int ed_probe_CNET98EL(device_t, int, int); 58112125Ssamstatic int ed_probe_EZ98(device_t, int, int); 59112125Ssamstatic int ed_probe_NEC77(device_t, int, int); 60112125Ssamstatic int ed_probe_NW98X(device_t, int, int); 61112125Ssamstatic int ed_probe_SB98(device_t, int, int); 62112125Ssamstatic int ed_probe_SIC98(device_t, int, int); 63112125Ssamstatic int ed98_probe_Novell(device_t, int, int); 64112125Ssamstatic int ed98_probe_generic8390(struct ed_softc *); 65112125Ssamstatic void ed_reset_CNET98(struct ed_softc *, int); 66112125Ssamstatic void ed_winsel_CNET98(struct ed_softc *, u_short); 67112125Ssamstatic void ed_get_SB98(struct ed_softc *); 68112125Ssam 69112125Ssamstatic int ed_cbus_probe(device_t); 70112125Ssamstatic int ed_cbus_attach(device_t); 71112125Ssam 72112125Ssamstatic struct isa_pnp_id ed_ids[] = { 73227309Sed/* TODO - list up PnP boards for PC-98 */ 74227309Sed { 0, NULL } 75112125Ssam}; 76116815Ssam 77112125Ssamstatic int 78112125Ssamed_cbus_probe(device_t dev) 79112125Ssam{ 80112125Ssam struct ed_softc *sc = device_get_softc(dev); 81112125Ssam int flags = device_get_flags(dev); 82112125Ssam int error = 0; 83112125Ssam 84112125Ssam sc->type = ED_TYPE98(flags); 85112125Ssam#ifdef ED_DEBUG 86112125Ssam device_printf(dev, "ed_cbus_probe: sc->type=%x\n", sc->type); 87112125Ssam#endif 88112125Ssam 89112125Ssam /* Check isapnp ids */ 90112125Ssam error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); 91112125Ssam#ifdef ED_DEBUG 92112125Ssam device_printf(dev, "ed_cbus_probe: ISA_PNP_PROBE returns %d\n", error); 93112125Ssam#endif 94112125Ssam 95112125Ssam /* If the card had a PnP ID that didn't match any we know about */ 96112125Ssam if (error == ENXIO) 97112125Ssam goto end; 98116815Ssam 99116815Ssam /* If we had some other problem. */ 100116815Ssam if (!(error == 0 || error == ENOENT)) 101119137Ssam goto end; 102116815Ssam 103112125Ssam /* Heuristic probes */ 104112125Ssam#ifdef ED_DEBUG 105112125Ssam device_printf(dev, "ed_cbus_probe: Heuristic probes start\n"); 106112125Ssam#endif 107112125Ssam switch (sc->type) { 108112125Ssam case ED_TYPE98_GENERIC: 109112125Ssam /* 110112125Ssam * CAUTION! 111112125Ssam * sc->type of these boards are overwritten by PC/AT's value. 112112125Ssam */ 113112125Ssam 114112125Ssam /* 115112125Ssam * SMC EtherEZ98 116112125Ssam */ 117112125Ssam error = ed_probe_EZ98(dev, 0, flags); 118116815Ssam if (error == 0) 119112125Ssam goto end; 120112125Ssam 121112125Ssam ed_release_resources(dev); 122112125Ssam 123112125Ssam /* 124112125Ssam * Allied Telesis CenterCom LA-98-T 125112125Ssam */ 126112125Ssam error = ed_probe_Novell(dev, 0, flags); 127112125Ssam if (error == 0) { 128112125Ssam ed_Novell_read_mac(sc); 129112125Ssam goto end; 130112125Ssam } 131112125Ssam break; 132112125Ssam 133112125Ssam /* 134112125Ssam * NE2000-like boards probe routine 135112125Ssam */ 136112125Ssam case ED_TYPE98_BDN: 137112125Ssam /* 138112125Ssam * ELECOM LANEED LD-BDN 139112125Ssam * PLANET SMART COM 98 EN-2298 140112125Ssam */ 141112125Ssam case ED_TYPE98_LGY: 142112125Ssam /* 143112125Ssam * MELCO LGY-98, IND-SP, IND-SS 144112125Ssam * MACNICA NE2098 145112125Ssam */ 146112125Ssam case ED_TYPE98_ICM: 147112125Ssam /* 148116815Ssam * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET 149116815Ssam * D-Link DE-298P, DE-298 150116815Ssam */ 151116815Ssam case ED_TYPE98_EGY: 152116815Ssam /* 153116815Ssam * MELCO EGY-98 154116815Ssam * Contec C-NET(98)E-A, C-NET(98)L-A 155256381Smarkm */ 156116815Ssam case ED_TYPE98_108: 157116815Ssam /* 158112125Ssam * NEC PC-9801-107,108 159112125Ssam */ 160112125Ssam case ED_TYPE98_NC5098: 161112125Ssam /* 162112125Ssam * NextCom NC5098 163112125Ssam */ 164112125Ssam error = ed98_probe_Novell(dev, 0, flags); 165112125Ssam break; 166112125Ssam 167112125Ssam /* 168112125Ssam * other boards with special probe routine 169112125Ssam */ 170112125Ssam case ED_TYPE98_SIC: 171112125Ssam /* 172112125Ssam * Allied Telesis SIC-98 173112125Ssam */ 174112125Ssam error = ed_probe_SIC98(dev, 0, flags); 175112125Ssam break; 176112125Ssam 177112125Ssam case ED_TYPE98_CNET98EL: 178112125Ssam /* 179112125Ssam * Contec C-NET(98)E/L 180112125Ssam */ 181112125Ssam error = ed_probe_CNET98EL(dev, 0, flags); 182112125Ssam break; 183112125Ssam 184112125Ssam case ED_TYPE98_CNET98: 185112125Ssam /* 186112125Ssam * Contec C-NET(98) 187112125Ssam */ 188112125Ssam error = ed_probe_CNET98(dev, 0, flags); 189112125Ssam break; 190112125Ssam 191112125Ssam case ED_TYPE98_LA98: 192112125Ssam /* 193112125Ssam * IO-DATA LA/T-98 194112125Ssam * NEC PC-9801-77,78 195112125Ssam */ 196112125Ssam error = ed_probe_NEC77(dev, 0, flags); 197112125Ssam break; 198112125Ssam 199112125Ssam case ED_TYPE98_NW98X: 200112125Ssam /* 201112125Ssam * Networld EC/EP-98X 202112125Ssam */ 203112125Ssam error = ed_probe_NW98X(dev, 0, flags); 204112125Ssam break; 205112125Ssam 206112125Ssam case ED_TYPE98_SB98: 207112125Ssam /* 208112125Ssam * Soliton SB-9801 209112125Ssam * Fujikura FN-9801 210112125Ssam */ 211112125Ssam error = ed_probe_SB98(dev, 0, flags); 212112125Ssam break; 213112125Ssam } 214112125Ssam 215112125Ssamend: 216112125Ssam#ifdef ED_DEBUG 217112125Ssam device_printf(dev, "ed_cbus_probe: end, error=%d\n", error); 218112125Ssam#endif 219112125Ssam if (error == 0) 220112125Ssam error = ed_alloc_irq(dev, 0, 0); 221112125Ssam 222112125Ssam ed_release_resources(dev); 223112125Ssam return (error); 224112125Ssam} 225112125Ssam 226112125Ssamstatic int 227112125Ssamed_cbus_attach(dev) 228112125Ssam device_t dev; 229112125Ssam{ 230112125Ssam struct ed_softc *sc = device_get_softc(dev); 231112125Ssam int flags = device_get_flags(dev); 232112125Ssam int error; 233112125Ssam 234112125Ssam if (sc->port_used > 0) { 235112125Ssam if (ED_TYPE98(flags) == ED_TYPE98_GENERIC) 236112125Ssam ed_alloc_port(dev, sc->port_rid, sc->port_used); 237112125Ssam else 238112125Ssam ed98_alloc_port(dev, sc->port_rid); 239112125Ssam } 240112125Ssam if (sc->mem_used) 241112125Ssam ed_alloc_memory(dev, sc->mem_rid, sc->mem_used); 242112125Ssam 243112125Ssam ed_alloc_irq(dev, sc->irq_rid, 0); 244112125Ssam 245112125Ssam if (sc->sc_media_ioctl == NULL) 246112125Ssam ed_gen_ifmedia_init(sc); 247112125Ssam error = ed_attach(dev); 248112125Ssam if (error) { 249112125Ssam ed_release_resources(dev); 250112125Ssam return (error); 251112125Ssam } 252112125Ssam error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 253112125Ssam NULL, edintr, sc, &sc->irq_handle); 254112125Ssam if (error) 255112125Ssam ed_release_resources(dev); 256112125Ssam return (error); 257112125Ssam} 258112125Ssam 259112125Ssam/* 260112125Ssam * Interrupt conversion table for EtherEZ98 261112125Ssam */ 262112125Ssamstatic uint16_t ed_EZ98_intr_val[] = { 263112125Ssam 0, 264112125Ssam 3, 265112125Ssam 5, 266112125Ssam 6, 267112125Ssam 0, 268112125Ssam 9, 269112125Ssam 12, 270112125Ssam 13 271112125Ssam}; 272112125Ssam 273112125Ssamstatic int 274112125Ssamed_probe_EZ98(device_t dev, int port_rid, int flags) 275112125Ssam{ 276112125Ssam struct ed_softc *sc = device_get_softc(dev); 277112125Ssam int error; 278112125Ssam static unsigned short *intr_vals[] = {NULL, ed_EZ98_intr_val}; 279112125Ssam 280112125Ssam error = ed_alloc_port(dev, port_rid, ED_EZ98_IO_PORTS); 281112125Ssam if (error) { 282112125Ssam return (error); 283112125Ssam } 284112125Ssam 285112125Ssam sc->asic_offset = ED_EZ98_ASIC_OFFSET; 286112125Ssam sc->nic_offset = ED_EZ98_NIC_OFFSET; 287112125Ssam 288112125Ssam return ed_probe_WD80x3_generic(dev, flags, intr_vals); 289112125Ssam} 290112125Ssam 291112125Ssam/* 292112125Ssam * I/O conversion tables 293112125Ssam */ 294112125Ssam 295112125Ssam/* LGY-98, ICM, C-NET(98)E/L */ 296112125Ssamstatic bus_addr_t ed98_ioaddr_generic[] = { 297112125Ssam 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 298112125Ssam}; 299112125Ssam 300112125Ssam/* 301112125Ssam * Definitions for Contec C-NET(98)E/L 302112125Ssam */ 303112125Ssam#define ED_CNET98EL_ICR 2 /* Interrupt Configuration Register */ 304112125Ssam 305112125Ssam#define ED_CNET98EL_ICR_IRQ3 0x01 306112125Ssam#define ED_CNET98EL_ICR_IRQ5 0x02 307112125Ssam#define ED_CNET98EL_ICR_IRQ6 0x04 308112125Ssam#define ED_CNET98EL_ICR_IRQ12 0x20 309112125Ssam 310112125Ssam#define ED_CNET98EL_IMR 4 /* Interrupt Mask Register */ 311112125Ssam#define ED_CNET98EL_ISR 5 /* Interrupt Status Register */ 312112125Ssam 313112125Ssam/* EGY-98 */ 314112125Ssamstatic bus_addr_t ed98_ioaddr_egy98[] = { 315112125Ssam 0, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 316112125Ssam 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e 317112125Ssam}; 318112125Ssam 319112125Ssam/* SIC-98 */ 320112125Ssamstatic bus_addr_t ed98_ioaddr_sic98[] = { 321112125Ssam 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00, 322112125Ssam 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00 323112125Ssam}; 324112125Ssam 325112125Ssam/* LA/T-98, LD-BDN, PC-9801-77, SB-9801 */ 326112125Ssamstatic bus_addr_t ed98_ioaddr_la98[] = { 327112125Ssam 0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 328112125Ssam 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000, 329112125Ssam 0x0100 /* for NEC 77(see below) */ 330112125Ssam}; 331112125Ssam 332112125Ssam/* 333112125Ssam * Definitions for NEC PC-9801-77 334112125Ssam */ 335112125Ssam#define ED_NEC77_IRQ 16 /* Interrupt Configuration Register */ 336112125Ssam 337112125Ssam#define ED_NEC77_IRQ3 0x04 338112125Ssam#define ED_NEC77_IRQ5 0x06 339112125Ssam#define ED_NEC77_IRQ6 0x08 340112125Ssam#define ED_NEC77_IRQ12 0x0a 341112125Ssam#define ED_NEC77_IRQ13 0x02 342112125Ssam 343112125Ssam/* 344112125Ssam * Definitions for Soliton SB-9801 345112125Ssam */ 346112125Ssam#define ED_SB98_CFG 1 /* Board configuration */ 347112125Ssam 348112125Ssam#define ED_SB98_CFG_IRQ3 0x00 349112125Ssam#define ED_SB98_CFG_IRQ5 0x04 350112125Ssam#define ED_SB98_CFG_IRQ6 0x08 351112125Ssam#define ED_SB98_CFG_IRQ12 0x0c 352112125Ssam#define ED_SB98_CFG_ALTPORT 0x40 /* use EXTERNAL media */ 353112125Ssam#define ED_SB98_CFG_ENABLE 0xa0 /* enable configuration */ 354112125Ssam 355112125Ssam#define ED_SB98_EEPENA 2 /* EEPROM access enable */ 356112125Ssam 357112125Ssam#define ED_SB98_EEPENA_DISABLE 0x00 358112125Ssam#define ED_SB98_EEPENA_ENABLE 0x01 359112125Ssam 360112125Ssam#define ED_SB98_EEP 3 /* EEPROM access */ 361112125Ssam 362112125Ssam#define ED_SB98_EEP_SDA 0x01 /* Serial Data */ 363249582Sgabor#define ED_SB98_EEP_SCL 0x02 /* Serial Clock */ 364112125Ssam#define ED_SB98_EEP_READ 0x01 /* Read Command */ 365112125Ssam 366112125Ssam#define ED_SB98_EEP_DELAY 300 367112125Ssam 368112125Ssam#define ED_SB98_ADDRESS 0x01 /* Station Address(1-6) */ 369112125Ssam 370112125Ssam#define ED_SB98_POLARITY 4 /* Polarity */ 371112125Ssam 372112125Ssam/* PC-9801-108 */ 373112125Ssamstatic bus_addr_t ed98_ioaddr_nec108[] = { 374112125Ssam 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 375112125Ssam 0x1000, 0x1002, 0x1004, 0x1006, 0x1008, 0x100a, 0x100c, 0x100e 376112125Ssam}; 377112125Ssam 378112125Ssam/* C-NET(98) */ 379112125Ssamstatic bus_addr_t ed98_ioaddr_cnet98[] = { 380112125Ssam 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 381112125Ssam 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e 382112125Ssam}; 383112125Ssam 384112125Ssam/* 385112125Ssam * Definitions for Contec C-NET(98) 386112125Ssam */ 387112125Ssam#define ED_CNET98_MAP_REG0L 0 /* MAPPING register0 Low */ 388112125Ssam#define ED_CNET98_MAP_REG1L 1 /* MAPPING register1 Low */ 389112125Ssam#define ED_CNET98_MAP_REG2L 2 /* MAPPING register2 Low */ 390112125Ssam#define ED_CNET98_MAP_REG3L 3 /* MAPPING register3 Low */ 391112125Ssam#define ED_CNET98_MAP_REG0H 4 /* MAPPING register0 Hi */ 392112125Ssam#define ED_CNET98_MAP_REG1H 5 /* MAPPING register1 Hi */ 393112125Ssam#define ED_CNET98_MAP_REG2H 6 /* MAPPING register2 Hi */ 394112125Ssam#define ED_CNET98_MAP_REG3H 7 /* MAPPING register3 Hi */ 395112125Ssam#define ED_CNET98_WIN_REG 8 /* Window register */ 396112125Ssam#define ED_CNET98_INT_LEV 9 /* Init level register */ 397112125Ssam 398112125Ssam#define ED_CNET98_INT_IRQ3 0x01 /* INT 0 */ 399112125Ssam#define ED_CNET98_INT_IRQ5 0x02 /* INT 1 */ 400112125Ssam#define ED_CNET98_INT_IRQ6 0x04 /* INT 2 */ 401112125Ssam#define ED_CNET98_INT_IRQ9 0x08 /* INT 3 */ 402112125Ssam#define ED_CNET98_INT_IRQ12 0x20 /* INT 5 */ 403112125Ssam#define ED_CNET98_INT_IRQ13 0x40 /* INT 6 */ 404112125Ssam 405241394Skevlo#define ED_CNET98_INT_REQ 10 /* Init request register */ 406112125Ssam#define ED_CNET98_INT_MASK 11 /* Init mask register */ 407112125Ssam#define ED_CNET98_INT_STAT 12 /* Init status register */ 408112125Ssam#define ED_CNET98_INT_CLR 12 /* Init clear register */ 409#define ED_CNET98_RESERVE1 13 410#define ED_CNET98_RESERVE2 14 411#define ED_CNET98_RESERVE3 15 412 413/* EC/EP-98X, NC5098 */ 414static bus_addr_t ed98_ioaddr_nw98x[] = { 415 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 416 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, 417 0x1000 /* for EC/EP-98X(see below) */ 418}; 419 420/* 421 * Definitions for Networld EC/EP-98X 422 */ 423#define ED_NW98X_IRQ 16 /* Interrupt Configuration Register */ 424 425#define ED_NW98X_IRQ3 0x04 426#define ED_NW98X_IRQ5 0x06 427#define ED_NW98X_IRQ6 0x08 428#define ED_NW98X_IRQ12 0x0a 429#define ED_NW98X_IRQ13 0x02 430 431/* NC5098 ASIC */ 432static bus_addr_t ed98_asic_nc5098[] = { 433/* DATA ENADDR RESET */ 434 0x0000, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x4000, 435 0, 0, 0, 0, 0, 0, 0, 0 436}; 437 438/* 439 * Definitions for NextCom NC5098 440 */ 441#define ED_NC5098_ENADDR 1 /* Station Address(1-6) */ 442 443/* 444 * Allocate a port resource with the given resource id. 445 */ 446static int 447ed98_alloc_port(device_t dev, int rid) 448{ 449 struct ed_softc *sc = device_get_softc(dev); 450 struct resource *res; 451 int error; 452 bus_addr_t *io_nic, *io_asic, adj; 453 static bus_addr_t io_res[ED_NOVELL_IO_PORTS + 1]; 454 int i, n; 455 int offset, reset, data; 456 457 /* Set i/o table for resource manager */ 458 io_nic = io_asic = ed98_ioaddr_generic; 459 offset = ED_NOVELL_ASIC_OFFSET; 460 reset = ED_NOVELL_RESET; 461 data = ED_NOVELL_DATA; 462 n = ED_NOVELL_IO_PORTS; 463 464 switch (sc->type) { 465 case ED_TYPE98_LGY: 466 io_asic = ed98_ioaddr_egy98; /* XXX - Yes, we use egy98 */ 467 offset = 0x0200; 468 reset = 8; 469 break; 470 471 case ED_TYPE98_EGY: 472 io_nic = io_asic = ed98_ioaddr_egy98; 473 offset = 0x0200; 474 reset = 8; 475 break; 476 477 case ED_TYPE98_ICM: 478 offset = 0x0100; 479 break; 480 481 case ED_TYPE98_BDN: 482 io_nic = io_asic = ed98_ioaddr_la98; 483 offset = 0x0100; 484 reset = 0x0c; 485 break; 486 487 case ED_TYPE98_SIC: 488 io_nic = io_asic = ed98_ioaddr_sic98; 489 offset = 0x2000; 490 n = 16+1; 491 break; 492 493 case ED_TYPE98_108: 494 io_nic = io_asic = ed98_ioaddr_nec108; 495 offset = 0x0888; /* XXX - overwritten after */ 496 reset = 1; 497 n = 16; /* XXX - does not set ASIC i/o here */ 498 break; 499 500 case ED_TYPE98_LA98: 501 io_nic = io_asic = ed98_ioaddr_la98; 502 offset = 0x0100; 503 break; 504 505 case ED_TYPE98_CNET98EL: 506 offset = 0x0400; 507 data = 0x0e; 508 break; 509 510 case ED_TYPE98_CNET98: 511 /* XXX - Yes, we use generic i/o here */ 512 offset = 0x0400; 513 break; 514 515 case ED_TYPE98_NW98X: 516 io_nic = io_asic = ed98_ioaddr_nw98x; 517 offset = 0x1000; 518 break; 519 520 case ED_TYPE98_SB98: 521 io_nic = io_asic = ed98_ioaddr_la98; 522 offset = 0x0400; 523 reset = 7; 524 break; 525 526 case ED_TYPE98_NC5098: 527 io_nic = ed98_ioaddr_nw98x; 528 io_asic = ed98_asic_nc5098; 529 offset = 0x2000; 530 reset = 7; 531 n = 16+8; /* XXX */ 532 break; 533 } 534 535 bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET); 536 for (i = ED_NOVELL_ASIC_OFFSET; i < ED_NOVELL_IO_PORTS; i++) 537 io_res[i] = io_asic[i - ED_NOVELL_ASIC_OFFSET] + offset; 538 539 res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, io_res, n, 540 RF_ACTIVE); 541 if (!res) 542 return (ENOENT); 543 544 sc->port_rid = rid; 545 sc->port_res = res; 546 sc->port_used = n; 547 sc->port_bst = rman_get_bustag(res); 548 sc->port_bsh = rman_get_bushandle(res); 549 550 /* Re-map i/o table if needed */ 551 switch (sc->type) { 552 case ED_TYPE98_LA98: 553 case ED_TYPE98_NW98X: 554 io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 555 n++; 556 break; 557 558 case ED_TYPE98_108: 559 adj = (rman_get_start(res) & 0xf000) / 2; 560 offset = (offset | adj) - rman_get_start(res); 561 562 for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++) 563 io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 564 break; 565 566 case ED_TYPE98_CNET98: 567 io_nic = io_asic = ed98_ioaddr_cnet98; 568 offset = 1; 569 570 bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET); 571 for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++) 572 io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 573 break; 574 575 case ED_TYPE98_NC5098: 576 n = ED_NOVELL_IO_PORTS; 577 break; 578 } 579 580 if (reset != ED_NOVELL_RESET) 581 io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_RESET] = 582 io_res[ED_NOVELL_ASIC_OFFSET + reset]; 583 if (data != ED_NOVELL_DATA) { 584 io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA] = 585 io_res[ED_NOVELL_ASIC_OFFSET + data]; 586#if 0 587 io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA + 1] = 588 io_res[ED_NOVELL_ASIC_OFFSET + data + 1]; 589#endif 590 } 591 592 error = isa_load_resourcev(res, io_res, n); 593 if (error != 0) 594 return (ENOENT); 595#ifdef ED_DEBUG 596 device_printf(dev, "ed98_alloc_port: i/o ports = %d\n", n); 597 for (i = 0; i < n; i++) 598 printf("%x,", io_res[i]); 599 printf("\n"); 600#endif 601 return (0); 602} 603 604static int 605ed98_alloc_memory(dev, rid) 606 device_t dev; 607 int rid; 608{ 609 struct ed_softc *sc = device_get_softc(dev); 610 int error; 611 u_long conf_maddr, conf_msize; 612 613 error = bus_get_resource(dev, SYS_RES_MEMORY, 0, &conf_maddr, 614 &conf_msize); 615 if (error) 616 return (error); 617 618 if ((conf_maddr == 0) || (conf_msize == 0)) 619 return (ENXIO); 620 621 error = ed_alloc_memory(dev, rid, (int) conf_msize); 622 if (error) 623 return (error); 624 625 sc->mem_start = 0; 626 sc->mem_size = conf_msize; 627 628 return (0); 629} 630 631/* 632 * Generic probe routine for testing for the existance of a DS8390. 633 * Must be called after the NIC has just been reset. This routine 634 * works by looking at certain register values that are guaranteed 635 * to be initialized a certain way after power-up or reset. Seems 636 * not to currently work on the 83C690. 637 * 638 * Specifically: 639 * 640 * Register reset bits set bits 641 * Command Register (CR) TXP, STA RD2, STP 642 * Interrupt Status (ISR) RST 643 * Interrupt Mask (IMR) All bits 644 * Data Control (DCR) LAS 645 * Transmit Config. (TCR) LB1, LB0 646 * 647 * XXX - We only check the CR register. 648 * 649 * Return 1 if 8390 was found, 0 if not. 650 */ 651 652static int 653ed98_probe_generic8390(struct ed_softc *sc) 654{ 655 u_char tmp = ed_nic_inb(sc, ED_P0_CR); 656#ifdef DIAGNOSTIC 657 printf("ed?: inb(ED_P0_CR)=%x\n", tmp); 658#endif 659 if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) != 660 (ED_CR_RD2 | ED_CR_STP)) 661 return (0); 662 663 (void) ed_nic_inb(sc, ED_P0_ISR); 664 665 return (1); 666} 667 668static int 669ed98_probe_Novell(device_t dev, int port_rid, int flags) 670{ 671 struct ed_softc *sc = device_get_softc(dev); 672 int error; 673 int n; 674 u_char romdata[ETHER_ADDR_LEN * 2], tmp; 675 676#ifdef ED_DEBUG 677 device_printf(dev, "ed98_probe_Novell: start\n"); 678#endif 679 error = ed98_alloc_port(dev, port_rid); 680 if (error) 681 return (error); 682 683 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 684 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 685 686 /* Reset the board */ 687#ifdef ED_DEBUG 688 device_printf(dev, "ed98_probe_Novell: reset\n"); 689#endif 690 switch (sc->type) { 691#if 1 /* XXX - I'm not sure this is really necessary... */ 692 case ED_TYPE98_BDN: 693 tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 694 ed_asic_outb(sc, ED_NOVELL_RESET, (tmp & 0xf0) | 0x08); 695 ed_nic_outb(sc, 0x04, tmp); 696 (void) ed_asic_inb(sc, 0x08); 697 ed_asic_outb(sc, 0x08, tmp); 698 ed_asic_outb(sc, 0x08, tmp & 0x7f); 699 break; 700#endif 701 case ED_TYPE98_NC5098: 702 ed_asic_outb(sc, ED_NOVELL_RESET, 0x00); 703 DELAY(5000); 704 ed_asic_outb(sc, ED_NOVELL_RESET, 0x01); 705 break; 706 707 default: 708 tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 709 710 /* 711 * I don't know if this is necessary; probably cruft leftover from 712 * Clarkson packet driver code. Doesn't do a thing on the boards I've 713 * tested. -DG [note that an outb(0x84, 0) seems to work here, and is 714 * non-invasive...but some boards don't seem to reset and I don't have 715 * complete documentation on what the 'right' thing to do is...so we 716 * do the invasive thing for now. Yuck.] 717 */ 718 ed_asic_outb(sc, ED_NOVELL_RESET, tmp); 719 break; 720 } 721 DELAY(5000); 722 723 /* 724 * This is needed because some NE clones apparently don't reset the 725 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 726 * - this makes the probe invasive! ...Done against my better 727 * judgement. -DLG 728 */ 729 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 730 DELAY(5000); 731 732 /* Make sure that we really have an 8390 based board */ 733 if (!ed98_probe_generic8390(sc)) 734 return (ENXIO); 735 736 /* Test memory via PIO */ 737#ifdef ED_DEBUG 738 device_printf(dev, "ed98_probe_Novell: test memory\n"); 739#endif 740 sc->cr_proto = ED_CR_RD2; 741 if (!ed_pio_testmem(sc, 8192, 0, flags) && 742 !ed_pio_testmem(sc, 16384, 1, flags)) 743 return (ENXIO); 744 745 /* Setup the board type */ 746#ifdef ED_DEBUG 747 device_printf(dev, "ed98_probe_Novell: board type\n"); 748#endif 749 switch (sc->type) { 750 case ED_TYPE98_BDN: 751 sc->type_str = "LD-BDN"; 752 break; 753 case ED_TYPE98_EGY: 754 sc->type_str = "EGY-98"; 755 break; 756 case ED_TYPE98_LGY: 757 sc->type_str = "LGY-98"; 758 break; 759 case ED_TYPE98_ICM: 760 sc->type_str = "ICM"; 761 break; 762 case ED_TYPE98_108: 763 sc->type_str = "PC-9801-108"; 764 break; 765 case ED_TYPE98_LA98: 766 sc->type_str = "LA-98"; 767 break; 768 case ED_TYPE98_NW98X: 769 sc->type_str = "NW98X"; 770 break; 771 case ED_TYPE98_NC5098: 772 sc->type_str = "NC5098"; 773 break; 774 default: 775 sc->type_str = NULL; 776 break; 777 } 778 779 /* Get station address */ 780 switch (sc->type) { 781 case ED_TYPE98_NC5098: 782 for (n = 0; n < ETHER_ADDR_LEN; n++) 783 sc->enaddr[n] = ed_asic_inb(sc, ED_NC5098_ENADDR + n); 784 break; 785 786 default: 787 ed_pio_readmem(sc, 0, romdata, sizeof(romdata)); 788 for (n = 0; n < ETHER_ADDR_LEN; n++) 789 sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)]; 790 break; 791 } 792 793 /* clear any pending interrupts that might have occurred above */ 794 ed_nic_outb(sc, ED_P0_ISR, 0xff); 795 796 sc->sc_write_mbufs = ed_pio_write_mbufs; 797 return (0); 798} 799 800/* 801 * Probe and vendor-specific initialization routine for SIC-98 boards 802 */ 803static int 804ed_probe_SIC98(device_t dev, int port_rid, int flags) 805{ 806 struct ed_softc *sc = device_get_softc(dev); 807 int error; 808 int i; 809 u_char sum; 810 811 /* 812 * Setup card RAM and I/O address 813 * Kernel Virtual to segment C0000-DFFFF???? 814 */ 815 error = ed98_alloc_port(dev, port_rid); 816 if (error) 817 return (error); 818 819 sc->asic_offset = ED_SIC_ASIC_OFFSET; 820 sc->nic_offset = ED_SIC_NIC_OFFSET; 821 822 error = ed98_alloc_memory(dev, 0); 823 if (error) 824 return (error); 825 826 /* Reset card to force it into a known state. */ 827 ed_asic_outb(sc, 0, 0x00); 828 DELAY(100); 829 if (ED_TYPE98SUB(flags) == 0) { 830 /* SIC-98/SIU-98 */ 831 ed_asic_outb(sc, 0, 0x94); 832 DELAY(100); 833 ed_asic_outb(sc, 0, 0x94); 834 } else { 835 /* SIU-98-D */ 836 ed_asic_outb(sc, 0, 0x80); 837 DELAY(100); 838 ed_asic_outb(sc, 0, 0x94); 839 DELAY(100); 840 ed_asic_outb(sc, 0, 0x9e); 841 } 842 DELAY(100); 843 844 /* 845 * Here we check the card ROM, if the checksum passes, and the 846 * type code and ethernet address check out, then we know we have 847 * an SIC card. 848 */ 849 sum = bus_space_read_1(sc->mem_bst, sc->mem_bsh, 6 * 2); 850 for (i = 0; i < ETHER_ADDR_LEN; i++) 851 sum ^= (sc->enaddr[i] = 852 bus_space_read_1(sc->mem_bst, sc->mem_bsh, i * 2)); 853#ifdef ED_DEBUG 854 device_printf(dev, "ed_probe_sic98: got address %6D\n", 855 sc->enaddr, ":"); 856#endif 857 if (sum != 0) 858 return (ENXIO); 859 if ((sc->enaddr[0] | sc->enaddr[1] | sc->enaddr[2]) == 0) 860 return (ENXIO); 861 862 sc->vendor = ED_VENDOR_SIC; 863 sc->type_str = "SIC98"; 864 sc->isa16bit = 1; 865 sc->cr_proto = 0; 866 867 /* 868 * SIC RAM page 0x0000-0x3fff(or 0x7fff) 869 */ 870 if (ED_TYPE98SUB(flags) == 0) 871 ed_asic_outb(sc, 0, 0x90); 872 else 873 ed_asic_outb(sc, 0, 0x8e); 874 DELAY(100); 875 876 error = ed_clear_memory(dev); 877 if (error) 878 return (error); 879 880 sc->mem_shared = 1; 881 sc->mem_end = sc->mem_start + sc->mem_size; 882 883 /* 884 * allocate one xmit buffer if < 16k, two buffers otherwise 885 */ 886 if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) 887 sc->txb_cnt = 1; 888 else 889 sc->txb_cnt = 2; 890 sc->tx_page_start = 0; 891 892 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt; 893 sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 894 895 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 896 897 sc->sc_write_mbufs = ed_shmem_write_mbufs; 898 return (0); 899} 900 901/* 902 * Contec C-NET(98) series support routines 903 */ 904static void 905ed_reset_CNET98(struct ed_softc *sc, int flags) 906{ 907 u_int init_addr = ED_CNET98_INIT; 908 u_char tmp; 909 910 /* Choose initial register address */ 911 if (ED_TYPE98SUB(flags) != 0) { 912 init_addr = ED_CNET98_INIT2; 913 } 914#ifdef ED_DEBUG 915 printf("ed?: initial register=%x\n", init_addr); 916#endif 917 /* 918 * Reset the board to force it into a known state. 919 */ 920 outb(init_addr, 0x00); /* request */ 921 DELAY(5000); 922 outb(init_addr, 0x01); /* cancel */ 923 DELAY(5000); 924 925 /* 926 * Set I/O address(A15-12) and cpu type 927 * 928 * AAAAIXXC(8bit) 929 * AAAA: A15-A12, I: I/O enable, XX: reserved, C: CPU type 930 * 931 * CPU type is 1:80286 or higher, 0:not. 932 * But FreeBSD runs under i386 or higher, thus it must be 1. 933 */ 934 tmp = (rman_get_start(sc->port_res) & 0xf000) >> 8; 935 tmp |= (0x08 | 0x01); 936#ifdef ED_DEBUG 937 printf("ed?: outb(%x, %x)\n", init_addr + 2, tmp); 938#endif 939 outb(init_addr + 2, tmp); 940 DELAY(5000); 941 942 /* 943 * This is needed because some NE clones apparently don't reset the 944 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 945 * - this makes the probe invasive! ...Done against my better 946 * judgement. -DLG 947 */ 948 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 949 DELAY(5000); 950} 951 952static void 953ed_winsel_CNET98(struct ed_softc *sc, u_short bank) 954{ 955 u_char mem = (rman_get_start(sc->mem_res) >> 12) & 0xff; 956 957 /* 958 * Disable window memory 959 * bit7 is 0:disable 960 */ 961 ed_asic_outb(sc, ED_CNET98_WIN_REG, mem & 0x7f); 962 DELAY(10); 963 964 /* 965 * Select window address 966 * FreeBSD address 0xf00xxxxx 967 */ 968 ed_asic_outb(sc, ED_CNET98_MAP_REG0L, bank & 0xff); 969 DELAY(10); 970 ed_asic_outb(sc, ED_CNET98_MAP_REG0H, (bank >> 8) & 0xff); 971 DELAY(10); 972 ed_asic_outb(sc, ED_CNET98_MAP_REG1L, 0x00); 973 DELAY(10); 974 ed_asic_outb(sc, ED_CNET98_MAP_REG1H, 0x41); 975 DELAY(10); 976 ed_asic_outb(sc, ED_CNET98_MAP_REG2L, 0x00); 977 DELAY(10); 978 ed_asic_outb(sc, ED_CNET98_MAP_REG2H, 0x42); 979 DELAY(10); 980 ed_asic_outb(sc, ED_CNET98_MAP_REG3L, 0x00); 981 DELAY(10); 982 ed_asic_outb(sc, ED_CNET98_MAP_REG3H, 0x43); 983 DELAY(10); 984 985 /* 986 * Enable window memory(16Kbyte) 987 * bit7 is 1:enable 988 */ 989#ifdef ED_DEBUG 990 printf("ed?: window start address=%x\n", mem); 991#endif 992 ed_asic_outb(sc, ED_CNET98_WIN_REG, mem); 993 DELAY(10); 994} 995 996/* 997 * Probe and vendor-specific initialization routine for C-NET(98) boards 998 */ 999static int 1000ed_probe_CNET98(device_t dev, int port_rid, int flags) 1001{ 1002 struct ed_softc *sc = device_get_softc(dev); 1003 int error; 1004 u_char tmp; 1005 u_long conf_irq, junk; 1006#ifdef DIAGNOSTIC 1007 u_char tmp_s; 1008#endif 1009 1010 error = ed98_alloc_port(dev, port_rid); 1011 if (error) 1012 return (error); 1013 1014 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1015 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1016 1017 error = ed98_alloc_memory(dev, 0); 1018 if (error) 1019 return (error); 1020 1021 /* Check I/O address. 0x[a-f]3d0 are allowed. */ 1022 if (((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) 1023 || ((rman_get_start(sc->port_res) & 0xf000) < (u_short) 0xa000)) { 1024#ifdef DIAGNOSTIC 1025 device_printf(dev, "Invalid i/o port configuration (0x%lx) " 1026 "must be %s for %s\n", rman_get_start(sc->port_res), 1027 "0x[a-f]3d0", "CNET98"); 1028#endif 1029 return (ENXIO); 1030 } 1031 1032#ifdef DIAGNOSTIC 1033 /* Check window area address */ 1034 tmp_s = rman_get_start(sc->mem_res) >> 12; 1035 if (tmp_s < 0x80) { 1036 device_printf(dev, "Please change window address(0x%lx)\n", 1037 rman_get_start(sc->mem_res)); 1038 return (ENXIO); 1039 } 1040 1041 tmp_s &= 0x0f; 1042 tmp = rman_get_start(sc->port_res) >> 12; 1043 if ((tmp_s <= tmp) && (tmp < (tmp_s + 4))) { 1044 device_printf(dev, "Please change iobase address(0x%lx) " 1045 "or window address(0x%lx)\n", 1046 rman_get_start(sc->port_res), 1047 rman_get_start(sc->mem_res)); 1048 return (ENXIO); 1049 } 1050#endif 1051 /* Reset the board */ 1052 ed_reset_CNET98(sc, flags); 1053 1054 /* 1055 * This is needed because some NE clones apparently don't reset the 1056 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1057 * - this makes the probe invasive! ...Done against my better 1058 * judgement. -DLG 1059 */ 1060 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1061 DELAY(5000); 1062 1063 /* Make sure that we really have an 8390 based board */ 1064 if (!ed98_probe_generic8390(sc)) 1065 return (ENXIO); 1066 1067 /* 1068 * Set window ethernet address area 1069 * board memory base 0x480000 data 256byte 1070 */ 1071 ed_winsel_CNET98(sc, 0x4800); 1072 1073 /* 1074 * Get station address from on-board ROM 1075 */ 1076 bus_space_read_region_1(sc->mem_bst, sc->mem_bsh, sc->mem_start, 1077 sc->enaddr, ETHER_ADDR_LEN); 1078 1079 sc->vendor = ED_VENDOR_MISC; 1080 sc->type_str = "CNET98"; 1081 sc->isa16bit = 0; 1082 sc->cr_proto = ED_CR_RD2; 1083 1084 /* 1085 * Set window buffer memory area 1086 * board memory base 0x400000 data 16kbyte 1087 */ 1088 ed_winsel_CNET98(sc, 0x4000); 1089 1090 error = ed_clear_memory(dev); 1091 if (error) 1092 return (error); 1093 1094 sc->mem_shared = 1; 1095 sc->mem_end = sc->mem_start + sc->mem_size; 1096 1097 sc->txb_cnt = 1; /* XXX */ 1098 sc->tx_page_start = 0; 1099 1100 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE; 1101 sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 1102 1103 sc->mem_ring = sc->mem_start + ED_PAGE_SIZE * ED_TXBUF_SIZE; 1104 1105 /* 1106 * Set interrupt level 1107 */ 1108 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk); 1109 if (error) 1110 return (error); 1111 1112 switch (conf_irq) { 1113 case 3: 1114 tmp = ED_CNET98_INT_IRQ3; 1115 break; 1116 case 5: 1117 tmp = ED_CNET98_INT_IRQ5; 1118 break; 1119 case 6: 1120 tmp = ED_CNET98_INT_IRQ6; 1121 break; 1122 case 9: 1123 tmp = ED_CNET98_INT_IRQ9; 1124 break; 1125 case 12: 1126 tmp = ED_CNET98_INT_IRQ12; 1127 break; 1128 case 13: 1129 tmp = ED_CNET98_INT_IRQ13; 1130 break; 1131 default: 1132 device_printf(dev, "Invalid irq configuration (%ld) must be " 1133 "%s for %s\n", conf_irq, "3,5,6,9,12,13", "CNET98"); 1134 return (ENXIO); 1135 } 1136 ed_asic_outb(sc, ED_CNET98_INT_LEV, tmp); 1137 DELAY(1000); 1138 /* 1139 * Set interrupt mask. 1140 * bit7:1 all interrupt mask 1141 * bit1:1 timer interrupt mask 1142 * bit0:0 NS controler interrupt enable 1143 */ 1144 ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e); 1145 DELAY(1000); 1146 1147 sc->sc_write_mbufs = ed_shmem_write_mbufs; 1148 return (0); 1149} 1150 1151/* 1152 * Probe and vendor-specific initialization routine for C-NET(98)E/L boards 1153 */ 1154static int 1155ed_probe_CNET98EL(device_t dev, int port_rid, int flags) 1156{ 1157 struct ed_softc *sc = device_get_softc(dev); 1158 int error; 1159 int i; 1160 u_char romdata[ETHER_ADDR_LEN * 2], tmp; 1161 u_long conf_irq, junk; 1162 1163 error = ed98_alloc_port(dev, port_rid); 1164 if (error) 1165 return (error); 1166 1167 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1168 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1169 1170 /* Check I/O address. 0x[0-f]3d0 are allowed. */ 1171 if ((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) { 1172#ifdef DIAGNOSTIC 1173 device_printf(dev, "Invalid i/o port configuration (0x%lx) " 1174 "must be %s for %s\n", rman_get_start(sc->port_res), 1175 "0x?3d0", "CNET98E/L"); 1176#endif 1177 return (ENXIO); 1178 } 1179 1180 /* Reset the board */ 1181 ed_reset_CNET98(sc, flags); 1182 1183 /* 1184 * This is needed because some NE clones apparently don't reset the 1185 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1186 * - this makes the probe invasive! ...Done against my better 1187 * judgement. -DLG 1188 */ 1189 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1190 DELAY(5000); 1191 1192 /* Make sure that we really have an 8390 based board */ 1193 if (!ed98_probe_generic8390(sc)) 1194 return (ENXIO); 1195 1196 /* Test memory via PIO */ 1197 sc->cr_proto = ED_CR_RD2; 1198 if (!ed_pio_testmem(sc, ED_CNET98EL_PAGE_OFFSET, 1, flags)) 1199 return (ENXIO); 1200 1201 /* This looks like a C-NET(98)E/L board. */ 1202 sc->type_str = "CNET98E/L"; 1203 1204 /* 1205 * Set IRQ. C-NET(98)E/L only allows a choice of irq 3,5,6. 1206 */ 1207 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk); 1208 if (error) 1209 return (error); 1210 1211 switch (conf_irq) { 1212 case 3: 1213 tmp = ED_CNET98EL_ICR_IRQ3; 1214 break; 1215 case 5: 1216 tmp = ED_CNET98EL_ICR_IRQ5; 1217 break; 1218 case 6: 1219 tmp = ED_CNET98EL_ICR_IRQ6; 1220 break; 1221#if 0 1222 case 12: 1223 tmp = ED_CNET98EL_ICR_IRQ12; 1224 break; 1225#endif 1226 default: 1227 device_printf(dev, "Invalid irq configuration (%ld) must be " 1228 "%s for %s\n", conf_irq, "3,5,6", "CNET98E/L"); 1229 return (ENXIO); 1230 } 1231 ed_asic_outb(sc, ED_CNET98EL_ICR, tmp); 1232 ed_asic_outb(sc, ED_CNET98EL_IMR, 0x7e); 1233 1234 /* Get station address from on-board ROM */ 1235 ed_pio_readmem(sc, 16384, romdata, sizeof(romdata)); 1236 for (i = 0; i < ETHER_ADDR_LEN; i++) 1237 sc->enaddr[i] = romdata[i * 2]; 1238 1239 /* clear any pending interrupts that might have occurred above */ 1240 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1241 1242 sc->sc_write_mbufs = ed_pio_write_mbufs; 1243 return (0); 1244} 1245 1246/* 1247 * Probe and vendor-specific initialization routine for PC-9801-77 boards 1248 */ 1249static int 1250ed_probe_NEC77(device_t dev, int port_rid, int flags) 1251{ 1252 struct ed_softc *sc = device_get_softc(dev); 1253 int error; 1254 u_char tmp; 1255 u_long conf_irq, junk; 1256 1257 error = ed98_probe_Novell(dev, port_rid, flags); 1258 if (error) 1259 return (error); 1260 1261 /* LA/T-98 does not need IRQ setting. */ 1262 if (ED_TYPE98SUB(flags) == 0) 1263 return (0); 1264 1265 /* 1266 * Set IRQ. PC-9801-77 only allows a choice of irq 3,5,6,12,13. 1267 */ 1268 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk); 1269 if (error) 1270 return (error); 1271 1272 switch (conf_irq) { 1273 case 3: 1274 tmp = ED_NEC77_IRQ3; 1275 break; 1276 case 5: 1277 tmp = ED_NEC77_IRQ5; 1278 break; 1279 case 6: 1280 tmp = ED_NEC77_IRQ6; 1281 break; 1282 case 12: 1283 tmp = ED_NEC77_IRQ12; 1284 break; 1285 case 13: 1286 tmp = ED_NEC77_IRQ13; 1287 break; 1288 default: 1289 device_printf(dev, "Invalid irq configuration (%ld) must be " 1290 "%s for %s\n", conf_irq, "3,5,6,12,13", "PC-9801-77"); 1291 return (ENXIO); 1292 } 1293 ed_asic_outb(sc, ED_NEC77_IRQ, tmp); 1294 1295 return (0); 1296} 1297 1298/* 1299 * Probe and vendor-specific initialization routine for EC/EP-98X boards 1300 */ 1301static int 1302ed_probe_NW98X(device_t dev, int port_rid, int flags) 1303{ 1304 struct ed_softc *sc = device_get_softc(dev); 1305 int error; 1306 u_char tmp; 1307 u_long conf_irq, junk; 1308 1309 error = ed98_probe_Novell(dev, port_rid, flags); 1310 if (error) 1311 return (error); 1312 1313 /* Networld 98X3 does not need IRQ setting. */ 1314 if (ED_TYPE98SUB(flags) == 0) 1315 return (0); 1316 1317 /* 1318 * Set IRQ. EC/EP-98X only allows a choice of irq 3,5,6,12,13. 1319 */ 1320 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk); 1321 if (error) 1322 return (error); 1323 1324 switch (conf_irq) { 1325 case 3: 1326 tmp = ED_NW98X_IRQ3; 1327 break; 1328 case 5: 1329 tmp = ED_NW98X_IRQ5; 1330 break; 1331 case 6: 1332 tmp = ED_NW98X_IRQ6; 1333 break; 1334 case 12: 1335 tmp = ED_NW98X_IRQ12; 1336 break; 1337 case 13: 1338 tmp = ED_NW98X_IRQ13; 1339 break; 1340 default: 1341 device_printf(dev, "Invalid irq configuration (%ld) must be " 1342 "%s for %s\n", conf_irq, "3,5,6,12,13", "EC/EP-98X"); 1343 return (ENXIO); 1344 } 1345 ed_asic_outb(sc, ED_NW98X_IRQ, tmp); 1346 1347 return (0); 1348} 1349 1350/* 1351 * Read SB-9801 station address from Serial Two-Wire EEPROM 1352 */ 1353static void 1354ed_get_SB98(struct ed_softc *sc) 1355{ 1356 int i, j; 1357 u_char mask, val; 1358 1359 /* enable EEPROM acceess */ 1360 ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_ENABLE); 1361 1362 /* output start command */ 1363 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1364 DELAY(ED_SB98_EEP_DELAY); 1365 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1366 DELAY(ED_SB98_EEP_DELAY); 1367 1368 /* output address (7bit) */ 1369 for (mask = 0x40; mask != 0; mask >>= 1) { 1370 val = 0; 1371 if (ED_SB98_ADDRESS & mask) 1372 val = ED_SB98_EEP_SDA; 1373 ed_asic_outb(sc, ED_SB98_EEP, val); 1374 DELAY(ED_SB98_EEP_DELAY); 1375 ed_asic_outb(sc, ED_SB98_EEP, val | ED_SB98_EEP_SCL); 1376 DELAY(ED_SB98_EEP_DELAY); 1377 } 1378 1379 /* output READ command */ 1380 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ); 1381 DELAY(ED_SB98_EEP_DELAY); 1382 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ | ED_SB98_EEP_SCL); 1383 DELAY(ED_SB98_EEP_DELAY); 1384 1385 /* read station address */ 1386 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1387 /* output ACK */ 1388 ed_asic_outb(sc, ED_SB98_EEP, 0); 1389 DELAY(ED_SB98_EEP_DELAY); 1390 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1391 DELAY(ED_SB98_EEP_DELAY); 1392 1393 val = 0; 1394 for (j = 0; j < 8; j++) { 1395 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA); 1396 DELAY(ED_SB98_EEP_DELAY); 1397 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1398 DELAY(ED_SB98_EEP_DELAY); 1399 val <<= 1; 1400 val |= (ed_asic_inb(sc, ED_SB98_EEP) & ED_SB98_EEP_SDA); 1401 DELAY(ED_SB98_EEP_DELAY); 1402 } 1403 sc->enaddr[i] = val; 1404 } 1405 1406 /* output Last ACK */ 1407 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA); 1408 DELAY(ED_SB98_EEP_DELAY); 1409 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1410 DELAY(ED_SB98_EEP_DELAY); 1411 1412 /* output stop command */ 1413 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1414 DELAY(ED_SB98_EEP_DELAY); 1415 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1416 DELAY(ED_SB98_EEP_DELAY); 1417 1418 /* disable EEPROM access */ 1419 ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_DISABLE); 1420} 1421 1422/* 1423 * Probe and vendor-specific initialization routine for SB-9801 boards 1424 */ 1425static int 1426ed_probe_SB98(device_t dev, int port_rid, int flags) 1427{ 1428 struct ed_softc *sc = device_get_softc(dev); 1429 int error; 1430 u_char tmp; 1431 u_long conf_irq, junk; 1432 1433 error = ed98_alloc_port(dev, port_rid); 1434 if (error) 1435 return (error); 1436 1437 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1438 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1439 1440 /* Check I/O address. 00d[02468ace] are allowed. */ 1441 if ((rman_get_start(sc->port_res) & ~0x000e) != 0x00d0) { 1442#ifdef DIAGNOSTIC 1443 device_printf(dev, "Invalid i/o port configuration (0x%lx) " 1444 "must be %s for %s\n", rman_get_start(sc->port_res), 1445 "0xd?", "SB9801"); 1446#endif 1447 return (ENXIO); 1448 } 1449 1450 /* Write I/O port address and read 4 times */ 1451 outb(ED_SB98_IO_INHIBIT, rman_get_start(sc->port_res) & 0xff); 1452 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1453 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1454 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1455 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1456 1457 /* 1458 * Check IRQ. Soliton SB-9801 only allows a choice of 1459 * irq 3,5,6,12 1460 */ 1461 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &conf_irq, &junk); 1462 if (error) 1463 return (error); 1464 1465 switch (conf_irq) { 1466 case 3: 1467 tmp = ED_SB98_CFG_IRQ3; 1468 break; 1469 case 5: 1470 tmp = ED_SB98_CFG_IRQ5; 1471 break; 1472 case 6: 1473 tmp = ED_SB98_CFG_IRQ6; 1474 break; 1475 case 12: 1476 tmp = ED_SB98_CFG_IRQ12; 1477 break; 1478 default: 1479 device_printf(dev, "Invalid irq configuration (%ld) must be " 1480 "%s for %s\n", conf_irq, "3,5,6,12", "SB9801"); 1481 return (ENXIO); 1482 } 1483 1484 if (flags & ED_FLAGS_DISABLE_TRANCEIVER) 1485 tmp |= ED_SB98_CFG_ALTPORT; 1486 ed_asic_outb(sc, ED_SB98_CFG, ED_SB98_CFG_ENABLE | tmp); 1487 ed_asic_outb(sc, ED_SB98_POLARITY, 0x01); 1488 1489 /* Reset the board. */ 1490 ed_asic_outb(sc, ED_NOVELL_RESET, 0x7a); 1491 DELAY(300); 1492 ed_asic_outb(sc, ED_NOVELL_RESET, 0x79); 1493 DELAY(300); 1494 1495 /* 1496 * This is needed because some NE clones apparently don't reset the 1497 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1498 * - this makes the probe invasive! ...Done against my better 1499 * judgement. -DLG 1500 */ 1501 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1502 DELAY(5000); 1503 1504 /* Make sure that we really have an 8390 based board */ 1505 if (!ed98_probe_generic8390(sc)) 1506 return (ENXIO); 1507 1508 /* Test memory via PIO */ 1509 sc->cr_proto = ED_CR_RD2; 1510 if (!ed_pio_testmem(sc, 16384, 1, flags)) 1511 return (ENXIO); 1512 1513 /* This looks like an SB9801 board. */ 1514 sc->type_str = "SB9801"; 1515 1516 /* Get station address */ 1517 ed_get_SB98(sc); 1518 1519 /* clear any pending interrupts that might have occurred above */ 1520 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1521 1522 sc->sc_write_mbufs = ed_pio_write_mbufs; 1523 return (0); 1524} 1525 1526/* 1527 * Test the ability to read and write to the NIC memory. 1528 */ 1529static int 1530ed_pio_testmem(struct ed_softc *sc, int page_offset, int isa16bit, int flags) 1531{ 1532 u_long memsize; 1533 static char test_pattern[32] = "THIS is A memory TEST pattern"; 1534 char test_buffer[32]; 1535#ifdef DIAGNOSTIC 1536 int page_end; 1537#endif 1538 1539 sc->vendor = ED_VENDOR_NOVELL; 1540 sc->mem_shared = 0; 1541 sc->isa16bit = isa16bit; 1542 1543 /* 8k of memory plus an additional 8k if 16bit */ 1544 memsize = (isa16bit ? 16384 : 8192); 1545 1546 /* 1547 * This prevents packets from being stored in the NIC memory when the 1548 * readmem routine turns on the start bit in the CR. 1549 */ 1550 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); 1551 1552 /* Initialize DCR for byte/word operations */ 1553 if (isa16bit) 1554 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 1555 else 1556 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 1557 ed_nic_outb(sc, ED_P0_PSTART, page_offset / ED_PAGE_SIZE); 1558 ed_nic_outb(sc, ED_P0_PSTOP, (page_offset + memsize) / ED_PAGE_SIZE); 1559#ifdef ED_DEBUG 1560 printf("ed?: ed_pio_testmem: page start=%x, end=%lx", 1561 page_offset, page_offset + memsize); 1562#endif 1563 1564 /* 1565 * Write a test pattern. If this fails, then we don't know 1566 * what this board is. 1567 */ 1568 ed_pio_writemem(sc, test_pattern, page_offset, sizeof(test_pattern)); 1569 ed_pio_readmem(sc, page_offset, test_buffer, sizeof(test_pattern)); 1570 1571 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) { 1572#ifdef ED_DEBUG 1573 printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_offset); 1574#endif 1575 return (0); 1576 } 1577 1578#ifdef DIAGNOSTIC 1579 /* Check the bottom. */ 1580 page_end = page_offset + memsize - ED_PAGE_SIZE; 1581 ed_pio_writemem(sc, test_pattern, page_end, sizeof(test_pattern)); 1582 ed_pio_readmem(sc, page_end, test_buffer, sizeof(test_pattern)); 1583 1584 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) { 1585#ifdef ED_DEBUG 1586 printf("ed?: ed_pio_testmem: bcmp(page %x) NG", page_end); 1587#endif 1588 return (0); 1589 } 1590#endif 1591 sc->mem_size = memsize; 1592 sc->mem_start = page_offset; 1593 sc->mem_end = sc->mem_start + memsize; 1594 sc->tx_page_start = page_offset / ED_PAGE_SIZE; 1595 1596 /* 1597 * Use one xmit buffer if < 16k, two buffers otherwise (if not told 1598 * otherwise). 1599 */ 1600 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) 1601 sc->txb_cnt = 1; 1602 else 1603 sc->txb_cnt = 2; 1604 1605 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 1606 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 1607 1608 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 1609 1610 return (1); 1611} 1612 1613static device_method_t ed_cbus_methods[] = { 1614 /* Device interface */ 1615 DEVMETHOD(device_probe, ed_cbus_probe), 1616 DEVMETHOD(device_attach, ed_cbus_attach), 1617 DEVMETHOD(device_detach, ed_detach), 1618 1619 { 0, 0 } 1620}; 1621 1622static driver_t ed_cbus_driver = { 1623 "ed", 1624 ed_cbus_methods, 1625 sizeof(struct ed_softc) 1626}; 1627 1628DRIVER_MODULE(ed, isa, ed_cbus_driver, ed_devclass, 0, 0); 1629MODULE_DEPEND(ed, isa, 1, 1, 1); 1630MODULE_DEPEND(ed, ether, 1, 1, 1); 1631