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

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

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

CVSweb