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/pci/if_sf_pci.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 /*      $NetBSD: if_sf_pci.c,v 1.7 2002/12/23 02:58:37 tsutsui Exp $    */
    2 
    3 /*-
    4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * PCI bus front-end for the Adaptec AIC-6915 (``Starfire'')
   41  * 10/100 Ethernet controller.
   42  */
   43 
   44 #include <sys/cdefs.h>
   45 __KERNEL_RCSID(0, "$NetBSD: if_sf_pci.c,v 1.7 2002/12/23 02:58:37 tsutsui Exp $");
   46 
   47 #include <sys/param.h>
   48 #include <sys/systm.h>
   49 #include <sys/mbuf.h>
   50 #include <sys/malloc.h>
   51 #include <sys/kernel.h>
   52 #include <sys/socket.h>
   53 #include <sys/ioctl.h>
   54 #include <sys/errno.h>
   55 #include <sys/device.h>
   56 
   57 #include <net/if.h>
   58 #include <net/if_dl.h>
   59 #include <net/if_media.h>
   60 #include <net/if_ether.h>
   61 
   62 #include <machine/bus.h>
   63 #include <machine/intr.h>
   64 
   65 #include <dev/mii/miivar.h>
   66 
   67 #include <dev/ic/aic6915reg.h>
   68 #include <dev/ic/aic6915var.h>
   69 
   70 #include <dev/pci/pcireg.h>
   71 #include <dev/pci/pcivar.h>
   72 #include <dev/pci/pcidevs.h>
   73 
   74 struct sf_pci_softc {
   75         struct sf_softc sc_starfire;    /* read Starfire softc */
   76 
   77         /* PCI-specific goo. */
   78         void    *sc_ih;                 /* interrupt handle */
   79 };
   80 
   81 int     sf_pci_match(struct device *, struct cfdata *, void *);
   82 void    sf_pci_attach(struct device *, struct device *, void *);
   83 
   84 CFATTACH_DECL(sf_pci, sizeof(struct sf_pci_softc),
   85     sf_pci_match, sf_pci_attach, NULL, NULL);
   86 
   87 struct sf_pci_product {
   88         uint32_t        spp_vendor;     /* PCI vendor ID */
   89         uint32_t        spp_product;    /* PCI product ID */
   90         const char      *spp_name;      /* product name */
   91         const struct sf_pci_product *spp_subsys; /* subsystm IDs */
   92 };
   93 
   94 const struct sf_pci_product sf_subsys_adaptec[] = {
   95         /* ANA-62011 (rev 0) Single port 10/100 64-bit */
   96         { PCI_VENDOR_ADP,                       0x0008,
   97           "ANA-62011 (rev 0) 10/100 Ethernet",  NULL },
   98 
   99         /* ANA-62011 (rev 1) Single port 10/100 64-bit */
  100         { PCI_VENDOR_ADP,                       0x0009,
  101           "ANA-62011 (rev 1) 10/100 Ethernet",  NULL },
  102 
  103         /* ANA-62022 Dual port 10/100 64-bit */
  104         { PCI_VENDOR_ADP,                       0x0010,
  105           "ANA-62022 10/100 Ethernet",          NULL },
  106 
  107         /* ANA-62044 (rev 0) Quad port 10/100 64-bit */
  108         { PCI_VENDOR_ADP,                       0x0018,
  109           "ANA-62044 (rev 0) 10/100 Ethernet",  NULL },
  110 
  111         /* ANA-62044 (rev 1) Quad port 10/100 64-bit */
  112         { PCI_VENDOR_ADP,                       0x0019,
  113           "ANA-62044 (rev 1) 10/100 Ethernet",  NULL },
  114 
  115         /* ANA-62020 Single port 100baseFX 64-bit */
  116         { PCI_VENDOR_ADP,                       0x0020,
  117           "ANA-62020 100baseFX Ethernet",       NULL },
  118 
  119         /* ANA-69011 Single port 10/100 32-bit */
  120         { PCI_VENDOR_ADP,                       0x0028,
  121           "ANA-69011 10/100 Ethernet",          NULL },
  122 
  123         { 0,                                    0,
  124           NULL,                                 NULL },
  125 };
  126 
  127 const struct sf_pci_product sf_pci_products[] = {
  128         { PCI_VENDOR_ADP,                       PCI_PRODUCT_ADP_AIC6915,
  129           "AIC-6915 10/100 Ethernet",           sf_subsys_adaptec },
  130 
  131         { 0,                                    0,
  132           NULL,                                 NULL },
  133 };
  134 
  135 static const struct sf_pci_product *
  136 sf_pci_lookup(const struct pci_attach_args *pa)
  137 {
  138         const struct sf_pci_product *spp, *subspp;
  139         pcireg_t subsysid;
  140 
  141         for (spp = sf_pci_products; spp->spp_name != NULL; spp++) {
  142                 if (PCI_VENDOR(pa->pa_id) == spp->spp_vendor &&
  143                     PCI_PRODUCT(pa->pa_id) == spp->spp_product) {
  144                         subsysid = pci_conf_read(pa->pa_pc, pa->pa_tag,
  145                             PCI_SUBSYS_ID_REG);
  146                         for (subspp = spp->spp_subsys;
  147                              subspp->spp_name != NULL; subspp++) {
  148                                 if (PCI_VENDOR(subsysid) ==
  149                                         subspp->spp_vendor ||
  150                                     PCI_PRODUCT(subsysid) ==
  151                                         subspp->spp_product) {
  152                                         return (subspp);
  153                                 }
  154                         }
  155                         return (spp);
  156                 }
  157         }
  158 
  159         return (NULL);
  160 }
  161 
  162 int
  163 sf_pci_match(struct device *parent, struct cfdata *match, void *aux)
  164 {
  165         struct pci_attach_args *pa = aux;
  166 
  167         if (sf_pci_lookup(pa) != NULL)
  168                 return (1);
  169 
  170         return (0);
  171 }
  172 
  173 void
  174 sf_pci_attach(struct device *parent, struct device *self, void *aux)
  175 {
  176         struct sf_pci_softc *psc = (void *) self;
  177         struct sf_softc *sc = &psc->sc_starfire;
  178         struct pci_attach_args *pa = aux;
  179         pci_intr_handle_t ih;
  180         const char *intrstr = NULL;
  181         const struct sf_pci_product *spp;
  182         bus_space_tag_t iot, memt;
  183         bus_space_handle_t ioh, memh;
  184         pcireg_t reg;
  185         int pmreg, ioh_valid, memh_valid;
  186 
  187         spp = sf_pci_lookup(pa);
  188         if (spp == NULL) {
  189                 printf("\n");
  190                 panic("sf_pci_attach: impossible");
  191         }
  192 
  193         printf(": %s, rev. %d\n", spp->spp_name, PCI_REVISION(pa->pa_class));
  194 
  195         if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
  196             &pmreg, 0)) {
  197                 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR);
  198                 switch (reg & PCI_PMCSR_STATE_MASK) {
  199                 case PCI_PMCSR_STATE_D1:
  200                 case PCI_PMCSR_STATE_D2:
  201                         printf(": waking up from power state D%d\n%s",
  202                             reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname);
  203                         pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR,
  204                             (reg & ~PCI_PMCSR_STATE_MASK) |
  205                             PCI_PMCSR_STATE_D0);
  206                         break;
  207 
  208                 case PCI_PMCSR_STATE_D3:
  209                         printf("%s: unable to wake up from power state D3\n",
  210                             sc->sc_dev.dv_xname);
  211                         pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR,
  212                             (reg & ~PCI_PMCSR_STATE_MASK) |
  213                             PCI_PMCSR_STATE_D0);
  214                         return;
  215                 }
  216         }
  217 
  218         /*
  219          * Map the device.
  220          */
  221         reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA);
  222         switch (reg) {
  223         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
  224         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
  225                 memh_valid = (pci_mapreg_map(pa, SF_PCI_MEMBA,
  226                     reg, 0, &memt, &memh, NULL, NULL) == 0);
  227                 break;
  228         default:
  229                 memh_valid = 0;
  230         }
  231 
  232         ioh_valid = (pci_mapreg_map(pa,
  233             (reg == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) ?
  234                 SF_PCI_IOBA : SF_PCI_IOBA - 0x04,
  235             PCI_MAPREG_TYPE_IO, 0,
  236             &iot, &ioh, NULL, NULL) == 0);
  237 
  238         if (memh_valid) {
  239                 sc->sc_st = memt;
  240                 sc->sc_sh = memh;
  241                 sc->sc_iomapped = 0;
  242         } else if (ioh_valid) {
  243                 sc->sc_st = iot;
  244                 sc->sc_sh = ioh;
  245                 sc->sc_iomapped = 1;
  246         } else {
  247                 printf("%s: unable to map device registers\n",
  248                     sc->sc_dev.dv_xname);
  249                 return;
  250         }
  251 
  252         sc->sc_dmat = pa->pa_dmat;
  253 
  254         /* Make sure bus mastering is enabled. */
  255         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
  256             pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
  257             PCI_COMMAND_MASTER_ENABLE);
  258 
  259         /*
  260          * Map and establish our interrupt.
  261          */
  262         if (pci_intr_map(pa, &ih)) {
  263                 printf("%s: unable to map interrupt\n", sc->sc_dev.dv_xname);
  264                 return;
  265         }
  266         intrstr = pci_intr_string(pa->pa_pc, ih);
  267         psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc);
  268         if (psc->sc_ih == NULL) {
  269                 printf("%s: unable to establish interrupt",
  270                     sc->sc_dev.dv_xname);
  271                 if (intrstr != NULL)
  272                         printf(" at %s", intrstr);
  273                 printf("\n");
  274                 return;
  275         }
  276         printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  277 
  278         /*
  279          * Finish off the attach.
  280          */
  281         sf_attach(sc);
  282 }

Cache object: 625ca167421eedaab11d62a986a6bdb6


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