[BACK]Return to if_ath_cardbus.c CVS log [TXT][DIR] Up to [local] / sys / dev / cardbus

Annotation of sys/dev/cardbus/if_ath_cardbus.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb