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/netif/ral/if_ral_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 /*      $FreeBSD: head/sys/dev/ral/if_ral_pci.c 189575 2009-03-09 13:23:54Z imp $       */
    2 
    3 /*-
    4  * Copyright (c) 2005, 2006
    5  *      Damien Bergamini <damien.bergamini@free.fr>
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  */
   19 
   20 
   21 /*
   22  * PCI/Cardbus front-end for the Ralink RT2560/RT2561/RT2561S/RT2661 driver.
   23  */
   24 
   25 #include <sys/param.h>
   26 #include <sys/sysctl.h>
   27 #include <sys/sockio.h>
   28 #include <sys/mbuf.h>
   29 #include <sys/kernel.h>
   30 #include <sys/socket.h>
   31 #include <sys/systm.h>
   32 #include <sys/malloc.h>
   33 #include <sys/module.h>
   34 #include <sys/bus.h>
   35 #include <sys/endian.h>
   36 #include <sys/rman.h>
   37 
   38 #include <net/bpf.h>
   39 #include <net/if.h>
   40 #include <net/if_arp.h>
   41 #include <net/ethernet.h>
   42 #include <net/if_dl.h>
   43 #include <net/if_media.h>
   44 #include <net/if_types.h>
   45 
   46 #include <netproto/802_11/ieee80211_var.h>
   47 #include <netproto/802_11/ieee80211_radiotap.h>
   48 #include <netproto/802_11/ieee80211_amrr.h>
   49 
   50 #include <bus/pci/pcireg.h>
   51 #include <bus/pci/pcivar.h>
   52 
   53 #include <dev/netif/ral/rt2560var.h>
   54 #include <dev/netif/ral/rt2661var.h>
   55 
   56 MODULE_DEPEND(ral, pci, 1, 1, 1);
   57 MODULE_DEPEND(ral, firmware, 1, 1, 1);
   58 MODULE_DEPEND(ral, wlan, 1, 1, 1);
   59 MODULE_DEPEND(ral, wlan_amrr, 1, 1, 1);
   60 
   61 struct ral_pci_ident {
   62         uint16_t        vendor;
   63         uint16_t        device;
   64         const char      *name;
   65 };
   66 
   67 static const struct ral_pci_ident ral_pci_ids[] = {
   68         { 0x1814, 0x0201, "Ralink Technology RT2560" },
   69         { 0x1814, 0x0301, "Ralink Technology RT2561S" },
   70         { 0x1814, 0x0302, "Ralink Technology RT2561" },
   71         { 0x1814, 0x0401, "Ralink Technology RT2661" },
   72 
   73         { 0, 0, NULL }
   74 };
   75 
   76 static struct ral_opns {
   77         int     (*attach)(device_t, int);
   78         int     (*detach)(void *);
   79         void    (*shutdown)(void *);
   80         void    (*suspend)(void *);
   81         void    (*resume)(void *);
   82         void    (*intr)(void *);
   83 
   84 }  ral_rt2560_opns = {
   85         rt2560_attach,
   86         rt2560_detach,
   87         rt2560_stop,
   88         rt2560_stop,
   89         rt2560_resume,
   90         rt2560_intr
   91 
   92 }, ral_rt2661_opns = {
   93         rt2661_attach,
   94         rt2661_detach,
   95         rt2661_shutdown,
   96         rt2661_suspend,
   97         rt2661_resume,
   98         rt2661_intr
   99 };
  100 
  101 struct ral_pci_softc {
  102         union {
  103                 struct rt2560_softc sc_rt2560;
  104                 struct rt2661_softc sc_rt2661;
  105         } u;
  106 
  107         struct ral_opns         *sc_opns;
  108         int                     irq_rid;
  109         int                     mem_rid;
  110         struct resource         *irq;
  111         struct resource         *mem;
  112         void                    *sc_ih;
  113 };
  114 
  115 static int ral_pci_probe(device_t);
  116 static int ral_pci_attach(device_t);
  117 static int ral_pci_detach(device_t);
  118 static int ral_pci_shutdown(device_t);
  119 static int ral_pci_suspend(device_t);
  120 static int ral_pci_resume(device_t);
  121 
  122 static device_method_t ral_pci_methods[] = {
  123         /* Device interface */
  124         DEVMETHOD(device_probe,         ral_pci_probe),
  125         DEVMETHOD(device_attach,        ral_pci_attach),
  126         DEVMETHOD(device_detach,        ral_pci_detach),
  127         DEVMETHOD(device_shutdown,      ral_pci_shutdown),
  128         DEVMETHOD(device_suspend,       ral_pci_suspend),
  129         DEVMETHOD(device_resume,        ral_pci_resume),
  130 
  131         DEVMETHOD_END
  132 };
  133 
  134 static driver_t ral_pci_driver = {
  135         "ral",
  136         ral_pci_methods,
  137         sizeof (struct ral_pci_softc)
  138 };
  139 
  140 static devclass_t ral_devclass;
  141 
  142 DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, NULL, NULL);
  143 
  144 static int
  145 ral_pci_probe(device_t dev)
  146 {
  147         const struct ral_pci_ident *ident;
  148 
  149         wlan_serialize_enter();
  150 
  151         for (ident = ral_pci_ids; ident->name != NULL; ident++) {
  152                 if (pci_get_vendor(dev) == ident->vendor &&
  153                     pci_get_device(dev) == ident->device) {
  154                         device_set_desc(dev, ident->name);
  155                         wlan_serialize_exit();
  156                         return 0;
  157                 }
  158         }
  159         wlan_serialize_exit();
  160         return ENXIO;
  161 }
  162 
  163 /* Base Address Register */
  164 #define RAL_PCI_BAR0    0x10
  165 
  166 static int
  167 ral_pci_attach(device_t dev)
  168 {
  169         struct ral_pci_softc *psc = device_get_softc(dev);
  170         struct rt2560_softc *sc = &psc->u.sc_rt2560;
  171         int error;
  172 
  173         wlan_serialize_enter();
  174         if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
  175                 device_printf(dev, "chip is in D%d power mode "
  176                     "-- setting to D0\n", pci_get_powerstate(dev));
  177                 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
  178         }
  179 
  180         /* enable bus-mastering */
  181         pci_enable_busmaster(dev);
  182 
  183         psc->sc_opns = (pci_get_device(dev) == 0x0201) ? &ral_rt2560_opns :
  184             &ral_rt2661_opns;
  185 
  186         psc->mem_rid = RAL_PCI_BAR0;
  187         psc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &psc->mem_rid,
  188             RF_ACTIVE);
  189         if (psc->mem == NULL) {
  190                 device_printf(dev, "could not allocate memory resource\n");
  191                 wlan_serialize_exit();
  192                 return ENXIO;
  193         }
  194 
  195         sc->sc_st = rman_get_bustag(psc->mem);
  196         sc->sc_sh = rman_get_bushandle(psc->mem);
  197         sc->sc_invalid = 1;
  198         
  199         psc->irq_rid = 0;
  200         psc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &psc->irq_rid,
  201             RF_ACTIVE | RF_SHAREABLE);
  202         if (psc->irq == NULL) {
  203                 device_printf(dev, "could not allocate interrupt resource\n");
  204                 wlan_serialize_exit();
  205                 return ENXIO;
  206         }
  207 
  208         error = (*psc->sc_opns->attach)(dev, pci_get_device(dev));
  209         if (error != 0) {
  210                 wlan_serialize_exit();
  211                 return error;
  212         }
  213 
  214         /*
  215          * Hook our interrupt after all initialization is complete.
  216          */
  217         error = bus_setup_intr(dev, psc->irq, INTR_MPSAFE,
  218             psc->sc_opns->intr, psc, &psc->sc_ih, &wlan_global_serializer);
  219         if (error != 0) {
  220                 device_printf(dev, "could not set up interrupt\n");
  221                 wlan_serialize_exit();
  222                 return error;
  223         }
  224         sc->sc_invalid = 0;
  225         
  226         wlan_serialize_exit();
  227         return 0;
  228 }
  229 
  230 static int
  231 ral_pci_detach(device_t dev)
  232 {
  233         struct ral_pci_softc *psc = device_get_softc(dev);
  234         struct rt2560_softc *sc = &psc->u.sc_rt2560;
  235         
  236         wlan_serialize_enter();
  237         /* check if device was removed */
  238         sc->sc_invalid = !bus_child_present(dev);
  239         
  240         (*psc->sc_opns->detach)(psc);
  241 
  242         bus_generic_detach(dev);
  243         bus_teardown_intr(dev, psc->irq, psc->sc_ih);
  244         bus_release_resource(dev, SYS_RES_IRQ, psc->irq_rid, psc->irq);
  245 
  246         bus_release_resource(dev, SYS_RES_MEMORY, psc->mem_rid, psc->mem);
  247 
  248         wlan_serialize_exit();
  249         return 0;
  250 }
  251 
  252 static int
  253 ral_pci_shutdown(device_t dev)
  254 {
  255         struct ral_pci_softc *psc = device_get_softc(dev);
  256 
  257         wlan_serialize_enter();
  258         (*psc->sc_opns->shutdown)(psc);
  259         wlan_serialize_exit();
  260 
  261         return 0;
  262 }
  263 
  264 static int
  265 ral_pci_suspend(device_t dev)
  266 {
  267         struct ral_pci_softc *psc = device_get_softc(dev);
  268 
  269         wlan_serialize_enter();
  270         (*psc->sc_opns->suspend)(psc);
  271         wlan_serialize_exit();
  272 
  273         return 0;
  274 }
  275 
  276 static int
  277 ral_pci_resume(device_t dev)
  278 {
  279         struct ral_pci_softc *psc = device_get_softc(dev);
  280 
  281         wlan_serialize_enter();
  282         (*psc->sc_opns->resume)(psc);
  283         wlan_serialize_exit();
  284 
  285         return 0;
  286 }

Cache object: ed9e28240c2fc9f0b7c95f4589c7e6ef


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