if_ed_cbus.c revision 108533
1142425Snectar/* 2142425Snectar * Copyright (c) 1995, David Greenman 3142425Snectar * All rights reserved. 4142425Snectar * 5142425Snectar * Redistribution and use in source and binary forms, with or without 6142425Snectar * modification, are permitted provided that the following conditions 7142425Snectar * are met: 8142425Snectar * 1. Redistributions of source code must retain the above copyright 9142425Snectar * notice unmodified, this list of conditions, and the following 10142425Snectar * disclaimer. 11142425Snectar * 2. Redistributions in binary form must reproduce the above copyright 12142425Snectar * notice, this list of conditions and the following disclaimer in the 13142425Snectar * documentation and/or other materials provided with the distribution. 14142425Snectar * 15142425Snectar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16142425Snectar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17142425Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18142425Snectar * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19142425Snectar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20142425Snectar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21142425Snectar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22142425Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23142425Snectar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24142425Snectar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25142425Snectar * SUCH DAMAGE. 26142425Snectar * 27142425Snectar * $FreeBSD: head/sys/dev/ed/if_ed_cbus.c 108533 2003-01-01 18:49:04Z schweikh $ 28142425Snectar */ 29142425Snectar 30142425Snectar#include <sys/param.h> 31142425Snectar#include <sys/systm.h> 32142425Snectar#include <sys/socket.h> 33142425Snectar#include <sys/kernel.h> 34238405Sjkim 35142425Snectar#include <sys/module.h> 36142425Snectar#include <sys/bus.h> 37142425Snectar#include <machine/bus.h> 38142425Snectar#ifdef PC98 39160814Ssimon#include <sys/rman.h> 40238405Sjkim#include <machine/resource.h> 41194206Ssimon#include <machine/clock.h> 42238405Sjkim#include <machine/md_var.h> 43142425Snectar#endif 44142425Snectar 45142425Snectar#include <net/ethernet.h> 46142425Snectar#include <net/if.h> 47142425Snectar#include <net/if_arp.h> 48142425Snectar#include <net/if_mib.h> 49142425Snectar 50142425Snectar#include <isa/isavar.h> 51142425Snectar 52142425Snectar#include <dev/ed/if_edvar.h> 53142425Snectar#ifdef PC98 54142425Snectar#include <dev/ed/if_edreg.h> 55160814Ssimon#include <dev/ed/if_ed98.h> 56238405Sjkim 57142425Snectarstatic int ed98_alloc_port (device_t, int); 58238405Sjkimstatic int ed98_alloc_memory (device_t, int); 59238405Sjkimstatic int ed_pio_testmem (struct ed_softc *, int, int, int); 60142425Snectarstatic int ed_probe_SIC98 (device_t, int, int); 61142425Snectarstatic int ed_probe_CNET98 (device_t, int, int); 62142425Snectarstatic int ed_probe_CNET98EL (device_t, int, int); 63160814Ssimonstatic int ed_probe_NEC77 (device_t, int, int); 64238405Sjkimstatic int ed_probe_NW98X (device_t, int, int); 65142425Snectarstatic int ed_probe_SB98 (device_t, int, int); 66238405Sjkimstatic int ed_probe_EZ98 (device_t, int, int); 67238405Sjkimstatic int ed98_probe_Novell (device_t, int, int); 68142425Snectarstatic int ed98_probe_generic8390 (struct ed_softc *); 69142425Snectarstatic void ed_reset_CNET98 (struct ed_softc *, int); 70142425Snectarstatic void ed_winsel_CNET98 (struct ed_softc *, u_short); 71142425Snectarstatic void ed_get_SB98 (struct ed_softc *); 72142425Snectar#endif 73142425Snectar 74142425Snectarstatic int ed_isa_probe (device_t); 75142425Snectarstatic int ed_isa_attach (device_t); 76142425Snectar 77142425Snectarstatic struct isa_pnp_id ed_ids[] = { 78142425Snectar#ifdef PC98 79142425Snectar/* TODO - list up PnP boards for PC-98 */ 80142425Snectar { 0, NULL } 81142425Snectar#endif 82142425Snectar}; 83142425Snectar 84142425Snectarstatic int 85142425Snectared_isa_probe(dev) 86160814Ssimon device_t dev; 87160814Ssimon{ 88160814Ssimon struct ed_softc *sc = device_get_softc(dev); 89160814Ssimon int flags = device_get_flags(dev); 90160814Ssimon int error = 0; 91160814Ssimon 92160814Ssimon bzero(sc, sizeof(struct ed_softc)); 93142425Snectar#ifdef PC98 94142425Snectar sc->type = ED_TYPE98(flags); 95142425Snectar#ifdef ED_DEBUG 96142425Snectar device_printf(dev, "ed_isa_probe: sc->type=%x\n", sc->type); 97142425Snectar#endif 98142425Snectar#endif 99142425Snectar 100142425Snectar /* Check isapnp ids */ 101160814Ssimon error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); 102160814Ssimon#ifdef ED_DEBUG 103142425Snectar device_printf(dev, "ed_isa_probe: ISA_PNP_PROBE returns %d\n", error); 104142425Snectar#endif 105142425Snectar 106142425Snectar /* If the card had a PnP ID that didn't match any we know about */ 107142425Snectar if (error == ENXIO) { 108142425Snectar goto end; 109160814Ssimon } 110142425Snectar 111142425Snectar /* If we had some other problem. */ 112142425Snectar if (!(error == 0 || error == ENOENT)) { 113142425Snectar goto end; 114142425Snectar } 115142425Snectar 116142425Snectar /* Heuristic probes */ 117142425Snectar#ifdef ED_DEBUG 118142425Snectar device_printf(dev, "ed_isa_probe: Heuristic probes start\n"); 119142425Snectar#endif 120142425Snectar#ifdef PC98 121142425Snectar switch (sc->type) { 122142425Snectar case ED_TYPE98_GENERIC: 123142425Snectar /* 124142425Snectar * CAUTION! 125142425Snectar * sc->type of these boards are overwritten by PC/AT's value. 126142425Snectar */ 127142425Snectar 128142425Snectar /* 129142425Snectar * SMC EtherEZ98 130142425Snectar */ 131160814Ssimon error = ed_probe_EZ98(dev, 0, flags); 132160814Ssimon if (error == 0) { 133160814Ssimon goto end; 134160814Ssimon } 135160814Ssimon 136142425Snectar ed_release_resources(dev); 137142425Snectar 138142425Snectar /* 139142425Snectar * Allied Telesis CenterCom LA-98-T 140238405Sjkim */ 141142425Snectar error = ed_probe_Novell(dev, 0, flags); 142142425Snectar if (error == 0) { 143238405Sjkim goto end; 144142425Snectar } 145142425Snectar 146142425Snectar break; 147142425Snectar 148142425Snectar /* 149142425Snectar * NE2000-like boards probe routine 150142425Snectar */ 151142425Snectar case ED_TYPE98_BDN: 152142425Snectar /* 153142425Snectar * ELECOM LANEED LD-BDN 154160814Ssimon * PLANET SMART COM 98 EN-2298 155160814Ssimon */ 156194206Ssimon case ED_TYPE98_LGY: 157238405Sjkim /* 158160814Ssimon * MELCO LGY-98, IND-SP, IND-SS 159194206Ssimon * MACNICA NE2098 160160814Ssimon */ 161238405Sjkim case ED_TYPE98_ICM: 162160814Ssimon /* 163160814Ssimon * ICM DT-ET-25, DT-ET-T5, IF-2766ET, IF-2771ET 164238405Sjkim * D-Link DE-298P, DE-298 165142425Snectar */ 166142425Snectar case ED_TYPE98_EGY: 167142425Snectar /* 168142425Snectar * MELCO EGY-98 169142425Snectar * Contec C-NET(98)E-A, C-NET(98)L-A 170142425Snectar */ 171142425Snectar case ED_TYPE98_108: 172160814Ssimon /* 173160814Ssimon * NEC PC-9801-107,108 174160814Ssimon */ 175238405Sjkim case ED_TYPE98_NC5098: 176238405Sjkim /* 177238405Sjkim * NextCom NC5098 178237657Sjkim */ 179237657Sjkim 180237657Sjkim error = ed98_probe_Novell(dev, 0, flags); 181237657Sjkim 182237657Sjkim break; 183237657Sjkim 184237657Sjkim /* 185237657Sjkim * other boards with special probe routine 186237657Sjkim */ 187160814Ssimon case ED_TYPE98_SIC: 188142425Snectar /* 189160814Ssimon * Allied Telesis SIC-98 190160814Ssimon */ 191238405Sjkim error = ed_probe_SIC98(dev, 0, flags); 192238405Sjkim 193238405Sjkim break; 194237657Sjkim 195237657Sjkim case ED_TYPE98_CNET98EL: 196237657Sjkim /* 197237657Sjkim * Contec C-NET(98)E/L 198237657Sjkim */ 199237657Sjkim error = ed_probe_CNET98EL(dev, 0, flags); 200237657Sjkim 201237657Sjkim break; 202237657Sjkim 203237657Sjkim case ED_TYPE98_CNET98: 204160814Ssimon /* 205160814Ssimon * Contec C-NET(98) 206160814Ssimon */ 207238405Sjkim error = ed_probe_CNET98(dev, 0, flags); 208238405Sjkim 209238405Sjkim break; 210237657Sjkim 211237657Sjkim case ED_TYPE98_LA98: 212237657Sjkim /* 213237657Sjkim * IO-DATA LA/T-98 214237657Sjkim * NEC PC-9801-77,78 215237657Sjkim */ 216237657Sjkim error = ed_probe_NEC77(dev, 0, flags); 217237657Sjkim 218237657Sjkim break; 219237657Sjkim 220160814Ssimon case ED_TYPE98_NW98X: 221142425Snectar /* 222160814Ssimon * Networld EC/EP-98X 223160814Ssimon */ 224238405Sjkim error = ed_probe_NW98X(dev, 0, flags); 225238405Sjkim 226238405Sjkim break; 227237657Sjkim 228237657Sjkim case ED_TYPE98_SB98: 229237657Sjkim /* 230237657Sjkim * Soliton SB-9801 231237657Sjkim * Fujikura FN-9801 232237657Sjkim */ 233237657Sjkim 234237657Sjkim error = ed_probe_SB98(dev, 0, flags); 235237657Sjkim 236160814Ssimon break; 237238405Sjkim } 238238405Sjkim#endif 239238405Sjkim 240238405Sjkimend: 241237657Sjkim#ifdef ED_DEBUG 242237657Sjkim device_printf(dev, "ed_isa_probe: end, error=%d\n", error); 243238405Sjkim#endif 244238405Sjkim if (error == 0) 245238405Sjkim error = ed_alloc_irq(dev, 0, 0); 246238405Sjkim 247238405Sjkim ed_release_resources(dev); 248238405Sjkim return (error); 249237657Sjkim} 250238405Sjkim 251238405Sjkimstatic int 252238405Sjkimed_isa_attach(dev) 253238405Sjkim device_t dev; 254238405Sjkim{ 255238405Sjkim struct ed_softc *sc = device_get_softc(dev); 256238405Sjkim int flags = device_get_flags(dev); 257194206Ssimon int error; 258238405Sjkim 259238405Sjkim if (sc->port_used > 0) { 260238405Sjkim#ifdef PC98 261238405Sjkim if (ED_TYPE98(flags) == ED_TYPE98_GENERIC) { 262238405Sjkim ed_alloc_port(dev, sc->port_rid, sc->port_used); 263238405Sjkim } else { 264237657Sjkim ed98_alloc_port(dev, sc->port_rid); 265237657Sjkim } 266237657Sjkim#endif 267238405Sjkim } 268237657Sjkim if (sc->mem_used) 269237657Sjkim ed_alloc_memory(dev, sc->mem_rid, sc->mem_used); 270237657Sjkim 271237657Sjkim ed_alloc_irq(dev, sc->irq_rid, 0); 272237657Sjkim 273160814Ssimon error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, 274160814Ssimon edintr, sc, &sc->irq_handle); 275160814Ssimon if (error) { 276238405Sjkim ed_release_resources(dev); 277238405Sjkim return (error); 278238405Sjkim } 279237657Sjkim 280237657Sjkim return ed_attach(sc, device_get_unit(dev), flags); 281237657Sjkim} 282237657Sjkim 283237657Sjkim#ifdef PC98 284237657Sjkim/* 285237657Sjkim * Interrupt conversion table for EtherEZ98 286237657Sjkim */ 287237657Sjkimstatic unsigned short ed_EZ98_intr_val[] = { 288160814Ssimon 0, 289160814Ssimon 3, 290160814Ssimon 5, 291238405Sjkim 6, 292238405Sjkim 0, 293238405Sjkim 9, 294237657Sjkim 12, 295237657Sjkim 13 296237657Sjkim}; 297237657Sjkim 298237657Sjkimstatic int 299237657Sjkimed_probe_EZ98(dev, port_rid, flags) 300237657Sjkim device_t dev; 301237657Sjkim int port_rid; 302237657Sjkim int flags; 303237657Sjkim{ 304160814Ssimon struct ed_softc *sc = device_get_softc(dev); 305160814Ssimon int error; 306160814Ssimon static unsigned short *intr_vals[] = {NULL, ed_EZ98_intr_val}; 307238405Sjkim 308238405Sjkim error = ed_alloc_port(dev, port_rid, ED_EZ98_IO_PORTS); 309238405Sjkim if (error) { 310237657Sjkim return (error); 311237657Sjkim } 312237657Sjkim 313237657Sjkim sc->asic_offset = ED_EZ98_ASIC_OFFSET; 314237657Sjkim sc->nic_offset = ED_EZ98_NIC_OFFSET; 315237657Sjkim 316237657Sjkim return ed_probe_WD80x3_generic(dev, flags, intr_vals); 317237657Sjkim} 318237657Sjkim 319237657Sjkim/* 320160814Ssimon * I/O conversion tables 321142425Snectar */ 322160814Ssimon 323160814Ssimon/* LGY-98, ICM, C-NET(98)E/L */ 324238405Sjkimstatic bus_addr_t ed98_ioaddr_generic[] = { 325238405Sjkim 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 326238405Sjkim}; 327237657Sjkim 328237657Sjkim/* 329237657Sjkim * Definitions for Contec C-NET(98)E/L 330237657Sjkim */ 331237657Sjkim#define ED_CNET98EL_ICR 2 /* Interrupt Configuration Register */ 332237657Sjkim 333237657Sjkim#define ED_CNET98EL_ICR_IRQ3 0x01 334237657Sjkim#define ED_CNET98EL_ICR_IRQ5 0x02 335237657Sjkim#define ED_CNET98EL_ICR_IRQ6 0x04 336160814Ssimon#define ED_CNET98EL_ICR_IRQ12 0x20 337142425Snectar 338160814Ssimon#define ED_CNET98EL_IMR 4 /* Interrupt Mask Register */ 339142425Snectar#define ED_CNET98EL_ISR 5 /* Interrupt Status Register */ 340238405Sjkim 341238405Sjkim/* EGY-98 */ 342238405Sjkimstatic bus_addr_t ed98_ioaddr_egy98[] = { 343237657Sjkim 0, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 344237657Sjkim 0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e 345237657Sjkim}; 346237657Sjkim 347237657Sjkim/* SIC-98 */ 348237657Sjkimstatic bus_addr_t ed98_ioaddr_sic98[] = { 349237657Sjkim 0x0000, 0x0200, 0x0400, 0x0600, 0x0800, 0x0a00, 0x0c00, 0x0e00, 350237657Sjkim 0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00 351237657Sjkim}; 352160814Ssimon 353142425Snectar/* LA/T-98, LD-BDN, PC-9801-77, SB-9801 */ 354160814Ssimonstatic bus_addr_t ed98_ioaddr_la98[] = { 355160814Ssimon 0x0000, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 356160814Ssimon 0x8000, 0x9000, 0xa000, 0xb000, 0xc000, 0xd000, 0xe000, 0xf000, 357238405Sjkim 0x0100 /* for NEC 77(see below) */ 358238405Sjkim}; 359238405Sjkim 360237657Sjkim/* 361237657Sjkim * Definitions for NEC PC-9801-77 362237657Sjkim */ 363237657Sjkim#define ED_NEC77_IRQ 16 /* Interrupt Configuration Register */ 364237657Sjkim 365237657Sjkim#define ED_NEC77_IRQ3 0x04 366237657Sjkim#define ED_NEC77_IRQ5 0x06 367238405Sjkim#define ED_NEC77_IRQ6 0x08 368238405Sjkim#define ED_NEC77_IRQ12 0x0a 369238405Sjkim#define ED_NEC77_IRQ13 0x02 370238405Sjkim 371160814Ssimon/* 372160814Ssimon * Definitions for Soliton SB-9801 373160814Ssimon */ 374238405Sjkim#define ED_SB98_CFG 1 /* Board configuration */ 375238405Sjkim 376238405Sjkim#define ED_SB98_CFG_IRQ3 0x00 377237657Sjkim#define ED_SB98_CFG_IRQ5 0x04 378237657Sjkim#define ED_SB98_CFG_IRQ6 0x08 379237657Sjkim#define ED_SB98_CFG_IRQ12 0x0c 380237657Sjkim#define ED_SB98_CFG_ALTPORT 0x40 /* use EXTERNAL media */ 381237657Sjkim#define ED_SB98_CFG_ENABLE 0xa0 /* enable configuration */ 382237657Sjkim 383237657Sjkim#define ED_SB98_EEPENA 2 /* EEPROM access enable */ 384237657Sjkim 385237657Sjkim#define ED_SB98_EEPENA_DISABLE 0x00 386160814Ssimon#define ED_SB98_EEPENA_ENABLE 0x01 387160814Ssimon 388160814Ssimon#define ED_SB98_EEP 3 /* EEPROM access */ 389160814Ssimon 390238405Sjkim#define ED_SB98_EEP_SDA 0x01 /* Serial Data */ 391238405Sjkim#define ED_SB98_EEP_SCL 0x02 /* Serial Clock */ 392238405Sjkim#define ED_SB98_EEP_READ 0x01 /* Read Command */ 393237657Sjkim 394237657Sjkim#define ED_SB98_EEP_DELAY 300 395237657Sjkim 396237657Sjkim#define ED_SB98_ADDRESS 0x01 /* Station Address(1-6) */ 397237657Sjkim 398237657Sjkim#define ED_SB98_POLARITY 4 /* Polarity */ 399237657Sjkim 400237657Sjkim/* PC-9801-108 */ 401237657Sjkimstatic bus_addr_t ed98_ioaddr_nec108[] = { 402160814Ssimon 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 403238405Sjkim 0x1000, 0x1002, 0x1004, 0x1006, 0x1008, 0x100a, 0x100c, 0x100e 404238405Sjkim}; 405238405Sjkim 406238405Sjkim/* C-NET(98) */ 407237657Sjkimstatic bus_addr_t ed98_ioaddr_cnet98[] = { 408238405Sjkim 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e, 409238405Sjkim 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e 410238405Sjkim}; 411238405Sjkim 412238405Sjkim/* 413238405Sjkim * Definitions for Contec C-NET(98) 414238405Sjkim */ 415238405Sjkim#define ED_CNET98_MAP_REG0L 0 /* MAPPING register0 Low */ 416238405Sjkim#define ED_CNET98_MAP_REG1L 1 /* MAPPING register1 Low */ 417238405Sjkim#define ED_CNET98_MAP_REG2L 2 /* MAPPING register2 Low */ 418160814Ssimon#define ED_CNET98_MAP_REG3L 3 /* MAPPING register3 Low */ 419238405Sjkim#define ED_CNET98_MAP_REG0H 4 /* MAPPING register0 Hi */ 420238405Sjkim#define ED_CNET98_MAP_REG1H 5 /* MAPPING register1 Hi */ 421238405Sjkim#define ED_CNET98_MAP_REG2H 6 /* MAPPING register2 Hi */ 422238405Sjkim#define ED_CNET98_MAP_REG3H 7 /* MAPPING register3 Hi */ 423237657Sjkim#define ED_CNET98_WIN_REG 8 /* Window register */ 424237657Sjkim#define ED_CNET98_INT_LEV 9 /* Init level register */ 425238405Sjkim 426238405Sjkim#define ED_CNET98_INT_IRQ3 0x01 /* INT 0 */ 427238405Sjkim#define ED_CNET98_INT_IRQ5 0x02 /* INT 1 */ 428238405Sjkim#define ED_CNET98_INT_IRQ6 0x04 /* INT 2 */ 429238405Sjkim#define ED_CNET98_INT_IRQ9 0x08 /* INT 3 */ 430238405Sjkim#define ED_CNET98_INT_IRQ12 0x20 /* INT 5 */ 431237657Sjkim#define ED_CNET98_INT_IRQ13 0x40 /* INT 6 */ 432238405Sjkim 433238405Sjkim#define ED_CNET98_INT_REQ 10 /* Init request register */ 434238405Sjkim#define ED_CNET98_INT_MASK 11 /* Init mask register */ 435238405Sjkim#define ED_CNET98_INT_STAT 12 /* Init status register */ 436238405Sjkim#define ED_CNET98_INT_CLR 12 /* Init clear register */ 437238405Sjkim#define ED_CNET98_RESERVE1 13 438238405Sjkim#define ED_CNET98_RESERVE2 14 439160814Ssimon#define ED_CNET98_RESERVE3 15 440238405Sjkim 441238405Sjkim/* EC/EP-98X, NC5098 */ 442238405Sjkimstatic bus_addr_t ed98_ioaddr_nw98x[] = { 443238405Sjkim 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700, 444237657Sjkim 0x0800, 0x0900, 0x0a00, 0x0b00, 0x0c00, 0x0d00, 0x0e00, 0x0f00, 445237657Sjkim 0x1000 /* for EC/EP-98X(see below) */ 446238405Sjkim}; 447238405Sjkim 448238405Sjkim/* 449238405Sjkim * Definitions for Networld EC/EP-98X 450238405Sjkim */ 451238405Sjkim#define ED_NW98X_IRQ 16 /* Interrupt Configuration Register */ 452237657Sjkim 453238405Sjkim#define ED_NW98X_IRQ3 0x04 454238405Sjkim#define ED_NW98X_IRQ5 0x06 455238405Sjkim#define ED_NW98X_IRQ6 0x08 456238405Sjkim#define ED_NW98X_IRQ12 0x0a 457238405Sjkim#define ED_NW98X_IRQ13 0x02 458238405Sjkim 459238405Sjkim/* NC5098 ASIC */ 460160814Ssimonstatic bus_addr_t ed98_asic_nc5098[] = { 461142425Snectar/* DATA ENADDR RESET */ 462160814Ssimon 0x0000, 0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x4000, 463160814Ssimon 0, 0, 0, 0, 0, 0, 0, 0 464160814Ssimon}; 465238405Sjkim 466238405Sjkim/* 467238405Sjkim * Definitions for NextCom NC5098 468237657Sjkim */ 469237657Sjkim#define ED_NC5098_ENADDR 1 /* Station Address(1-6) */ 470237657Sjkim 471237657Sjkim/* 472237657Sjkim * Allocate a port resource with the given resource id. 473237657Sjkim */ 474237657Sjkimstatic int 475238405Sjkimed98_alloc_port(dev, rid) 476238405Sjkim device_t dev; 477238405Sjkim int rid; 478238405Sjkim{ 479160814Ssimon struct ed_softc *sc = device_get_softc(dev); 480142425Snectar struct resource *res; 481160814Ssimon int error; 482142425Snectar bus_addr_t *io_nic, *io_asic, adj; 483238405Sjkim static bus_addr_t io_res[ED_NOVELL_IO_PORTS + 1]; 484238405Sjkim int i, n; 485238405Sjkim int offset, reset, data; 486237657Sjkim 487237657Sjkim /* Set i/o table for resource manager */ 488237657Sjkim io_nic = io_asic = ed98_ioaddr_generic; 489237657Sjkim offset = ED_NOVELL_ASIC_OFFSET; 490237657Sjkim reset = ED_NOVELL_RESET; 491237657Sjkim data = ED_NOVELL_DATA; 492237657Sjkim n = ED_NOVELL_IO_PORTS; 493237657Sjkim 494237657Sjkim switch (sc->type) { 495237657Sjkim case ED_TYPE98_LGY: 496238405Sjkim io_asic = ed98_ioaddr_egy98; /* XXX - Yes, we use egy98 */ 497238405Sjkim offset = 0x0200; 498238405Sjkim reset = 8; 499238405Sjkim break; 500238405Sjkim 501238405Sjkim case ED_TYPE98_EGY: 502238405Sjkim io_nic = io_asic = ed98_ioaddr_egy98; 503238405Sjkim offset = 0x0200; 504238405Sjkim reset = 8; 505238405Sjkim break; 506238405Sjkim 507238405Sjkim case ED_TYPE98_ICM: 508238405Sjkim offset = 0x0100; 509238405Sjkim break; 510238405Sjkim 511238405Sjkim case ED_TYPE98_BDN: 512160814Ssimon io_nic = io_asic = ed98_ioaddr_la98; 513142425Snectar offset = 0x0100; 514160814Ssimon reset = 0x0c; 515160814Ssimon break; 516160814Ssimon 517238405Sjkim case ED_TYPE98_SIC: 518238405Sjkim io_nic = io_asic = ed98_ioaddr_sic98; 519238405Sjkim offset = 0x2000; 520237657Sjkim n = 16+1; 521237657Sjkim break; 522237657Sjkim 523237657Sjkim case ED_TYPE98_108: 524237657Sjkim io_nic = io_asic = ed98_ioaddr_nec108; 525237657Sjkim offset = 0x0888; /* XXX - overwritten after */ 526237657Sjkim reset = 1; 527238405Sjkim n = 16; /* XXX - does not set ASIC i/o here */ 528238405Sjkim break; 529238405Sjkim 530238405Sjkim case ED_TYPE98_LA98: 531160814Ssimon io_nic = io_asic = ed98_ioaddr_la98; 532160814Ssimon offset = 0x0100; 533160814Ssimon break; 534238405Sjkim 535238405Sjkim case ED_TYPE98_CNET98EL: 536238405Sjkim offset = 0x0400; 537237657Sjkim data = 0x0e; 538237657Sjkim break; 539237657Sjkim 540237657Sjkim case ED_TYPE98_CNET98: 541237657Sjkim /* XXX - Yes, we use generic i/o here */ 542237657Sjkim offset = 0x0400; 543237657Sjkim break; 544237657Sjkim 545237657Sjkim case ED_TYPE98_NW98X: 546160814Ssimon io_nic = io_asic = ed98_ioaddr_nw98x; 547142425Snectar offset = 0x1000; 548160814Ssimon break; 549160814Ssimon 550160814Ssimon case ED_TYPE98_SB98: 551238405Sjkim io_nic = io_asic = ed98_ioaddr_la98; 552238405Sjkim offset = 0x0400; 553238405Sjkim reset = 7; 554237657Sjkim break; 555237657Sjkim 556237657Sjkim case ED_TYPE98_NC5098: 557237657Sjkim io_nic = ed98_ioaddr_nw98x; 558237657Sjkim io_asic = ed98_asic_nc5098; 559238405Sjkim offset = 0x2000; 560238405Sjkim reset = 7; 561238405Sjkim n = 16+8; /* XXX */ 562237657Sjkim break; 563237657Sjkim } 564237657Sjkim 565237657Sjkim bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET); 566237657Sjkim for (i = ED_NOVELL_ASIC_OFFSET; i < ED_NOVELL_IO_PORTS; i++) { 567160814Ssimon io_res[i] = io_asic[i - ED_NOVELL_ASIC_OFFSET] + offset; 568238405Sjkim } 569238405Sjkim 570238405Sjkim res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, 571238405Sjkim io_res, n, RF_ACTIVE); 572237657Sjkim if (!res) { 573237657Sjkim return (ENOENT); 574238405Sjkim } 575238405Sjkim 576238405Sjkim sc->port_rid = rid; 577238405Sjkim sc->port_res = res; 578238405Sjkim sc->port_used = n; 579238405Sjkim 580279264Sdelphij /* Re-map i/o table if needed */ 581279264Sdelphij switch (sc->type) { 582279264Sdelphij case ED_TYPE98_LA98: 583279264Sdelphij case ED_TYPE98_NW98X: 584279264Sdelphij io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 585279264Sdelphij n++; 586279264Sdelphij break; 587279264Sdelphij 588279264Sdelphij case ED_TYPE98_108: 589160814Ssimon adj = (rman_get_start(res) & 0xf000) / 2; 590160814Ssimon offset = (offset | adj) - rman_get_start(res); 591142425Snectar 592160814Ssimon for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++) { 593238405Sjkim io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 594238405Sjkim } 595238405Sjkim break; 596237657Sjkim 597237657Sjkim case ED_TYPE98_CNET98: 598237657Sjkim io_nic = io_asic = ed98_ioaddr_cnet98; 599237657Sjkim offset = 1; 600237657Sjkim 601237657Sjkim bcopy(io_nic, io_res, sizeof(io_nic[0]) * ED_NOVELL_ASIC_OFFSET); 602237657Sjkim for (n = ED_NOVELL_ASIC_OFFSET; n < ED_NOVELL_IO_PORTS; n++) { 603237657Sjkim io_res[n] = io_asic[n - ED_NOVELL_ASIC_OFFSET] + offset; 604237657Sjkim } 605237657Sjkim break; 606237657Sjkim 607160814Ssimon case ED_TYPE98_NC5098: 608160814Ssimon n = ED_NOVELL_IO_PORTS; 609160814Ssimon break; 610238405Sjkim } 611238405Sjkim 612238405Sjkim if (reset != ED_NOVELL_RESET) { 613237657Sjkim io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_RESET] = 614237657Sjkim io_res[ED_NOVELL_ASIC_OFFSET + reset]; 615237657Sjkim } 616237657Sjkim if (data != ED_NOVELL_DATA) { 617237657Sjkim io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA] = 618237657Sjkim io_res[ED_NOVELL_ASIC_OFFSET + data]; 619237657Sjkim#if 0 620237657Sjkim io_res[ED_NOVELL_ASIC_OFFSET + ED_NOVELL_DATA + 1] = 621237657Sjkim io_res[ED_NOVELL_ASIC_OFFSET + data + 1]; 622237657Sjkim#endif 623160814Ssimon } 624160814Ssimon 625160814Ssimon error = isa_load_resourcev(res, io_res, n); 626238405Sjkim if (error != 0) { 627238405Sjkim return (ENOENT); 628238405Sjkim } 629237657Sjkim#ifdef ED_DEBUG 630237657Sjkim device_printf(dev, "ed98_alloc_port: i/o ports = %d\n", n); 631237657Sjkim for (i = 0; i < n; i++) { 632237657Sjkim printf("%x,", io_res[i]); 633237657Sjkim } 634237657Sjkim printf("\n"); 635237657Sjkim#endif 636237657Sjkim return (0); 637237657Sjkim} 638237657Sjkim 639160814Ssimonstatic int 640160814Ssimoned98_alloc_memory(dev, rid) 641160814Ssimon device_t dev; 642238405Sjkim int rid; 643238405Sjkim{ 644238405Sjkim struct ed_softc *sc = device_get_softc(dev); 645237657Sjkim int error; 646237657Sjkim u_long conf_maddr, conf_msize; 647237657Sjkim 648237657Sjkim error = bus_get_resource(dev, SYS_RES_MEMORY, 0, 649237657Sjkim &conf_maddr, &conf_msize); 650237657Sjkim if (error) { 651237657Sjkim return (error); 652237657Sjkim } 653237657Sjkim 654237657Sjkim if ((conf_maddr == 0) || (conf_msize == 0)) { 655238405Sjkim return (ENXIO); 656238405Sjkim } 657238405Sjkim 658238405Sjkim error = ed_alloc_memory(dev, rid, (int) conf_msize); 659238405Sjkim if (error) { 660238405Sjkim return (error); 661238405Sjkim } 662238405Sjkim 663238405Sjkim sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); 664238405Sjkim sc->mem_size = conf_msize; 665238405Sjkim 666238405Sjkim return (0); 667238405Sjkim} 668238405Sjkim 669238405Sjkim/* 670238405Sjkim * Generic probe routine for testing for the existance of a DS8390. 671238405Sjkim * Must be called after the NIC has just been reset. This routine 672238405Sjkim * works by looking at certain register values that are guaranteed 673238405Sjkim * to be initialized a certain way after power-up or reset. Seems 674238405Sjkim * not to currently work on the 83C690. 675238405Sjkim * 676238405Sjkim * Specifically: 677238405Sjkim * 678238405Sjkim * Register reset bits set bits 679238405Sjkim * Command Register (CR) TXP, STA RD2, STP 680238405Sjkim * Interrupt Status (ISR) RST 681238405Sjkim * Interrupt Mask (IMR) All bits 682238405Sjkim * Data Control (DCR) LAS 683238405Sjkim * Transmit Config. (TCR) LB1, LB0 684238405Sjkim * 685238405Sjkim * XXX - We only check the CR register. 686238405Sjkim * 687238405Sjkim * Return 1 if 8390 was found, 0 if not. 688238405Sjkim */ 689238405Sjkim 690238405Sjkimstatic int 691238405Sjkimed98_probe_generic8390(sc) 692238405Sjkim struct ed_softc *sc; 693238405Sjkim{ 694238405Sjkim u_char tmp = ed_nic_inb(sc, ED_P0_CR); 695238405Sjkim#ifdef DIAGNOSTIC 696238405Sjkim printf("ed?: inb(ED_P0_CR)=%x\n", tmp); 697238405Sjkim#endif 698238405Sjkim if ((tmp & (ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) != 699238405Sjkim (ED_CR_RD2 | ED_CR_STP)) { 700238405Sjkim return (0); 701238405Sjkim } 702160814Ssimon 703142425Snectar (void) ed_nic_inb(sc, ED_P0_ISR); 704160814Ssimon 705160814Ssimon return (1); 706238405Sjkim} 707238405Sjkim 708237657Sjkimstatic int 709237657Sjkimed98_probe_Novell(dev, port_rid, flags) 710237657Sjkim device_t dev; 711237657Sjkim int port_rid; 712237657Sjkim int flags; 713237657Sjkim{ 714237657Sjkim struct ed_softc *sc = device_get_softc(dev); 715237657Sjkim int error; 716237657Sjkim int n; 717160814Ssimon u_char romdata[ETHER_ADDR_LEN * 2], tmp; 718160814Ssimon 719160814Ssimon#ifdef ED_DEBUG 720238405Sjkim device_printf(dev, "ed98_probe_Novell: start\n"); 721238405Sjkim#endif 722238405Sjkim error = ed98_alloc_port(dev, port_rid); 723237657Sjkim if (error) { 724237657Sjkim return (error); 725237657Sjkim } 726237657Sjkim 727237657Sjkim sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 728237657Sjkim sc->nic_offset = ED_NOVELL_NIC_OFFSET; 729237657Sjkim 730237657Sjkim /* Reset the board */ 731237657Sjkim#ifdef ED_DEBUG 732160814Ssimon device_printf(dev, "ed98_probe_Novell: reset\n"); 733160814Ssimon#endif 734142425Snectar switch (sc->type) { 735142425Snectar#if 1 /* XXX - I'm not sure this is really necessary... */ 736160814Ssimon case ED_TYPE98_BDN: 737238405Sjkim tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 738238405Sjkim ed_asic_outb(sc, ED_NOVELL_RESET, (tmp & 0xf0) | 0x08); 739238405Sjkim ed_nic_outb(sc, 0x04, tmp); 740237657Sjkim (void) ed_asic_inb(sc, 0x08); 741237657Sjkim ed_asic_outb(sc, 0x08, tmp); 742237657Sjkim ed_asic_outb(sc, 0x08, tmp & 0x7f); 743237657Sjkim break; 744237657Sjkim#endif 745237657Sjkim case ED_TYPE98_NC5098: 746237657Sjkim ed_asic_outb(sc, ED_NOVELL_RESET, 0x00); 747238405Sjkim DELAY(5000); 748238405Sjkim ed_asic_outb(sc, ED_NOVELL_RESET, 0x01); 749238405Sjkim break; 750160814Ssimon 751142425Snectar default: 752160814Ssimon tmp = ed_asic_inb(sc, ED_NOVELL_RESET); 753160814Ssimon 754238405Sjkim /* 755238405Sjkim * I don't know if this is necessary; probably cruft leftover from 756238405Sjkim * Clarkson packet driver code. Doesn't do a thing on the boards I've 757237657Sjkim * tested. -DG [note that an outb(0x84, 0) seems to work here, and is 758237657Sjkim * non-invasive...but some boards don't seem to reset and I don't have 759237657Sjkim * complete documentation on what the 'right' thing to do is...so we 760237657Sjkim * do the invasive thing for now. Yuck.] 761237657Sjkim */ 762237657Sjkim ed_asic_outb(sc, ED_NOVELL_RESET, tmp); 763237657Sjkim break; 764237657Sjkim } 765237657Sjkim DELAY(5000); 766160814Ssimon 767160814Ssimon /* 768160814Ssimon * This is needed because some NE clones apparently don't reset the 769238405Sjkim * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 770238405Sjkim * - this makes the probe invasive! ...Done against my better 771238405Sjkim * judgement. -DLG 772237657Sjkim */ 773237657Sjkim ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 774237657Sjkim DELAY(5000); 775237657Sjkim 776237657Sjkim /* Make sure that we really have an 8390 based board */ 777237657Sjkim if (!ed98_probe_generic8390(sc)) { 778237657Sjkim return (ENXIO); 779237657Sjkim } 780237657Sjkim 781237657Sjkim /* Test memory via PIO */ 782160814Ssimon#ifdef ED_DEBUG 783238405Sjkim device_printf(dev, "ed98_probe_Novell: test memory\n"); 784238405Sjkim#endif 785238405Sjkim sc->cr_proto = ED_CR_RD2; 786238405Sjkim if (!ed_pio_testmem(sc, 8192, 0, flags) 787237657Sjkim && !ed_pio_testmem(sc, 16384, 1, flags)) { 788237657Sjkim return (ENXIO); 789238405Sjkim } 790238405Sjkim 791238405Sjkim /* Setup the board type */ 792238405Sjkim#ifdef ED_DEBUG 793238405Sjkim device_printf(dev, "ed98_probe_Novell: board type\n"); 794238405Sjkim#endif 795237657Sjkim switch (sc->type) { 796237657Sjkim case ED_TYPE98_BDN: 797238405Sjkim sc->type_str = "LD-BDN"; 798238405Sjkim break; 799238405Sjkim case ED_TYPE98_EGY: 800238405Sjkim sc->type_str = "EGY-98"; 801238405Sjkim break; 802238405Sjkim case ED_TYPE98_LGY: 803238405Sjkim sc->type_str = "LGY-98"; 804160814Ssimon break; 805142425Snectar case ED_TYPE98_ICM: 806160814Ssimon sc->type_str = "ICM"; 807160814Ssimon break; 808160814Ssimon case ED_TYPE98_108: 809238405Sjkim sc->type_str = "PC-9801-108"; 810238405Sjkim break; 811238405Sjkim case ED_TYPE98_LA98: 812237657Sjkim sc->type_str = "LA-98"; 813237657Sjkim break; 814237657Sjkim case ED_TYPE98_NW98X: 815237657Sjkim sc->type_str = "NW98X"; 816237657Sjkim break; 817238405Sjkim case ED_TYPE98_NC5098: 818238405Sjkim sc->type_str = "NC5098"; 819238405Sjkim break; 820238405Sjkim default: 821238405Sjkim sc->type_str = NULL; 822238405Sjkim break; 823238405Sjkim } 824238405Sjkim 825238405Sjkim /* Get station address */ 826238405Sjkim switch (sc->type) { 827160814Ssimon case ED_TYPE98_NC5098: 828142425Snectar for (n = 0; n < ETHER_ADDR_LEN; n++) { 829160814Ssimon sc->arpcom.ac_enaddr[n] = 830160814Ssimon ed_asic_inb(sc, ED_NC5098_ENADDR + n); 831160814Ssimon } 832160814Ssimon break; 833238405Sjkim 834238405Sjkim default: 835238405Sjkim ed_pio_readmem(sc, 0, romdata, sizeof(romdata)); 836237657Sjkim for (n = 0; n < ETHER_ADDR_LEN; n++) { 837237657Sjkim sc->arpcom.ac_enaddr[n] = 838237657Sjkim romdata[n * (sc->isa16bit + 1)]; 839237657Sjkim } 840237657Sjkim break; 841238405Sjkim } 842238405Sjkim 843238405Sjkim /* clear any pending interrupts that might have occurred above */ 844238405Sjkim ed_nic_outb(sc, ED_P0_ISR, 0xff); 845238405Sjkim 846238405Sjkim return (0); 847238405Sjkim} 848237657Sjkim 849237657Sjkim/* 850237657Sjkim * Probe and vendor-specific initialization routine for SIC-98 boards 851237657Sjkim */ 852205128Ssimonstatic int 853238405Sjkimed_probe_SIC98(dev, port_rid, flags) 854238405Sjkim device_t dev; 855238405Sjkim int port_rid; 856238405Sjkim int flags; 857238405Sjkim{ 858237657Sjkim struct ed_softc *sc = device_get_softc(dev); 859238405Sjkim int error; 860238405Sjkim int i; 861238405Sjkim u_char sum; 862238405Sjkim 863238405Sjkim /* 864238405Sjkim * Setup card RAM and I/O address 865237657Sjkim * Kernel Virtual to segment C0000-DFFFF???? 866238405Sjkim */ 867238405Sjkim error = ed98_alloc_port(dev, port_rid); 868238405Sjkim if (error) { 869238405Sjkim return (error); 870238405Sjkim } 871238405Sjkim 872238405Sjkim sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 873160814Ssimon sc->nic_offset = ED_NOVELL_NIC_OFFSET; 874238405Sjkim 875238405Sjkim error = ed98_alloc_memory(dev, 0); 876238405Sjkim if (error) { 877238405Sjkim return (error); 878237657Sjkim } 879237657Sjkim 880238405Sjkim /* Reset card to force it into a known state. */ 881238405Sjkim ed_asic_outb(sc, 0, 0x00); 882238405Sjkim DELAY(100); 883238405Sjkim if (ED_TYPE98SUB(flags) == 0) { 884238405Sjkim /* SIC-98/SIU-98 */ 885238405Sjkim ed_asic_outb(sc, 0, 0x94); 886237657Sjkim DELAY(100); 887238405Sjkim ed_asic_outb(sc, 0, 0x94); 888238405Sjkim } else { 889238405Sjkim /* SIU-98-D */ 890238405Sjkim ed_asic_outb(sc, 0, 0x80); 891238405Sjkim DELAY(100); 892238405Sjkim ed_asic_outb(sc, 0, 0x94); 893238405Sjkim DELAY(100); 894160814Ssimon ed_asic_outb(sc, 0, 0x9e); 895238405Sjkim } 896238405Sjkim DELAY(100); 897238405Sjkim 898238405Sjkim /* 899237657Sjkim * Here we check the card ROM, if the checksum passes, and the 900237657Sjkim * type code and ethernet address check out, then we know we have 901238405Sjkim * an SIC card. 902238405Sjkim */ 903238405Sjkim sum = sc->mem_start[6 * 2]; 904238405Sjkim for (i = 0; i < ETHER_ADDR_LEN; i++) { 905238405Sjkim sum ^= (sc->arpcom.ac_enaddr[i] = sc->mem_start[i * 2]); 906238405Sjkim } 907237657Sjkim#ifdef ED_DEBUG 908238405Sjkim device_printf(dev, "ed_probe_sic98: got address %6D\n", 909238405Sjkim sc->arpcom.ac_enaddr, ":"); 910238405Sjkim#endif 911238405Sjkim if (sum != 0) { 912238405Sjkim return (ENXIO); 913238405Sjkim } 914238405Sjkim if ((sc->arpcom.ac_enaddr[0] | sc->arpcom.ac_enaddr[1] | 915160814Ssimon sc->arpcom.ac_enaddr[2]) == 0) { 916160814Ssimon return (ENXIO); 917160814Ssimon } 918238405Sjkim 919238405Sjkim sc->vendor = ED_VENDOR_MISC; 920238405Sjkim sc->type_str = "SIC98"; 921237657Sjkim sc->isa16bit = 1; 922237657Sjkim sc->cr_proto = 0; 923237657Sjkim 924237657Sjkim /* 925237657Sjkim * SIC RAM page 0x0000-0x3fff(or 0x7fff) 926237657Sjkim */ 927237657Sjkim if (ED_TYPE98SUB(flags) == 0) { 928237657Sjkim ed_asic_outb(sc, 0, 0x90); 929237657Sjkim } else { 930237657Sjkim ed_asic_outb(sc, 0, 0x8e); 931142425Snectar } 932142425Snectar DELAY(100); 933142425Snectar 934238405Sjkim /* 935238405Sjkim * clear interface memory, then sum to make sure its valid 936238405Sjkim */ 937238405Sjkim bzero(sc->mem_start, sc->mem_size); 938238405Sjkim 939237657Sjkim for (i = 0; i < sc->mem_size; i++) { 940237657Sjkim if (sc->mem_start[i]) { 941238405Sjkim device_printf(dev, "failed to clear shared memory " 942238405Sjkim "at %lx - check configuration\n", 943238405Sjkim kvtop(sc->mem_start + i)); 944238405Sjkim 945237657Sjkim return (ENXIO); 946237657Sjkim } 947237657Sjkim } 948237657Sjkim 949237657Sjkim sc->mem_shared = 1; 950237657Sjkim sc->mem_end = sc->mem_start + sc->mem_size; 951238405Sjkim 952238405Sjkim /* 953238405Sjkim * allocate one xmit buffer if < 16k, two buffers otherwise 954238405Sjkim */ 955237657Sjkim if ((sc->mem_size < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { 956237657Sjkim sc->txb_cnt = 1; 957160814Ssimon } else { 958160814Ssimon sc->txb_cnt = 2; 959160814Ssimon } 960238405Sjkim sc->tx_page_start = 0; 961238405Sjkim 962238405Sjkim sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE * sc->txb_cnt; 963237657Sjkim sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 964237657Sjkim 965237657Sjkim sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 966237657Sjkim 967237657Sjkim return (0); 968237657Sjkim} 969237657Sjkim 970237657Sjkim/* 971237657Sjkim * Contec C-NET(98) series support routines 972237657Sjkim */ 973238405Sjkimstatic void 974238405Sjkimed_reset_CNET98(sc, flags) 975238405Sjkim struct ed_softc *sc; 976238405Sjkim int flags; 977238405Sjkim{ 978238405Sjkim u_short init_addr = ED_CNET98_INIT; 979238405Sjkim u_char tmp; 980238405Sjkim 981238405Sjkim /* Choose initial register address */ 982238405Sjkim if (ED_TYPE98SUB(flags) != 0) { 983238405Sjkim init_addr = ED_CNET98_INIT2; 984238405Sjkim } 985238405Sjkim#ifdef ED_DEBUG 986238405Sjkim printf("ed?: initial register=%x\n", init_addr); 987238405Sjkim#endif 988238405Sjkim /* 989238405Sjkim * Reset the board to force it into a known state. 990238405Sjkim */ 991238405Sjkim outb(init_addr, 0x00); /* request */ 992238405Sjkim DELAY(5000); 993238405Sjkim outb(init_addr, 0x01); /* cancel */ 994238405Sjkim DELAY(5000); 995238405Sjkim 996238405Sjkim /* 997238405Sjkim * Set I/O address(A15-12) and cpu type 998238405Sjkim * 999238405Sjkim * AAAAIXXC(8bit) 1000238405Sjkim * AAAA: A15-A12, I: I/O enable, XX: reserved, C: CPU type 1001238405Sjkim * 1002238405Sjkim * CPU type is 1:80286 or higher, 0:not. 1003238405Sjkim * But FreeBSD runs under i386 or higher, thus it must be 1. 1004238405Sjkim */ 1005238405Sjkim tmp = (rman_get_start(sc->port_res) & 0xf000) >> 8; 1006160814Ssimon tmp |= (0x08 | 0x01); 1007160814Ssimon#ifdef ED_DEBUG 1008160814Ssimon printf("ed?: outb(%x, %x)\n", init_addr + 2, tmp); 1009238405Sjkim#endif 1010238405Sjkim outb(init_addr + 2, tmp); 1011238405Sjkim DELAY(5000); 1012237657Sjkim 1013237657Sjkim /* 1014237657Sjkim * This is needed because some NE clones apparently don't reset the 1015237657Sjkim * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1016237657Sjkim * - this makes the probe invasive! ...Done against my better 1017237657Sjkim * judgement. -DLG 1018237657Sjkim */ 1019237657Sjkim ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1020237657Sjkim DELAY(5000); 1021237657Sjkim} 1022160814Ssimon 1023160814Ssimonstatic void 1024160814Ssimoned_winsel_CNET98(sc, bank) 1025142425Snectar struct ed_softc *sc; 1026160814Ssimon u_short bank; 1027238405Sjkim{ 1028238405Sjkim u_char mem = (kvtop(sc->mem_start) >> 12) & 0xff; 1029238405Sjkim 1030238405Sjkim /* 1031238405Sjkim * Disable window memory 1032238405Sjkim * bit7 is 0:disable 1033238405Sjkim */ 1034238405Sjkim ed_asic_outb(sc, ED_CNET98_WIN_REG, mem & 0x7f); 1035238405Sjkim DELAY(10); 1036238405Sjkim 1037238405Sjkim /* 1038238405Sjkim * Select window address 1039238405Sjkim * FreeBSD address 0xf00xxxxx 1040160814Ssimon */ 1041142425Snectar ed_asic_outb(sc, ED_CNET98_MAP_REG0L, bank & 0xff); 1042160814Ssimon DELAY(10); 1043142425Snectar ed_asic_outb(sc, ED_CNET98_MAP_REG0H, (bank >> 8) & 0xff); 1044238405Sjkim DELAY(10); 1045238405Sjkim ed_asic_outb(sc, ED_CNET98_MAP_REG1L, 0x00); 1046238405Sjkim DELAY(10); 1047237657Sjkim ed_asic_outb(sc, ED_CNET98_MAP_REG1H, 0x41); 1048237657Sjkim DELAY(10); 1049237657Sjkim ed_asic_outb(sc, ED_CNET98_MAP_REG2L, 0x00); 1050237657Sjkim DELAY(10); 1051237657Sjkim ed_asic_outb(sc, ED_CNET98_MAP_REG2H, 0x42); 1052237657Sjkim DELAY(10); 1053237657Sjkim ed_asic_outb(sc, ED_CNET98_MAP_REG3L, 0x00); 1054237657Sjkim DELAY(10); 1055237657Sjkim ed_asic_outb(sc, ED_CNET98_MAP_REG3H, 0x43); 1056237657Sjkim DELAY(10); 1057 1058 /* 1059 * Enable window memory(16Kbyte) 1060 * bit7 is 1:enable 1061 */ 1062#ifdef ED_DEBUG 1063 printf("ed?: window start address=%x\n", mem); 1064#endif 1065 ed_asic_outb(sc, ED_CNET98_WIN_REG, mem); 1066 DELAY(10); 1067} 1068 1069/* 1070 * Probe and vendor-specific initialization routine for C-NET(98) boards 1071 */ 1072static int 1073ed_probe_CNET98(dev, port_rid, flags) 1074 device_t dev; 1075 int port_rid; 1076 int flags; 1077{ 1078 struct ed_softc *sc = device_get_softc(dev); 1079 int error; 1080 u_char tmp; 1081 u_long conf_irq, junk; 1082 int i; 1083#ifdef DIAGNOSTIC 1084 u_char tmp_s; 1085#endif 1086 1087 error = ed98_alloc_port(dev, port_rid); 1088 if (error) { 1089 return (error); 1090 } 1091 1092 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1093 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1094 1095 error = ed98_alloc_memory(dev, 0); 1096 if (error) { 1097 return (error); 1098 } 1099 1100 /* Check I/O address. 0x[a-f]3d0 are allowed. */ 1101 if (((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) 1102 || ((rman_get_start(sc->port_res) & 0xf000) < (u_short) 0xa000)) { 1103#ifdef DIAGNOSTIC 1104 device_printf(dev, "Invalid i/o port configuration (0x%x) " 1105 "must be %s for %s\n", rman_get_start(sc->port_res), 1106 "0x[a-f]3d0", "CNET98"); 1107#endif 1108 return (ENXIO); 1109 } 1110 1111#ifdef DIAGNOSTIC 1112 /* Check window area address */ 1113 tmp_s = kvtop(sc->mem_start) >> 12; 1114 if (tmp_s < 0x80) { 1115 device_printf(dev, "Please change window address(0x%x)\n", 1116 kvtop(sc->mem_start)); 1117 return (ENXIO); 1118 } 1119 1120 tmp_s &= 0x0f; 1121 tmp = rman_get_start(sc->port_res) >> 12; 1122 if ((tmp_s <= tmp) && (tmp < (tmp_s + 4))) { 1123 device_printf(dev, "Please change iobase address(0x%x) " 1124 "or window address(0x%x)\n", 1125 rman_get_start(sc->port_res), kvtop(sc->mem_start)); 1126 return (ENXIO); 1127 } 1128#endif 1129 /* Reset the board */ 1130 ed_reset_CNET98(sc, flags); 1131 1132 /* 1133 * This is needed because some NE clones apparently don't reset the 1134 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1135 * - this makes the probe invasive! ...Done against my better 1136 * judgement. -DLG 1137 */ 1138 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1139 DELAY(5000); 1140 1141 /* Make sure that we really have an 8390 based board */ 1142 if (!ed98_probe_generic8390(sc)) { 1143 return (ENXIO); 1144 } 1145 1146 /* 1147 * Set window ethernet address area 1148 * board memory base 0x480000 data 256byte 1149 */ 1150 ed_winsel_CNET98(sc, 0x4800); 1151 1152 /* 1153 * Get station address from on-board ROM 1154 */ 1155 bcopy(sc->mem_start, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN); 1156 1157 sc->vendor = ED_VENDOR_MISC; 1158 sc->type_str = "CNET98"; 1159 sc->isa16bit = 0; 1160 sc->cr_proto = ED_CR_RD2; 1161 1162 /* 1163 * Set window buffer memory area 1164 * board memory base 0x400000 data 16kbyte 1165 */ 1166 ed_winsel_CNET98(sc, 0x4000); 1167 1168 /* 1169 * clear interface memory, then sum to make sure its valid 1170 */ 1171 bzero(sc->mem_start, sc->mem_size); 1172 1173 for (i = 0; i < sc->mem_size; i++) { 1174 if (sc->mem_start[i]) { 1175 device_printf(dev, "failed to clear shared memory " 1176 "at %lx - check configuration\n", 1177 kvtop(sc->mem_start + i)); 1178 1179 return (ENXIO); 1180 } 1181 } 1182 1183 sc->mem_shared = 1; 1184 sc->mem_end = sc->mem_start + sc->mem_size; 1185 1186 sc->txb_cnt = 1; /* XXX */ 1187 sc->tx_page_start = 0; 1188 1189 sc->rec_page_start = sc->tx_page_start + ED_TXBUF_SIZE; 1190 sc->rec_page_stop = sc->tx_page_start + sc->mem_size / ED_PAGE_SIZE; 1191 1192 sc->mem_ring = sc->mem_start + ED_PAGE_SIZE * ED_TXBUF_SIZE; 1193 1194 /* 1195 * Set interrupt level 1196 */ 1197 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1198 &conf_irq, &junk); 1199 if (error) 1200 return (error); 1201 1202 switch (conf_irq) { 1203 case 3: 1204 tmp = ED_CNET98_INT_IRQ3; 1205 break; 1206 case 5: 1207 tmp = ED_CNET98_INT_IRQ5; 1208 break; 1209 case 6: 1210 tmp = ED_CNET98_INT_IRQ6; 1211 break; 1212 case 9: 1213 tmp = ED_CNET98_INT_IRQ9; 1214 break; 1215 case 12: 1216 tmp = ED_CNET98_INT_IRQ12; 1217 break; 1218 case 13: 1219 tmp = ED_CNET98_INT_IRQ13; 1220 break; 1221 default: 1222 device_printf(dev, "Invalid irq configuration (%ld) must be " 1223 "%s for %s\n", conf_irq, "3,5,6,9,12,13", "CNET98"); 1224 return (ENXIO); 1225 } 1226 ed_asic_outb(sc, ED_CNET98_INT_LEV, tmp); 1227 DELAY(1000); 1228 /* 1229 * Set interrupt mask. 1230 * bit7:1 all interrupt mask 1231 * bit1:1 timer interrupt mask 1232 * bit0:0 NS controler interrupt enable 1233 */ 1234 ed_asic_outb(sc, ED_CNET98_INT_MASK, 0x7e); 1235 DELAY(1000); 1236 1237 return (0); 1238} 1239 1240/* 1241 * Probe and vendor-specific initialization routine for C-NET(98)E/L boards 1242 */ 1243static int 1244ed_probe_CNET98EL(dev, port_rid, flags) 1245 device_t dev; 1246 int port_rid; 1247 int flags; 1248{ 1249 struct ed_softc *sc = device_get_softc(dev); 1250 int error; 1251 int i; 1252 u_char romdata[ETHER_ADDR_LEN * 2], tmp; 1253 u_long conf_irq, junk; 1254 1255 error = ed98_alloc_port(dev, port_rid); 1256 if (error) { 1257 return (error); 1258 } 1259 1260 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1261 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1262 1263 /* Check I/O address. 0x[0-f]3d0 are allowed. */ 1264 if ((rman_get_start(sc->port_res) & 0x0fff) != 0x03d0) { 1265#ifdef DIAGNOSTIC 1266 device_printf(dev, "Invalid i/o port configuration (0x%x) " 1267 "must be %s for %s\n", rman_get_start(sc->port_res), 1268 "0x?3d0", "CNET98E/L"); 1269#endif 1270 return (ENXIO); 1271 } 1272 1273 /* Reset the board */ 1274 ed_reset_CNET98(sc, flags); 1275 1276 /* 1277 * This is needed because some NE clones apparently don't reset the 1278 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1279 * - this makes the probe invasive! ...Done against my better 1280 * judgement. -DLG 1281 */ 1282 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1283 DELAY(5000); 1284 1285 /* Make sure that we really have an 8390 based board */ 1286 if (!ed98_probe_generic8390(sc)) { 1287 return (ENXIO); 1288 } 1289 1290 /* Test memory via PIO */ 1291 sc->cr_proto = ED_CR_RD2; 1292 if (!ed_pio_testmem(sc, ED_CNET98EL_PAGE_OFFSET, 1, flags)) { 1293 return (ENXIO); 1294 } 1295 1296 /* This looks like a C-NET(98)E/L board. */ 1297 sc->type_str = "CNET98E/L"; 1298 1299 /* 1300 * Set IRQ. C-NET(98)E/L only allows a choice of irq 3,5,6. 1301 */ 1302 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1303 &conf_irq, &junk); 1304 if (error) { 1305 return (error); 1306 } 1307 1308 switch (conf_irq) { 1309 case 3: 1310 tmp = ED_CNET98EL_ICR_IRQ3; 1311 break; 1312 case 5: 1313 tmp = ED_CNET98EL_ICR_IRQ5; 1314 break; 1315 case 6: 1316 tmp = ED_CNET98EL_ICR_IRQ6; 1317 break; 1318#if 0 1319 case 12: 1320 tmp = ED_CNET98EL_ICR_IRQ12; 1321 break; 1322#endif 1323 default: 1324 device_printf(dev, "Invalid irq configuration (%ld) must be " 1325 "%s for %s\n", conf_irq, "3,5,6", "CNET98E/L"); 1326 return (ENXIO); 1327 } 1328 ed_asic_outb(sc, ED_CNET98EL_ICR, tmp); 1329 ed_asic_outb(sc, ED_CNET98EL_IMR, 0x7e); 1330 1331 /* Get station address from on-board ROM */ 1332 ed_pio_readmem(sc, 16384, romdata, sizeof(romdata)); 1333 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1334 sc->arpcom.ac_enaddr[i] = romdata[i * 2]; 1335 } 1336 1337 /* clear any pending interrupts that might have occurred above */ 1338 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1339 1340 return (0); 1341} 1342 1343/* 1344 * Probe and vendor-specific initialization routine for PC-9801-77 boards 1345 */ 1346static int 1347ed_probe_NEC77(dev, port_rid, flags) 1348 device_t dev; 1349 int port_rid; 1350 int flags; 1351{ 1352 struct ed_softc *sc = device_get_softc(dev); 1353 int error; 1354 u_char tmp; 1355 u_long conf_irq, junk; 1356 1357 error = ed98_probe_Novell(dev, port_rid, flags); 1358 if (error) { 1359 return (error); 1360 } 1361 1362 /* LA/T-98 does not need IRQ setting. */ 1363 if (ED_TYPE98SUB(flags) == 0) { 1364 return (0); 1365 } 1366 1367 /* 1368 * Set IRQ. PC-9801-77 only allows a choice of irq 3,5,6,12,13. 1369 */ 1370 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1371 &conf_irq, &junk); 1372 if (error) { 1373 return (error); 1374 } 1375 1376 switch (conf_irq) { 1377 case 3: 1378 tmp = ED_NEC77_IRQ3; 1379 break; 1380 case 5: 1381 tmp = ED_NEC77_IRQ5; 1382 break; 1383 case 6: 1384 tmp = ED_NEC77_IRQ6; 1385 break; 1386 case 12: 1387 tmp = ED_NEC77_IRQ12; 1388 break; 1389 case 13: 1390 tmp = ED_NEC77_IRQ13; 1391 break; 1392 default: 1393 device_printf(dev, "Invalid irq configuration (%ld) must be " 1394 "%s for %s\n", conf_irq, "3,5,6,12,13", "PC-9801-77"); 1395 return (ENXIO); 1396 } 1397 ed_asic_outb(sc, ED_NEC77_IRQ, tmp); 1398 1399 return (0); 1400} 1401 1402/* 1403 * Probe and vendor-specific initialization routine for EC/EP-98X boards 1404 */ 1405static int 1406ed_probe_NW98X(dev, port_rid, flags) 1407 device_t dev; 1408 int port_rid; 1409 int flags; 1410{ 1411 struct ed_softc *sc = device_get_softc(dev); 1412 int error; 1413 u_char tmp; 1414 u_long conf_irq, junk; 1415 1416 error = ed98_probe_Novell(dev, port_rid, flags); 1417 if (error) { 1418 return (error); 1419 } 1420 1421 /* Networld 98X3 does not need IRQ setting. */ 1422 if (ED_TYPE98SUB(flags) == 0) { 1423 return (0); 1424 } 1425 1426 /* 1427 * Set IRQ. EC/EP-98X only allows a choice of irq 3,5,6,12,13. 1428 */ 1429 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1430 &conf_irq, &junk); 1431 if (error) { 1432 return (error); 1433 } 1434 1435 switch (conf_irq) { 1436 case 3: 1437 tmp = ED_NW98X_IRQ3; 1438 break; 1439 case 5: 1440 tmp = ED_NW98X_IRQ5; 1441 break; 1442 case 6: 1443 tmp = ED_NW98X_IRQ6; 1444 break; 1445 case 12: 1446 tmp = ED_NW98X_IRQ12; 1447 break; 1448 case 13: 1449 tmp = ED_NW98X_IRQ13; 1450 break; 1451 default: 1452 device_printf(dev, "Invalid irq configuration (%ld) must be " 1453 "%s for %s\n", conf_irq, "3,5,6,12,13", "EC/EP-98X"); 1454 return (ENXIO); 1455 } 1456 ed_asic_outb(sc, ED_NW98X_IRQ, tmp); 1457 1458 return (0); 1459} 1460 1461/* 1462 * Read SB-9801 station address from Serial Two-Wire EEPROM 1463 */ 1464static void 1465ed_get_SB98(sc) 1466 struct ed_softc *sc; 1467{ 1468 int i, j; 1469 u_char mask, val; 1470 1471 /* enable EEPROM acceess */ 1472 ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_ENABLE); 1473 1474 /* output start command */ 1475 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1476 DELAY(ED_SB98_EEP_DELAY); 1477 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1478 DELAY(ED_SB98_EEP_DELAY); 1479 1480 /* output address (7bit) */ 1481 for (mask = 0x40; mask != 0; mask >>= 1) { 1482 val = 0; 1483 if (ED_SB98_ADDRESS & mask) 1484 val = ED_SB98_EEP_SDA; 1485 ed_asic_outb(sc, ED_SB98_EEP, val); 1486 DELAY(ED_SB98_EEP_DELAY); 1487 ed_asic_outb(sc, ED_SB98_EEP, val | ED_SB98_EEP_SCL); 1488 DELAY(ED_SB98_EEP_DELAY); 1489 } 1490 1491 /* output READ command */ 1492 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ); 1493 DELAY(ED_SB98_EEP_DELAY); 1494 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_READ | ED_SB98_EEP_SCL); 1495 DELAY(ED_SB98_EEP_DELAY); 1496 1497 /* read station address */ 1498 for (i = 0; i < ETHER_ADDR_LEN; i++) { 1499 /* output ACK */ 1500 ed_asic_outb(sc, ED_SB98_EEP, 0); 1501 DELAY(ED_SB98_EEP_DELAY); 1502 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1503 DELAY(ED_SB98_EEP_DELAY); 1504 1505 val = 0; 1506 for (j = 0; j < 8; j++) { 1507 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA); 1508 DELAY(ED_SB98_EEP_DELAY); 1509 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1510 DELAY(ED_SB98_EEP_DELAY); 1511 val <<= 1; 1512 val |= (ed_asic_inb(sc, ED_SB98_EEP) & ED_SB98_EEP_SDA); 1513 DELAY(ED_SB98_EEP_DELAY); 1514 } 1515 sc->arpcom.ac_enaddr[i] = val; 1516 } 1517 1518 /* output Last ACK */ 1519 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA); 1520 DELAY(ED_SB98_EEP_DELAY); 1521 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1522 DELAY(ED_SB98_EEP_DELAY); 1523 1524 /* output stop command */ 1525 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SCL); 1526 DELAY(ED_SB98_EEP_DELAY); 1527 ed_asic_outb(sc, ED_SB98_EEP, ED_SB98_EEP_SDA | ED_SB98_EEP_SCL); 1528 DELAY(ED_SB98_EEP_DELAY); 1529 1530 /* disable EEPROM access */ 1531 ed_asic_outb(sc, ED_SB98_EEPENA, ED_SB98_EEPENA_DISABLE); 1532} 1533 1534/* 1535 * Probe and vendor-specific initialization routine for SB-9801 boards 1536 */ 1537static int 1538ed_probe_SB98(dev, port_rid, flags) 1539 device_t dev; 1540 int port_rid; 1541 int flags; 1542{ 1543 struct ed_softc *sc = device_get_softc(dev); 1544 int error; 1545 u_char tmp; 1546 u_long conf_irq, junk; 1547 1548 error = ed98_alloc_port(dev, port_rid); 1549 if (error) { 1550 return (error); 1551 } 1552 1553 sc->asic_offset = ED_NOVELL_ASIC_OFFSET; 1554 sc->nic_offset = ED_NOVELL_NIC_OFFSET; 1555 1556 /* Check I/O address. 00d[02468ace] are allowed. */ 1557 if ((rman_get_start(sc->port_res) & ~0x000e) != 0x00d0) { 1558#ifdef DIAGNOSTIC 1559 device_printf(dev, "Invalid i/o port configuration (0x%x) " 1560 "must be %s for %s\n", rman_get_start(sc->port_res), 1561 "0xd?", "SB9801"); 1562#endif 1563 return (ENXIO); 1564 } 1565 1566 /* Write I/O port address and read 4 times */ 1567 outb(ED_SB98_IO_INHIBIT, rman_get_start(sc->port_res) & 0xff); 1568 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1569 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1570 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1571 (void) inb(ED_SB98_IO_INHIBIT); DELAY(300); 1572 1573 /* 1574 * Check IRQ. Soliton SB-9801 only allows a choice of 1575 * irq 3,5,6,12 1576 */ 1577 error = bus_get_resource(dev, SYS_RES_IRQ, 0, 1578 &conf_irq, &junk); 1579 if (error) { 1580 return (error); 1581 } 1582 1583 switch (conf_irq) { 1584 case 3: 1585 tmp = ED_SB98_CFG_IRQ3; 1586 break; 1587 case 5: 1588 tmp = ED_SB98_CFG_IRQ5; 1589 break; 1590 case 6: 1591 tmp = ED_SB98_CFG_IRQ6; 1592 break; 1593 case 12: 1594 tmp = ED_SB98_CFG_IRQ12; 1595 break; 1596 default: 1597 device_printf(dev, "Invalid irq configuration (%ld) must be " 1598 "%s for %s\n", conf_irq, "3,5,6,12", "SB9801"); 1599 return (ENXIO); 1600 } 1601 1602 if (flags & ED_FLAGS_DISABLE_TRANCEIVER) { 1603 tmp |= ED_SB98_CFG_ALTPORT; 1604 } 1605 ed_asic_outb(sc, ED_SB98_CFG, ED_SB98_CFG_ENABLE | tmp); 1606 ed_asic_outb(sc, ED_SB98_POLARITY, 0x01); 1607 1608 /* Reset the board. */ 1609 ed_asic_outb(sc, ED_NOVELL_RESET, 0x7a); 1610 DELAY(300); 1611 ed_asic_outb(sc, ED_NOVELL_RESET, 0x79); 1612 DELAY(300); 1613 1614 /* 1615 * This is needed because some NE clones apparently don't reset the 1616 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX 1617 * - this makes the probe invasive! ...Done against my better 1618 * judgement. -DLG 1619 */ 1620 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1621 DELAY(5000); 1622 1623 /* Make sure that we really have an 8390 based board */ 1624 if (!ed98_probe_generic8390(sc)) { 1625 return (ENXIO); 1626 } 1627 1628 /* Test memory via PIO */ 1629 sc->cr_proto = ED_CR_RD2; 1630 if (!ed_pio_testmem(sc, 16384, 1, flags)) { 1631 return (ENXIO); 1632 } 1633 1634 /* This looks like an SB9801 board. */ 1635 sc->type_str = "SB9801"; 1636 1637 /* Get station address */ 1638 ed_get_SB98(sc); 1639 1640 /* clear any pending interrupts that might have occurred above */ 1641 ed_nic_outb(sc, ED_P0_ISR, 0xff); 1642 1643 return (0); 1644} 1645 1646/* 1647 * Test the ability to read and write to the NIC memory. 1648 */ 1649static int 1650ed_pio_testmem(sc, page_offset, isa16bit, flags) 1651 struct ed_softc *sc; 1652 int page_offset; 1653 int isa16bit; 1654 int flags; 1655{ 1656 u_long memsize; 1657 static char test_pattern[32] = "THIS is A memory TEST pattern"; 1658 char test_buffer[32]; 1659#ifdef DIAGNOSTIC 1660 int page_end; 1661#endif 1662 1663 sc->vendor = ED_VENDOR_NOVELL; 1664 sc->mem_shared = 0; 1665 sc->isa16bit = isa16bit; 1666 1667 /* 8k of memory plus an additional 8k if 16bit */ 1668 memsize = (isa16bit ? 16384 : 8192); 1669 1670 /* 1671 * This prevents packets from being stored in the NIC memory when the 1672 * readmem routine turns on the start bit in the CR. 1673 */ 1674 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON); 1675 1676 /* Initialize DCR for byte/word operations */ 1677 if (isa16bit) { 1678 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); 1679 } else { 1680 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); 1681 } 1682 ed_nic_outb(sc, ED_P0_PSTART, page_offset / ED_PAGE_SIZE); 1683 ed_nic_outb(sc, ED_P0_PSTOP, (page_offset + memsize) / ED_PAGE_SIZE); 1684#ifdef ED_DEBUG 1685 printf("ed?: ed_pio_testmem: page start=%x, end=%x", 1686 page_offset, page_offset + memsize); 1687#endif 1688 1689 /* 1690 * Write a test pattern. If this fails, then we don't know 1691 * what this board is. 1692 */ 1693 ed_pio_writemem(sc, test_pattern, page_offset, sizeof(test_pattern)); 1694 ed_pio_readmem(sc, page_offset, test_buffer, sizeof(test_pattern)); 1695 1696 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) { 1697#ifdef ED_DEBUG 1698 printf("ed?: ed_pio_testmem: bcmp(page %x) NG", 1699 page_offset); 1700#endif 1701 return (0); 1702 } 1703 1704#ifdef DIAGNOSTIC 1705 /* Check the bottom. */ 1706 page_end = page_offset + memsize - ED_PAGE_SIZE; 1707 ed_pio_writemem(sc, test_pattern, page_end, sizeof(test_pattern)); 1708 ed_pio_readmem(sc, page_end, test_buffer, sizeof(test_pattern)); 1709 1710 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) { 1711#ifdef ED_DEBUG 1712 printf("ed?: ed_pio_testmem: bcmp(page %x) NG", 1713 page_end); 1714#endif 1715 return (0); 1716 } 1717#endif 1718 sc->mem_size = memsize; 1719 sc->mem_start = (char *) page_offset; 1720 sc->mem_end = sc->mem_start + memsize; 1721 sc->tx_page_start = page_offset / ED_PAGE_SIZE; 1722 1723 /* 1724 * Use one xmit buffer if < 16k, two buffers otherwise (if not told 1725 * otherwise). 1726 */ 1727 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { 1728 sc->txb_cnt = 1; 1729 } else { 1730 sc->txb_cnt = 2; 1731 } 1732 1733 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; 1734 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE; 1735 1736 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE; 1737 1738 return (1); 1739} 1740#endif /* PC98 */ 1741 1742static device_method_t ed_isa_methods[] = { 1743 /* Device interface */ 1744 DEVMETHOD(device_probe, ed_isa_probe), 1745 DEVMETHOD(device_attach, ed_isa_attach), 1746 1747 { 0, 0 } 1748}; 1749 1750static driver_t ed_isa_driver = { 1751 "ed", 1752 ed_isa_methods, 1753 sizeof(struct ed_softc) 1754}; 1755 1756DRIVER_MODULE(if_ed, isa, ed_isa_driver, ed_devclass, 0, 0); 1757