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/bwi/if_bwi_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) 2002-2007 Sam Leffler, Errno Consulting
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer,
   12  *    without modification.
   13  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   14  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
   15  *    redistribution must be conditioned upon including a substantially
   16  *    similar Disclaimer requirement for further binary redistribution.
   17  *
   18  * NO WARRANTY
   19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   21  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
   22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   23  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
   24  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   27  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   29  * THE POSSIBILITY OF SUCH DAMAGES.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 /*
   36  * PCI/Cardbus front-end for the Broadcom Wireless LAN controller driver.
   37  */
   38 
   39 #include "opt_wlan.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/systm.h> 
   43 #include <sys/module.h>
   44 #include <sys/kernel.h>
   45 #include <sys/lock.h>
   46 #include <sys/malloc.h>
   47 #include <sys/mutex.h>
   48 #include <sys/errno.h>
   49 
   50 #include <machine/bus.h>
   51 #include <machine/resource.h>
   52 #include <sys/bus.h>
   53 #include <sys/rman.h>
   54 
   55 #include <sys/socket.h>
   56 
   57 #include <net/if.h>
   58 #include <net/if_var.h>
   59 #include <net/if_media.h>
   60 #include <net/if_arp.h>
   61 #include <net/ethernet.h>
   62 
   63 #include <net80211/ieee80211_var.h>
   64 #include <net80211/ieee80211_radiotap.h>
   65 #include <net80211/ieee80211_amrr.h>
   66 
   67 #include <dev/pci/pcivar.h>
   68 #include <dev/pci/pcireg.h>
   69 
   70 #include <dev/bwi/if_bwivar.h>
   71 #include <dev/bwi/if_bwireg.h>
   72 #include <dev/bwi/bitops.h>
   73 
   74 /*
   75  * PCI glue.
   76  */
   77 
   78 struct bwi_pci_softc {
   79         struct bwi_softc        sc_sc;
   80 };
   81 
   82 #define BS_BAR  0x10
   83 #define PCIR_RETRY_TIMEOUT      0x41
   84 
   85 static const struct bwi_dev {
   86         uint16_t        vid;
   87         uint16_t        did;
   88         const char      *desc;
   89 } bwi_devices[] = {
   90         { PCI_VENDOR_BROADCOM, 0x4301,"Broadcom BCM4301 802.11b Wireless Lan" },
   91         { PCI_VENDOR_BROADCOM, 0x4307,"Broadcom BCM4307 802.11b Wireless Lan" },
   92         { PCI_VENDOR_BROADCOM, 0x4311,"Broadcom BCM4311 802.11b/g Wireless Lan" },
   93         { PCI_VENDOR_BROADCOM, 0x4312,"Broadcom BCM4312 802.11a/b/g Wireless Lan" },
   94         { PCI_VENDOR_BROADCOM, 0x4313,"Broadcom BCM4312 802.11a Wireless Lan" },
   95         { PCI_VENDOR_BROADCOM, 0x4320,"Broadcom BCM4306 802.11b/g Wireless Lan"},
   96         { PCI_VENDOR_BROADCOM, 0x4321,"Broadcom BCM4306 802.11a Wireless Lan"},
   97         { PCI_VENDOR_BROADCOM, 0x4325,"Broadcom BCM4306 802.11b/g Wireless Lan"},
   98         { PCI_VENDOR_BROADCOM, 0x4324,"Broadcom BCM4309 802.11a/b/g Wireless Lan" },
   99         { PCI_VENDOR_BROADCOM, 0x4318,"Broadcom BCM4318 802.11b/g Wireless Lan" },
  100         { PCI_VENDOR_BROADCOM, 0x4319,"Broadcom BCM4318 802.11a/b/g Wireless Lan" },
  101         { PCI_VENDOR_BROADCOM, 0x431a,"Broadcom BCM4318 802.11a Wireless Lan" },
  102         { 0, 0, NULL }
  103 };
  104 
  105 static int
  106 bwi_pci_probe(device_t dev)
  107 {
  108         const struct bwi_dev *b;
  109         uint16_t did, vid;
  110 
  111         did = pci_get_device(dev);
  112         vid = pci_get_vendor(dev);
  113 
  114         for (b = bwi_devices; b->desc != NULL; ++b) {
  115                 if (b->did == did && b->vid == vid) {
  116                         device_set_desc(dev, b->desc);
  117                         return BUS_PROBE_DEFAULT;
  118                 }
  119         }
  120         return ENXIO;
  121 }
  122 
  123 static int
  124 bwi_pci_attach(device_t dev)
  125 {
  126         struct bwi_pci_softc *psc = device_get_softc(dev);
  127         struct bwi_softc *sc = &psc->sc_sc;
  128         int error = ENXIO;
  129 
  130         sc->sc_dev = dev;
  131 
  132         /*
  133          * Enable bus mastering.
  134          */
  135         pci_enable_busmaster(dev);
  136 
  137         /* 
  138          * Setup memory-mapping of PCI registers.
  139          */
  140         sc->sc_mem_rid = BWI_PCIR_BAR;
  141         sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
  142                 &sc->sc_mem_rid, RF_ACTIVE);
  143         if (sc->sc_mem_res == NULL) {
  144                 device_printf(dev, "cannot map register space\n");
  145                 goto bad;
  146         }
  147         sc->sc_mem_bt = rman_get_bustag(sc->sc_mem_res);
  148         sc->sc_mem_bh = rman_get_bushandle(sc->sc_mem_res);
  149         /*
  150          * Mark device invalid so any interrupts (shared or otherwise)
  151          * that arrive before the card is setup are discarded.
  152          */
  153         sc->sc_invalid = 1;
  154 
  155         /*
  156          * Arrange interrupt line.
  157          */
  158         sc->sc_irq_rid = 0;
  159         sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
  160                                                 &sc->sc_irq_rid,
  161                                                 RF_SHAREABLE|RF_ACTIVE);
  162         if (sc->sc_irq_res == NULL) {
  163                 device_printf(dev, "could not map interrupt\n");
  164                 goto bad1;
  165         }
  166 
  167         /* Get more PCI information */
  168         sc->sc_pci_did = pci_get_device(dev);
  169         sc->sc_pci_revid = pci_get_revid(dev);
  170         sc->sc_pci_subvid = pci_get_subvendor(dev);
  171         sc->sc_pci_subdid = pci_get_subdevice(dev);
  172 
  173         if ((error = bwi_attach(sc)) != 0)
  174                 goto bad2;
  175 
  176         if (bus_setup_intr(dev, sc->sc_irq_res,
  177                            INTR_TYPE_NET | INTR_MPSAFE,
  178                            NULL, bwi_intr, sc, &sc->sc_irq_handle)) {
  179                 device_printf(dev, "could not establish interrupt\n");
  180                 goto bad2;
  181         }
  182         return (0);
  183 
  184 bad2:
  185         bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
  186 bad1:
  187         bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, sc->sc_mem_res);
  188 bad:
  189         return (error);
  190 }
  191 
  192 static int
  193 bwi_pci_detach(device_t dev)
  194 {
  195         struct bwi_pci_softc *psc = device_get_softc(dev);
  196         struct bwi_softc *sc = &psc->sc_sc;
  197 
  198         /* check if device was removed */
  199         sc->sc_invalid = !bus_child_present(dev);
  200 
  201         bwi_detach(sc);
  202 
  203         bus_generic_detach(dev);
  204         bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_handle);
  205         bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
  206 
  207         bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, sc->sc_mem_res);
  208 
  209         return (0);
  210 }
  211 
  212 static int
  213 bwi_pci_shutdown(device_t dev)
  214 {
  215         struct bwi_pci_softc *psc = device_get_softc(dev);
  216 
  217         bwi_shutdown(&psc->sc_sc);
  218         return (0);
  219 }
  220 
  221 static int
  222 bwi_pci_suspend(device_t dev)
  223 {
  224         struct bwi_pci_softc *psc = device_get_softc(dev);
  225 
  226         bwi_suspend(&psc->sc_sc);
  227 
  228         return (0);
  229 }
  230 
  231 static int
  232 bwi_pci_resume(device_t dev)
  233 {
  234         struct bwi_pci_softc *psc = device_get_softc(dev);
  235 
  236         bwi_resume(&psc->sc_sc);
  237 
  238         return (0);
  239 }
  240 
  241 static device_method_t bwi_pci_methods[] = {
  242         /* Device interface */
  243         DEVMETHOD(device_probe,         bwi_pci_probe),
  244         DEVMETHOD(device_attach,        bwi_pci_attach),
  245         DEVMETHOD(device_detach,        bwi_pci_detach),
  246         DEVMETHOD(device_shutdown,      bwi_pci_shutdown),
  247         DEVMETHOD(device_suspend,       bwi_pci_suspend),
  248         DEVMETHOD(device_resume,        bwi_pci_resume),
  249         { 0,0 }
  250 };
  251 
  252 static driver_t bwi_driver = {
  253         "bwi",
  254         bwi_pci_methods,
  255         sizeof (struct bwi_pci_softc)
  256 };
  257 
  258 DRIVER_MODULE(bwi, pci, bwi_driver, 0, 0);
  259 MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwi, bwi_devices,
  260     nitems(bwi_devices) - 1);
  261 MODULE_DEPEND(bwi, wlan, 1, 1, 1);              /* 802.11 media layer */
  262 MODULE_DEPEND(bwi, firmware, 1, 1, 1);          /* firmware support */
  263 MODULE_DEPEND(bwi, wlan_amrr, 1, 1, 1);

Cache object: c890463b85d78c5108496df888a725c2


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