LCOV - code coverage report
Current view: top level - dev/cardbus - if_bwi_cardbus.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 97 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: if_bwi_cardbus.c,v 1.15 2013/12/06 21:03:02 deraadt 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             : 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           0 : bwi_cardbus_match(struct device *parent, void *match, void *aux)
      91             : {
      92           0 :         return (cardbus_matchbyid(aux, bwi_cardbus_devices,
      93             :             sizeof (bwi_cardbus_devices) / sizeof (bwi_cardbus_devices[0])));
      94             : }
      95             : 
      96             : void
      97           0 : bwi_cardbus_attach(struct device *parent, struct device *self, void *aux)
      98             : {
      99           0 :         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
     100           0 :         struct cardbus_attach_args *ca = aux;
     101           0 :         struct bwi_softc *sc = &csc->csc_bwi;
     102           0 :         cardbus_devfunc_t ct = ca->ca_ct;
     103             :         pcireg_t reg;
     104           0 :         bus_addr_t base;
     105             :         int error;
     106             : 
     107           0 :         sc->sc_dmat = ca->ca_dmat;
     108           0 :         csc->csc_ct = ct;
     109           0 :         csc->csc_tag = ca->ca_tag;
     110           0 :         csc->csc_intrline = ca->ca_intrline;
     111           0 :         csc->csc_pc = ca->ca_pc;
     112             : 
     113             :         /* power management hooks */
     114           0 :         sc->sc_enable = bwi_cardbus_enable;
     115           0 :         sc->sc_disable = bwi_cardbus_disable;
     116             :         //sc->sc_power = bwi_cardbus_power;
     117             : 
     118             :         /* map control/status registers */
     119           0 :         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           0 :         if (error != 0) {
     123           0 :                 printf(": can't map mem space\n");
     124           0 :                 return;
     125             :         }
     126           0 :         csc->csc_bar_val = base | PCI_MAPREG_TYPE_MEM;
     127             : 
     128             :         /* set up the PCI configuration registers */
     129           0 :         bwi_cardbus_setup(csc);
     130             : 
     131           0 :         printf(": irq %d", csc->csc_intrline);
     132             : 
     133             :         /* we need to access Cardbus config space from the driver */
     134           0 :         sc->sc_conf_read = bwi_cardbus_conf_read;
     135           0 :         sc->sc_conf_write = bwi_cardbus_conf_write;
     136             : 
     137           0 :         reg = (sc->sc_conf_read)(sc, PCI_SUBSYS_ID_REG);
     138             : 
     139           0 :         sc->sc_pci_revid = PCI_REVISION(ca->ca_class);
     140           0 :         sc->sc_pci_did = PCI_PRODUCT(ca->ca_id);
     141           0 :         sc->sc_pci_subvid = PCI_VENDOR(reg);
     142           0 :         sc->sc_pci_subdid = PCI_PRODUCT(reg);
     143             : 
     144           0 :         error = bwi_attach(sc);
     145           0 :         if (error != 0)
     146           0 :                 bwi_cardbus_detach(&sc->sc_dev, 0);
     147             : 
     148           0 :         Cardbus_function_disable(ct);
     149           0 : }
     150             : 
     151             : int
     152           0 : bwi_cardbus_detach(struct device *self, int flags)
     153             : {
     154           0 :         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
     155           0 :         struct bwi_softc *sc = &csc->csc_bwi;
     156           0 :         cardbus_devfunc_t ct = csc->csc_ct;
     157           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     158           0 :         cardbus_function_tag_t cf = ct->ct_cf;
     159             :         int error;
     160             : 
     161           0 :         error = bwi_detach(sc);
     162           0 :         if (error != 0)
     163           0 :                 return (error);
     164             : 
     165             :         /* unhook the interrupt handler */
     166           0 :         if (csc->csc_ih != NULL) {
     167           0 :                 cardbus_intr_disestablish(cc, cf, csc->csc_ih);
     168           0 :                 csc->csc_ih = NULL;
     169           0 :         }
     170             : 
     171             :         /* release bus space and close window */
     172           0 :         Cardbus_mapreg_unmap(ct, CARDBUS_BASE0_REG, sc->sc_mem_bt,
     173             :             sc->sc_mem_bh, csc->csc_mapsize);
     174             : 
     175           0 :         return (0);
     176           0 : }
     177             : 
     178             : void
     179           0 : bwi_cardbus_setup(struct bwi_cardbus_softc *csc)
     180             : {
     181           0 :         cardbus_devfunc_t ct = csc->csc_ct;
     182           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     183           0 :         pci_chipset_tag_t pc = csc->csc_pc;
     184           0 :         cardbus_function_tag_t cf = ct->ct_cf;
     185             :         pcireg_t reg;
     186             : 
     187             :         /* program the BAR */
     188           0 :         pci_conf_write(pc, csc->csc_tag, CARDBUS_BASE0_REG,
     189           0 :             csc->csc_bar_val);
     190             : 
     191             :         /* make sure the right access type is on the cardbus bridge */
     192           0 :         (*cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
     193           0 :         (*cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
     194             : 
     195             :         /* enable the appropriate bits in the PCI CSR */
     196           0 :         reg = pci_conf_read(pc, csc->csc_tag,
     197             :             PCI_COMMAND_STATUS_REG);
     198           0 :         reg |= PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE;
     199           0 :         pci_conf_write(pc, csc->csc_tag, PCI_COMMAND_STATUS_REG,
     200             :             reg);
     201           0 : }
     202             : 
     203             : int
     204           0 : bwi_cardbus_enable(struct bwi_softc *sc)
     205             : {
     206           0 :         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)sc;
     207           0 :         cardbus_devfunc_t ct = csc->csc_ct;
     208           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     209           0 :         cardbus_function_tag_t cf = ct->ct_cf;
     210             : 
     211             :         /* power on the socket */
     212           0 :         Cardbus_function_enable(ct);
     213             : 
     214             :         /* setup the PCI configuration registers */
     215           0 :         bwi_cardbus_setup(csc);
     216             : 
     217             :         /* map and establish the interrupt handler */
     218           0 :         csc->csc_ih = cardbus_intr_establish(cc, cf, csc->csc_intrline, IPL_NET,
     219           0 :             bwi_intr, sc, sc->sc_dev.dv_xname);
     220           0 :         if (csc->csc_ih == NULL) {
     221           0 :                 printf("%s: could not establish interrupt at %d\n",
     222           0 :                     sc->sc_dev.dv_xname, csc->csc_intrline);
     223           0 :                 Cardbus_function_disable(ct);
     224           0 :                 return (1);
     225             :         }
     226             : 
     227           0 :         return (0);
     228           0 : }
     229             : 
     230             : void
     231           0 : bwi_cardbus_disable(struct bwi_softc *sc)
     232             : {
     233           0 :         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)sc;
     234           0 :         cardbus_devfunc_t ct = csc->csc_ct;
     235           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     236           0 :         cardbus_function_tag_t cf = ct->ct_cf;
     237             : 
     238             :         /* unhook the interrupt handler */
     239           0 :         cardbus_intr_disestablish(cc, cf, csc->csc_ih);
     240           0 :         csc->csc_ih = NULL;
     241             : 
     242             :         /* power down the socket */
     243           0 :         Cardbus_function_disable(ct);
     244           0 : }
     245             : 
     246             : void
     247           0 : bwi_cardbus_conf_write(void *self, uint32_t reg, uint32_t val)
     248             : {
     249           0 :         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
     250           0 :         pci_chipset_tag_t pc = csc->csc_pc;
     251             : 
     252           0 :         pci_conf_write(pc, csc->csc_tag, reg, val);
     253           0 : }
     254             : 
     255             : uint32_t
     256           0 : bwi_cardbus_conf_read(void *self, uint32_t reg)
     257             : {
     258           0 :         struct bwi_cardbus_softc *csc = (struct bwi_cardbus_softc *)self;
     259           0 :         pci_chipset_tag_t pc = csc->csc_pc;
     260             : 
     261           0 :         return (pci_conf_read(pc, csc->csc_tag, reg));
     262             : }

Generated by: LCOV version 1.13