The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ed/if_ed_cbus.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 5a57923869a6d4c2bac6ec0c286b8c54


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.