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_le_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_le_pci.c,v 1.40 2003/08/07 16:31:11 agc Exp $       */
    2 
    3 /*-
    4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center.
   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  * Copyright (c) 1992, 1993
   42  *      The Regents of the University of California.  All rights reserved.
   43  *
   44  * This code is derived from software contributed to Berkeley by
   45  * Ralph Campbell and Rick Macklem.
   46  *
   47  * Redistribution and use in source and binary forms, with or without
   48  * modification, are permitted provided that the following conditions
   49  * are met:
   50  * 1. Redistributions of source code must retain the above copyright
   51  *    notice, this list of conditions and the following disclaimer.
   52  * 2. Redistributions in binary form must reproduce the above copyright
   53  *    notice, this list of conditions and the following disclaimer in the
   54  *    documentation and/or other materials provided with the distribution.
   55  * 3. Neither the name of the University nor the names of its contributors
   56  *    may be used to endorse or promote products derived from this software
   57  *    without specific prior written permission.
   58  *
   59  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   60  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   61  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   62  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   63  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   64  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   65  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   66  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   67  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   68  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   69  * SUCH DAMAGE.
   70  *
   71  *      @(#)if_le.c     8.2 (Berkeley) 11/16/93
   72  */
   73 
   74 #include <sys/cdefs.h>
   75 __KERNEL_RCSID(0, "$NetBSD: if_le_pci.c,v 1.40 2003/08/07 16:31:11 agc Exp $");
   76 
   77 #include <sys/param.h>
   78 #include <sys/systm.h>
   79 #include <sys/mbuf.h>
   80 #include <sys/syslog.h>
   81 #include <sys/socket.h>
   82 #include <sys/device.h>
   83 
   84 #include <uvm/uvm_extern.h>
   85 
   86 #include <net/if.h>
   87 #include <net/if_ether.h>
   88 #include <net/if_media.h>
   89 
   90 #include <machine/cpu.h>
   91 #include <machine/bus.h>
   92 #include <machine/intr.h>
   93 
   94 #include <dev/pci/pcireg.h>
   95 #include <dev/pci/pcivar.h>
   96 #include <dev/pci/pcidevs.h>
   97 
   98 #include <dev/ic/lancereg.h>
   99 #include <dev/ic/lancevar.h>
  100 #include <dev/ic/am79900reg.h>
  101 #include <dev/ic/am79900var.h>
  102 
  103 #include <dev/pci/if_levar.h>
  104 
  105 int le_pci_match __P((struct device *, struct cfdata *, void *));
  106 void le_pci_attach __P((struct device *, struct device *, void *));
  107 int le_pci_mediachange __P((struct lance_softc *));
  108 
  109 CFATTACH_DECL(le_pci, sizeof(struct le_softc),
  110     le_pci_match, le_pci_attach, NULL, NULL);
  111 
  112 #if defined(_KERNEL_OPT)
  113 #include "opt_ddb.h"
  114 #endif
  115 
  116 #ifdef DDB
  117 #define integrate
  118 #define hide
  119 #else
  120 #define integrate       static __inline
  121 #define hide            static
  122 #endif
  123 
  124 hide void le_pci_wrcsr __P((struct lance_softc *, u_int16_t, u_int16_t));
  125 hide u_int16_t le_pci_rdcsr __P((struct lance_softc *, u_int16_t));
  126 
  127 /*
  128  * PCI constants.
  129  * XXX These should be in a common file!
  130  */
  131 #define PCI_CBIO        0x10            /* Configuration Base IO Address */
  132 
  133 #define LE_PCI_MEMSIZE  16384
  134 
  135 static int le_pci_supmedia[] = {
  136         IFM_ETHER|IFM_AUTO,
  137         IFM_ETHER|IFM_AUTO|IFM_FDX,
  138         IFM_ETHER|IFM_10_T,
  139         IFM_ETHER|IFM_10_T|IFM_FDX,
  140         IFM_ETHER|IFM_10_5,
  141         IFM_ETHER|IFM_10_5|IFM_FDX,
  142 };
  143 
  144 hide void
  145 le_pci_wrcsr(sc, port, val)
  146         struct lance_softc *sc;
  147         u_int16_t port, val;
  148 {
  149         struct le_softc *lesc = (struct le_softc *)sc;
  150         bus_space_tag_t iot = lesc->sc_iot;
  151         bus_space_handle_t ioh = lesc->sc_ioh;
  152 
  153         bus_space_write_2(iot, ioh, lesc->sc_rap, port);
  154         bus_space_write_2(iot, ioh, lesc->sc_rdp, val);
  155 }
  156 
  157 hide u_int16_t
  158 le_pci_rdcsr(sc, port)
  159         struct lance_softc *sc;
  160         u_int16_t port;
  161 {
  162         struct le_softc *lesc = (struct le_softc *)sc;
  163         bus_space_tag_t iot = lesc->sc_iot;
  164         bus_space_handle_t ioh = lesc->sc_ioh;
  165         u_int16_t val;
  166 
  167         bus_space_write_2(iot, ioh, lesc->sc_rap, port);
  168         val = bus_space_read_2(iot, ioh, lesc->sc_rdp);
  169         return (val);
  170 }
  171 
  172 int
  173 le_pci_mediachange(sc)
  174         struct lance_softc *sc;
  175 {
  176         struct le_softc *lesc = (struct le_softc *)sc;
  177         bus_space_tag_t iot = lesc->sc_iot;
  178         bus_space_handle_t ioh = lesc->sc_ioh;
  179         int newmedia = sc->sc_media.ifm_media;
  180         u_int16_t reg;
  181 
  182         if (IFM_SUBTYPE(newmedia) !=
  183             IFM_SUBTYPE(lesc->sc_currentmedia)) {
  184                 if (IFM_SUBTYPE(newmedia) == IFM_AUTO) {
  185                         /* switch to autoselect - BCR2 bit 1 */
  186                         bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 2);
  187                         reg = bus_space_read_2(iot, ioh, PCNET_PCI_BDP);
  188                         reg |= 2;
  189                         bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 2);
  190                         bus_space_write_2(iot, ioh, PCNET_PCI_BDP, reg);
  191                 } else {
  192                         /* force media type (in init block) */
  193                         lance_reset(sc);
  194                         if (IFM_SUBTYPE(newmedia) == IFM_10_T)
  195                                 sc->sc_initmodemedia = 1; /* UTP */
  196                         else
  197                                 sc->sc_initmodemedia = 0; /* AUI */
  198                         lance_init(&sc->sc_ethercom.ec_if);
  199 
  200                         if (IFM_SUBTYPE(lesc->sc_currentmedia) == IFM_AUTO) {
  201                                 /* take away autoselect - BCR2 bit 1 */
  202                                 bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 2);
  203                                 reg = bus_space_read_2(iot, ioh, PCNET_PCI_BDP);
  204                                 reg &= ~2;
  205                                 bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 2);
  206                                 bus_space_write_2(iot, ioh, PCNET_PCI_BDP, reg);
  207                         }
  208                 }
  209                 
  210         }
  211 
  212         if ((IFM_OPTIONS(newmedia) ^ IFM_OPTIONS(lesc->sc_currentmedia))
  213             & IFM_FDX) {
  214                 /* toggle full duplex - BCR9 */
  215                 bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 9);
  216                 reg = bus_space_read_2(iot, ioh, PCNET_PCI_BDP);
  217                 if (IFM_OPTIONS(newmedia) & IFM_FDX) {
  218                         reg |= 1; /* FDEN */
  219                         /* allow FDX on AUI only if explicitly chosen,
  220                          not in autoselect mode */
  221                         if (IFM_SUBTYPE(newmedia) == IFM_10_5)
  222                                 reg |= 2; /* AUIFD */
  223                         else
  224                                 reg &= ~2;
  225                 } else
  226                         reg &= ~1;
  227                 bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 9);
  228                 bus_space_write_2(iot, ioh, PCNET_PCI_BDP, reg);
  229         }
  230 
  231         lesc->sc_currentmedia = newmedia;
  232         return (0);
  233 }
  234 
  235 int
  236 le_pci_match(parent, match, aux)
  237         struct device *parent;
  238         struct cfdata *match;
  239         void *aux;
  240 {
  241         struct pci_attach_args *pa = aux;
  242 
  243         if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AMD)
  244                 return (0);
  245 
  246         switch (PCI_PRODUCT(pa->pa_id)) {
  247         case PCI_PRODUCT_AMD_PCNET_PCI:
  248                 return (1);
  249         }
  250 
  251         return (0);
  252 }
  253 
  254 void
  255 le_pci_attach(parent, self, aux)
  256         struct device *parent, *self;
  257         void *aux;
  258 {
  259         struct le_softc *lesc = (void *)self;
  260         struct lance_softc *sc = &lesc->sc_am79900.lsc;
  261         struct pci_attach_args *pa = aux;
  262         pci_intr_handle_t ih;
  263         bus_space_tag_t iot;
  264         bus_space_handle_t ioh;
  265         bus_dma_tag_t dmat = pa->pa_dmat;
  266         bus_dma_segment_t seg;
  267         pci_chipset_tag_t pc = pa->pa_pc;
  268         pcireg_t csr;
  269         int i, rseg;
  270         const char *model, *intrstr;
  271 
  272         switch (PCI_PRODUCT(pa->pa_id)) {
  273         case PCI_PRODUCT_AMD_PCNET_PCI:
  274                 model = "PCnet-PCI Ethernet";
  275                 lesc->sc_rap = PCNET_PCI_RAP;
  276                 lesc->sc_rdp = PCNET_PCI_RDP;
  277                 break;
  278 
  279         default:
  280                 model = "unknown model!";
  281         }
  282 
  283         printf(": %s\n", model);
  284 
  285         if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_IO, 0,
  286             &iot, &ioh, NULL, NULL)) {
  287                 printf("%s: can't map I/O space\n", sc->sc_dev.dv_xname);
  288                 return;
  289         }
  290 
  291         /*
  292          * Extract the physical MAC address from the ROM.
  293          */
  294         for (i = 0; i < sizeof(sc->sc_enaddr); i++)
  295                 sc->sc_enaddr[i] = bus_space_read_1(iot, ioh, i);
  296 
  297         lesc->sc_iot = iot;
  298         lesc->sc_ioh = ioh;
  299         lesc->sc_dmat = dmat;
  300 
  301         /*
  302          * Allocate a DMA area for the card.
  303          */
  304         if (bus_dmamem_alloc(dmat, LE_PCI_MEMSIZE, PAGE_SIZE, 0, &seg, 1,
  305             &rseg, BUS_DMA_NOWAIT)) {
  306                 printf("%s: couldn't allocate memory for card\n",
  307                     sc->sc_dev.dv_xname);
  308                 return;
  309         }
  310         if (bus_dmamem_map(dmat, &seg, rseg, LE_PCI_MEMSIZE,
  311             (caddr_t *)&sc->sc_mem,
  312             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) {
  313                 printf("%s: couldn't map memory for card\n",
  314                     sc->sc_dev.dv_xname);
  315                 return;
  316         }
  317 
  318         /*
  319          * Create and load the DMA map for the DMA area.
  320          */
  321         if (bus_dmamap_create(dmat, LE_PCI_MEMSIZE, 1,
  322             LE_PCI_MEMSIZE, 0, BUS_DMA_NOWAIT, &lesc->sc_dmam)) {
  323                 printf("%s: couldn't create DMA map\n",
  324                     sc->sc_dev.dv_xname);
  325                 bus_dmamem_free(dmat, &seg, rseg);
  326                 return;
  327         }
  328         if (bus_dmamap_load(dmat, lesc->sc_dmam,
  329             sc->sc_mem, LE_PCI_MEMSIZE, NULL, BUS_DMA_NOWAIT)) {
  330                 printf("%s: coundn't load DMA map\n",
  331                     sc->sc_dev.dv_xname);
  332                 bus_dmamem_free(dmat, &seg, rseg);
  333                 return;
  334         }
  335 
  336         sc->sc_conf3 = 0;
  337         sc->sc_addr = lesc->sc_dmam->dm_segs[0].ds_addr;
  338         sc->sc_memsize = LE_PCI_MEMSIZE;
  339 
  340         sc->sc_copytodesc = lance_copytobuf_contig;
  341         sc->sc_copyfromdesc = lance_copyfrombuf_contig;
  342         sc->sc_copytobuf = lance_copytobuf_contig;
  343         sc->sc_copyfrombuf = lance_copyfrombuf_contig;
  344         sc->sc_zerobuf = lance_zerobuf_contig;
  345 
  346         sc->sc_rdcsr = le_pci_rdcsr;
  347         sc->sc_wrcsr = le_pci_wrcsr;
  348         sc->sc_hwinit = NULL;
  349 
  350         sc->sc_supmedia = le_pci_supmedia;
  351         sc->sc_nsupmedia = sizeof(le_pci_supmedia) / sizeof(int);
  352         sc->sc_defaultmedia = le_pci_supmedia[0];
  353         sc->sc_mediachange = le_pci_mediachange;
  354         lesc->sc_currentmedia = le_pci_supmedia[0];
  355 
  356         printf("%s", sc->sc_dev.dv_xname);
  357         am79900_config(&lesc->sc_am79900);
  358 
  359         /* Chip is stopped. Set "software style" to 32-bit. */
  360         bus_space_write_2(iot, ioh, PCNET_PCI_RAP, 20);
  361         bus_space_write_2(iot, ioh, PCNET_PCI_BDP, 2);
  362 
  363         /* Enable the card. */
  364         csr = pci_conf_read(pc, pa->pa_tag,
  365             PCI_COMMAND_STATUS_REG);
  366         pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
  367             csr | PCI_COMMAND_MASTER_ENABLE);
  368 
  369         /* Map and establish the interrupt. */
  370         if (pci_intr_map(pa, &ih)) {
  371                 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
  372                 return;
  373         }
  374         intrstr = pci_intr_string(pc, ih);
  375         lesc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, am79900_intr, sc);
  376         if (lesc->sc_ih == NULL) {
  377                 printf("%s: couldn't establish interrupt",
  378                     sc->sc_dev.dv_xname);
  379                 if (intrstr != NULL)
  380                         printf(" at %s", intrstr);
  381                 printf("\n");
  382                 return;
  383         }
  384         printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  385 }

Cache object: d80782b1cc62de67e857ecb51e6171e6


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