root/dev/pci/if_dc_pci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dc_pci_match
  2. dc_pci_acpi
  3. dc_pci_attach

    1 /*      $OpenBSD: if_dc_pci.c,v 1.58 2007/08/01 16:30:03 miod Exp $     */
    2 
    3 /*
    4  * Copyright (c) 1997, 1998, 1999
    5  *      Bill Paul <wpaul@ee.columbia.edu>.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. All advertising materials mentioning features or use of this software
   16  *    must display the following acknowledgement:
   17  *      This product includes software developed by Bill Paul.
   18  * 4. Neither the name of the author nor the names of any co-contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   32  * THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  * $FreeBSD: src/sys/pci/if_dc.c,v 1.5 2000/01/12 22:24:05 wpaul Exp $
   35  */
   36 
   37 #include "bpfilter.h"
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/mbuf.h>
   42 #include <sys/protosw.h>
   43 #include <sys/socket.h>
   44 #include <sys/ioctl.h>
   45 #include <sys/errno.h>
   46 #include <sys/timeout.h>
   47 #include <sys/malloc.h>
   48 #include <sys/kernel.h>
   49 #include <sys/device.h>
   50 
   51 #include <net/if.h>
   52 #include <net/if_dl.h>
   53 #include <net/if_types.h>
   54 
   55 #ifdef INET
   56 #include <netinet/in.h>
   57 #include <netinet/in_systm.h>
   58 #include <netinet/in_var.h>
   59 #include <netinet/ip.h>
   60 #include <netinet/if_ether.h>
   61 #endif
   62 
   63 #include <net/if_media.h>
   64 
   65 #if NBPFILTER > 0
   66 #include <net/bpf.h>
   67 #endif
   68 
   69 #include <dev/mii/mii.h>
   70 #include <dev/mii/miivar.h>
   71 
   72 #include <dev/pci/pcireg.h>
   73 #include <dev/pci/pcivar.h>
   74 #include <dev/pci/pcidevs.h>
   75 
   76 #ifdef __sparc64__
   77 #include <dev/ofw/openfirm.h>
   78 #endif
   79 
   80 #ifndef __hppa__
   81 #define DC_USEIOSPACE
   82 #endif
   83 
   84 #include <dev/ic/dcreg.h>
   85 
   86 /*
   87  * Various supported device vendors/types and their names.
   88  */
   89 struct dc_type dc_devs[] = {
   90         { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21140 },
   91         { PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21142 },
   92         { PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9009 },
   93         { PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9100 },
   94         { PCI_VENDOR_DAVICOM, PCI_PRODUCT_DAVICOM_DM9102 },
   95         { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM9511 },
   96         { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM9513 },
   97         { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AL981 },
   98         { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN983 },
   99         { PCI_VENDOR_ASIX, PCI_PRODUCT_ASIX_AX88140A },
  100         { PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98713 },
  101         { PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98715 },
  102         { PCI_VENDOR_MACRONIX, PCI_PRODUCT_MACRONIX_MX98727 },
  103         { PCI_VENDOR_COMPEX, PCI_PRODUCT_COMPEX_98713 },
  104         { PCI_VENDOR_LITEON, PCI_PRODUCT_LITEON_PNIC },
  105         { PCI_VENDOR_LITEON, PCI_PRODUCT_LITEON_PNICII },
  106         { PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN1217 },
  107         { PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN2242 },
  108         { PCI_VENDOR_CONEXANT, PCI_PRODUCT_CONEXANT_RS7112 },
  109         { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_21145 },
  110         { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CSHO100BTX },
  111         { PCI_VENDOR_MICROSOFT, PCI_PRODUCT_MICROSOFT_MN130 },
  112         { 0, 0 }
  113 };
  114 
  115 int dc_pci_match(struct device *, void *, void *);
  116 void dc_pci_attach(struct device *, struct device *, void *);
  117 void dc_pci_acpi(struct device *, void *);
  118 
  119 /*
  120  * Probe for a 21143 or clone chip. Check the PCI vendor and device
  121  * IDs against our list and return a device name if we find a match.
  122  */
  123 int
  124 dc_pci_match(parent, match, aux)
  125         struct device *parent;
  126         void *match, *aux;
  127 {
  128         struct pci_attach_args *pa = (struct pci_attach_args *)aux;
  129         struct dc_type *t;
  130 
  131         /*
  132          * Support for the 21140 chip is experimental.  If it works for you,
  133          * that's great.  By default, this chip will use de.
  134          */
  135         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
  136             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140)
  137                 return (1);
  138 
  139         /*
  140          * The following chip revision doesn't seem to work so well with dc,
  141          * so let's have de handle it.  (de will return a match of 2)
  142          */
  143         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_DEC &&
  144             PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142 &&
  145             PCI_REVISION(pa->pa_class) == 0x21)
  146                 return (1);
  147 
  148         for (t = dc_devs; t->dc_vid != 0; t++) {
  149                 if ((PCI_VENDOR(pa->pa_id) == t->dc_vid) &&
  150                     (PCI_PRODUCT(pa->pa_id) == t->dc_did)) {
  151                         return (3);
  152                 }
  153         }
  154 
  155         return (0);
  156 }
  157 
  158 void dc_pci_acpi(self, aux)
  159         struct device *self;
  160         void *aux;
  161 {
  162         struct dc_softc         *sc = (struct dc_softc *)self;
  163         struct pci_attach_args  *pa = (struct pci_attach_args *)aux;
  164         pci_chipset_tag_t       pc = pa->pa_pc;
  165         u_int32_t               r, cptr;
  166 
  167         /* Find the location of the capabilities block */
  168         cptr = pci_conf_read(pc, pa->pa_tag, DC_PCI_CCAP) & 0xFF;
  169 
  170         r = pci_conf_read(pc, pa->pa_tag, cptr) & 0xFF;
  171         if (r == 0x01) {
  172 
  173                 r = pci_conf_read(pc, pa->pa_tag, cptr + PCI_PMCSR);
  174                 if (r & DC_PSTATE_D3) {
  175                         u_int32_t               iobase, membase, irq;
  176 
  177                         /* Save important PCI config data. */
  178                         iobase = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFBIO);
  179                         membase = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFBMA);
  180                         irq = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFIT);
  181 
  182                         /* Reset the power state. */
  183                         printf("%s: chip is in D%d power mode "
  184                             "-- setting to D0\n", sc->sc_dev.dv_xname,
  185                             r & DC_PSTATE_D3);
  186                         r &= 0xFFFFFFFC;
  187                         pci_conf_write(pc, pa->pa_tag, cptr + PCI_PMCSR, r);
  188 
  189                         /* Restore PCI config data. */
  190                         pci_conf_write(pc, pa->pa_tag, DC_PCI_CFBIO, iobase);
  191                         pci_conf_write(pc, pa->pa_tag, DC_PCI_CFBMA, membase);
  192                         pci_conf_write(pc, pa->pa_tag, DC_PCI_CFIT, irq);
  193                 }
  194         }
  195         return;
  196 }
  197 
  198 /*
  199  * Attach the interface. Allocate softc structures, do ifmedia
  200  * setup and ethernet/BPF attach.
  201  */
  202 void dc_pci_attach(parent, self, aux)
  203         struct device *parent, *self;
  204         void *aux;
  205 {
  206         const char              *intrstr = NULL;
  207         pcireg_t                command;
  208         struct dc_softc         *sc = (struct dc_softc *)self;
  209         struct pci_attach_args  *pa = aux;
  210         pci_chipset_tag_t       pc = pa->pa_pc;
  211         pci_intr_handle_t       ih;
  212         bus_size_t              size;
  213         u_int32_t               revision;
  214         int                     found = 0;
  215 
  216         sc->sc_dmat = pa->pa_dmat;
  217 
  218         /*
  219          * Handle power management nonsense.
  220          */
  221         dc_pci_acpi(self, aux);
  222 
  223         sc->dc_csid = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
  224 
  225         /*
  226          * Map control/status registers.
  227          */
  228 #ifdef DC_USEIOSPACE
  229         if (pci_mapreg_map(pa, DC_PCI_CFBIO,
  230             PCI_MAPREG_TYPE_IO, 0,
  231             &sc->dc_btag, &sc->dc_bhandle, NULL, &size, 0)) {
  232                 printf(": can't map i/o space\n");
  233                 return;
  234         }
  235 #else
  236         if (pci_mapreg_map(pa, DC_PCI_CFBMA,
  237             PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
  238             &sc->dc_btag, &sc->dc_bhandle, NULL, &size, 0)) {
  239                 printf(": can't map mem space\n");
  240                 return;
  241         }
  242 #endif
  243 
  244         /* Allocate interrupt */
  245         if (pci_intr_map(pa, &ih)) {
  246                 printf(": couldn't map interrupt\n");
  247                 goto fail_1;
  248         }
  249         intrstr = pci_intr_string(pc, ih);
  250         sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, dc_intr, sc,
  251             self->dv_xname);
  252         if (sc->sc_ih == NULL) {
  253                 printf(": couldn't establish interrupt");
  254                 if (intrstr != NULL)
  255                         printf(" at %s", intrstr);
  256                 printf("\n");
  257                 goto fail_1;
  258         }
  259         printf(": %s,", intrstr);
  260 
  261         /* Need this info to decide on a chip type. */
  262         sc->dc_revision = revision = PCI_REVISION(pa->pa_class);
  263 
  264         /* Get the eeprom width, but PNIC has no eeprom */
  265         if (!(PCI_VENDOR(pa->pa_id) == PCI_VENDOR_LITEON &&
  266               PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC))
  267                 dc_eeprom_width(sc);
  268 
  269         switch (PCI_VENDOR(pa->pa_id)) {
  270         case PCI_VENDOR_DEC:
  271                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21140 ||
  272                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DEC_21142) {
  273                         found = 1;
  274                         sc->dc_type = DC_TYPE_21143;
  275                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  276                         sc->dc_flags |= DC_REDUCED_MII_POLL;
  277                         dc_read_srom(sc, sc->dc_romwidth);
  278                 }
  279                 break;
  280         case PCI_VENDOR_INTEL:
  281                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_21145) {
  282                         found = 1;
  283                         sc->dc_type = DC_TYPE_21145;
  284                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  285                         sc->dc_flags |= DC_REDUCED_MII_POLL;
  286                         dc_read_srom(sc, sc->dc_romwidth);
  287                 }
  288                 break;
  289         case PCI_VENDOR_DAVICOM:
  290                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9100 ||
  291                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9102 ||
  292                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_DAVICOM_DM9009) {
  293                         found = 1;
  294                         sc->dc_type = DC_TYPE_DM9102;
  295                         sc->dc_flags |= DC_TX_COALESCE|DC_TX_INTR_ALWAYS;
  296                         sc->dc_flags |= DC_REDUCED_MII_POLL|DC_TX_STORENFWD;
  297                         sc->dc_flags |= DC_TX_ALIGN;
  298                         sc->dc_pmode = DC_PMODE_MII;
  299 
  300                         /* Increase the latency timer value. */
  301                         command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFLT);
  302                         command &= 0xFFFF00FF;
  303                         command |= 0x00008000;
  304                         pci_conf_write(pc, pa->pa_tag, DC_PCI_CFLT, command);
  305                 }
  306                 break;
  307         case PCI_VENDOR_ADMTEK:
  308         case PCI_VENDOR_3COM:
  309         case PCI_VENDOR_MICROSOFT:
  310                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AL981) {
  311                         found = 1;
  312                         sc->dc_type = DC_TYPE_AL981;
  313                         sc->dc_flags |= DC_TX_USE_TX_INTR;
  314                         sc->dc_flags |= DC_TX_ADMTEK_WAR;
  315                         sc->dc_pmode = DC_PMODE_MII;
  316                         dc_read_srom(sc, sc->dc_romwidth);
  317                 }
  318                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9511 ||
  319                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_ADM9513 ||
  320                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ADMTEK_AN983 ||
  321                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3COM_3CSHO100BTX ||
  322                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MICROSOFT_MN130) {
  323                         found = 1;
  324                         sc->dc_type = DC_TYPE_AN983;
  325                         sc->dc_flags |= DC_TX_USE_TX_INTR;
  326                         sc->dc_flags |= DC_TX_ADMTEK_WAR;
  327                         sc->dc_flags |= DC_64BIT_HASH;
  328                         sc->dc_pmode = DC_PMODE_MII;
  329                         /* Don't read SROM for - auto-loaded on reset */
  330                 }
  331                 break;
  332         case PCI_VENDOR_MACRONIX:
  333         case PCI_VENDOR_ACCTON:
  334                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN2242) {
  335                         found = 1;
  336                         sc->dc_type = DC_TYPE_AN983;
  337                         sc->dc_flags |= DC_TX_USE_TX_INTR;
  338                         sc->dc_flags |= DC_TX_ADMTEK_WAR;
  339                         sc->dc_flags |= DC_64BIT_HASH;
  340                         sc->dc_pmode = DC_PMODE_MII;
  341                         /* Don't read SROM for - auto-loaded on reset */
  342                 }
  343                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98713) {
  344                         found = 1;
  345                         if (revision < DC_REVISION_98713A) {
  346                                 sc->dc_type = DC_TYPE_98713;
  347                         }
  348                         if (revision >= DC_REVISION_98713A) {
  349                                 sc->dc_type = DC_TYPE_98713A;
  350                                 sc->dc_flags |= DC_21143_NWAY;
  351                         }
  352                         sc->dc_flags |= DC_REDUCED_MII_POLL;
  353                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  354                 }
  355                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98715 ||
  356                     PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ACCTON_EN1217) {
  357                         found = 1;
  358                         if (revision >= DC_REVISION_98715AEC_C &&
  359                             revision < DC_REVISION_98725)
  360                                 sc->dc_flags |= DC_128BIT_HASH;
  361                         sc->dc_type = DC_TYPE_987x5;
  362                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  363                         sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
  364                 }
  365                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_MACRONIX_MX98727) {
  366                         found = 1;
  367                         sc->dc_type = DC_TYPE_987x5;
  368                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  369                         sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
  370                 }
  371                 break;
  372         case PCI_VENDOR_COMPEX:
  373                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_COMPEX_98713) {
  374                         found = 1;
  375                         if (revision < DC_REVISION_98713A) {
  376                                 sc->dc_type = DC_TYPE_98713;
  377                                 sc->dc_flags |= DC_REDUCED_MII_POLL;
  378                         }
  379                         if (revision >= DC_REVISION_98713A)
  380                                 sc->dc_type = DC_TYPE_98713A;
  381                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  382                 }
  383                 break;
  384         case PCI_VENDOR_LITEON:
  385                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNICII) {
  386                         found = 1;
  387                         sc->dc_type = DC_TYPE_PNICII;
  388                         sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
  389                         sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
  390                         sc->dc_flags |= DC_128BIT_HASH;
  391                 }
  392                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_LITEON_PNIC) {
  393                         found = 1;
  394                         sc->dc_type = DC_TYPE_PNIC;
  395                         sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS;
  396                         sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
  397                         sc->dc_pnic_rx_buf = malloc(ETHER_MAX_DIX_LEN * 5, M_DEVBUF,
  398                             M_NOWAIT);
  399                         if (sc->dc_pnic_rx_buf == NULL)
  400                                 panic("dc_pci_attach");
  401                         if (revision < DC_REVISION_82C169)
  402                                 sc->dc_pmode = DC_PMODE_SYM;
  403                 }
  404                 break;
  405         case PCI_VENDOR_ASIX:
  406                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ASIX_AX88140A) {
  407                         found = 1;
  408                         sc->dc_type = DC_TYPE_ASIX;
  409                         sc->dc_flags |= DC_TX_USE_TX_INTR|DC_TX_INTR_FIRSTFRAG;
  410                         sc->dc_flags |= DC_REDUCED_MII_POLL;
  411                         sc->dc_pmode = DC_PMODE_MII;
  412                 }
  413                 break;
  414         case PCI_VENDOR_CONEXANT:
  415                 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_CONEXANT_RS7112) {
  416                         found = 1;
  417                         sc->dc_type = DC_TYPE_CONEXANT;
  418                         sc->dc_flags |= DC_TX_INTR_ALWAYS;
  419                         sc->dc_flags |= DC_REDUCED_MII_POLL;
  420                         sc->dc_pmode = DC_PMODE_MII;
  421                         dc_read_srom(sc, sc->dc_romwidth);
  422                 }
  423                 break;
  424         }
  425         if (found == 0) {
  426                 /* This shouldn't happen if probe has done its job... */
  427                 printf(": unknown device: %x:%x\n",
  428                     PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id));
  429                 goto fail_2;
  430         }
  431 
  432         /* Save the cache line size. */
  433         if (DC_IS_DAVICOM(sc))
  434                 sc->dc_cachesize = 0;
  435         else
  436                 sc->dc_cachesize = pci_conf_read(pc, pa->pa_tag,
  437                     DC_PCI_CFLT) & 0xFF;
  438 
  439         /* Reset the adapter. */
  440         dc_reset(sc);
  441 
  442         /* Take 21143 out of snooze mode */
  443         if (DC_IS_INTEL(sc)) {
  444                 command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD);
  445                 command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
  446                 pci_conf_write(pc, pa->pa_tag, DC_PCI_CFDD, command);
  447         }
  448 
  449         /*
  450          * If we discover later (in dc_attach) that we have an
  451          * MII with no PHY, we need to have the 21143 drive the LEDs.
  452          * Except there are some systems like the NEC VersaPro NoteBook PC
  453          * which have no LEDs, and twiddling these bits has adverse effects
  454          * on them. (I.e. you suddenly can't get a link.)
  455          *
  456          * If mii_attach() returns an error, we leave the DC_TULIP_LEDS
  457          * bit set, else we clear it. Since our dc(4) driver is split into
  458          * bus-dependent and bus-independent parts, we must do set this bit
  459          * here while we are able to do PCI configuration reads.
  460          */
  461         if (DC_IS_INTEL(sc)) {
  462                 if (pci_conf_read(pc, pa->pa_tag, DC_PCI_CSID) != 0x80281033)
  463                         sc->dc_flags |= DC_TULIP_LEDS;
  464         }
  465 
  466         /*
  467          * Try to learn something about the supported media.
  468          * We know that ASIX and ADMtek and Davicom devices
  469          * will *always* be using MII media, so that's a no-brainer.
  470          * The tricky ones are the Macronix/PNIC II and the
  471          * Intel 21143.
  472          */
  473         if (DC_IS_INTEL(sc))
  474                 dc_parse_21143_srom(sc);
  475         else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
  476                 if (sc->dc_type == DC_TYPE_98713)
  477                         sc->dc_pmode = DC_PMODE_MII;
  478                 else
  479                         sc->dc_pmode = DC_PMODE_SYM;
  480         } else if (!sc->dc_pmode)
  481                 sc->dc_pmode = DC_PMODE_MII;
  482 
  483 #ifdef __sparc64__
  484         {
  485                 extern void myetheraddr(u_char *);
  486 
  487                 if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
  488                     sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
  489                         myetheraddr(sc->sc_arpcom.ac_enaddr);
  490                 if (sc->sc_arpcom.ac_enaddr[0] == 0x00 &&
  491                     sc->sc_arpcom.ac_enaddr[1] == 0x03 &&
  492                     sc->sc_arpcom.ac_enaddr[2] == 0xcc)
  493                         sc->dc_flags |= DC_MOMENCO_BOTCH;
  494                 sc->sc_hasmac = 1;
  495         }
  496 #endif
  497 
  498 #ifdef SRM_MEDIA
  499         sc->dc_srm_media = 0;
  500 
  501         /* Remember the SRM console media setting */
  502         if (DC_IS_INTEL(sc)) {
  503                 command = pci_conf_read(pc, pa->pa_tag, DC_PCI_CFDD);
  504                 command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
  505                 switch ((command >> 8) & 0xff) {
  506                 case 3: 
  507                         sc->dc_srm_media = IFM_10_T;
  508                         break;
  509                 case 4: 
  510                         sc->dc_srm_media = IFM_10_T | IFM_FDX;
  511                         break;
  512                 case 5: 
  513                         sc->dc_srm_media = IFM_100_TX;
  514                         break;
  515                 case 6: 
  516                         sc->dc_srm_media = IFM_100_TX | IFM_FDX;
  517                         break;
  518                 }
  519                 if (sc->dc_srm_media)
  520                         sc->dc_srm_media |= IFM_ACTIVE | IFM_ETHER;
  521         }
  522 #endif
  523         dc_attach(sc);
  524 
  525         return;
  526 
  527 fail_2:
  528         pci_intr_disestablish(pc, sc->sc_ih);
  529 
  530 fail_1:
  531         bus_space_unmap(sc->dc_btag, sc->dc_bhandle, size);
  532 }
  533 
  534 struct cfattach dc_pci_ca = {
  535         sizeof(struct dc_softc), dc_pci_match, dc_pci_attach
  536 };

/* [<][>][^][v][top][bottom][index][help] */