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/mwl/if_mwl_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 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting
    5  * Copyright (c) 2007-2009 Marvell Semiconductor, Inc.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer,
   13  *    without modification.
   14  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   15  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   16  *    redistribution must be conditioned upon including a substantially
   17  *    similar Disclaimer requirement for further binary redistribution.
   18  *
   19  * NO WARRANTY
   20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   22  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   23  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   24  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   25  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   28  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGES.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 #ifdef __FreeBSD__
   35 __FBSDID("$FreeBSD$");
   36 #endif
   37 
   38 /*
   39  * PCI front-end for the Marvell Wireless LAN controller driver.
   40  */
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h> 
   44 #include <sys/module.h>
   45 #include <sys/kernel.h>
   46 #include <sys/lock.h>
   47 #include <sys/malloc.h>
   48 #include <sys/mbuf.h>
   49 #include <sys/mutex.h>
   50 #include <sys/errno.h>
   51 
   52 #include <machine/bus.h>
   53 #include <machine/resource.h>
   54 #include <sys/bus.h>
   55 #include <sys/rman.h>
   56 
   57 #include <sys/socket.h>
   58 
   59 #include <net/ethernet.h>
   60 #include <net/if.h>
   61 #include <net/if_media.h>
   62 #include <net/if_arp.h>
   63 #include <net/route.h>
   64 
   65 #include <net80211/ieee80211_var.h>
   66 
   67 #include <dev/mwl/if_mwlvar.h>
   68 
   69 #include <dev/pci/pcivar.h>
   70 #include <dev/pci/pcireg.h>
   71 
   72 /*
   73  * PCI glue.
   74  */
   75 
   76 struct mwl_pci_softc {
   77         struct mwl_softc        sc_sc;
   78         struct resource         *sc_sr0;        /* BAR0 memory resource */
   79         struct resource         *sc_sr1;        /* BAR1 memory resource */
   80         struct resource         *sc_irq;        /* irq resource */
   81         void                    *sc_ih;         /* interrupt handler */
   82 };
   83 
   84 #define BS_BAR0 0x10
   85 #define BS_BAR1 0x14
   86 
   87 struct mwl_pci_ident {
   88         uint16_t        vendor;
   89         uint16_t        device;
   90         const char      *name;
   91 };
   92 
   93 static const struct mwl_pci_ident mwl_pci_ids[] = {
   94         { 0x11ab, 0x2a02, "Marvell 88W8363" },
   95         { 0x11ab, 0x2a03, "Marvell 88W8363" },
   96         { 0x11ab, 0x2a0a, "Marvell 88W8363" },
   97         { 0x11ab, 0x2a0b, "Marvell 88W8363" },
   98         { 0x11ab, 0x2a0c, "Marvell 88W8363" },
   99         { 0x11ab, 0x2a21, "Marvell 88W8363" },
  100         { 0x11ab, 0x2a24, "Marvell 88W8363" },
  101         { 0, 0, NULL }
  102 };
  103 
  104 const static struct mwl_pci_ident *
  105 mwl_pci_lookup(int vendor, int device)
  106 {
  107         const struct mwl_pci_ident *ident;
  108 
  109         for (ident = mwl_pci_ids; ident->name != NULL; ident++)
  110                 if (vendor == ident->vendor && device == ident->device)
  111                         return ident;
  112         return NULL;
  113 }
  114 
  115 static int
  116 mwl_pci_probe(device_t dev)
  117 {
  118         const struct mwl_pci_ident *ident;
  119 
  120         ident = mwl_pci_lookup(pci_get_vendor(dev), pci_get_device(dev));
  121         if (ident != NULL) {
  122                 device_set_desc(dev, ident->name);
  123                 return BUS_PROBE_DEFAULT;
  124         }
  125         return ENXIO;
  126 }
  127 
  128 static int
  129 mwl_pci_attach(device_t dev)
  130 {
  131         struct mwl_pci_softc *psc = device_get_softc(dev);
  132         struct mwl_softc *sc = &psc->sc_sc;
  133         int rid, error = ENXIO;
  134 
  135         sc->sc_dev = dev;
  136 
  137         pci_enable_busmaster(dev);
  138 
  139         /* 
  140          * Setup memory-mapping of PCI registers.
  141          */
  142         rid = BS_BAR0;
  143         psc->sc_sr0 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
  144                                             RF_ACTIVE);
  145         if (psc->sc_sr0 == NULL) {
  146                 device_printf(dev, "cannot map BAR0 register space\n");
  147                 goto bad;
  148         }
  149         rid = BS_BAR1;
  150         psc->sc_sr1 = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
  151                                             RF_ACTIVE);
  152         if (psc->sc_sr1 == NULL) {
  153                 device_printf(dev, "cannot map BAR1 register space\n");
  154                 goto bad1;
  155         }
  156         sc->sc_invalid = 1;
  157 
  158         /*
  159          * Arrange interrupt line.
  160          */
  161         rid = 0;
  162         psc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  163                                              RF_SHAREABLE|RF_ACTIVE);
  164         if (psc->sc_irq == NULL) {
  165                 device_printf(dev, "could not map interrupt\n");
  166                 goto bad2;
  167         }
  168         if (bus_setup_intr(dev, psc->sc_irq,
  169                            INTR_TYPE_NET | INTR_MPSAFE,
  170                            NULL, mwl_intr, sc, &psc->sc_ih)) {
  171                 device_printf(dev, "could not establish interrupt\n");
  172                 goto bad3;
  173         }
  174 
  175         /*
  176          * Setup DMA descriptor area.
  177          */
  178         if (bus_dma_tag_create(bus_get_dma_tag(dev),    /* parent */
  179                                1, 0,                    /* alignment, bounds */
  180                                BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
  181                                BUS_SPACE_MAXADDR,       /* highaddr */
  182                                NULL, NULL,              /* filter, filterarg */
  183                                BUS_SPACE_MAXSIZE,       /* maxsize */
  184                                MWL_TXDESC,              /* nsegments */
  185                                BUS_SPACE_MAXSIZE,       /* maxsegsize */
  186                                0,                       /* flags */
  187                                NULL,                    /* lockfunc */
  188                                NULL,                    /* lockarg */
  189                                &sc->sc_dmat)) {
  190                 device_printf(dev, "cannot allocate DMA tag\n");
  191                 goto bad4;
  192         }
  193 
  194         /*
  195          * Finish off the attach.
  196          */
  197         MWL_LOCK_INIT(sc);
  198         sc->sc_io0t = rman_get_bustag(psc->sc_sr0);
  199         sc->sc_io0h = rman_get_bushandle(psc->sc_sr0);
  200         sc->sc_io1t = rman_get_bustag(psc->sc_sr1);
  201         sc->sc_io1h = rman_get_bushandle(psc->sc_sr1);
  202         if (mwl_attach(pci_get_device(dev), sc) == 0)
  203                 return (0);
  204 
  205         MWL_LOCK_DESTROY(sc);
  206         bus_dma_tag_destroy(sc->sc_dmat);
  207 bad4:
  208         bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih);
  209 bad3:
  210         bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq);
  211 bad2:
  212         bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR1, psc->sc_sr1);
  213 bad1:
  214         bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR0, psc->sc_sr0);
  215 bad:
  216         return (error);
  217 }
  218 
  219 static int
  220 mwl_pci_detach(device_t dev)
  221 {
  222         struct mwl_pci_softc *psc = device_get_softc(dev);
  223         struct mwl_softc *sc = &psc->sc_sc;
  224 
  225         /* check if device was removed */
  226         sc->sc_invalid = !bus_child_present(dev);
  227 
  228         mwl_detach(sc);
  229 
  230         bus_generic_detach(dev);
  231         bus_teardown_intr(dev, psc->sc_irq, psc->sc_ih);
  232         bus_release_resource(dev, SYS_RES_IRQ, 0, psc->sc_irq);
  233 
  234         bus_dma_tag_destroy(sc->sc_dmat);
  235         bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR1, psc->sc_sr1);
  236         bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR0, psc->sc_sr0);
  237 
  238         MWL_LOCK_DESTROY(sc);
  239 
  240         return (0);
  241 }
  242 
  243 static int
  244 mwl_pci_shutdown(device_t dev)
  245 {
  246         struct mwl_pci_softc *psc = device_get_softc(dev);
  247 
  248         mwl_shutdown(&psc->sc_sc);
  249         return (0);
  250 }
  251 
  252 static int
  253 mwl_pci_suspend(device_t dev)
  254 {
  255         struct mwl_pci_softc *psc = device_get_softc(dev);
  256 
  257         mwl_suspend(&psc->sc_sc);
  258 
  259         return (0);
  260 }
  261 
  262 static int
  263 mwl_pci_resume(device_t dev)
  264 {
  265         struct mwl_pci_softc *psc = device_get_softc(dev);
  266 
  267         pci_enable_busmaster(dev);
  268 
  269         mwl_resume(&psc->sc_sc);
  270 
  271         return (0);
  272 }
  273 
  274 static device_method_t mwl_pci_methods[] = {
  275         /* Device interface */
  276         DEVMETHOD(device_probe,         mwl_pci_probe),
  277         DEVMETHOD(device_attach,        mwl_pci_attach),
  278         DEVMETHOD(device_detach,        mwl_pci_detach),
  279         DEVMETHOD(device_shutdown,      mwl_pci_shutdown),
  280         DEVMETHOD(device_suspend,       mwl_pci_suspend),
  281         DEVMETHOD(device_resume,        mwl_pci_resume),
  282         { 0,0 }
  283 };
  284 
  285 static driver_t mwl_pci_driver = {
  286         "mwl",
  287         mwl_pci_methods,
  288         sizeof (struct mwl_pci_softc)
  289 };
  290 
  291 DRIVER_MODULE(mwl, pci, mwl_pci_driver, 0, 0);
  292 MODULE_VERSION(mwl, 1);
  293 MODULE_DEPEND(mwl, wlan, 1, 1, 1);              /* 802.11 media layer */
  294 MODULE_DEPEND(mwl, firmware, 1, 1, 1);

Cache object: 675f21d5eead93fc1b96f870ca7bcf65


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