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/fe/if_fe_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  * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
    3  *
    4  * This software may be used, modified, copied, distributed, and sold, in
    5  * both source and binary form provided that the above copyright, these
    6  * terms and the following disclaimer are retained.  The name of the author
    7  * and/or the contributor may not be used to endorse or promote products
    8  * derived from this software without specific prior written permission.
    9  *
   10  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
   11  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   12  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   13  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
   14  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   15  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   16  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
   17  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   18  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   19  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   20  * SUCH DAMAGE.
   21  *
   22  */
   23 
   24 #include <sys/cdefs.h>
   25 __FBSDID("$FreeBSD$");
   26 
   27 #include <sys/param.h>
   28 #include <sys/systm.h>
   29 #include <sys/kernel.h>
   30 #include <sys/socket.h>
   31 #include <sys/module.h>
   32 
   33 #include <sys/bus.h>
   34 #include <machine/bus.h>
   35 #include <sys/rman.h>
   36 #include <machine/resource.h>
   37 
   38 #include <net/ethernet.h>
   39 #include <net/if.h>
   40 #include <net/if_mib.h>
   41 #include <net/if_media.h>
   42 
   43 #include <netinet/in.h>
   44 #include <netinet/if_ether.h>
   45 
   46 #include <i386/isa/ic/mb86960.h>
   47 #include <dev/fe/if_fereg.h>
   48 #include <dev/fe/if_fevar.h>
   49 
   50 #include <isa/isavar.h>
   51 
   52 /*
   53  *      Cbus specific code.
   54  */
   55 static int fe_isa_probe(device_t);
   56 static int fe_isa_attach(device_t);
   57 
   58 static struct isa_pnp_id fe_ids[] = {
   59         { 0x101ee0d,    NULL },         /* CON0101 - Contec C-NET(98)P2-T */
   60         { 0,            NULL }
   61 };
   62 
   63 static device_method_t fe_isa_methods[] = {
   64         /* Device interface */
   65         DEVMETHOD(device_probe,         fe_isa_probe),
   66         DEVMETHOD(device_attach,        fe_isa_attach),
   67 
   68         { 0, 0 }
   69 };
   70 
   71 static driver_t fe_isa_driver = {
   72         "fe",
   73         fe_isa_methods,
   74         sizeof (struct fe_softc)
   75 };
   76 
   77 DRIVER_MODULE(fe, isa, fe_isa_driver, fe_devclass, 0, 0);
   78 
   79 
   80 static int fe98_alloc_port(device_t, int);
   81 
   82 static int fe_probe_re1000(device_t);
   83 static int fe_probe_cnet9ne(device_t);
   84 static int fe_probe_rex(device_t);
   85 static int fe_probe_ssi(device_t);
   86 static int fe_probe_jli(device_t);
   87 static int fe_probe_lnx(device_t);
   88 static int fe_probe_gwy(device_t);
   89 static int fe_probe_ubn(device_t);
   90 
   91 /*
   92  * Determine if the device is present at a specified I/O address.  The
   93  * main entry to the driver.
   94  */
   95 static int
   96 fe_isa_probe(device_t dev)
   97 {
   98         struct fe_softc *sc;
   99         int error;
  100 
  101         /* Prepare for the softc struct.  */
  102         sc = device_get_softc(dev);
  103         sc->sc_unit = device_get_unit(dev);
  104 
  105         /* Check isapnp ids */
  106         error = ISA_PNP_PROBE(device_get_parent(dev), dev, fe_ids);
  107 
  108         /* If the card had a PnP ID that didn't match any we know about */
  109         if (error == ENXIO)
  110                 goto end;
  111 
  112         /* If we had some other problem. */
  113         if (!(error == 0 || error == ENOENT))
  114                 goto end;
  115 
  116         /* Probe for supported boards.  */
  117         if ((error = fe_probe_re1000(dev)) == 0)
  118                 goto end;
  119         fe_release_resource(dev);
  120 
  121         if ((error = fe_probe_cnet9ne(dev)) == 0)
  122                 goto end;
  123         fe_release_resource(dev);
  124 
  125         if ((error = fe_probe_rex(dev)) == 0)
  126                 goto end;
  127         fe_release_resource(dev);
  128 
  129         if ((error = fe_probe_ssi(dev)) == 0)
  130                 goto end;
  131         fe_release_resource(dev);
  132 
  133         if ((error = fe_probe_jli(dev)) == 0)
  134                 goto end;
  135         fe_release_resource(dev);
  136 
  137         if ((error = fe_probe_lnx(dev)) == 0)
  138                 goto end;
  139         fe_release_resource(dev);
  140 
  141         if ((error = fe_probe_ubn(dev)) == 0)
  142                 goto end;
  143         fe_release_resource(dev);
  144 
  145         if ((error = fe_probe_gwy(dev)) == 0)
  146                 goto end;
  147         fe_release_resource(dev);
  148 
  149 end:
  150         if (error == 0)
  151                 error = fe_alloc_irq(dev, 0);
  152 
  153         fe_release_resource(dev);
  154         return (error);
  155 }
  156 
  157 static int
  158 fe_isa_attach(device_t dev)
  159 {
  160         struct fe_softc *sc = device_get_softc(dev);
  161 
  162         if (sc->port_used)
  163                 fe98_alloc_port(dev, sc->type);
  164         fe_alloc_irq(dev, 0);
  165 
  166         return fe_attach(dev);
  167 }
  168 
  169 
  170 /* Generic I/O address table */
  171 static bus_addr_t ioaddr_generic[MAXREGISTERS] = {
  172         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
  173         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
  174         0x010, 0x011, 0x012, 0x013, 0x014, 0x015, 0x016, 0x017,
  175         0x018, 0x019, 0x01a, 0x01b, 0x01c, 0x01d, 0x01e, 0x01f,
  176 };
  177 
  178 /* I/O address table for RE1000/1000Plus */
  179 static bus_addr_t ioaddr_re1000[MAXREGISTERS] = {
  180         0x0000, 0x0001, 0x0200, 0x0201, 0x0400, 0x0401, 0x0600, 0x0601,
  181         0x0800, 0x0801, 0x0a00, 0x0a01, 0x0c00, 0x0c01, 0x0e00, 0x0e01,
  182         0x1000, 0x1200, 0x1400, 0x1600, 0x1800, 0x1a00, 0x1c00, 0x1e00,
  183         0x1001, 0x1201, 0x1401, 0x1601, 0x1801, 0x1a01, 0x1c01, 0x1e01,
  184 };
  185 
  186 /* I/O address table for CNET9NE */
  187 static bus_addr_t ioaddr_cnet9ne[MAXREGISTERS] = {
  188         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
  189         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
  190         0x400, 0x402, 0x404, 0x406, 0x408, 0x40a, 0x40c, 0x40e,
  191         0x401, 0x403, 0x405, 0x407, 0x409, 0x40b, 0x40d, 0x40f,
  192 };
  193 
  194 /* I/O address table for LAC-98 */
  195 static bus_addr_t ioaddr_lnx[MAXREGISTERS] = {
  196         0x000, 0x002, 0x004, 0x006, 0x008, 0x00a, 0x00c, 0x00e,
  197         0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e,
  198         0x200, 0x202, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x20e,
  199         0x300, 0x302, 0x304, 0x306, 0x308, 0x30a, 0x30c, 0x30e,
  200 };
  201 
  202 /* I/O address table for Access/PC N98C+ */
  203 static bus_addr_t ioaddr_ubn[MAXREGISTERS] = {
  204         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
  205         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
  206         0x200, 0x201, 0x202, 0x203, 0x204, 0x205, 0x206, 0x207,
  207         0x208, 0x209, 0x20a, 0x20b, 0x20c, 0x20d, 0x20e, 0x20f,
  208 };
  209 
  210 /* I/O address table for REX-9880 */
  211 static bus_addr_t ioaddr_rex[MAXREGISTERS] = {
  212         0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007,
  213         0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f,
  214         0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107,
  215         0x108, 0x109, 0x10a, 0x10b, 0x10c, 0x10d, 0x10e, 0x10f,
  216 };
  217 
  218 static int
  219 fe98_alloc_port(device_t dev, int type)
  220 {
  221         struct fe_softc *sc = device_get_softc(dev);
  222         struct resource *res;
  223         bus_addr_t *iat;
  224         int size, rid;
  225 
  226         switch (type) {
  227         case FE_TYPE_RE1000:
  228                 iat = ioaddr_re1000;
  229                 size = MAXREGISTERS;
  230                 break;
  231         case FE_TYPE_CNET9NE:
  232                 iat = ioaddr_cnet9ne;
  233                 size = MAXREGISTERS;
  234                 break;
  235         case FE_TYPE_SSI:
  236                 iat = ioaddr_generic;
  237                 size = MAXREGISTERS;
  238                 break;
  239         case FE_TYPE_LNX:
  240                 iat = ioaddr_lnx;
  241                 size = MAXREGISTERS;
  242                 break;
  243         case FE_TYPE_GWY:
  244                 iat = ioaddr_generic;
  245                 size = MAXREGISTERS;
  246                 break;
  247         case FE_TYPE_UBN:
  248                 iat = ioaddr_ubn;
  249                 size = MAXREGISTERS;
  250                 break;
  251         case FE_TYPE_REX:
  252                 iat = ioaddr_rex;
  253                 size = MAXREGISTERS;
  254                 break;
  255         default:
  256                 iat = ioaddr_generic;
  257                 size = MAXREGISTERS;
  258                 break;
  259         }
  260 
  261         rid = 0;
  262         res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid,
  263                                   iat, size, RF_ACTIVE);
  264         if (res == NULL)
  265                 return ENOENT;
  266 
  267         isa_load_resourcev(res, iat, size);
  268 
  269         sc->type = type;
  270         sc->port_used = size;
  271         sc->port_res = res;
  272         sc->iot = rman_get_bustag(res);
  273         sc->ioh = rman_get_bushandle(res);
  274         return (0);
  275 }
  276 
  277 
  278 /*
  279  * Probe and initialization for Allied-Telesis RE1000 series.
  280  */
  281 static void
  282 fe_init_re1000(struct fe_softc *sc)
  283 {
  284         /* Setup IRQ control register on the ASIC.  */
  285         fe_outb(sc, FE_RE1000_IRQCONF, sc->priv_info);
  286 }
  287 
  288 static int
  289 fe_probe_re1000(device_t dev)
  290 {
  291         struct fe_softc *sc = device_get_softc(dev);
  292         int i, n;
  293         u_long iobase, irq;
  294         u_char sum;
  295 
  296         static struct fe_simple_probe_struct probe_table [] = {
  297                 { FE_DLCR2, 0x58, 0x00 },
  298                 { FE_DLCR4, 0x08, 0x00 },
  299                 { 0 }
  300         };
  301 
  302         /* See if the specified I/O address is possible for RE1000.  */
  303         /* [01]D[02468ACE] are allowed.  */ 
  304         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  305                 return ENXIO;
  306         if ((iobase & ~0x10E) != 0xD0)
  307                 return ENXIO;
  308 
  309         if (fe98_alloc_port(dev, FE_TYPE_RE1000))
  310                 return ENXIO;
  311 
  312         /* Fill the softc struct with default values.  */
  313         fe_softc_defaults(sc);
  314 
  315         /* See if the card is on its address.  */
  316         if (!fe_simple_probe(sc, probe_table))
  317                 return ENXIO;
  318 
  319         /* Get our station address from EEPROM.  */
  320         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
  321 
  322         /* Make sure it is Allied-Telesis's.  */
  323         if (!fe_valid_Ether_p(sc->sc_enaddr, 0x0000F4))
  324                 return ENXIO;
  325 #if 1
  326         /* Calculate checksum.  */
  327         sum = fe_inb(sc, 0x1e);
  328         for (i = 0; i < ETHER_ADDR_LEN; i++)
  329                 sum ^= sc->sc_enaddr[i];
  330         if (sum != 0)
  331                 return ENXIO;
  332 #endif
  333         /* Setup the board type.  */
  334         sc->typestr = "RE1000";
  335 
  336         /* This looks like an RE1000 board.  It requires an
  337            explicit IRQ setting in config.  Make sure we have one,
  338            determining an appropriate value for the IRQ control
  339            register.  */
  340         irq = 0;
  341         bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
  342         switch (irq) {
  343         case 3:  n = 0x10; break;
  344         case 5:  n = 0x20; break;
  345         case 6:  n = 0x40; break;
  346         case 12: n = 0x80; break;
  347         default:
  348                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
  349                 return ENXIO;
  350         }
  351         sc->priv_info = (fe_inb(sc, FE_RE1000_IRQCONF) & 0x0f) | n;
  352 
  353         /* Setup hooks.  We need a special initialization procedure.  */
  354         sc->init = fe_init_re1000;
  355 
  356         return 0;
  357 }
  358 
  359 /* JLI sub-probe for Allied-Telesis RE1000Plus/ME1500 series.  */
  360 static u_short const *
  361 fe_probe_jli_re1000p(struct fe_softc * sc, u_char const * eeprom)
  362 {
  363         int i;
  364         static u_short const irqmaps_re1000p [4] = { 3, 5, 6, 12 };
  365 
  366         /* Make sure the EEPROM contains Allied-Telesis bit pattern.  */
  367         if (eeprom[1] != 0xFF) return NULL;
  368         for (i =  2; i <  8; i++) if (eeprom[i] != 0xFF) return NULL;
  369         for (i = 14; i < 24; i++) if (eeprom[i] != 0xFF) return NULL;
  370 
  371         /* Get our station address from EEPROM, and make sure the
  372            EEPROM contains Allied-Telesis's address.  */
  373         bcopy(eeprom + 8, sc->sc_enaddr, ETHER_ADDR_LEN);
  374         if (!fe_valid_Ether_p(sc->sc_enaddr, 0x0000F4))
  375                 return NULL;
  376 
  377         /* I don't know any sub-model identification.  */
  378         sc->typestr = "RE1000Plus/ME1500";
  379 
  380         /* Returns the IRQ table for the RE1000Plus.  */
  381         return irqmaps_re1000p;
  382 }
  383 
  384 
  385 /*
  386  * Probe for Allied-Telesis RE1000Plus/ME1500 series.
  387  */
  388 static int
  389 fe_probe_jli(device_t dev)
  390 {
  391         struct fe_softc *sc = device_get_softc(dev);
  392         int i, n, xirq, error;
  393         u_long iobase, irq;
  394         u_char eeprom [JLI_EEPROM_SIZE];
  395         u_short const * irqmap;
  396 
  397         static u_short const baseaddr [8] =
  398                 { 0x1D6, 0x1D8, 0x1DA, 0x1D4, 0x0D4, 0x0D2, 0x0D8, 0x0D0 };
  399         static struct fe_simple_probe_struct const probe_table [] = {
  400         /*      { FE_DLCR1,  0x20, 0x00 },      Doesn't work. */
  401                 { FE_DLCR2,  0x50, 0x00 },
  402                 { FE_DLCR4,  0x08, 0x00 },
  403         /*      { FE_DLCR5,  0x80, 0x00 },      Doesn't work. */
  404 #if 0
  405                 { FE_BMPR16, 0x1B, 0x00 },
  406                 { FE_BMPR17, 0x7F, 0x00 },
  407 #endif
  408                 { 0 }
  409         };
  410 
  411         /*
  412          * See if the specified address is possible for MB86965A JLI mode.
  413          */
  414         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  415                 return ENXIO;
  416         for (i = 0; i < 8; i++) {
  417                 if (baseaddr[i] == iobase)
  418                         break;
  419         }
  420         if (i == 8)
  421                 return ENXIO;
  422 
  423         if (fe98_alloc_port(dev, FE_TYPE_RE1000))
  424                 return ENXIO;
  425 
  426         /* Fill the softc struct with default values.  */
  427         fe_softc_defaults(sc);
  428 
  429         /*
  430          * We should test if MB86965A is on the base address now.
  431          * Unfortunately, it is very hard to probe it reliably, since
  432          * we have no way to reset the chip under software control.
  433          * On cold boot, we could check the "signature" bit patterns
  434          * described in the Fujitsu document.  On warm boot, however,
  435          * we can predict almost nothing about register values.
  436          */
  437         if (!fe_simple_probe(sc, probe_table))
  438                 return ENXIO;
  439 
  440         /* Check if our I/O address matches config info on 86965.  */
  441         n = (fe_inb(sc, FE_BMPR19) & FE_B19_ADDR) >> FE_B19_ADDR_SHIFT;
  442         if (baseaddr[n] != iobase)
  443                 return ENXIO;
  444 
  445         /*
  446          * We are now almost sure we have an MB86965 at the given
  447          * address.  So, read EEPROM through it.  We have to write
  448          * into LSI registers to read from EEPROM.  I want to avoid it
  449          * at this stage, but I cannot test the presence of the chip
  450          * any further without reading EEPROM.  FIXME.
  451          */
  452         fe_read_eeprom_jli(sc, eeprom);
  453 
  454         /* Make sure that config info in EEPROM and 86965 agree.  */
  455         if (eeprom[FE_EEPROM_CONF] != fe_inb(sc, FE_BMPR19))
  456                 return ENXIO;
  457 
  458         /* Use 86965 media selection scheme, unless othewise
  459            specified.  It is "AUTO always" and "select with BMPR13".
  460            This behaviour covers most of the 86965 based board (as
  461            minimum requirements.)  It is backward compatible with
  462            previous versions, also.  */
  463         sc->mbitmap = MB_HA;
  464         sc->defmedia = MB_HA;
  465         sc->msel = fe_msel_965;
  466 
  467         /* Perform board-specific probe.  */
  468         if ((irqmap = fe_probe_jli_re1000p(sc, eeprom)) == NULL)
  469                 return ENXIO;
  470 
  471         /* Find the IRQ read from EEPROM.  */
  472         n = (fe_inb(sc, FE_BMPR19) & FE_B19_IRQ) >> FE_B19_IRQ_SHIFT;
  473         xirq = irqmap[n];
  474 
  475         /* Try to determine IRQ setting.  */
  476         error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
  477         if (error && xirq == NO_IRQ) {
  478                 /* The device must be configured with an explicit IRQ.  */
  479                 device_printf(dev, "IRQ auto-detection does not work\n");
  480                 return ENXIO;
  481         } else if (error && xirq != NO_IRQ) {
  482                 /* Just use the probed IRQ value.  */
  483                 bus_set_resource(dev, SYS_RES_IRQ, 0, xirq, 1);
  484         } else if (!error && xirq == NO_IRQ) {
  485                 /* No problem.  Go ahead.  */
  486         } else if (irq == xirq) {
  487                 /* Good.  Go ahead.  */
  488         } else {
  489                 /* User must be warned in this case.  */
  490                 sc->stability |= UNSTABLE_IRQ;
  491         }
  492 
  493         /* Setup a hook, which resets te 86965 when the driver is being
  494            initialized.  This may solve a nasty bug.  FIXME.  */
  495         sc->init = fe_init_jli;
  496 
  497         return 0;
  498 }
  499 
  500 
  501 /*
  502  * Probe and initialization for Contec C-NET(9N)E series.
  503  */
  504 
  505 /* TODO: Should be in "if_fereg.h" */
  506 #define FE_CNET9NE_INTR         0x10            /* Interrupt Mask? */
  507 
  508 static void
  509 fe_init_cnet9ne(struct fe_softc *sc)
  510 {
  511         /* Enable interrupt?  FIXME.  */
  512         fe_outb(sc, FE_CNET9NE_INTR, 0x10);
  513 }
  514 
  515 static int
  516 fe_probe_cnet9ne (device_t dev)
  517 {
  518         struct fe_softc *sc = device_get_softc(dev);
  519         u_long iobase, irq;
  520 
  521         static struct fe_simple_probe_struct probe_table [] = {
  522                 { FE_DLCR2, 0x58, 0x00 },
  523                 { FE_DLCR4, 0x08, 0x00 },
  524                 { 0 }
  525         };
  526 
  527         /* See if the specified I/O address is possible for C-NET(9N)E.  */
  528         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  529                 return ENXIO;
  530         if (iobase != 0x73D0)
  531                 return ENXIO;
  532 
  533         if (fe98_alloc_port(dev, FE_TYPE_CNET9NE))
  534                 return ENXIO;
  535 
  536         /* Fill the softc struct with default values.  */
  537         fe_softc_defaults(sc);
  538 
  539         /* See if the card is on its address.  */
  540         if (!fe_simple_probe(sc, probe_table))
  541                 return ENXIO;
  542 
  543         /* Get our station address from EEPROM.  */
  544         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
  545 
  546         /* Make sure it is Contec's.  */
  547         if (!fe_valid_Ether_p(sc->sc_enaddr, 0x00804C))
  548                 return ENXIO;
  549 
  550         /* Determine the card type.  */
  551         if (sc->sc_enaddr[3] == 0x06) {
  552                 sc->typestr = "C-NET(9N)C";
  553 
  554                 /* We seems to need our own IDENT bits...  FIXME.  */
  555                 sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE;
  556 
  557                 /* C-NET(9N)C requires an explicit IRQ to work.  */
  558                 if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0) {
  559                         fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL);
  560                         return ENXIO;
  561                 }
  562         } else {
  563                 sc->typestr = "C-NET(9N)E";
  564 
  565                 /* C-NET(9N)E works only IRQ5.  */
  566                 if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0)
  567                         return ENXIO;
  568                 if (irq != 5) {
  569                         fe_irq_failure(sc->typestr, sc->sc_unit, irq, "5");
  570                         return ENXIO;
  571                 }
  572 
  573                 /* We need an init hook to initialize ASIC before we start.  */
  574                 sc->init = fe_init_cnet9ne;
  575         }
  576 
  577         /* C-NET(9N)E has 64KB SRAM.  */
  578         sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
  579                         | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;
  580 
  581         return 0;
  582 }
  583 
  584 
  585 /*
  586  * Probe for Contec C-NET(98)P2 series.
  587  * (Logitec LAN-98TP/LAN-98T25P - parhaps)
  588  */
  589 static int
  590 fe_probe_ssi(device_t dev)
  591 {
  592         struct fe_softc *sc = device_get_softc(dev);
  593         u_long iobase, irq;
  594 
  595         u_char eeprom [SSI_EEPROM_SIZE];
  596         static struct fe_simple_probe_struct probe_table [] = {
  597                 { FE_DLCR2, 0x08, 0x00 },
  598                 { FE_DLCR4, 0x08, 0x00 },
  599                 { 0 }
  600         };
  601         static u_short const irqmap[] = {
  602                 /*                        INT0          INT1    INT2       */
  603                 NO_IRQ, NO_IRQ, NO_IRQ,      3, NO_IRQ,    5,      6, NO_IRQ,
  604                 NO_IRQ,      9,     10, NO_IRQ,     12,   13, NO_IRQ, NO_IRQ,
  605                 /*        INT3   INT41            INT5  INT6               */
  606         };
  607 
  608         /* See if the specified I/O address is possible for 78Q8377A.  */
  609         /* [0-D]3D0 are allowed.  */
  610         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  611                 return ENXIO;
  612         if ((iobase & 0xFFF) != 0x3D0)
  613                 return ENXIO;
  614                 
  615         if (fe98_alloc_port(dev, FE_TYPE_SSI))
  616                 return ENXIO;
  617 
  618         /* Fill the softc struct with default values.  */
  619         fe_softc_defaults(sc);
  620 
  621         /* See if the card is on its address.  */
  622         if (!fe_simple_probe(sc, probe_table))
  623                 return ENXIO;
  624 
  625         /* We now have to read the config EEPROM.  We should be very
  626            careful, since doing so destroys a register.  (Remember, we
  627            are not yet sure we have a C-NET(98)P2 board here.)  Don't
  628            remember to select BMPRs bofore reading EEPROM, since other
  629            register bank may be selected before the probe() is called.  */
  630         fe_read_eeprom_ssi(sc, eeprom);
  631 
  632         /* Make sure the Ethernet (MAC) station address is of Contec's.  */
  633         if (!fe_valid_Ether_p(eeprom + FE_SSI_EEP_ADDR, 0x00804C))
  634                 return ENXIO;
  635         bcopy(eeprom + FE_SSI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN);
  636 
  637         /* Setup the board type.  */
  638         sc->typestr = "C-NET(98)P2";
  639 
  640         /* Non-PnP mode, set static resource from eeprom. */
  641         if (!isa_get_vendorid(dev)) {
  642                 /* Get IRQ configuration from EEPROM.  */
  643                 irq = irqmap[eeprom[FE_SSI_EEP_IRQ]];
  644                 if (irq == NO_IRQ) {
  645                         fe_irq_failure(sc->typestr, sc->sc_unit, irq,
  646                                        "3/5/6/9/10/12/13");
  647                         return ENXIO;
  648                 }
  649                 bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
  650         }
  651 
  652         /* Get Duplex-mode configuration from EEPROM.  */
  653         sc->proto_dlcr4 |= (eeprom[FE_SSI_EEP_DUPLEX] & FE_D4_DSC);
  654 
  655         /* Fill softc struct accordingly.  */
  656         sc->mbitmap = MB_HT;
  657         sc->defmedia = MB_HT;
  658 
  659         return 0;
  660 }
  661 
  662 
  663 /*
  664  * Probe for TDK LAC-98012/013/025/9N011 - parhaps.
  665  */
  666 static int
  667 fe_probe_lnx(device_t dev)
  668 {
  669         struct fe_softc *sc = device_get_softc(dev);
  670 
  671         u_long iobase, irq;
  672         u_char eeprom [LNX_EEPROM_SIZE];
  673 
  674         static struct fe_simple_probe_struct probe_table [] = {
  675                 { FE_DLCR2, 0x58, 0x00 },
  676                 { FE_DLCR4, 0x08, 0x00 },
  677                 { 0 }
  678         };
  679 
  680         /* See if the specified I/O address is possible for TDK/LANX boards. */
  681         /* 0D0, 4D0, 8D0, and CD0 are allowed.  */
  682         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  683                 return ENXIO;
  684         if ((iobase & ~0xC00) != 0xD0)
  685                 return ENXIO;
  686 
  687         if (fe98_alloc_port(dev, FE_TYPE_LNX))
  688                 return ENXIO;
  689 
  690         /* Fill the softc struct with default values.  */
  691         fe_softc_defaults(sc);
  692 
  693         /* See if the card is on its address.  */
  694         if (!fe_simple_probe(sc, probe_table))
  695                 return ENXIO;
  696 
  697         /* We now have to read the config EEPROM.  We should be very
  698            careful, since doing so destroys a register.  (Remember, we
  699            are not yet sure we have a LAC-98012/98013 board here.)  */
  700         fe_read_eeprom_lnx(sc, eeprom);
  701 
  702         /* Make sure the Ethernet (MAC) station address is of TDK/LANX's.  */
  703         if (!fe_valid_Ether_p(eeprom, 0x008098))
  704                 return ENXIO;
  705         bcopy(eeprom, sc->sc_enaddr, ETHER_ADDR_LEN);
  706 
  707         /* Setup the board type.  */
  708         sc->typestr = "LAC-98012/98013";
  709 
  710         /* This looks like a TDK/LANX board.  It requires an
  711            explicit IRQ setting in config.  Make sure we have one,
  712            determining an appropriate value for the IRQ control
  713            register.  */
  714         irq = 0;
  715         if (bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL) != 0)
  716                 return ENXIO;
  717         switch (irq) {
  718         case 3 : sc->priv_info = 0x10 | LNX_CLK_LO | LNX_SDA_HI; break;
  719         case 5 : sc->priv_info = 0x20 | LNX_CLK_LO | LNX_SDA_HI; break;
  720         case 6 : sc->priv_info = 0x40 | LNX_CLK_LO | LNX_SDA_HI; break;
  721         case 12: sc->priv_info = 0x80 | LNX_CLK_LO | LNX_SDA_HI; break;
  722         default:
  723                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
  724                 return ENXIO;
  725         }
  726 
  727         /* LAC-98's system bus width is 8-bit.  */ 
  728         sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x2KB
  729                         | FE_D6_BBW_BYTE | FE_D6_SBW_BYTE | FE_D6_SRAM_150ns;
  730 
  731         /* Setup hooks.  We need a special initialization procedure.  */
  732         sc->init = fe_init_lnx;
  733 
  734         return 0;
  735 }
  736 
  737 
  738 /*
  739  * Probe for Gateway Communications' old cards.
  740  * (both as Generic MB86960 probe routine)
  741  */
  742 static int
  743 fe_probe_gwy(device_t dev)
  744 {
  745         struct fe_softc *sc = device_get_softc(dev);
  746 
  747         static struct fe_simple_probe_struct probe_table [] = {
  748             /*  { FE_DLCR2, 0x70, 0x00 }, */
  749                 { FE_DLCR2, 0x58, 0x00 },
  750                 { FE_DLCR4, 0x08, 0x00 },
  751                 { 0 }
  752         };
  753 
  754         /*
  755          * XXX
  756          * I'm not sure which address is possible, so accepts any.
  757          */
  758 
  759         if (fe98_alloc_port(dev, FE_TYPE_GWY))
  760                 return ENXIO;
  761 
  762         /* Fill the softc struct with default values.  */
  763         fe_softc_defaults(sc);
  764 
  765         /* See if the card is on its address.  */
  766         if (!fe_simple_probe(sc, probe_table))
  767                 return ENXIO;
  768 
  769         /* Get our station address from EEPROM. */
  770         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
  771         if (!fe_valid_Ether_p(sc->sc_enaddr, 0x000000))
  772                 return ENXIO;
  773 
  774         /* Determine the card type.  */
  775         sc->typestr = "Generic MB86960 Ethernet";
  776         if (fe_valid_Ether_p(sc->sc_enaddr, 0x000061))
  777                 sc->typestr = "Gateway Ethernet (Fujitsu chipset)";
  778 
  779         /* Gateway's board requires an explicit IRQ to work, since it
  780            is not possible to probe the setting of jumpers.  */
  781         if (bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0) {
  782                 fe_irq_failure(sc->typestr, sc->sc_unit, NO_IRQ, NULL);
  783                 return ENXIO;
  784         }
  785 
  786         return 0;
  787 }
  788 
  789 
  790 /*
  791  * Probe for Ungermann-Bass Access/PC N98C+(Model 85152).
  792  */
  793 static int
  794 fe_probe_ubn(device_t dev)
  795 {
  796         struct fe_softc *sc = device_get_softc(dev);
  797 
  798         u_char sum, save7;
  799         u_long iobase, irq;
  800         int i;
  801         static struct fe_simple_probe_struct const probe_table [] = {
  802                 { FE_DLCR2, 0x58, 0x00 },
  803                 { FE_DLCR4, 0x08, 0x00 },
  804                 { 0 }
  805         };
  806 
  807         /* See if the specified I/O address is possible for Access/PC.  */
  808         /* [01][048C]D0 are allowed.  */ 
  809         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  810                 return ENXIO;
  811         if ((iobase & ~0x1C00) != 0xD0)
  812                 return ENXIO;
  813 
  814         if (fe98_alloc_port(dev, FE_TYPE_UBN))
  815                 return ENXIO;
  816 
  817         /* Fill the softc struct with default values.  */
  818         fe_softc_defaults(sc);
  819 
  820         /* Simple probe.  */
  821         if (!fe_simple_probe(sc, probe_table))
  822                 return ENXIO;
  823 
  824         /* NOTE: Access/NOTE N98 sometimes freeze when reading station
  825            address.  In case of using it togather with C-NET(9N)C,
  826            this problem usually happens.
  827            Writing DLCR7 prevents freezing, but I don't know why.  FIXME.  */
  828 
  829         /* Save the current value for the DLCR7 register we are about
  830            to destroy.  */
  831         save7 = fe_inb(sc, FE_DLCR7);
  832         fe_outb(sc, FE_DLCR7,
  833                 sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP);
  834 
  835         /* Get our station address form ID ROM and make sure it is UBN's.  */
  836         fe_inblk(sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN);
  837         if (!fe_valid_Ether_p(sc->sc_enaddr, 0x00DD01))
  838                 goto fail_ubn;
  839 #if 1
  840         /* Calculate checksum.  */
  841         sum = fe_inb(sc, 0x1e);
  842         for (i = 0; i < ETHER_ADDR_LEN; i++)
  843                 sum ^= sc->sc_enaddr[i];
  844         if (sum != 0)
  845                 goto fail_ubn;
  846 #endif
  847 
  848         /* Setup the board type.  */
  849         sc->typestr = "Access/PC";
  850 
  851         /* This looks like an AccessPC/N98C+ board.  It requires an
  852            explicit IRQ setting in config.  Make sure we have one,
  853            determining an appropriate value for the IRQ control
  854            register.  */
  855         irq = 0;
  856         bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
  857         switch (irq) {
  858         case 3:  sc->priv_info = 0x01; break;
  859         case 5:  sc->priv_info = 0x02; break;
  860         case 6:  sc->priv_info = 0x04; break;
  861         case 12: sc->priv_info = 0x08; break;
  862         default:
  863                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
  864                 goto fail_ubn;
  865         }
  866 
  867         /* Setup hooks.  We need a special initialization procedure.  */
  868         sc->init = fe_init_ubn;
  869 
  870         return 0;
  871 
  872 fail_ubn:
  873         fe_outb(sc, FE_DLCR7, save7);
  874         return ENXIO;
  875 }
  876 
  877 
  878 /*
  879  * REX boards(non-JLI type) support routine.
  880  */
  881 
  882 #define REX_EEPROM_SIZE 32
  883 #define REX_DAT 0x01
  884 
  885 static void
  886 fe_read_eeprom_rex(struct fe_softc *sc, u_char *data)
  887 {
  888         int i;
  889         u_char bit, val;
  890         u_char save16;
  891 
  892         save16 = fe_inb(sc, 0x10);
  893 
  894         /* Issue a start condition.  */
  895         val = fe_inb(sc, 0x10) & 0xf0;
  896         fe_outb(sc, 0x10, val);
  897 
  898         (void) fe_inb(sc, 0x10);
  899         (void) fe_inb(sc, 0x10);
  900         (void) fe_inb(sc, 0x10);
  901         (void) fe_inb(sc, 0x10);
  902 
  903         /* Read bytes from EEPROM.  */
  904         for (i = 0; i < REX_EEPROM_SIZE; i++) {
  905                 /* Read a byte and store it into the buffer.  */
  906                 val = 0x00;
  907                 for (bit = 0x01; bit != 0x00; bit <<= 1)
  908                         if (fe_inb(sc, 0x10) & REX_DAT)
  909                                 val |= bit;
  910                 *data++ = val;
  911         }
  912 
  913         fe_outb(sc, 0x10, save16);
  914 
  915 #if 1
  916         /* Report what we got.  */
  917         if (bootverbose) {
  918                 data -= REX_EEPROM_SIZE;
  919                 for (i = 0; i < REX_EEPROM_SIZE; i += 16) {
  920                         printf("fe%d: EEPROM(REX):%3x: %16D\n",
  921                                sc->sc_unit, i, data + i, " ");
  922                 }
  923         }
  924 #endif
  925 }
  926 
  927 
  928 static void
  929 fe_init_rex(struct fe_softc *sc)
  930 {
  931         /* Setup IRQ control register on the ASIC.  */
  932         fe_outb(sc, 0x10, sc->priv_info);
  933 }
  934 
  935 /*
  936  * Probe for RATOC REX-9880/81/82/83 series.
  937  */
  938 static int
  939 fe_probe_rex(device_t dev)
  940 {
  941         struct fe_softc *sc = device_get_softc(dev);
  942 
  943         int i;
  944         u_long iobase, irq;
  945         u_char eeprom [REX_EEPROM_SIZE];
  946 
  947         static struct fe_simple_probe_struct probe_table [] = {
  948                 { FE_DLCR2, 0x58, 0x00 },
  949                 { FE_DLCR4, 0x08, 0x00 },
  950                 { 0 }
  951         };
  952 
  953         /* See if the specified I/O address is possible for REX-9880.  */
  954         /* 6[46CE]D0 are allowed.  */ 
  955         if (bus_get_resource(dev, SYS_RES_IOPORT, 0, &iobase, NULL) != 0)
  956                 return ENXIO;
  957         if ((iobase & ~0xA00) != 0x64D0)
  958                 return ENXIO;
  959 
  960         if (fe98_alloc_port(dev, FE_TYPE_REX))
  961                 return ENXIO;
  962 
  963         /* Fill the softc struct with default values.  */
  964         fe_softc_defaults(sc);
  965 
  966         /* See if the card is on its address.  */
  967         if (!fe_simple_probe(sc, probe_table))
  968                 return ENXIO;
  969 
  970         /* We now have to read the config EEPROM.  We should be very
  971            careful, since doing so destroys a register.  (Remember, we
  972            are not yet sure we have a REX-9880 board here.)  */
  973         fe_read_eeprom_rex(sc, eeprom);
  974         for (i = 0; i < ETHER_ADDR_LEN; i++)
  975                 sc->sc_enaddr[i] = eeprom[7 - i];
  976 
  977         /* Make sure it is RATOC's.  */
  978         if (!fe_valid_Ether_p(sc->sc_enaddr, 0x00C0D0) &&
  979             !fe_valid_Ether_p(sc->sc_enaddr, 0x00803D))
  980                 return 0;
  981 
  982         /* Setup the board type.  */
  983         sc->typestr = "REX-9880/9883";
  984 
  985         /* This looks like a REX-9880 board.  It requires an
  986            explicit IRQ setting in config.  Make sure we have one,
  987            determining an appropriate value for the IRQ control
  988            register.  */
  989         irq = 0;
  990         bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, NULL);
  991         switch (irq) {
  992         case 3:  sc->priv_info = 0x10; break;
  993         case 5:  sc->priv_info = 0x20; break;
  994         case 6:  sc->priv_info = 0x40; break;
  995         case 12: sc->priv_info = 0x80; break;
  996         default:
  997                 fe_irq_failure(sc->typestr, sc->sc_unit, irq, "3/5/6/12");
  998                 return ENXIO;
  999         }
 1000 
 1001         /* Setup hooks.  We need a special initialization procedure.  */
 1002         sc->init = fe_init_rex;
 1003 
 1004         /* REX-9880 has 64KB SRAM.  */
 1005         sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
 1006                         | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;
 1007 #if 1
 1008         sc->proto_dlcr7 |= FE_D7_EOPPOL;        /* XXX */
 1009 #endif
 1010 
 1011         return 0;
 1012 }

Cache object: 474b6873163c5f58e777497488e3fd60


[ 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.