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/cardbus/if_bwi_cardbus.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 /*      $OpenBSD: if_bwi_cardbus.c,v 1.16 2022/04/06 18:59:28 naddy Exp $ */
    2 
    3 /*
    4  * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
    5  * Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
    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  * Cardbus front-end for the Broadcom AirForce
   22  */
   23 
   24 #include "bpfilter.h"
   25 
   26 #include <sys/param.h>
   27 #include <sys/mbuf.h>
   28 #include <sys/socket.h>
   29 #include <sys/systm.h>
   30 #include <sys/timeout.h>
   31 
   32 #include <net/if.h>
   33 #include <net/if_media.h>
   34 
   35 #include <netinet/in.h>
   36 #include <netinet/if_ether.h>
   37 
   38 #include <net80211/ieee80211_var.h>
   39 #include <net80211/ieee80211_amrr.h>
   40 #include <net80211/ieee80211_radiotap.h>
   41 
   42 #include <dev/pci/pcireg.h>
   43 #include <dev/pci/pcivar.h>
   44 #include <dev/pci/pcidevs.h>
   45 
   46 #include <dev/cardbus/cardbusvar.h>
   47 
   48 #include <dev/ic/bwivar.h>
   49 
   50 struct bwi_cardbus_softc {
   51         struct bwi_softc         csc_bwi;
   52 
   53         /* cardbus specific goo */
   54         cardbus_devfunc_t        csc_ct;
   55         pcitag_t                 csc_tag;
   56         void                    *csc_ih;
   57 
   58         bus_size_t               csc_mapsize;
   59         pcireg_t                 csc_bar_val;
   60         int                      csc_intrline;
   61         pci_chipset_tag_t        csc_pc;
   62 };
   63 
   64 int             bwi_cardbus_match(struct device *, void *, void*);
   65 void            bwi_cardbus_attach(struct device *, struct device *, void *);
   66 int             bwi_cardbus_detach(struct device *, int);
   67 void            bwi_cardbus_setup(struct bwi_cardbus_softc *);
   68 int             bwi_cardbus_enable(struct bwi_softc *);
   69 void            bwi_cardbus_disable(struct bwi_softc *);
   70 void            bwi_cardbus_conf_write(void *, uint32_t, uint32_t);
   71 uint32_t        bwi_cardbus_conf_read(void *, uint32_t);
   72 
   73 const struct cfattach bwi_cardbus_ca = {
   74         sizeof (struct bwi_cardbus_softc), bwi_cardbus_match,
   75         bwi_cardbus_attach, bwi_cardbus_detach
   76 };
   77 
   78 static const struct pci_matchid bwi_cardbus_devices[] = {
   79         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4303 },
   80         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4306 },
   81         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4306_2 },
   82         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4307 },
   83         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4309 },
   84         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4318 },
   85         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4319 },
   86         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM43XG }
   87 };
   88 
   89 int
   90 bwi_cardbus_match(struct device *parent, void *match, void *aux)
   91 {
   92         return (cardbus_matchbyid(aux, bwi_cardbus_devices,
   93             sizeof (bwi_cardbus_devices) / sizeof (bwi_cardbus_devices[0])));
   94 }
   95 
   96 void
   97 bwi_cardbus_attach(struct device *parent, struct device *self, void *aux)
   98 {
   99         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
  100         struct cardbus_attach_args *ca = aux;
  101         struct bwi_softc *sc = &csc->csc_bwi;
  102         cardbus_devfunc_t ct = ca->ca_ct;
  103         pcireg_t reg;
  104         bus_addr_t base;
  105         int error;
  106 
  107         sc->sc_dmat = ca->ca_dmat;
  108         csc->csc_ct = ct;
  109         csc->csc_tag = ca->ca_tag;
  110         csc->csc_intrline = ca->ca_intrline;
  111         csc->csc_pc = ca->ca_pc;
  112 
  113         /* power management hooks */
  114         sc->sc_enable = bwi_cardbus_enable;
  115         sc->sc_disable = bwi_cardbus_disable;
  116         //sc->sc_power = bwi_cardbus_power;
  117 
  118         /* map control/status registers */
  119         error = Cardbus_mapreg_map(ct, CARDBUS_BASE0_REG,
  120             PCI_MAPREG_TYPE_MEM, 0, &sc->sc_mem_bt,
  121             &sc->sc_mem_bh, &base, &csc->csc_mapsize);
  122         if (error != 0) {
  123                 printf(": can't map mem space\n");
  124                 return;
  125         }
  126         csc->csc_bar_val = base | PCI_MAPREG_TYPE_MEM;
  127 
  128         /* set up the PCI configuration registers */
  129         bwi_cardbus_setup(csc);
  130 
  131         printf(": irq %d", csc->csc_intrline);
  132 
  133         /* we need to access Cardbus config space from the driver */
  134         sc->sc_conf_read = bwi_cardbus_conf_read;
  135         sc->sc_conf_write = bwi_cardbus_conf_write;
  136 
  137         reg = (sc->sc_conf_read)(sc, PCI_SUBSYS_ID_REG);
  138 
  139         sc->sc_pci_revid = PCI_REVISION(ca->ca_class);
  140         sc->sc_pci_did = PCI_PRODUCT(ca->ca_id);
  141         sc->sc_pci_subvid = PCI_VENDOR(reg);
  142         sc->sc_pci_subdid = PCI_PRODUCT(reg);
  143 
  144         error = bwi_attach(sc);
  145         if (error != 0)
  146                 bwi_cardbus_detach(&sc->sc_dev, 0);
  147 
  148         Cardbus_function_disable(ct);
  149 }
  150 
  151 int
  152 bwi_cardbus_detach(struct device *self, int flags)
  153 {
  154         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
  155         struct bwi_softc *sc = &csc->csc_bwi;
  156         cardbus_devfunc_t ct = csc->csc_ct;
  157         cardbus_chipset_tag_t cc = ct->ct_cc;
  158         cardbus_function_tag_t cf = ct->ct_cf;
  159         int error;
  160 
  161         error = bwi_detach(sc);
  162         if (error != 0)
  163                 return (error);
  164 
  165         /* unhook the interrupt handler */
  166         if (csc->csc_ih != NULL) {
  167                 cardbus_intr_disestablish(cc, cf, csc->csc_ih);
  168                 csc->csc_ih = NULL;
  169         }
  170 
  171         /* release bus space and close window */
  172         Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_mem_bt,
  173             sc->sc_mem_bh, csc->csc_mapsize);
  174 
  175         return (0);
  176 }
  177 
  178 void
  179 bwi_cardbus_setup(struct bwi_cardbus_softc *csc)
  180 {
  181         cardbus_devfunc_t ct = csc->csc_ct;
  182         cardbus_chipset_tag_t cc = ct->ct_cc;
  183         pci_chipset_tag_t pc = csc->csc_pc;
  184         cardbus_function_tag_t cf = ct->ct_cf;
  185         pcireg_t reg;
  186 
  187         /* program the BAR */
  188         pci_conf_write(pc, csc->csc_tag, CARDBUS_BASE0_REG,
  189             csc->csc_bar_val);
  190 
  191         /* make sure the right access type is on the cardbus bridge */
  192         (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
  193         (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
  194 
  195         /* enable the appropriate bits in the PCI CSR */
  196         reg = pci_conf_read(pc, csc->csc_tag,
  197             PCI_COMMAND_STATUS_REG);
  198         reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
  199         pci_conf_write(pc, csc->csc_tag, PCI_COMMAND_STATUS_REG,
  200             reg);
  201 }
  202 
  203 int
  204 bwi_cardbus_enable(struct bwi_softc *sc)
  205 {
  206         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)sc;
  207         cardbus_devfunc_t ct = csc->csc_ct;
  208         cardbus_chipset_tag_t cc = ct->ct_cc;
  209         cardbus_function_tag_t cf = ct->ct_cf;
  210 
  211         /* power on the socket */
  212         Cardbus_function_enable(ct);
  213 
  214         /* setup the PCI configuration registers */
  215         bwi_cardbus_setup(csc);
  216 
  217         /* map and establish the interrupt handler */
  218         csc->csc_ih = cardbus_intr_establish(cc, cf, csc->csc_intrline, IPL_NET,
  219             bwi_intr, sc, sc->sc_dev.dv_xname);
  220         if (csc->csc_ih == NULL) {
  221                 printf("%s: could not establish interrupt at %d\n",
  222                     sc->sc_dev.dv_xname, csc->csc_intrline);
  223                 Cardbus_function_disable(ct);
  224                 return (1);
  225         }
  226 
  227         return (0);
  228 }
  229 
  230 void
  231 bwi_cardbus_disable(struct bwi_softc *sc)
  232 {
  233         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)sc;
  234         cardbus_devfunc_t ct = csc->csc_ct;
  235         cardbus_chipset_tag_t cc = ct->ct_cc;
  236         cardbus_function_tag_t cf = ct->ct_cf;
  237 
  238         /* unhook the interrupt handler */
  239         cardbus_intr_disestablish(cc, cf, csc->csc_ih);
  240         csc->csc_ih = NULL;
  241 
  242         /* power down the socket */
  243         Cardbus_function_disable(ct);
  244 }
  245 
  246 void
  247 bwi_cardbus_conf_write(void *self, uint32_t reg, uint32_t val)
  248 {
  249         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
  250         pci_chipset_tag_t pc = csc->csc_pc;
  251 
  252         pci_conf_write(pc, csc->csc_tag, reg, val);
  253 }
  254 
  255 uint32_t
  256 bwi_cardbus_conf_read(void *self, uint32_t reg)
  257 {
  258         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
  259         pci_chipset_tag_t pc = csc->csc_pc;
  260 
  261         return (pci_conf_read(pc, csc->csc_tag, reg));
  262 }

Cache object: a92f175d34e0e97043afeb2319a5b8c7


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