LCOV - code coverage report
Current view: top level - dev/cardbus - if_atw_cardbus.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 102 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_atw_cardbus.c,v 1.24 2015/11/24 17:11:39 mpi Exp $ */
       2             : /*      $NetBSD: if_atw_cardbus.c,v 1.9 2004/07/23 07:07:55 dyoung Exp $        */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 1999, 2000, 2003 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      10             :  * NASA Ames Research Center.  This code was adapted for the ADMtek ADM8211
      11             :  * by David Young.
      12             :  *
      13             :  * Redistribution and use in source and binary forms, with or without
      14             :  * modification, are permitted provided that the following conditions
      15             :  * are met:
      16             :  * 1. Redistributions of source code must retain the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer.
      18             :  * 2. Redistributions in binary form must reproduce the above copyright
      19             :  *    notice, this list of conditions and the following disclaimer in the
      20             :  *    documentation and/or other materials provided with the distribution.
      21             :  *
      22             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      23             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      24             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      25             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      26             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      27             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      28             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      29             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      30             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      31             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      32             :  * POSSIBILITY OF SUCH DAMAGE.
      33             :  */
      34             : 
      35             : /*
      36             :  * CardBus bus front-end for the ADMtek ADM8211 802.11 MAC/BBP driver.
      37             :  */
      38             : 
      39             : #include "bpfilter.h"
      40             : 
      41             : #include <sys/param.h>
      42             : #include <sys/systm.h> 
      43             : #include <sys/mbuf.h>   
      44             : #include <sys/malloc.h>
      45             : #include <sys/kernel.h>
      46             : #include <sys/socket.h>
      47             : #include <sys/ioctl.h>
      48             : #include <sys/errno.h>
      49             : #include <sys/device.h>
      50             : #include <sys/endian.h>
      51             :  
      52             : #include <net/if.h>
      53             : #include <net/if_media.h>
      54             : 
      55             : #include <netinet/in.h>
      56             : #include <netinet/if_ether.h>
      57             : 
      58             : #include <net80211/ieee80211_radiotap.h>
      59             : #include <net80211/ieee80211_var.h>
      60             : 
      61             : #if NBPFILTER > 0 
      62             : #include <net/bpf.h>
      63             : #endif 
      64             : 
      65             : #include <machine/bus.h>
      66             : #include <machine/intr.h>
      67             : 
      68             : #include <dev/ic/atwreg.h>
      69             : #include <dev/ic/si4136reg.h>
      70             : #include <dev/ic/atwvar.h>
      71             : 
      72             : #include <dev/pci/pcivar.h>
      73             : #include <dev/pci/pcireg.h>
      74             : #include <dev/pci/pcidevs.h>
      75             : 
      76             : #include <dev/cardbus/cardbusvar.h>
      77             : 
      78             : /*
      79             :  * PCI configuration space registers used by the ADM8211.
      80             :  */
      81             : #define ATW_PCI_IOBA            0x10    /* i/o mapped base */
      82             : #define ATW_PCI_MMBA            0x14    /* memory mapped base */
      83             : 
      84             : struct atw_cardbus_softc {
      85             :         struct atw_softc sc_atw;        /* real ADM8211 softc */
      86             : 
      87             :         /* CardBus-specific goo. */
      88             :         void    *sc_ih;                 /* interrupt handle */
      89             :         cardbus_devfunc_t sc_ct;        /* our CardBus devfuncs */
      90             :         pcitag_t sc_tag;                /* our CardBus tag */
      91             :         int     sc_csr;                 /* CSR bits */
      92             :         bus_size_t sc_mapsize;          /* the size of mapped bus space
      93             :                                            region */
      94             : 
      95             :         int     sc_cben;                /* CardBus enables */
      96             :         int     sc_bar_reg;             /* which BAR to use */
      97             :         pcireg_t sc_bar_val;            /* value of the BAR */
      98             : 
      99             :         int     sc_intrline;            /* interrupt line */
     100             :         pci_chipset_tag_t sc_pc;
     101             : };
     102             : 
     103             : int     atw_cardbus_match(struct device *, void *, void *);
     104             : void    atw_cardbus_attach(struct device *, struct device *, void *);
     105             : int     atw_cardbus_detach(struct device *, int);
     106             : 
     107             : struct cfattach atw_cardbus_ca = {
     108             :         sizeof(struct atw_cardbus_softc), atw_cardbus_match, atw_cardbus_attach,
     109             :             atw_cardbus_detach
     110             : };
     111             : 
     112             : void    atw_cardbus_setup(struct atw_cardbus_softc *);
     113             : 
     114             : int     atw_cardbus_enable(struct atw_softc *);
     115             : void    atw_cardbus_disable(struct atw_softc *);
     116             : void    atw_cardbus_power(struct atw_softc *, int);
     117             : 
     118             : const struct pci_matchid atw_cardbus_devices[] = {
     119             :         { PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_ADM8211 },
     120             :         { PCI_VENDOR_3COM, PCI_PRODUCT_3COM_3CRSHPW796 },
     121             : };
     122             : 
     123             : int
     124           0 : atw_cardbus_match(struct device *parent, void *match, void *aux)
     125             : {
     126           0 :         return (cardbus_matchbyid((struct cardbus_attach_args *)aux,
     127             :             atw_cardbus_devices, nitems(atw_cardbus_devices)));
     128             : }
     129             : 
     130             : void
     131           0 : atw_cardbus_attach(struct device *parent, struct device *self, void *aux)
     132             : {
     133           0 :         struct atw_cardbus_softc *csc = (void *)self;
     134           0 :         struct atw_softc *sc = &csc->sc_atw;
     135           0 :         struct cardbus_attach_args *ca = aux;
     136           0 :         cardbus_devfunc_t ct = ca->ca_ct;
     137           0 :         bus_addr_t adr;
     138             : 
     139           0 :         sc->sc_dmat = ca->ca_dmat;
     140           0 :         csc->sc_ct = ct;
     141           0 :         csc->sc_tag = ca->ca_tag;
     142           0 :         csc->sc_pc = ca->ca_pc;
     143             : 
     144             :         /*
     145             :          * Power management hooks.
     146             :          */
     147           0 :         sc->sc_enable = atw_cardbus_enable;
     148           0 :         sc->sc_disable = atw_cardbus_disable;
     149           0 :         sc->sc_power = atw_cardbus_power;
     150             : 
     151             :         /* Get revision info. */
     152           0 :         sc->sc_rev = PCI_REVISION(ca->ca_class);
     153             : 
     154             : #if 0
     155             :         printf(": signature %08x\n%s",
     156             :             pci_conf_read(ca->ca_pc, csc->sc_tag, 0x80),
     157             :             sc->sc_dev.dv_xname);
     158             : #endif
     159             : 
     160             :         /*
     161             :          * Map the device.
     162             :          */
     163           0 :         csc->sc_csr = PCI_COMMAND_MASTER_ENABLE;
     164           0 :         if (Cardbus_mapreg_map(ct, ATW_PCI_MMBA,
     165             :             PCI_MAPREG_TYPE_MEM, 0, &sc->sc_st, &sc->sc_sh, &adr,
     166           0 :             &csc->sc_mapsize) == 0) {
     167             : #if 0
     168             :                 printf(": atw_cardbus_attach mapped %d bytes mem space\n%s",
     169             :                     csc->sc_mapsize, sc->sc_dev.dv_xname);
     170             : #endif
     171           0 :                 csc->sc_cben = CARDBUS_MEM_ENABLE;
     172           0 :                 csc->sc_csr |= PCI_COMMAND_MEM_ENABLE;
     173           0 :                 csc->sc_bar_reg = ATW_PCI_MMBA;
     174           0 :                 csc->sc_bar_val = adr | PCI_MAPREG_TYPE_MEM;
     175           0 :         } else if (Cardbus_mapreg_map(ct, ATW_PCI_IOBA,
     176             :             PCI_MAPREG_TYPE_IO, 0, &sc->sc_st, &sc->sc_sh, &adr,
     177           0 :             &csc->sc_mapsize) == 0) {
     178             : #if 0
     179             :                 printf(": atw_cardbus_attach mapped %d bytes I/O space\n%s",
     180             :                     csc->sc_mapsize, sc->sc_dev.dv_xname);
     181             : #endif
     182           0 :                 csc->sc_cben = CARDBUS_IO_ENABLE;
     183           0 :                 csc->sc_csr |= PCI_COMMAND_IO_ENABLE;
     184           0 :                 csc->sc_bar_reg = ATW_PCI_IOBA;
     185           0 :                 csc->sc_bar_val = adr | PCI_MAPREG_TYPE_IO;
     186             :         } else {
     187           0 :                 printf(": unable to map device registers\n");
     188           0 :                 return;
     189             :         }
     190             : 
     191             :         /*
     192             :          * Bring the chip out of powersave mode and initialize the
     193             :          * configuration registers.
     194             :          */
     195           0 :         atw_cardbus_setup(csc);
     196             : 
     197             :         /* Remember which interrupt line. */
     198           0 :         csc->sc_intrline = ca->ca_intrline;
     199             : 
     200           0 :         printf(": revision %d.%d: irq %d\n",
     201           0 :             (sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf, csc->sc_intrline);
     202             : #if 0
     203             :         /*
     204             :          * The CardBus cards will make it to store-and-forward mode as
     205             :          * soon as you put them under any kind of load, so just start
     206             :          * out there.
     207             :          */
     208             :         sc->sc_txthresh = 3; /* TBD name constant */
     209             : #endif
     210             : 
     211             :         /*
     212             :          * Finish off the attach.
     213             :          */
     214           0 :         atw_attach(sc);
     215             : 
     216           0 :         ATW_WRITE(sc, ATW_FER, ATW_FER_INTR);
     217             : 
     218             :         /*
     219             :          * Power down the socket.
     220             :          */
     221           0 :         Cardbus_function_disable(csc->sc_ct);
     222           0 : }
     223             : 
     224             : int
     225           0 : atw_cardbus_detach(struct device *self, int flags)
     226             : {
     227           0 :         struct atw_cardbus_softc *csc = (void *)self;
     228           0 :         struct atw_softc *sc = &csc->sc_atw;
     229           0 :         struct cardbus_devfunc *ct = csc->sc_ct;
     230             :         int rv;
     231             : 
     232             : #if defined(DIAGNOSTIC)
     233           0 :         if (ct == NULL)
     234           0 :                 panic("%s: data structure lacks", sc->sc_dev.dv_xname);
     235             : #endif
     236             : 
     237           0 :         rv = atw_detach(sc);
     238           0 :         if (rv)
     239           0 :                 return (rv);
     240             : 
     241             :         /*
     242             :          * Unhook the interrupt handler.
     243             :          */
     244           0 :         if (csc->sc_ih != NULL)
     245           0 :                 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
     246             : 
     247             :         /*
     248             :          * Release bus space and close window.
     249             :          */
     250           0 :         if (csc->sc_bar_reg != 0)
     251           0 :                 Cardbus_mapreg_unmap(ct, csc->sc_bar_reg,
     252             :                     sc->sc_st, sc->sc_sh, csc->sc_mapsize);
     253             : 
     254           0 :         return (0);
     255           0 : }
     256             : 
     257             : int
     258           0 : atw_cardbus_enable(struct atw_softc *sc)
     259             : {
     260           0 :         struct atw_cardbus_softc *csc = (void *) sc;
     261           0 :         cardbus_devfunc_t ct = csc->sc_ct;
     262           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     263           0 :         cardbus_function_tag_t cf = ct->ct_cf;
     264             : 
     265             :         /*
     266             :          * Power on the socket.
     267             :          */
     268           0 :         Cardbus_function_enable(ct);
     269             : 
     270             :         /*
     271             :          * Set up the PCI configuration registers.
     272             :          */
     273           0 :         atw_cardbus_setup(csc);
     274             : 
     275             :         /*
     276             :          * Map and establish the interrupt.
     277             :          */
     278           0 :         csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
     279           0 :             atw_intr, sc, sc->sc_dev.dv_xname);
     280           0 :         if (csc->sc_ih == NULL) {
     281           0 :                 printf("%s: unable to establish interrupt at %d\n",
     282           0 :                     sc->sc_dev.dv_xname, csc->sc_intrline);
     283           0 :                 Cardbus_function_disable(csc->sc_ct);
     284           0 :                 return (1);
     285             :         }
     286             : 
     287           0 :         return (0);
     288           0 : }
     289             : 
     290             : void
     291           0 : atw_cardbus_disable(struct atw_softc *sc)
     292             : {
     293           0 :         struct atw_cardbus_softc *csc = (void *) sc;
     294           0 :         cardbus_devfunc_t ct = csc->sc_ct;
     295           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     296           0 :         cardbus_function_tag_t cf = ct->ct_cf;
     297             : 
     298             :         /* Unhook the interrupt handler. */
     299           0 :         cardbus_intr_disestablish(cc, cf, csc->sc_ih);
     300           0 :         csc->sc_ih = NULL;
     301             : 
     302             :         /* Power down the socket. */
     303           0 :         Cardbus_function_disable(ct);
     304           0 : }
     305             : 
     306             : void
     307           0 : atw_cardbus_power(struct atw_softc *sc, int why)
     308             : {
     309           0 :         if (why == DVACT_RESUME)
     310           0 :                 atw_enable(sc);
     311           0 : }
     312             : 
     313             : void
     314           0 : atw_cardbus_setup(struct atw_cardbus_softc *csc)
     315             : {
     316             : #ifdef notyet
     317             :         struct atw_softc *sc = &csc->sc_atw;
     318             : #endif
     319           0 :         cardbus_devfunc_t ct = csc->sc_ct;
     320           0 :         cardbus_chipset_tag_t cc = ct->ct_cc;
     321           0 :         pci_chipset_tag_t pc = csc->sc_pc;
     322             :         pcireg_t reg;
     323             : 
     324             : #ifdef notyet
     325             :         (void)cardbus_setpowerstate(sc->sc_dev.dv_xname, ct, csc->sc_tag,
     326             :             PCI_PWR_D0);
     327             : #endif
     328             : 
     329             :         /* Program the BAR. */
     330           0 :         pci_conf_write(pc, csc->sc_tag, csc->sc_bar_reg,
     331           0 :             csc->sc_bar_val);
     332             : 
     333             :         /* Make sure the right access type is on the CardBus bridge. */
     334           0 :         (*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_cben);
     335           0 :         (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
     336             : 
     337             :         /* Enable the appropriate bits in the PCI CSR. */
     338           0 :         reg = pci_conf_read(pc, csc->sc_tag,
     339             :             PCI_COMMAND_STATUS_REG);
     340           0 :         reg &= ~(PCI_COMMAND_IO_ENABLE|PCI_COMMAND_MEM_ENABLE);
     341           0 :         reg |= csc->sc_csr;
     342           0 :         pci_conf_write(pc, csc->sc_tag, PCI_COMMAND_STATUS_REG,
     343             :             reg);
     344             : 
     345             :         /*
     346             :          * Make sure the latency timer is set to some reasonable
     347             :          * value.
     348             :          */
     349           0 :         reg = pci_conf_read(pc, csc->sc_tag, PCI_BHLC_REG);
     350           0 :         if (PCI_LATTIMER(reg) < 0x20) {
     351           0 :                 reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
     352           0 :                 reg |= (0x20 << PCI_LATTIMER_SHIFT);
     353           0 :                 pci_conf_write(pc, csc->sc_tag, PCI_BHLC_REG, reg);
     354           0 :         }
     355           0 : }

Generated by: LCOV version 1.13