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

          Line data    Source code
       1             : /*      $OpenBSD: if_bwi_pci.c,v 1.16 2015/11/24 17:11:39 mpi Exp $ */
       2             : 
       3             : /*
       4             :  * Copyright (c) 2007 Marcus Glocker <mglocker@openbsd.org>
       5             :  *
       6             :  * Permission to use, copy, modify, and distribute this software for any
       7             :  * purpose with or without fee is hereby granted, provided that the above
       8             :  * copyright notice and this permission notice appear in all copies.
       9             :  *
      10             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      11             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      12             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      13             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      14             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      15             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      16             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      17             :  */
      18             : 
      19             : /*
      20             :  * PCI front-end for the Broadcom AirForce
      21             :  */
      22             : 
      23             : #include "bpfilter.h"
      24             : 
      25             : #include <sys/param.h>
      26             : #include <sys/sockio.h>
      27             : #include <sys/mbuf.h>
      28             : #include <sys/kernel.h>
      29             : #include <sys/socket.h>
      30             : #include <sys/systm.h>
      31             : #include <sys/malloc.h>
      32             : #include <sys/timeout.h>
      33             : #include <sys/device.h>
      34             : 
      35             : #include <machine/bus.h>
      36             : 
      37             : #include <net/if.h>
      38             : #include <net/if_media.h>
      39             : 
      40             : #include <netinet/in.h>
      41             : #include <netinet/if_ether.h>
      42             : 
      43             : #include <net80211/ieee80211_var.h>
      44             : #include <net80211/ieee80211_amrr.h>
      45             : #include <net80211/ieee80211_radiotap.h>
      46             : 
      47             : #include <dev/ic/bwivar.h>
      48             : 
      49             : #include <dev/pci/pcireg.h>
      50             : #include <dev/pci/pcivar.h>
      51             : #include <dev/pci/pcidevs.h>
      52             : 
      53             : /* Base Address Register */
      54             : #define BWI_PCI_BAR0    0x10
      55             : 
      56             : int             bwi_pci_match(struct device *, void *, void *);
      57             : void            bwi_pci_attach(struct device *, struct device *, void *);
      58             : int             bwi_pci_detach(struct device *, int);
      59             : void            bwi_pci_conf_write(void *, uint32_t, uint32_t);
      60             : uint32_t        bwi_pci_conf_read(void *, uint32_t);
      61             : int             bwi_pci_activate(struct device *, int);
      62             : void            bwi_pci_wakeup(struct bwi_softc *);
      63             : 
      64             : struct bwi_pci_softc {
      65             :         struct bwi_softc         psc_bwi;
      66             : 
      67             :         pci_chipset_tag_t        psc_pc;
      68             :         pcitag_t                 psc_pcitag;
      69             :         void                    *psc_ih;
      70             : 
      71             :         bus_size_t               psc_mapsize;
      72             : };
      73             : 
      74             : struct cfattach bwi_pci_ca = {
      75             :         sizeof(struct bwi_pci_softc), bwi_pci_match, bwi_pci_attach,
      76             :         bwi_pci_detach, bwi_pci_activate
      77             : };
      78             : 
      79             : const struct pci_matchid bwi_pci_devices[] = {
      80             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4303 },
      81             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4306 },
      82             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4306_2 },
      83             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4307 },
      84             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4309 },
      85             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4311 },
      86             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4312 },
      87             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4318 },
      88             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM4319 },
      89             :         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM43XG }
      90             : };
      91             : 
      92             : int
      93           0 : bwi_pci_match(struct device *parent, void *match, void *aux)
      94             : {
      95           0 :         struct pci_attach_args *pa = aux;
      96             : 
      97             :         /*
      98             :          * The second revision of the BCM4311/BCM4312
      99             :          * chips require v4 firmware.
     100             :          */
     101           0 :         if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_BROADCOM &&
     102           0 :             (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM4311 ||
     103           0 :              PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_BROADCOM_BCM4312) &&
     104           0 :              PCI_REVISION(pa->pa_class) == 0x02)
     105           0 :                 return (0);
     106             : 
     107           0 :         return (pci_matchbyid((struct pci_attach_args *)aux, bwi_pci_devices,
     108             :             sizeof(bwi_pci_devices) / sizeof(bwi_pci_devices[0])));
     109           0 : }
     110             : 
     111             : void
     112           0 : bwi_pci_attach(struct device *parent, struct device *self, void *aux)
     113             : {
     114           0 :         struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
     115           0 :         struct pci_attach_args *pa = aux;
     116           0 :         struct bwi_softc *sc = &psc->psc_bwi;
     117             :         const char *intrstr = NULL;
     118           0 :         pci_intr_handle_t ih;
     119             :         pcireg_t memtype, reg;
     120             : 
     121           0 :         sc->sc_dmat = pa->pa_dmat;
     122           0 :         psc->psc_pc = pa->pa_pc;
     123           0 :         psc->psc_pcitag = pa->pa_tag;
     124             : 
     125             :         /* map control / status registers */
     126           0 :         memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BWI_PCI_BAR0); 
     127           0 :         if (pci_mapreg_map(pa, BWI_PCI_BAR0, memtype, 0, &sc->sc_mem_bt,
     128           0 :             &sc->sc_mem_bh, NULL, &psc->psc_mapsize, 0)) {
     129           0 :                 printf(": can't map mem space\n");
     130           0 :                 return;
     131             :         }
     132             : 
     133             :         /* map interrupt */
     134           0 :         if (pci_intr_map(pa, &ih) != 0) {
     135           0 :                 printf(": can't map interrupt\n");
     136           0 :                 return;
     137             :         }
     138             : 
     139             :         /* establish interrupt */
     140           0 :         intrstr = pci_intr_string(psc->psc_pc, ih);
     141           0 :         psc->psc_ih = pci_intr_establish(psc->psc_pc, ih, IPL_NET, bwi_intr, sc,
     142           0 :             sc->sc_dev.dv_xname);
     143           0 :         if (psc->psc_ih == NULL) {
     144           0 :                 printf(": can't establish interrupt");
     145           0 :                 if (intrstr != NULL)
     146           0 :                         printf(" at %s", intrstr);
     147           0 :                 printf("\n");
     148           0 :                 return;
     149             :         }
     150           0 :         printf(": %s", intrstr);
     151             : 
     152             :         /* we need to access PCI config space from the driver */
     153           0 :         sc->sc_conf_write = bwi_pci_conf_write;
     154           0 :         sc->sc_conf_read = bwi_pci_conf_read;
     155             : 
     156           0 :         reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
     157             : 
     158           0 :         sc->sc_pci_revid = PCI_REVISION(pa->pa_class);
     159           0 :         sc->sc_pci_did = PCI_PRODUCT(pa->pa_id);
     160           0 :         sc->sc_pci_subvid = PCI_VENDOR(reg);
     161           0 :         sc->sc_pci_subdid = PCI_PRODUCT(reg);
     162             : 
     163           0 :         bwi_attach(sc);
     164           0 : }
     165             : 
     166             : int
     167           0 : bwi_pci_detach(struct device *self, int flags)
     168             : {
     169           0 :         struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
     170           0 :         struct bwi_softc *sc = &psc->psc_bwi;
     171             : 
     172           0 :         bwi_detach(sc);
     173           0 :         pci_intr_disestablish(psc->psc_pc, psc->psc_ih);
     174             : 
     175           0 :         return (0);
     176             : }
     177             : 
     178             : int
     179           0 : bwi_pci_activate(struct device *self, int act)
     180             : {
     181           0 :         struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
     182           0 :         struct bwi_softc *sc = &psc->psc_bwi;
     183           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     184             : 
     185           0 :         switch (act) {
     186             :         case DVACT_SUSPEND:
     187           0 :                 if (ifp->if_flags & IFF_RUNNING)
     188           0 :                         bwi_stop(sc, 1);
     189             :                 break;
     190             :         case DVACT_WAKEUP:
     191           0 :                 bwi_pci_wakeup(sc);
     192           0 :                 break;
     193             :         }
     194             : 
     195           0 :         return (0);
     196             : }
     197             : 
     198             : void
     199           0 : bwi_pci_wakeup(struct bwi_softc *sc)
     200             : {
     201           0 :         struct ifnet *ifp = &sc->sc_ic.ic_if;
     202             : 
     203           0 :         if (ifp->if_flags & IFF_UP)
     204           0 :                 bwi_init(ifp);
     205           0 : }
     206             : 
     207             : void
     208           0 : bwi_pci_conf_write(void *self, uint32_t reg, uint32_t val)
     209             : {
     210           0 :         struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
     211             : 
     212           0 :         pci_conf_write(psc->psc_pc, psc->psc_pcitag, reg, val);
     213           0 : }
     214             : 
     215             : uint32_t
     216           0 : bwi_pci_conf_read(void *self, uint32_t reg)
     217             : {
     218           0 :         struct bwi_pci_softc *psc = (struct bwi_pci_softc *)self;
     219             : 
     220           0 :         return (pci_conf_read(psc->psc_pc, psc->psc_pcitag, reg));
     221             : }

Generated by: LCOV version 1.13