root/dev/cardbus/if_ath_cardbus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ath_cardbus_match
  2. ath_cardbus_attach
  3. ath_cardbus_detach
  4. ath_cardbus_enable
  5. ath_cardbus_disable
  6. ath_cardbus_power
  7. ath_cardbus_setup

    1 /*      $OpenBSD: if_ath_cardbus.c,v 1.10 2006/10/12 16:35:52 grange Exp $   */
    2 /*      $NetBSD: if_ath_cardbus.c,v 1.4 2004/08/02 19:14:28 mycroft Exp $ */
    3 
    4 /*
    5  * Copyright (c) 2003
    6  *      Ichiro FUKUHARA <ichiro@ichiro.org>.
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. All advertising materials mentioning features or use of this software
   18  *    must display the following acknowledgement:
   19  *      This product includes software developed by Ichiro FUKUHARA.
   20  * 4. The name of the company nor the name of the author may be used to
   21  *    endorse or promote products derived from this software without specific
   22  *    prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
   25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   26  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   27  * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
   28  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  */
   36 
   37 /*
   38  * CardBus bus front-end for the AR5001 Wireless LAN 802.11a/b/g CardBus.
   39  */
   40 
   41 #include "bpfilter.h"
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h> 
   45 #include <sys/mbuf.h>   
   46 #include <sys/malloc.h>
   47 #include <sys/kernel.h>
   48 #include <sys/socket.h>
   49 #include <sys/ioctl.h>
   50 #include <sys/errno.h>
   51 #include <sys/device.h>
   52 #include <sys/gpio.h>
   53 
   54 #include <machine/endian.h>
   55  
   56 #include <net/if.h>
   57 #include <net/if_dl.h>
   58 #include <net/if_media.h>
   59 
   60 #ifdef INET
   61 #include <netinet/in.h> 
   62 #include <netinet/if_ether.h>
   63 #endif
   64 
   65 #include <net80211/ieee80211_var.h>
   66 #include <net80211/ieee80211_rssadapt.h>
   67 
   68 #if NBPFILTER > 0 
   69 #include <net/bpf.h>
   70 #endif 
   71 
   72 #include <machine/bus.h>
   73 #include <machine/intr.h>
   74 
   75 #include <dev/gpio/gpiovar.h>
   76 
   77 #include <dev/pci/pcivar.h>
   78 #include <dev/pci/pcireg.h>
   79 #include <dev/pci/pcidevs.h>
   80 
   81 #include <dev/cardbus/cardbusvar.h>
   82 
   83 #include <dev/ic/athvar.h>
   84 
   85 /*
   86  * PCI configuration space registers
   87  */
   88 #define ATH_PCI_MMBA            0x10    /* memory mapped base */
   89 
   90 struct ath_cardbus_softc {
   91         struct ath_softc        sc_ath;
   92 
   93         /* CardBus-specific goo. */
   94         void    *sc_ih;                 /* interrupt handle */
   95         cardbus_devfunc_t sc_ct;        /* our CardBus devfuncs */
   96         cardbustag_t sc_tag;            /* our CardBus tag */
   97         bus_size_t sc_mapsize;          /* the size of mapped bus space region */
   98 
   99         pcireg_t sc_bar_val;            /* value of the BAR */
  100 
  101         int     sc_intrline;            /* interrupt line */
  102 };
  103 
  104 int     ath_cardbus_match(struct device *, void *, void *);
  105 void    ath_cardbus_attach(struct device *, struct device *, void *);
  106 int     ath_cardbus_detach(struct device *, int);
  107 
  108 struct cfattach ath_cardbus_ca = {
  109         sizeof(struct ath_cardbus_softc),
  110         ath_cardbus_match,
  111         ath_cardbus_attach,
  112         ath_cardbus_detach
  113 };
  114 
  115 
  116 void    ath_cardbus_setup(struct ath_cardbus_softc *);
  117 
  118 int     ath_cardbus_enable(struct ath_softc *);
  119 void    ath_cardbus_disable(struct ath_softc *);
  120 void    ath_cardbus_power(struct ath_softc *, int);
  121 
  122 int
  123 ath_cardbus_match(struct device *parent, void *match, void *aux)
  124 {
  125         struct cardbus_attach_args *ca = aux;
  126         const char* devname;
  127 
  128         devname = ath_hal_probe(PCI_VENDOR(ca->ca_id),
  129                                 PCI_PRODUCT(ca->ca_id));
  130 
  131         if (devname)
  132                 return (1);
  133 
  134         return (0);
  135 }
  136 
  137 void
  138 ath_cardbus_attach(struct device *parent, struct device *self, void *aux)
  139 {
  140         struct ath_cardbus_softc *csc = (void *)self;
  141         struct ath_softc *sc = &csc->sc_ath;
  142         struct cardbus_attach_args *ca = aux;
  143         cardbus_devfunc_t ct = ca->ca_ct;
  144         bus_addr_t adr;
  145 
  146         sc->sc_dmat = ca->ca_dmat;
  147         csc->sc_ct = ct;
  148         csc->sc_tag = ca->ca_tag;
  149 
  150         /*
  151          * Power management hooks.
  152          */
  153         sc->sc_enable = ath_cardbus_enable;
  154         sc->sc_disable = ath_cardbus_disable;
  155         sc->sc_power = ath_cardbus_power;
  156 
  157         /*
  158          * Map the device.
  159          */
  160         if (Cardbus_mapreg_map(ct, ATH_PCI_MMBA, CARDBUS_MAPREG_TYPE_MEM, 0,
  161             &sc->sc_st, &sc->sc_sh, &adr, &csc->sc_mapsize) == 0) {
  162                 csc->sc_bar_val = adr | CARDBUS_MAPREG_TYPE_MEM;
  163         }
  164 
  165         else {
  166                 printf(": unable to map device registers\n");
  167                 return;
  168         }
  169 
  170         /*
  171          * Set up the PCI configuration registers.
  172          */
  173         ath_cardbus_setup(csc);
  174 
  175         /* Remember which interrupt line. */
  176         csc->sc_intrline = ca->ca_intrline;
  177 
  178         printf(": irq %d\n", csc->sc_intrline);
  179 
  180         /*
  181          * Finish off the attach.
  182          */
  183         ath_attach(PCI_PRODUCT(ca->ca_id), sc);
  184 
  185         /*
  186          * Power down the socket.
  187          */
  188         Cardbus_function_disable(csc->sc_ct);
  189 }
  190 
  191 int
  192 ath_cardbus_detach(struct device *self, int flags)
  193 {
  194         struct ath_cardbus_softc *csc = (void *)self;
  195         struct ath_softc *sc = &csc->sc_ath;
  196         struct cardbus_devfunc *ct = csc->sc_ct;
  197         int rv;
  198 
  199 #if defined(DIAGNOSTIC)
  200         if (ct == NULL)
  201                 panic("%s: data structure lacks", sc->sc_dev.dv_xname);
  202 #endif
  203 
  204         rv = ath_detach(sc, flags);
  205         if (rv)
  206                 return (rv);
  207 
  208         /*
  209          * Unhook the interrupt handler.
  210          */
  211         if (csc->sc_ih != NULL) {
  212                 cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, csc->sc_ih);
  213                 csc->sc_ih = NULL;
  214         }
  215 
  216         /*
  217          * Release bus space and close window.
  218          */
  219         Cardbus_mapreg_unmap(ct, ATH_PCI_MMBA,
  220                     sc->sc_st, sc->sc_sh, csc->sc_mapsize);
  221 
  222         return (0);
  223 }
  224 
  225 int
  226 ath_cardbus_enable(struct ath_softc *sc)
  227 {
  228         struct ath_cardbus_softc *csc = (void *) sc;
  229         cardbus_devfunc_t ct = csc->sc_ct;
  230         cardbus_chipset_tag_t cc = ct->ct_cc;
  231         cardbus_function_tag_t cf = ct->ct_cf;
  232 
  233         /*
  234          * Power on the socket.
  235          */
  236         Cardbus_function_enable(ct);
  237 
  238         /*
  239          * Set up the PCI configuration registers.
  240          */
  241         ath_cardbus_setup(csc);
  242 
  243         /*
  244          * Map and establish the interrupt.
  245          */
  246         csc->sc_ih = cardbus_intr_establish(cc, cf, csc->sc_intrline, IPL_NET,
  247             ath_intr, sc, sc->sc_dev.dv_xname);
  248         if (csc->sc_ih == NULL) {
  249                 printf(": unable to establish irq %d\n",
  250                        csc->sc_intrline);
  251                 Cardbus_function_disable(csc->sc_ct);
  252                 return (1);
  253         }
  254         return (0);
  255 }
  256 
  257 void
  258 ath_cardbus_disable(struct ath_softc *sc)
  259 {
  260         struct ath_cardbus_softc *csc = (void *) sc;
  261         cardbus_devfunc_t ct = csc->sc_ct;
  262         cardbus_chipset_tag_t cc = ct->ct_cc;
  263         cardbus_function_tag_t cf = ct->ct_cf;
  264 
  265         /* Unhook the interrupt handler. */
  266         cardbus_intr_disestablish(cc, cf, csc->sc_ih);
  267         csc->sc_ih = NULL;
  268 
  269         /* Power down the socket. */
  270         Cardbus_function_disable(ct);
  271 }
  272 
  273 void
  274 ath_cardbus_power(struct ath_softc *sc, int why)
  275 {
  276         if (why == PWR_RESUME)
  277                 ath_enable(sc);
  278 }
  279 
  280 void
  281 ath_cardbus_setup(struct ath_cardbus_softc *csc)
  282 {
  283         cardbus_devfunc_t ct = csc->sc_ct;
  284         cardbus_chipset_tag_t cc = ct->ct_cc;
  285         cardbus_function_tag_t cf = ct->ct_cf;
  286         pcireg_t reg;
  287 
  288 #ifdef notyet
  289         (void)cardbus_setpowerstate(sc->sc_dev.dv_xname, ct, csc->sc_tag,
  290             PCI_PWR_D0);
  291 #endif
  292 
  293         /* Program the BAR. */
  294         cardbus_conf_write(cc, cf, csc->sc_tag, ATH_PCI_MMBA,
  295             csc->sc_bar_val);
  296 
  297         /* Make sure the right access type is on the CardBus bridge. */
  298         (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE);
  299         (*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
  300 
  301         /* Enable the appropriate bits in the PCI CSR. */
  302         reg = cardbus_conf_read(cc, cf, csc->sc_tag,
  303             CARDBUS_COMMAND_STATUS_REG);
  304         reg |= CARDBUS_COMMAND_MASTER_ENABLE | CARDBUS_COMMAND_MEM_ENABLE;
  305         cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_COMMAND_STATUS_REG,
  306             reg);
  307 
  308         /*
  309          * Make sure the latency timer is set to some reasonable
  310          * value.
  311          */
  312         reg = cardbus_conf_read(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG);
  313         if (CARDBUS_LATTIMER(reg) < 0x20) {
  314                 reg &= ~(CARDBUS_LATTIMER_MASK << CARDBUS_LATTIMER_SHIFT);
  315                 reg |= (0x20 << CARDBUS_LATTIMER_SHIFT);
  316                 cardbus_conf_write(cc, cf, csc->sc_tag, CARDBUS_BHLC_REG, reg);
  317         }
  318 }

/* [<][>][^][v][top][bottom][index][help] */