root/dev/pci/if_sf_pci.c

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

DEFINITIONS

This source file includes following definitions.
  1. sf_pci_match
  2. sf_pci_attach

    1 /*      $OpenBSD: if_sf_pci.c,v 1.2 2006/12/06 22:43:38 martin Exp $    */
    2 /*      $NetBSD: if_sf_pci.c,v 1.10 2006/06/17 23:34:27 christos Exp $  */
    3 
    4 /*-
    5  * Copyright (c) 2001 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Jason R. Thorpe.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by the NetBSD
   22  *      Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * PCI bus front-end for the Adaptec AIC-6915 (``Starfire'')
   42  * 10/100 Ethernet controller.
   43  */
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/mbuf.h>
   48 #include <sys/malloc.h>
   49 #include <sys/kernel.h>
   50 #include <sys/socket.h>
   51 #include <sys/ioctl.h>
   52 #include <sys/errno.h>
   53 #include <sys/device.h>
   54 
   55 #include <net/if.h>
   56 #include <net/if_dl.h>
   57 #include <net/if_types.h>
   58 
   59 #ifdef INET
   60 #include <netinet/in.h>
   61 #include <netinet/in_systm.h>
   62 #include <netinet/in_var.h>
   63 #include <netinet/ip.h>
   64 #include <netinet/if_ether.h>
   65 #endif
   66 
   67 #include <net/if_media.h>
   68 
   69 #include <machine/bus.h>
   70 #include <machine/intr.h>
   71 
   72 #include <dev/mii/miivar.h>
   73 
   74 #include <dev/ic/aic6915.h>
   75 
   76 #include <dev/pci/pcireg.h>
   77 #include <dev/pci/pcivar.h>
   78 #include <dev/pci/pcidevs.h>
   79 
   80 struct sf_pci_softc {
   81         struct sf_softc sc_starfire;    /* read Starfire softc */
   82 
   83         /* PCI-specific goo. */
   84         void    *sc_ih;                 /* interrupt handle */
   85 };
   86 
   87 int     sf_pci_match(struct device *, void *, void *);
   88 void    sf_pci_attach(struct device *, struct device *, void *);
   89 
   90 struct cfattach sf_pci_ca = {
   91         sizeof(struct sf_pci_softc), sf_pci_match, sf_pci_attach
   92 };
   93 
   94 const struct pci_matchid sf_pci_products[] = {
   95         { PCI_VENDOR_ADP, PCI_PRODUCT_ADP_AIC6915 },
   96 };
   97 
   98 int
   99 sf_pci_match(struct device *parent, void *match, void *aux)
  100 {
  101         return (pci_matchbyid((struct pci_attach_args *)aux, sf_pci_products,
  102             sizeof(sf_pci_products)/sizeof(sf_pci_products[0])));
  103 }
  104 
  105 void
  106 sf_pci_attach(struct device *parent, struct device *self, void *aux)
  107 {
  108         struct sf_pci_softc *psc = (void *) self;
  109         struct sf_softc *sc = &psc->sc_starfire;
  110         struct pci_attach_args *pa = aux;
  111         pci_intr_handle_t ih;
  112         const char *intrstr = NULL;
  113         bus_space_tag_t iot, memt;
  114         bus_space_handle_t ioh, memh;
  115         pcireg_t reg;
  116         int pmreg, ioh_valid, memh_valid;
  117 
  118         if (pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_PWRMGMT,
  119             &pmreg, 0)) {
  120                 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR);
  121                 switch (reg & PCI_PMCSR_STATE_MASK) {
  122                 case PCI_PMCSR_STATE_D1:
  123                 case PCI_PMCSR_STATE_D2:
  124                         printf(": waking up from power state D%d\n%s",
  125                             reg & PCI_PMCSR_STATE_MASK, sc->sc_dev.dv_xname);
  126                         pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR,
  127                             (reg & ~PCI_PMCSR_STATE_MASK) |
  128                             PCI_PMCSR_STATE_D0);
  129                         break;
  130 
  131                 case PCI_PMCSR_STATE_D3:
  132                         printf("%s: unable to wake up from power state D3\n",
  133                             sc->sc_dev.dv_xname);
  134                         pci_conf_write(pa->pa_pc, pa->pa_tag, pmreg + PCI_PMCSR,
  135                             (reg & ~PCI_PMCSR_STATE_MASK) |
  136                             PCI_PMCSR_STATE_D0);
  137                         return;
  138                 }
  139         }
  140 
  141         /*
  142          * Map the device.
  143          */
  144         reg = pci_mapreg_type(pa->pa_pc, pa->pa_tag, SF_PCI_MEMBA);
  145         switch (reg) {
  146         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
  147         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
  148                 memh_valid = (pci_mapreg_map(pa, SF_PCI_MEMBA,
  149                     reg, 0, &memt, &memh, NULL, NULL, 0) == 0);
  150                 break;
  151         default:
  152                 memh_valid = 0;
  153         }
  154 
  155         ioh_valid = (pci_mapreg_map(pa,
  156             (reg == (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT)) ?
  157                 SF_PCI_IOBA : SF_PCI_IOBA - 0x04,
  158             PCI_MAPREG_TYPE_IO, 0,
  159             &iot, &ioh, NULL, NULL, 0) == 0);
  160 
  161         if (memh_valid) {
  162                 sc->sc_st = memt;
  163                 sc->sc_sh = memh;
  164                 sc->sc_iomapped = 0;
  165         } else if (ioh_valid) {
  166                 sc->sc_st = iot;
  167                 sc->sc_sh = ioh;
  168                 sc->sc_iomapped = 1;
  169         } else {
  170                 printf("%s: unable to map device registers\n",
  171                     sc->sc_dev.dv_xname);
  172                 return;
  173         }
  174 
  175         sc->sc_dmat = pa->pa_dmat;
  176 
  177         /* Make sure bus mastering is enabled. */
  178         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
  179             pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG) |
  180             PCI_COMMAND_MASTER_ENABLE);
  181 
  182         /*
  183          * Map and establish our interrupt.
  184          */
  185         if (pci_intr_map(pa, &ih)) {
  186                 printf("%s: unable to map interrupt\n", sc->sc_dev.dv_xname);
  187                 return;
  188         }
  189         intrstr = pci_intr_string(pa->pa_pc, ih);
  190         psc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_NET, sf_intr, sc,
  191             self->dv_xname);
  192         if (psc->sc_ih == NULL) {
  193                 printf("%s: unable to establish interrupt",
  194                     sc->sc_dev.dv_xname);
  195                 if (intrstr != NULL)
  196                         printf(" at %s", intrstr);
  197                 return;
  198         }
  199         printf(": %s", intrstr);
  200 
  201         /*
  202          * Finish off the attach.
  203          */
  204         sf_attach(sc);
  205 }

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