root/dev/pci/if_epic_pci.c

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

DEFINITIONS

This source file includes following definitions.
  1. epic_pci_subsys_lookup
  2. epic_pci_match
  3. epic_pci_attach

    1 /*      $OpenBSD: if_epic_pci.c,v 1.5 2006/04/20 20:31:12 miod Exp $    */
    2 /*      $NetBSD: if_epic_pci.c,v 1.28 2005/02/27 00:27:32 perry Exp $   */
    3 
    4 /*-
    5  * Copyright (c) 1998, 1999 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 of the Numerical Aerospace Simulation Facility,
   10  * NASA Ames Research Center.
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above copyright
   18  *    notice, this list of conditions and the following disclaimer in the
   19  *    documentation and/or other materials provided with the distribution.
   20  * 3. All advertising materials mentioning features or use of this software
   21  *    must display the following acknowledgement:
   22  *      This product includes software developed by the NetBSD
   23  *      Foundation, Inc. and its contributors.
   24  * 4. Neither the name of The NetBSD Foundation nor the names of its
   25  *    contributors may be used to endorse or promote products derived
   26  *    from this software without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   38  * POSSIBILITY OF SUCH DAMAGE.
   39  */
   40 
   41 /*
   42  * PCI bus front-end for the Standard Microsystems Corp. 83C170
   43  * Ethernet PCI Integrated Controller (EPIC/100) driver.
   44  */
   45 
   46 #if 0
   47 #include <sys/cdefs.h>
   48 __KERNEL_RCSID(0, "$NetBSD: if_epic_pci.c,v 1.28 2005/02/27 00:27:32 perry Exp $");
   49 #endif
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/mbuf.h>
   54 #include <sys/malloc.h>
   55 #include <sys/kernel.h>
   56 #include <sys/socket.h>
   57 #include <sys/ioctl.h>
   58 #include <sys/errno.h>
   59 #include <sys/device.h>
   60 
   61 #include <net/if.h>
   62 #include <net/if_dl.h>
   63 #include <net/if_types.h>
   64 
   65 #ifdef INET
   66 #include <netinet/in.h>
   67 #include <netinet/in_systm.h>
   68 #include <netinet/in_var.h>
   69 #include <netinet/ip.h>
   70 #include <netinet/if_ether.h>
   71 #endif
   72 
   73 #include <net/if_media.h>
   74 
   75 #include <machine/bus.h>
   76 #include <machine/intr.h>
   77 
   78 #include <dev/mii/miivar.h>
   79 
   80 #include <dev/ic/smc83c170reg.h>
   81 #include <dev/ic/smc83c170var.h>
   82 
   83 #include <dev/pci/pcivar.h>
   84 #include <dev/pci/pcireg.h>
   85 #include <dev/pci/pcidevs.h>
   86 
   87 /*
   88  * PCI configuration space registers used by the EPIC.
   89  */
   90 #define EPIC_PCI_IOBA           0x10    /* i/o mapped base */
   91 #define EPIC_PCI_MMBA           0x14    /* memory mapped base */
   92 
   93 struct epic_pci_softc {
   94         struct epic_softc sc_epic;      /* real EPIC softc */
   95 
   96         /* PCI-specific goo. */
   97         void    *sc_ih;                 /* interrupt handle */
   98 };
   99 
  100 int     epic_pci_match(struct device *, void *, void *);
  101 void    epic_pci_attach(struct device *, struct device *, void *);
  102 
  103 struct cfattach epic_pci_ca = {
  104         sizeof(struct epic_pci_softc), epic_pci_match, epic_pci_attach
  105 };
  106 
  107 const struct pci_matchid epic_pci_devices[] = {
  108         { PCI_VENDOR_SMC, PCI_PRODUCT_SMC_83C170 },
  109         { PCI_VENDOR_SMC, PCI_PRODUCT_SMC_83C175 },
  110 };
  111 
  112 static const struct epic_pci_subsys_info {
  113         pcireg_t subsysid;
  114         int flags;
  115 } epic_pci_subsys_info[] = {
  116         { PCI_ID_CODE(PCI_VENDOR_SMC, 0xa015), /* SMC9432BTX */
  117           EPIC_HAS_BNC },
  118         { PCI_ID_CODE(PCI_VENDOR_SMC, 0xa024), /* SMC9432BTX1 */
  119           EPIC_HAS_BNC },
  120         { PCI_ID_CODE(PCI_VENDOR_SMC, 0xa016), /* SMC9432FTX */
  121           EPIC_HAS_MII_FIBER | EPIC_DUPLEXLED_ON_694 },
  122         { 0xffffffff,
  123           0 }
  124 };
  125 
  126 static const struct epic_pci_subsys_info *
  127 epic_pci_subsys_lookup(const struct pci_attach_args *pa)
  128 {
  129         pci_chipset_tag_t pc = pa->pa_pc;
  130         pcireg_t reg;
  131         const struct epic_pci_subsys_info *esp;
  132 
  133         reg = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
  134 
  135         for (esp = epic_pci_subsys_info; esp->subsysid != 0xffffffff; esp++)
  136                 if (esp->subsysid == reg)
  137                         return (esp);
  138 
  139         return (NULL);
  140 }
  141 
  142 int
  143 epic_pci_match(struct device *parent, void *match, void *aux)
  144 {
  145         return (pci_matchbyid((struct pci_attach_args *)aux, epic_pci_devices,
  146             sizeof(epic_pci_devices)/sizeof(epic_pci_devices[0])));
  147 }
  148 
  149 void
  150 epic_pci_attach(struct device *parent, struct device *self, void *aux)
  151 {
  152         struct epic_pci_softc *psc = (struct epic_pci_softc *)self;
  153         struct epic_softc *sc = &psc->sc_epic;
  154         struct pci_attach_args *pa = aux;
  155         pci_chipset_tag_t pc = pa->pa_pc;
  156         pci_intr_handle_t ih;
  157         const char *intrstr = NULL;
  158         const struct epic_pci_subsys_info *esp;
  159         bus_space_tag_t iot, memt;
  160         bus_space_handle_t ioh, memh;
  161         pcireg_t reg;
  162         int pmreg, ioh_valid, memh_valid;
  163 
  164         if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
  165                 reg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
  166                 switch (reg & PCI_PMCSR_STATE_MASK) {
  167                 case PCI_PMCSR_STATE_D1:
  168                 case PCI_PMCSR_STATE_D2:
  169                         printf(": waking up from power state D%d\n",
  170                             reg & PCI_PMCSR_STATE_MASK);
  171                         pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
  172                             (reg & ~PCI_PMCSR_STATE_MASK) |
  173                             PCI_PMCSR_STATE_D0);
  174                         break;
  175                 case PCI_PMCSR_STATE_D3:
  176                         /*
  177                          * IO and MEM are disabled. We can't enable
  178                          * the card because the BARs might be invalid.
  179                          */
  180                         printf(
  181                             ": unable to wake up from power state D3, "
  182                             "reboot required.\n");
  183                         pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
  184                             (reg & ~PCI_PMCSR_STATE_MASK) |
  185                             PCI_PMCSR_STATE_D0);
  186                         return;
  187                 }
  188         }
  189 
  190         /*
  191          * Map the device.
  192          */
  193         ioh_valid = (pci_mapreg_map(pa, EPIC_PCI_IOBA,
  194             PCI_MAPREG_TYPE_IO, 0,
  195             &iot, &ioh, NULL, NULL, 0) == 0);
  196         memh_valid = (pci_mapreg_map(pa, EPIC_PCI_MMBA,
  197             PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
  198             &memt, &memh, NULL, NULL, 0) == 0);
  199 
  200         if (memh_valid) {
  201                 sc->sc_st = memt;
  202                 sc->sc_sh = memh;
  203         } else if (ioh_valid) {
  204                 sc->sc_st = iot;
  205                 sc->sc_sh = ioh;
  206         } else {
  207                 printf(": unable to map device registers\n");
  208                 return;
  209         }
  210 
  211         sc->sc_dmat = pa->pa_dmat;
  212 
  213         /*
  214          * Map and establish our interrupt.
  215          */
  216         if (pci_intr_map(pa, &ih)) {
  217                 printf(": unable to map interrupt\n");
  218                 return;
  219         }
  220         intrstr = pci_intr_string(pc, ih);
  221         psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, epic_intr, sc,
  222             self->dv_xname);
  223         if (psc->sc_ih == NULL) {
  224                 printf(": unable to establish interrupt");
  225                 if (intrstr != NULL)
  226                         printf(" at %s", intrstr);
  227                 printf("\n");
  228                 return;
  229         }
  230 
  231         esp = epic_pci_subsys_lookup(pa);
  232         if (esp)
  233                 sc->sc_hwflags = esp->flags;
  234 
  235         /*
  236          * Finish off the attach.
  237          */
  238         epic_attach(sc, intrstr);
  239 }

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