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

Annotation of sys/dev/ic/atw.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: atw.c,v 1.54 2007/07/18 18:22:26 damien Exp $ */
                      2: /*     $NetBSD: atw.c,v 1.69 2004/07/23 07:07:55 dyoung Exp $  */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by David Young, by Jason R. Thorpe, and by Charles M. Hannum.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the NetBSD
                     22:  *     Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: /*
                     41:  * Device driver for the ADMtek ADM8211 802.11 MAC/BBP.
                     42:  */
                     43:
                     44: #include <sys/cdefs.h>
                     45: #if defined(__NetBSD__)
                     46: __KERNEL_RCSID(0, "$NetBSD: atw.c,v 1.69 2004/07/23 07:07:55 dyoung Exp $");
                     47: #endif
                     48:
                     49: #include "bpfilter.h"
                     50:
                     51: #include <sys/param.h>
                     52: #include <sys/systm.h>
                     53: #include <sys/mbuf.h>
                     54: #include <sys/malloc.h>
                     55: #include <sys/kernel.h>
                     56: #include <sys/socket.h>
                     57: #include <sys/ioctl.h>
                     58: #include <sys/errno.h>
                     59: #include <sys/device.h>
                     60: #include <sys/time.h>
                     61:
                     62: #include <machine/endian.h>
                     63:
                     64: #include <uvm/uvm_extern.h>
                     65:
                     66: #include <net/if.h>
                     67: #include <net/if_dl.h>
                     68: #include <net/if_media.h>
                     69:
                     70: #if NBPFILTER > 0
                     71: #include <net/bpf.h>
                     72: #endif
                     73:
                     74: #ifdef INET
                     75: #include <netinet/in.h>
                     76: #include <netinet/if_ether.h>
                     77: #endif
                     78:
                     79: #include <net80211/ieee80211_var.h>
                     80: #include <net80211/ieee80211_radiotap.h>
                     81:
                     82: #include <machine/bus.h>
                     83: #include <machine/intr.h>
                     84:
                     85: #include <dev/ic/atwreg.h>
                     86: #include <dev/ic/rf3000reg.h>
                     87: #include <dev/ic/si4136reg.h>
                     88: #include <dev/ic/atwvar.h>
                     89: #include <dev/ic/smc93cx6var.h>
                     90:
                     91: /* XXX TBD open questions
                     92:  *
                     93:  *
                     94:  * When should I set DSSS PAD in reg 0x15 of RF3000? In 1-2Mbps
                     95:  * modes only, or all modes (5.5-11 Mbps CCK modes, too?) Does the MAC
                     96:  * handle this for me?
                     97:  *
                     98:  */
                     99: /* device attachment
                    100:  *
                    101:  *    print TOFS[012]
                    102:  *
                    103:  * device initialization
                    104:  *
                    105:  *    clear ATW_FRCTL_MAXPSP to disable max power saving
                    106:  *    set ATW_TXBR_ALCUPDATE to enable ALC
                    107:  *    set TOFS[012]? (hope not)
                    108:  *    disable rx/tx
                    109:  *    set ATW_PAR_SWR (software reset)
                    110:  *    wait for ATW_PAR_SWR clear
                    111:  *    disable interrupts
                    112:  *    ack status register
                    113:  *    enable interrupts
                    114:  *
                    115:  * rx/tx initialization
                    116:  *
                    117:  *    disable rx/tx w/ ATW_NAR_SR, ATW_NAR_ST
                    118:  *    allocate and init descriptor rings
                    119:  *    write ATW_PAR_DSL (descriptor skip length)
                    120:  *    write descriptor base addrs: ATW_TDBD, ATW_TDBP, write ATW_RDB
                    121:  *    write ATW_NAR_SQ for one/both transmit descriptor rings
                    122:  *    write ATW_NAR_SQ for one/both transmit descriptor rings
                    123:  *    enable rx/tx w/ ATW_NAR_SR, ATW_NAR_ST
                    124:  *
                    125:  * rx/tx end
                    126:  *
                    127:  *    stop DMA
                    128:  *    disable rx/tx w/ ATW_NAR_SR, ATW_NAR_ST
                    129:  *    flush tx w/ ATW_NAR_HF
                    130:  *
                    131:  * scan
                    132:  *
                    133:  *    initialize rx/tx
                    134:  *
                    135:  * BSS join: (re)association response
                    136:  *
                    137:  *    set ATW_FRCTL_AID
                    138:  *
                    139:  * optimizations ???
                    140:  *
                    141:  */
                    142:
                    143: #define ATW_REFSLAVE   /* slavishly do what the reference driver does */
                    144:
                    145: int atw_bbp_io_enable_delay = 20 * 1000;
                    146: int atw_bbp_io_disable_delay = 2 * 1000;
                    147: int atw_writewep_delay = 1000;
                    148: int atw_beacon_len_adjust = 4;
                    149: int atw_dwelltime = 200;
                    150: int atw_xindiv2 = 0;
                    151:
                    152: #ifdef ATW_DEBUG
                    153: int atw_debug = 0;
                    154:
                    155: #define ATW_DPRINTF(x) if (atw_debug > 0) printf x
                    156: #define ATW_DPRINTF2(x)        if (atw_debug > 1) printf x
                    157: #define ATW_DPRINTF3(x)        if (atw_debug > 2) printf x
                    158: #define        DPRINTF(sc, x)  if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) printf x
                    159: #define        DPRINTF2(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) ATW_DPRINTF2(x)
                    160: #define        DPRINTF3(sc, x) if ((sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) ATW_DPRINTF3(x)
                    161: void atw_print_regs(struct atw_softc *, const char *);
                    162: void atw_dump_pkt(struct ifnet *, struct mbuf *);
                    163:
                    164: /* Note well: I never got atw_rf3000_read or atw_si4126_read to work. */
                    165: #      ifdef ATW_BBPDEBUG
                    166: int atw_rf3000_read(struct atw_softc *sc, u_int, u_int *);
                    167: void atw_rf3000_print(struct atw_softc *);
                    168: #      endif /* ATW_BBPDEBUG */
                    169:
                    170: #      ifdef ATW_SYNDEBUG
                    171: int atw_si4126_read(struct atw_softc *, u_int, u_int *);
                    172: void atw_si4126_print(struct atw_softc *);
                    173: #      endif /* ATW_SYNDEBUG */
                    174:
                    175: #else
                    176: #define ATW_DPRINTF(x)
                    177: #define ATW_DPRINTF2(x)
                    178: #define ATW_DPRINTF3(x)
                    179: #define        DPRINTF(sc, x)  /* nothing */
                    180: #define        DPRINTF2(sc, x) /* nothing */
                    181: #define        DPRINTF3(sc, x) /* nothing */
                    182: #endif
                    183:
                    184: #ifdef ATW_STATS
                    185: void   atw_print_stats(struct atw_softc *);
                    186: #endif
                    187:
                    188: const char *atw_printmac(u_int8_t);
                    189:
                    190: /* ifnet methods */
                    191: void   atw_start(struct ifnet *);
                    192: void   atw_watchdog(struct ifnet *);
                    193: int    atw_ioctl(struct ifnet *, u_long, caddr_t);
                    194: int    atw_init(struct ifnet *);
                    195: void   atw_stop(struct ifnet *, int);
                    196:
                    197: /* Rx/Tx process */
                    198: void   atw_rxdrain(struct atw_softc *);
                    199: void   atw_txdrain(struct atw_softc *);
                    200: int    atw_add_rxbuf(struct atw_softc *, int);
                    201: void   atw_idle(struct atw_softc *, u_int32_t);
                    202:
                    203: /* Device (de)activation and power state */
                    204: void   atw_disable(struct atw_softc *);
                    205: void   atw_reset(struct atw_softc *);
                    206:
                    207: /* Interrupt handlers */
                    208: void   atw_rxintr(struct atw_softc *);
                    209: void   atw_txintr(struct atw_softc *);
                    210: void   atw_linkintr(struct atw_softc *, u_int32_t);
                    211:
                    212: /* 802.11 state machine */
                    213: int    atw_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    214: int    atw_tune(struct atw_softc *);
                    215: void   atw_recv_mgmt(struct ieee80211com *, struct mbuf *,
                    216:            struct ieee80211_node *, int, int, u_int32_t);
                    217: void   atw_next_scan(void *);
                    218:
                    219: /* Device initialization */
                    220: void   atw_wcsr_init(struct atw_softc *);
                    221: void   atw_cmdr_init(struct atw_softc *);
                    222: void   atw_tofs2_init(struct atw_softc *);
                    223: void   atw_txlmt_init(struct atw_softc *);
                    224: void   atw_test1_init(struct atw_softc *);
                    225: void   atw_rf_reset(struct atw_softc *);
                    226: void   atw_cfp_init(struct atw_softc *);
                    227: void   atw_tofs0_init(struct atw_softc *);
                    228: void   atw_ifs_init(struct atw_softc *);
                    229: void   atw_response_times_init(struct atw_softc *);
                    230: void   atw_bbp_io_init(struct atw_softc *);
                    231: void   atw_nar_init(struct atw_softc *);
                    232:
                    233: /* RAM/ROM utilities */
                    234: void   atw_clear_sram(struct atw_softc *);
                    235: void   atw_write_sram(struct atw_softc *, u_int, u_int8_t *, u_int);
                    236: int    atw_read_srom(struct atw_softc *);
                    237:
                    238: /* BSS setup */
                    239: void   atw_predict_beacon(struct atw_softc *sc);
                    240: void   atw_start_beacon(struct atw_softc *, int);
                    241: void   atw_write_bssid(struct atw_softc *);
                    242: void   atw_write_ssid(struct atw_softc *);
                    243: void   atw_write_sup_rates(struct atw_softc *);
                    244: void   atw_write_wep(struct atw_softc *);
                    245:
                    246: /* Media */
                    247: int    atw_media_change(struct ifnet *);
                    248: void   atw_media_status(struct ifnet *, struct ifmediareq *);
                    249:
                    250: void   atw_filter_setup(struct atw_softc *);
                    251:
                    252: /* 802.11 utilities */
                    253: struct ieee80211_node *atw_node_alloc(struct ieee80211com *);
                    254: void   atw_node_free(struct ieee80211com *, struct ieee80211_node *);
                    255: static __inline uint32_t atw_last_even_tsft(uint32_t, uint32_t, uint32_t);
                    256: uint64_t atw_get_tsft(struct atw_softc *sc);
                    257: void   atw_change_ibss(struct atw_softc *);
                    258: int    atw_compute_duration1(int, int, uint32_t, int, struct atw_duration *);
                    259: int    atw_compute_duration(struct ieee80211_frame *, int, uint32_t, int,
                    260:            int, struct atw_duration *, struct atw_duration *, int *, int);
                    261:
                    262: /*
                    263:  * Tuner/transceiver/modem
                    264:  */
                    265: void   atw_bbp_io_enable(struct atw_softc *, int);
                    266:
                    267: /* RFMD RF3000 Baseband Processor */
                    268: int    atw_rf3000_init(struct atw_softc *);
                    269: int    atw_rf3000_tune(struct atw_softc *, u_int);
                    270: int    atw_rf3000_write(struct atw_softc *, u_int, u_int);
                    271:
                    272: /* Silicon Laboratories Si4126 RF/IF Synthesizer */
                    273: void   atw_si4126_tune(struct atw_softc *, u_int);
                    274: void   atw_si4126_write(struct atw_softc *, u_int, u_int);
                    275: void   atw_si4126_init(struct atw_softc *);
                    276:
                    277: const struct atw_txthresh_tab atw_txthresh_tab_lo[] = ATW_TXTHRESH_TAB_LO_RATE;
                    278: const struct atw_txthresh_tab atw_txthresh_tab_hi[] = ATW_TXTHRESH_TAB_HI_RATE;
                    279:
                    280: struct cfdriver atw_cd = {
                    281:     NULL, "atw", DV_IFNET
                    282: };
                    283:
                    284: static const u_int atw_rfmd2958_ifn[] = {
                    285:        0x22bd, 0x22d2, 0x22e8, 0x22fe, 0x2314, 0x232a, 0x2340,
                    286:        0x2355, 0x236b, 0x2381, 0x2397, 0x23ad, 0x23c2, 0x23f7
                    287: };
                    288:
                    289: static const u_int atw_rfmd2958_rf1r[] = {
                    290:        0x05d17, 0x3a2e8, 0x2e8ba, 0x22e8b, 0x1745d, 0x0ba2e, 0x00000,
                    291:        0x345d1, 0x28ba2, 0x1d174, 0x11745, 0x05d17, 0x3a2e8, 0x11745
                    292: };
                    293:
                    294:
                    295: #ifdef ATW_DEBUG
                    296:
                    297: const char *atw_tx_state[] = {
                    298:        "STOPPED",
                    299:        "RUNNING - read descriptor",
                    300:        "RUNNING - transmitting",
                    301:        "RUNNING - filling fifo",       /* XXX */
                    302:        "SUSPENDED",
                    303:        "RUNNING -- write descriptor",
                    304:        "RUNNING -- write last descriptor",
                    305:        "RUNNING - fifo full"
                    306: };
                    307:
                    308: const char *atw_rx_state[] = {
                    309:        "STOPPED",
                    310:        "RUNNING - read descriptor",
                    311:        "RUNNING - check this packet, pre-fetch next",
                    312:        "RUNNING - wait for reception",
                    313:        "SUSPENDED",
                    314:        "RUNNING - write descriptor",
                    315:        "RUNNING - flush fifo",
                    316:        "RUNNING - fifo drain"
                    317: };
                    318:
                    319: #endif
                    320:
                    321: #ifndef __OpenBSD__
                    322: int
                    323: atw_activate(struct device *self, enum devact act)
                    324: {
                    325:        struct atw_softc *sc = (struct atw_softc *)self;
                    326:        int rv = 0, s;
                    327:
                    328:        s = splnet();
                    329:        switch (act) {
                    330:        case DVACT_ACTIVATE:
                    331:                break;
                    332:
                    333:        case DVACT_DEACTIVATE:
                    334:                if_deactivate(&sc->sc_ic.ic_if);
                    335:                break;
                    336:        }
                    337:        splx(s);
                    338:        return rv;
                    339: }
                    340: #endif
                    341:
                    342: /*
                    343:  * atw_enable:
                    344:  *
                    345:  *     Enable the ADM8211 chip.
                    346:  */
                    347: int
                    348: atw_enable(struct atw_softc *sc)
                    349: {
                    350:
                    351:        if (ATW_IS_ENABLED(sc) == 0) {
                    352:                if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
                    353:                        printf("%s: device enable failed\n",
                    354:                            sc->sc_dev.dv_xname);
                    355:                        return (EIO);
                    356:                }
                    357:                sc->sc_flags |= ATWF_ENABLED;
                    358:        }
                    359:        return (0);
                    360: }
                    361:
                    362: /*
                    363:  * atw_disable:
                    364:  *
                    365:  *     Disable the ADM8211 chip.
                    366:  */
                    367: void
                    368: atw_disable(struct atw_softc *sc)
                    369: {
                    370:        if (!ATW_IS_ENABLED(sc))
                    371:                return;
                    372:        if (sc->sc_disable != NULL)
                    373:                (*sc->sc_disable)(sc);
                    374:        sc->sc_flags &= ~ATWF_ENABLED;
                    375: }
                    376:
                    377: /* Returns -1 on failure. */
                    378: int
                    379: atw_read_srom(struct atw_softc *sc)
                    380: {
                    381:        struct seeprom_descriptor sd;
                    382:        u_int32_t test0, fail_bits;
                    383:
                    384:        (void)memset(&sd, 0, sizeof(sd));
                    385:
                    386:        test0 = ATW_READ(sc, ATW_TEST0);
                    387:
                    388:        switch (sc->sc_rev) {
                    389:        case ATW_REVISION_BA:
                    390:        case ATW_REVISION_CA:
                    391:                fail_bits = ATW_TEST0_EPNE;
                    392:                break;
                    393:        default:
                    394:                fail_bits = ATW_TEST0_EPNE|ATW_TEST0_EPSNM;
                    395:                break;
                    396:        }
                    397:        if ((test0 & fail_bits) != 0) {
                    398:                printf("%s: bad or missing/bad SROM\n", sc->sc_dev.dv_xname);
                    399:                return -1;
                    400:        }
                    401:
                    402:        switch (test0 & ATW_TEST0_EPTYP_MASK) {
                    403:        case ATW_TEST0_EPTYP_93c66:
                    404:                ATW_DPRINTF(("%s: 93c66 SROM\n", sc->sc_dev.dv_xname));
                    405:                sc->sc_sromsz = 512;
                    406:                sd.sd_chip = C56_66;
                    407:                break;
                    408:        case ATW_TEST0_EPTYP_93c46:
                    409:                ATW_DPRINTF(("%s: 93c46 SROM\n", sc->sc_dev.dv_xname));
                    410:                sc->sc_sromsz = 128;
                    411:                sd.sd_chip = C46;
                    412:                break;
                    413:        default:
                    414:                printf("%s: unknown SROM type %d\n", sc->sc_dev.dv_xname,
                    415:                    MASK_AND_RSHIFT(test0, ATW_TEST0_EPTYP_MASK));
                    416:                return -1;
                    417:        }
                    418:
                    419:        sc->sc_srom = malloc(sc->sc_sromsz, M_DEVBUF, M_NOWAIT);
                    420:        if (sc->sc_srom == NULL) {
                    421:                printf("%s: unable to allocate SROM buffer\n",
                    422:                    sc->sc_dev.dv_xname);
                    423:                return -1;
                    424:        }
                    425:
                    426:        (void)memset(sc->sc_srom, 0, sc->sc_sromsz);
                    427:        /* ADM8211 has a single 32-bit register for controlling the
                    428:         * 93cx6 SROM.  Bit SRS enables the serial port. There is no
                    429:         * "ready" bit. The ADM8211 input/output sense is the reverse
                    430:         * of read_seeprom's.
                    431:         */
                    432:        sd.sd_tag = sc->sc_st;
                    433:        sd.sd_bsh = sc->sc_sh;
                    434:        sd.sd_regsize = 4;
                    435:        sd.sd_control_offset = ATW_SPR;
                    436:        sd.sd_status_offset = ATW_SPR;
                    437:        sd.sd_dataout_offset = ATW_SPR;
                    438:        sd.sd_CK = ATW_SPR_SCLK;
                    439:        sd.sd_CS = ATW_SPR_SCS;
                    440:        sd.sd_DI = ATW_SPR_SDO;
                    441:        sd.sd_DO = ATW_SPR_SDI;
                    442:        sd.sd_MS = ATW_SPR_SRS;
                    443:        sd.sd_RDY = 0;
                    444:
                    445:        if (!read_seeprom(&sd, sc->sc_srom, 0, sc->sc_sromsz/2)) {
                    446:                printf("%s: could not read SROM\n", sc->sc_dev.dv_xname);
                    447:                free(sc->sc_srom, M_DEVBUF);
                    448:                return -1;
                    449:        }
                    450: #ifdef ATW_DEBUG
                    451:        {
                    452:                int i;
                    453:                ATW_DPRINTF(("\nSerial EEPROM:\n\t"));
                    454:                for (i = 0; i < sc->sc_sromsz/2; i = i + 1) {
                    455:                        if (((i % 8) == 0) && (i != 0)) {
                    456:                                ATW_DPRINTF(("\n\t"));
                    457:                        }
                    458:                        ATW_DPRINTF((" 0x%x", sc->sc_srom[i]));
                    459:                }
                    460:                ATW_DPRINTF(("\n"));
                    461:        }
                    462: #endif /* ATW_DEBUG */
                    463:        return 0;
                    464: }
                    465:
                    466: #ifdef ATW_DEBUG
                    467: void
                    468: atw_print_regs(struct atw_softc *sc, const char *where)
                    469: {
                    470: #define PRINTREG(sc, reg) \
                    471:        ATW_DPRINTF2(("%s: reg[ " #reg " / %03x ] = %08x\n", \
                    472:            sc->sc_dev.dv_xname, reg, ATW_READ(sc, reg)))
                    473:
                    474:        ATW_DPRINTF2(("%s: %s\n", sc->sc_dev.dv_xname, where));
                    475:
                    476:        PRINTREG(sc, ATW_PAR);
                    477:        PRINTREG(sc, ATW_FRCTL);
                    478:        PRINTREG(sc, ATW_TDR);
                    479:        PRINTREG(sc, ATW_WTDP);
                    480:        PRINTREG(sc, ATW_RDR);
                    481:        PRINTREG(sc, ATW_WRDP);
                    482:        PRINTREG(sc, ATW_RDB);
                    483:        PRINTREG(sc, ATW_CSR3A);
                    484:        PRINTREG(sc, ATW_TDBD);
                    485:        PRINTREG(sc, ATW_TDBP);
                    486:        PRINTREG(sc, ATW_STSR);
                    487:        PRINTREG(sc, ATW_CSR5A);
                    488:        PRINTREG(sc, ATW_NAR);
                    489:        PRINTREG(sc, ATW_CSR6A);
                    490:        PRINTREG(sc, ATW_IER);
                    491:        PRINTREG(sc, ATW_CSR7A);
                    492:        PRINTREG(sc, ATW_LPC);
                    493:        PRINTREG(sc, ATW_TEST1);
                    494:        PRINTREG(sc, ATW_SPR);
                    495:        PRINTREG(sc, ATW_TEST0);
                    496:        PRINTREG(sc, ATW_WCSR);
                    497:        PRINTREG(sc, ATW_WPDR);
                    498:        PRINTREG(sc, ATW_GPTMR);
                    499:        PRINTREG(sc, ATW_GPIO);
                    500:        PRINTREG(sc, ATW_BBPCTL);
                    501:        PRINTREG(sc, ATW_SYNCTL);
                    502:        PRINTREG(sc, ATW_PLCPHD);
                    503:        PRINTREG(sc, ATW_MMIWADDR);
                    504:        PRINTREG(sc, ATW_MMIRADDR1);
                    505:        PRINTREG(sc, ATW_MMIRADDR2);
                    506:        PRINTREG(sc, ATW_TXBR);
                    507:        PRINTREG(sc, ATW_CSR15A);
                    508:        PRINTREG(sc, ATW_ALCSTAT);
                    509:        PRINTREG(sc, ATW_TOFS2);
                    510:        PRINTREG(sc, ATW_CMDR);
                    511:        PRINTREG(sc, ATW_PCIC);
                    512:        PRINTREG(sc, ATW_PMCSR);
                    513:        PRINTREG(sc, ATW_PAR0);
                    514:        PRINTREG(sc, ATW_PAR1);
                    515:        PRINTREG(sc, ATW_MAR0);
                    516:        PRINTREG(sc, ATW_MAR1);
                    517:        PRINTREG(sc, ATW_ATIMDA0);
                    518:        PRINTREG(sc, ATW_ABDA1);
                    519:        PRINTREG(sc, ATW_BSSID0);
                    520:        PRINTREG(sc, ATW_TXLMT);
                    521:        PRINTREG(sc, ATW_MIBCNT);
                    522:        PRINTREG(sc, ATW_BCNT);
                    523:        PRINTREG(sc, ATW_TSFTH);
                    524:        PRINTREG(sc, ATW_TSC);
                    525:        PRINTREG(sc, ATW_SYNRF);
                    526:        PRINTREG(sc, ATW_BPLI);
                    527:        PRINTREG(sc, ATW_CAP0);
                    528:        PRINTREG(sc, ATW_CAP1);
                    529:        PRINTREG(sc, ATW_RMD);
                    530:        PRINTREG(sc, ATW_CFPP);
                    531:        PRINTREG(sc, ATW_TOFS0);
                    532:        PRINTREG(sc, ATW_TOFS1);
                    533:        PRINTREG(sc, ATW_IFST);
                    534:        PRINTREG(sc, ATW_RSPT);
                    535:        PRINTREG(sc, ATW_TSFTL);
                    536:        PRINTREG(sc, ATW_WEPCTL);
                    537:        PRINTREG(sc, ATW_WESK);
                    538:        PRINTREG(sc, ATW_WEPCNT);
                    539:        PRINTREG(sc, ATW_MACTEST);
                    540:        PRINTREG(sc, ATW_FER);
                    541:        PRINTREG(sc, ATW_FEMR);
                    542:        PRINTREG(sc, ATW_FPSR);
                    543:        PRINTREG(sc, ATW_FFER);
                    544: #undef PRINTREG
                    545: }
                    546: #endif /* ATW_DEBUG */
                    547:
                    548: const char*
                    549: atw_printmac(u_int8_t rev) {
                    550:        switch (rev) {
                    551:        case ATW_REVISION_AB:
                    552:                return "ADM8211AB";
                    553:        case ATW_REVISION_AF:
                    554:                return "ADM8211AF";
                    555:        case ATW_REVISION_BA:
                    556:                return "ADM8211BA";
                    557:        case ATW_REVISION_CA:
                    558:                return "ADM8211CA";
                    559:        default:
                    560:                return "unknown";
                    561:        }
                    562: }
                    563:
                    564: /*
                    565:  * Finish attaching an ADMtek ADM8211 MAC.  Called by bus-specific front-end.
                    566:  */
                    567: void
                    568: atw_attach(struct atw_softc *sc)
                    569: {
                    570:        static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
                    571:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    572:        };
                    573:        struct ieee80211com *ic = &sc->sc_ic;
                    574:        struct ifnet *ifp = &ic->ic_if;
                    575:        int country_code, error, i, srom_major;
                    576:        u_int32_t reg;
                    577:        static const char *type_strings[] = {"Intersil (not supported)",
                    578:            "RFMD", "Marvel (not supported)"};
                    579:
                    580:        sc->sc_txth = atw_txthresh_tab_lo;
                    581:
                    582:        SIMPLEQ_INIT(&sc->sc_txfreeq);
                    583:        SIMPLEQ_INIT(&sc->sc_txdirtyq);
                    584:
                    585: #ifdef ATW_DEBUG
                    586:        atw_print_regs(sc, "atw_attach");
                    587: #endif /* ATW_DEBUG */
                    588:
                    589:        /*
                    590:         * Allocate the control data structures, and create and load the
                    591:         * DMA map for it.
                    592:         */
                    593:        if ((error = bus_dmamem_alloc(sc->sc_dmat,
                    594:            sizeof(struct atw_control_data), PAGE_SIZE, 0, &sc->sc_cdseg,
                    595:            1, &sc->sc_cdnseg, 0)) != 0) {
                    596:                printf("%s: unable to allocate control data, error = %d\n",
                    597:                    sc->sc_dev.dv_xname, error);
                    598:                goto fail_0;
                    599:        }
                    600:
                    601:        if ((error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg,
                    602:            sizeof(struct atw_control_data), (caddr_t *)&sc->sc_control_data,
                    603:            BUS_DMA_COHERENT)) != 0) {
                    604:                printf("%s: unable to map control data, error = %d\n",
                    605:                    sc->sc_dev.dv_xname, error);
                    606:                goto fail_1;
                    607:        }
                    608:
                    609:        if ((error = bus_dmamap_create(sc->sc_dmat,
                    610:            sizeof(struct atw_control_data), 1,
                    611:            sizeof(struct atw_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
                    612:                printf("%s: unable to create control data DMA map, "
                    613:                    "error = %d\n", sc->sc_dev.dv_xname, error);
                    614:                goto fail_2;
                    615:        }
                    616:
                    617:        if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_cddmamap,
                    618:            sc->sc_control_data, sizeof(struct atw_control_data), NULL,
                    619:            0)) != 0) {
                    620:                printf("%s: unable to load control data DMA map, error = %d\n",
                    621:                    sc->sc_dev.dv_xname, error);
                    622:                goto fail_3;
                    623:        }
                    624:
                    625:        /*
                    626:         * Create the transmit buffer DMA maps.
                    627:         */
                    628:        sc->sc_ntxsegs = ATW_NTXSEGS;
                    629:        for (i = 0; i < ATW_TXQUEUELEN; i++) {
                    630:                if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
                    631:                    sc->sc_ntxsegs, MCLBYTES, 0, 0,
                    632:                    &sc->sc_txsoft[i].txs_dmamap)) != 0) {
                    633:                        printf("%s: unable to create tx DMA map %d, "
                    634:                            "error = %d\n", sc->sc_dev.dv_xname, i, error);
                    635:                        goto fail_4;
                    636:                }
                    637:        }
                    638:
                    639:        /*
                    640:         * Create the receive buffer DMA maps.
                    641:         */
                    642:        for (i = 0; i < ATW_NRXDESC; i++) {
                    643:                if ((error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1,
                    644:                    MCLBYTES, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
                    645:                        printf("%s: unable to create rx DMA map %d, "
                    646:                            "error = %d\n", sc->sc_dev.dv_xname, i, error);
                    647:                        goto fail_5;
                    648:                }
                    649:        }
                    650:        for (i = 0; i < ATW_NRXDESC; i++) {
                    651:                sc->sc_rxsoft[i].rxs_mbuf = NULL;
                    652:        }
                    653:
                    654:        switch (sc->sc_rev) {
                    655:        case ATW_REVISION_AB:
                    656:        case ATW_REVISION_AF:
                    657:                sc->sc_sramlen = ATW_SRAM_A_SIZE;
                    658:                break;
                    659:        case ATW_REVISION_BA:
                    660:        case ATW_REVISION_CA:
                    661:                sc->sc_sramlen = ATW_SRAM_B_SIZE;
                    662:                break;
                    663:        }
                    664:
                    665:        /* Reset the chip to a known state. */
                    666:        atw_reset(sc);
                    667:
                    668:        if (atw_read_srom(sc) == -1)
                    669:                return;
                    670:
                    671:        sc->sc_rftype = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CSR20],
                    672:            ATW_SR_RFTYPE_MASK);
                    673:
                    674:        sc->sc_bbptype = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CSR20],
                    675:            ATW_SR_BBPTYPE_MASK);
                    676:
                    677:        if (sc->sc_rftype >= sizeof(type_strings)/sizeof(type_strings[0])) {
                    678:                printf("%s: unknown RF\n", sc->sc_dev.dv_xname);
                    679:                return;
                    680:        }
                    681:        if (sc->sc_bbptype >= sizeof(type_strings)/sizeof(type_strings[0])) {
                    682:                printf("%s: unknown BBP\n", sc->sc_dev.dv_xname);
                    683:                return;
                    684:        }
                    685:
                    686:        printf("%s: MAC %s, BBP %s, RF %s", sc->sc_dev.dv_xname,
                    687:            atw_printmac(sc->sc_rev), type_strings[sc->sc_bbptype],
                    688:            type_strings[sc->sc_rftype]);
                    689:
                    690:        /* XXX There exists a Linux driver which seems to use RFType = 0 for
                    691:         * MARVEL. My bug, or theirs?
                    692:         */
                    693:
                    694:        reg = LSHIFT(sc->sc_rftype, ATW_SYNCTL_RFTYPE_MASK);
                    695:
                    696:        switch (sc->sc_rftype) {
                    697:        case ATW_RFTYPE_INTERSIL:
                    698:                reg |= ATW_SYNCTL_CS1;
                    699:                break;
                    700:        case ATW_RFTYPE_RFMD:
                    701:                reg |= ATW_SYNCTL_CS0;
                    702:                break;
                    703:        case ATW_RFTYPE_MARVEL:
                    704:                break;
                    705:        }
                    706:
                    707:        sc->sc_synctl_rd = reg | ATW_SYNCTL_RD;
                    708:        sc->sc_synctl_wr = reg | ATW_SYNCTL_WR;
                    709:
                    710:        reg = LSHIFT(sc->sc_bbptype, ATW_BBPCTL_TYPE_MASK);
                    711:
                    712:        switch (sc->sc_bbptype) {
                    713:        case ATW_BBPTYPE_INTERSIL:
                    714:                reg |= ATW_BBPCTL_TWI;
                    715:                break;
                    716:        case ATW_BBPTYPE_RFMD:
                    717:                reg |= ATW_BBPCTL_RF3KADDR_ADDR | ATW_BBPCTL_NEGEDGE_DO |
                    718:                    ATW_BBPCTL_CCA_ACTLO;
                    719:                break;
                    720:        case ATW_BBPTYPE_MARVEL:
                    721:                break;
                    722:        case ATW_C_BBPTYPE_RFMD:
                    723:                printf("%s: ADM8211C MAC/RFMD BBP not supported yet.\n",
                    724:                    sc->sc_dev.dv_xname);
                    725:                break;
                    726:        }
                    727:
                    728:        sc->sc_bbpctl_wr = reg | ATW_BBPCTL_WR;
                    729:        sc->sc_bbpctl_rd = reg | ATW_BBPCTL_RD;
                    730:
                    731:        /*
                    732:         * From this point forward, the attachment cannot fail.  A failure
                    733:         * before this point releases all resources that may have been
                    734:         * allocated.
                    735:         */
                    736:        sc->sc_flags |= ATWF_ATTACHED /* | ATWF_RTSCTS */;
                    737:
                    738:        ATW_DPRINTF((" SROM MAC %04x%04x%04x",
                    739:            htole16(sc->sc_srom[ATW_SR_MAC00]),
                    740:            htole16(sc->sc_srom[ATW_SR_MAC01]),
                    741:            htole16(sc->sc_srom[ATW_SR_MAC10])));
                    742:
                    743:        srom_major = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_FORMAT_VERSION],
                    744:            ATW_SR_MAJOR_MASK);
                    745:
                    746:        if (srom_major < 2)
                    747:                sc->sc_rf3000_options1 = 0;
                    748:        else if (sc->sc_rev == ATW_REVISION_BA) {
                    749:                sc->sc_rf3000_options1 =
                    750:                    MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CR28_CR03],
                    751:                    ATW_SR_CR28_MASK);
                    752:        } else
                    753:                sc->sc_rf3000_options1 = 0;
                    754:
                    755:        sc->sc_rf3000_options2 = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CTRY_CR29],
                    756:            ATW_SR_CR29_MASK);
                    757:
                    758:        country_code = MASK_AND_RSHIFT(sc->sc_srom[ATW_SR_CTRY_CR29],
                    759:            ATW_SR_CTRY_MASK);
                    760:
                    761: #define ADD_CHANNEL(_ic, _chan) do {                                   \
                    762:        _ic->ic_channels[_chan].ic_flags = IEEE80211_CHAN_B;            \
                    763:        _ic->ic_channels[_chan].ic_freq =                               \
                    764:            ieee80211_ieee2mhz(_chan, _ic->ic_channels[_chan].ic_flags);\
                    765: } while (0)
                    766:
                    767:        /* Find available channels */
                    768:        switch (country_code) {
                    769:        case COUNTRY_MMK2:      /* 1-14 */
                    770:                ADD_CHANNEL(ic, 14);
                    771:                /*FALLTHROUGH*/
                    772:        case COUNTRY_ETSI:      /* 1-13 */
                    773:                for (i = 1; i <= 13; i++)
                    774:                        ADD_CHANNEL(ic, i);
                    775:                break;
                    776:        case COUNTRY_FCC:       /* 1-11 */
                    777:        case COUNTRY_IC:        /* 1-11 */
                    778:                for (i = 1; i <= 11; i++)
                    779:                        ADD_CHANNEL(ic, i);
                    780:                break;
                    781:        case COUNTRY_MMK:       /* 14 */
                    782:                ADD_CHANNEL(ic, 14);
                    783:                break;
                    784:        case COUNTRY_FRANCE:    /* 10-13 */
                    785:                for (i = 10; i <= 13; i++)
                    786:                        ADD_CHANNEL(ic, i);
                    787:                break;
                    788:        default:        /* assume channels 10-11 */
                    789:        case COUNTRY_SPAIN:     /* 10-11 */
                    790:                for (i = 10; i <= 11; i++)
                    791:                        ADD_CHANNEL(ic, i);
                    792:                break;
                    793:        }
                    794:
                    795:        /* Read the MAC address. */
                    796:        reg = ATW_READ(sc, ATW_PAR0);
                    797:        ic->ic_myaddr[0] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB0_MASK);
                    798:        ic->ic_myaddr[1] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB1_MASK);
                    799:        ic->ic_myaddr[2] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB2_MASK);
                    800:        ic->ic_myaddr[3] = MASK_AND_RSHIFT(reg, ATW_PAR0_PAB3_MASK);
                    801:        reg = ATW_READ(sc, ATW_PAR1);
                    802:        ic->ic_myaddr[4] = MASK_AND_RSHIFT(reg, ATW_PAR1_PAB4_MASK);
                    803:        ic->ic_myaddr[5] = MASK_AND_RSHIFT(reg, ATW_PAR1_PAB5_MASK);
                    804:
                    805:        if (IEEE80211_ADDR_EQ(ic->ic_myaddr, empty_macaddr)) {
                    806:                printf(" could not get mac address, attach failed\n");
                    807:                return;
                    808:        }
                    809:
                    810:        printf(", address %s\n", ether_sprintf(ic->ic_myaddr));
                    811:
                    812:        memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
                    813:        ifp->if_softc = sc;
                    814:        ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
                    815:            IFF_NOTRAILERS;
                    816:        ifp->if_ioctl = atw_ioctl;
                    817:        ifp->if_start = atw_start;
                    818:        ifp->if_watchdog = atw_watchdog;
                    819: #if !defined(__OpenBSD__)
                    820:        ifp->if_init = atw_init;
                    821:        ifp->if_stop = atw_stop;
                    822: #endif
                    823:        IFQ_SET_READY(&ifp->if_snd);
                    824:
                    825:        ic->ic_phytype = IEEE80211_T_DS;
                    826:        ic->ic_opmode = IEEE80211_M_STA;
                    827:        ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
                    828:            IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
                    829:
                    830:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    831:
                    832:        /*
                    833:         * Call MI attach routines.
                    834:         */
                    835:
                    836:        if_attach(ifp);
                    837:        ieee80211_ifattach(ifp);
                    838:
                    839:        sc->sc_newstate = ic->ic_newstate;
                    840:        ic->ic_newstate = atw_newstate;
                    841:
                    842:        sc->sc_recv_mgmt = ic->ic_recv_mgmt;
                    843:        ic->ic_recv_mgmt = atw_recv_mgmt;
                    844:
                    845:        sc->sc_node_free = ic->ic_node_free;
                    846:        ic->ic_node_free = atw_node_free;
                    847:
                    848:        sc->sc_node_alloc = ic->ic_node_alloc;
                    849:        ic->ic_node_alloc = atw_node_alloc;
                    850:
                    851:        /* possibly we should fill in our own sc_send_prresp, since
                    852:         * the ADM8211 is probably sending probe responses in ad hoc
                    853:         * mode.
                    854:         */
                    855:
                    856:        /* complete initialization */
                    857:        ieee80211_media_init(ifp, atw_media_change, atw_media_status);
                    858:        timeout_set(&sc->sc_scan_to, atw_next_scan, sc);
                    859:
                    860: #if NBPFILTER > 0
                    861:        bpfattach(&sc->sc_radiobpf, ifp, DLT_IEEE802_11_RADIO,
                    862:            sizeof(struct ieee80211_frame) + 64);
                    863: #endif
                    864:
                    865:        /*
                    866:         * Make sure the interface is shutdown during reboot.
                    867:         */
                    868:        sc->sc_sdhook = shutdownhook_establish(atw_shutdown, sc);
                    869:        if (sc->sc_sdhook == NULL)
                    870:                printf("%s: WARNING: unable to establish shutdown hook\n",
                    871:                    sc->sc_dev.dv_xname);
                    872:
                    873:        /*
                    874:         * Add a suspend hook to make sure we come back up after a
                    875:         * resume.
                    876:         */
                    877:        sc->sc_powerhook = powerhook_establish(atw_power, sc);
                    878:        if (sc->sc_powerhook == NULL)
                    879:                printf("%s: WARNING: unable to establish power hook\n",
                    880:                    sc->sc_dev.dv_xname);
                    881:
                    882:        memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
                    883:        sc->sc_rxtap.ar_ihdr.it_len = sizeof(sc->sc_rxtapu);
                    884:        sc->sc_rxtap.ar_ihdr.it_present = ATW_RX_RADIOTAP_PRESENT;
                    885:
                    886:        memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
                    887:        sc->sc_txtap.at_ihdr.it_len = sizeof(sc->sc_txtapu);
                    888:        sc->sc_txtap.at_ihdr.it_present = ATW_TX_RADIOTAP_PRESENT;
                    889:
                    890:        return;
                    891:
                    892:        /*
                    893:         * Free any resources we've allocated during the failed attach
                    894:         * attempt.  Do this in reverse order and fall through.
                    895:         */
                    896:  fail_5:
                    897:        for (i = 0; i < ATW_NRXDESC; i++) {
                    898:                if (sc->sc_rxsoft[i].rxs_dmamap == NULL)
                    899:                        continue;
                    900:                bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxsoft[i].rxs_dmamap);
                    901:        }
                    902:  fail_4:
                    903:        for (i = 0; i < ATW_TXQUEUELEN; i++) {
                    904:                if (sc->sc_txsoft[i].txs_dmamap == NULL)
                    905:                        continue;
                    906:                bus_dmamap_destroy(sc->sc_dmat, sc->sc_txsoft[i].txs_dmamap);
                    907:        }
                    908:        bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
                    909:  fail_3:
                    910:        bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
                    911:  fail_2:
                    912:        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
                    913:            sizeof(struct atw_control_data));
                    914:  fail_1:
                    915:        bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
                    916:  fail_0:
                    917:        return;
                    918: }
                    919:
                    920: struct ieee80211_node *
                    921: atw_node_alloc(struct ieee80211com *ic)
                    922: {
                    923:        struct atw_softc *sc = (struct atw_softc *)ic->ic_if.if_softc;
                    924:        struct ieee80211_node *ni = (*sc->sc_node_alloc)(ic);
                    925:
                    926:        DPRINTF(sc, ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
                    927:        return ni;
                    928: }
                    929:
                    930: void
                    931: atw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
                    932: {
                    933:        struct atw_softc *sc = (struct atw_softc *)ic->ic_if.if_softc;
                    934:
                    935:        DPRINTF(sc, ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
                    936:            ether_sprintf(ni->ni_bssid)));
                    937:        (*sc->sc_node_free)(ic, ni);
                    938: }
                    939:
                    940:
                    941: static void
                    942: atw_test1_reset(struct atw_softc *sc)
                    943: {
                    944:        switch (sc->sc_rev) {
                    945:        case ATW_REVISION_BA:
                    946:                if (1 /* XXX condition on transceiver type */) {
                    947:                        ATW_SET(sc, ATW_TEST1, ATW_TEST1_TESTMODE_MONITOR);
                    948:                }
                    949:                break;
                    950:        case ATW_REVISION_CA:
                    951:                ATW_CLR(sc, ATW_TEST1, ATW_TEST1_TESTMODE_MASK);
                    952:                break;
                    953:        default:
                    954:                break;
                    955:        }
                    956: }
                    957:
                    958: /*
                    959:  * atw_reset:
                    960:  *
                    961:  *     Perform a soft reset on the ADM8211.
                    962:  */
                    963: void
                    964: atw_reset(struct atw_softc *sc)
                    965: {
                    966:        int i;
                    967:        uint32_t lpc;
                    968:
                    969:        ATW_WRITE(sc, ATW_NAR, 0x0);
                    970:        DELAY(20 * 1000);
                    971:
                    972:        /* Reference driver has a cryptic remark indicating that this might
                    973:         * power-on the chip.  I know that it turns off power-saving....
                    974:         */
                    975:        ATW_WRITE(sc, ATW_FRCTL, 0x0);
                    976:
                    977:        ATW_WRITE(sc, ATW_PAR, ATW_PAR_SWR);
                    978:
                    979:        for (i = 0; i < 50; i++) {
                    980:                if (ATW_READ(sc, ATW_PAR) == 0)
                    981:                        break;
                    982:                DELAY(1000);
                    983:        }
                    984:
                    985:        /* ... and then pause 100ms longer for good measure. */
                    986:        DELAY(100 * 1000);
                    987:
                    988:        DPRINTF2(sc, ("%s: atw_reset %d iterations\n", sc->sc_dev.dv_xname, i));
                    989:
                    990:        if (ATW_ISSET(sc, ATW_PAR, ATW_PAR_SWR))
                    991:                printf("%s: reset failed to complete\n", sc->sc_dev.dv_xname);
                    992:
                    993:        atw_test1_reset(sc);
                    994:        /*
                    995:         * Initialize the PCI Access Register.
                    996:         */
                    997:        sc->sc_busmode = ATW_PAR_PBL_8DW;
                    998:
                    999:        ATW_WRITE(sc, ATW_PAR, sc->sc_busmode);
                   1000:        DPRINTF(sc, ("%s: ATW_PAR %08x busmode %08x\n", sc->sc_dev.dv_xname,
                   1001:            ATW_READ(sc, ATW_PAR), sc->sc_busmode));
                   1002:
                   1003:        /* Turn off maximum power saving, etc.
                   1004:         *
                   1005:         * XXX Following example of reference driver, should I set
                   1006:         * an AID of 1?  It didn't seem to help....
                   1007:         */
                   1008:        ATW_WRITE(sc, ATW_FRCTL, 0x0);
                   1009:
                   1010:        DELAY(100 * 1000);
                   1011:
                   1012:        /* Recall EEPROM. */
                   1013:        ATW_SET(sc, ATW_TEST0, ATW_TEST0_EPRLD);
                   1014:
                   1015:        DELAY(10 * 1000);
                   1016:
                   1017:        lpc = ATW_READ(sc, ATW_LPC);
                   1018:
                   1019:        DPRINTF(sc, ("%s: ATW_LPC %#08x\n", __func__, lpc));
                   1020:
                   1021:        /* A reset seems to affect the SRAM contents, so put them into
                   1022:         * a known state.
                   1023:         */
                   1024:        atw_clear_sram(sc);
                   1025:
                   1026:        memset(sc->sc_bssid, 0xff, sizeof(sc->sc_bssid));
                   1027: }
                   1028:
                   1029: void
                   1030: atw_clear_sram(struct atw_softc *sc)
                   1031: {
                   1032:        memset(sc->sc_sram, 0, sizeof(sc->sc_sram));
                   1033:        /* XXX not for revision 0x20. */
                   1034:        atw_write_sram(sc, 0, sc->sc_sram, sc->sc_sramlen);
                   1035: }
                   1036:
                   1037: /* TBD atw_init
                   1038:  *
                   1039:  * set MAC based on ic->ic_bss->myaddr
                   1040:  * write WEP keys
                   1041:  * set TX rate
                   1042:  */
                   1043:
                   1044: /* Tell the ADM8211 to raise ATW_INTR_LINKOFF if 7 beacon intervals pass
                   1045:  * without receiving a beacon with the preferred BSSID & SSID.
                   1046:  * atw_write_bssid & atw_write_ssid set the BSSID & SSID.
                   1047:  */
                   1048: void
                   1049: atw_wcsr_init(struct atw_softc *sc)
                   1050: {
                   1051:        uint32_t wcsr;
                   1052:
                   1053:        wcsr = ATW_READ(sc, ATW_WCSR);
                   1054:        wcsr &= ~(ATW_WCSR_BLN_MASK|ATW_WCSR_LSOE|ATW_WCSR_MPRE|ATW_WCSR_LSOE);
                   1055:        wcsr |= LSHIFT(7, ATW_WCSR_BLN_MASK);
                   1056:        ATW_WRITE(sc, ATW_WCSR, wcsr);  /* XXX resets wake-up status bits */
                   1057:
                   1058:        DPRINTF(sc, ("%s: %s reg[WCSR] = %08x\n",
                   1059:            sc->sc_dev.dv_xname, __func__, ATW_READ(sc, ATW_WCSR)));
                   1060: }
                   1061:
                   1062: /* Turn off power management.  Set Rx store-and-forward mode. */
                   1063: void
                   1064: atw_cmdr_init(struct atw_softc *sc)
                   1065: {
                   1066:        uint32_t cmdr;
                   1067:        cmdr = ATW_READ(sc, ATW_CMDR);
                   1068:        cmdr &= ~ATW_CMDR_APM;
                   1069:        cmdr |= ATW_CMDR_RTE;
                   1070:        cmdr &= ~ATW_CMDR_DRT_MASK;
                   1071:        cmdr |= ATW_CMDR_DRT_SF;
                   1072:
                   1073:        ATW_WRITE(sc, ATW_CMDR, cmdr);
                   1074: }
                   1075:
                   1076: void
                   1077: atw_tofs2_init(struct atw_softc *sc)
                   1078: {
                   1079:        uint32_t tofs2;
                   1080:        /* XXX this magic can probably be figured out from the RFMD docs */
                   1081: #ifndef ATW_REFSLAVE
                   1082:        tofs2 = LSHIFT(4, ATW_TOFS2_PWR1UP_MASK)    | /* 8 ms = 4 * 2 ms */
                   1083:              LSHIFT(13, ATW_TOFS2_PWR0PAPE_MASK) | /* 13 us */
                   1084:              LSHIFT(8, ATW_TOFS2_PWR1PAPE_MASK)  | /* 8 us */
                   1085:              LSHIFT(5, ATW_TOFS2_PWR0TRSW_MASK)  | /* 5 us */
                   1086:              LSHIFT(12, ATW_TOFS2_PWR1TRSW_MASK) | /* 12 us */
                   1087:              LSHIFT(13, ATW_TOFS2_PWR0PE2_MASK)  | /* 13 us */
                   1088:              LSHIFT(4, ATW_TOFS2_PWR1PE2_MASK)   | /* 4 us */
                   1089:              LSHIFT(5, ATW_TOFS2_PWR0TXPE_MASK);  /* 5 us */
                   1090: #else
                   1091:        /* XXX new magic from reference driver source */
                   1092:        tofs2 = LSHIFT(8, ATW_TOFS2_PWR1UP_MASK)    | /* 8 ms = 4 * 2 ms */
                   1093:              LSHIFT(8, ATW_TOFS2_PWR0PAPE_MASK) | /* 13 us */
                   1094:              LSHIFT(1, ATW_TOFS2_PWR1PAPE_MASK)  | /* 8 us */
                   1095:              LSHIFT(5, ATW_TOFS2_PWR0TRSW_MASK)  | /* 5 us */
                   1096:              LSHIFT(12, ATW_TOFS2_PWR1TRSW_MASK) | /* 12 us */
                   1097:              LSHIFT(13, ATW_TOFS2_PWR0PE2_MASK)  | /* 13 us */
                   1098:              LSHIFT(1, ATW_TOFS2_PWR1PE2_MASK)   | /* 4 us */
                   1099:              LSHIFT(8, ATW_TOFS2_PWR0TXPE_MASK);  /* 5 us */
                   1100: #endif
                   1101:        ATW_WRITE(sc, ATW_TOFS2, tofs2);
                   1102: }
                   1103:
                   1104: void
                   1105: atw_nar_init(struct atw_softc *sc)
                   1106: {
                   1107:        ATW_WRITE(sc, ATW_NAR, ATW_NAR_SF|ATW_NAR_PB);
                   1108: }
                   1109:
                   1110: void
                   1111: atw_txlmt_init(struct atw_softc *sc)
                   1112: {
                   1113:        ATW_WRITE(sc, ATW_TXLMT, LSHIFT(512, ATW_TXLMT_MTMLT_MASK) |
                   1114:                                 LSHIFT(1, ATW_TXLMT_SRTYLIM_MASK));
                   1115: }
                   1116:
                   1117: void
                   1118: atw_test1_init(struct atw_softc *sc)
                   1119: {
                   1120:        uint32_t test1;
                   1121:
                   1122:        test1 = ATW_READ(sc, ATW_TEST1);
                   1123:        test1 &= ~(ATW_TEST1_DBGREAD_MASK|ATW_TEST1_CONTROL);
                   1124:        /* XXX magic 0x1 */
                   1125:        test1 |= LSHIFT(0x1, ATW_TEST1_DBGREAD_MASK) | ATW_TEST1_CONTROL;
                   1126:        ATW_WRITE(sc, ATW_TEST1, test1);
                   1127: }
                   1128:
                   1129: void
                   1130: atw_rf_reset(struct atw_softc *sc)
                   1131: {
                   1132:        /* XXX this resets an Intersil RF front-end? */
                   1133:        /* TBD condition on Intersil RFType? */
                   1134:        ATW_WRITE(sc, ATW_SYNRF, ATW_SYNRF_INTERSIL_EN);
                   1135:        DELAY(10 * 1000);
                   1136:        ATW_WRITE(sc, ATW_SYNRF, 0);
                   1137:        DELAY(5 * 1000);
                   1138: }
                   1139:
                   1140: /* Set 16 TU max duration for the contention-free period (CFP). */
                   1141: void
                   1142: atw_cfp_init(struct atw_softc *sc)
                   1143: {
                   1144:        uint32_t cfpp;
                   1145:
                   1146:        cfpp = ATW_READ(sc, ATW_CFPP);
                   1147:        cfpp &= ~ATW_CFPP_CFPMD;
                   1148:        cfpp |= LSHIFT(16, ATW_CFPP_CFPMD);
                   1149:        ATW_WRITE(sc, ATW_CFPP, cfpp);
                   1150: }
                   1151:
                   1152: void
                   1153: atw_tofs0_init(struct atw_softc *sc)
                   1154: {
                   1155:        /* XXX I guess that the Cardbus clock is 22MHz?
                   1156:         * I am assuming that the role of ATW_TOFS0_USCNT is
                   1157:         * to divide the bus clock to get a 1MHz clock---the datasheet is not
                   1158:         * very clear on this point. It says in the datasheet that it is
                   1159:         * possible for the ADM8211 to accomodate bus speeds between 22MHz
                   1160:         * and 33MHz; maybe this is the way? I see a binary-only driver write
                   1161:         * these values. These values are also the power-on default.
                   1162:         */
                   1163:        ATW_WRITE(sc, ATW_TOFS0,
                   1164:            LSHIFT(22, ATW_TOFS0_USCNT_MASK) |
                   1165:            ATW_TOFS0_TUCNT_MASK /* set all bits in TUCNT */);
                   1166: }
                   1167:
                   1168: /* Initialize interframe spacing: 802.11b slot time, SIFS, DIFS, EIFS. */
                   1169: void
                   1170: atw_ifs_init(struct atw_softc *sc)
                   1171: {
                   1172:        uint32_t ifst;
                   1173:        /* XXX EIFS=0x64, SIFS=110 are used by the reference driver.
                   1174:         * Go figure.
                   1175:         */
                   1176:        ifst = LSHIFT(IEEE80211_DUR_DS_SLOT, ATW_IFST_SLOT_MASK) |
                   1177:            LSHIFT(22 * 5 /* IEEE80211_DUR_DS_SIFS */ /* # of 22MHz cycles */,
                   1178:                   ATW_IFST_SIFS_MASK) |
                   1179:            LSHIFT(IEEE80211_DUR_DS_DIFS, ATW_IFST_DIFS_MASK) |
                   1180:            LSHIFT(0x64 /* IEEE80211_DUR_DS_EIFS */, ATW_IFST_EIFS_MASK);
                   1181:
                   1182:        ATW_WRITE(sc, ATW_IFST, ifst);
                   1183: }
                   1184:
                   1185: void
                   1186: atw_response_times_init(struct atw_softc *sc)
                   1187: {
                   1188:        /* XXX More magic. Relates to ACK timing?  The datasheet seems to
                   1189:         * indicate that the MAC expects at least SIFS + MIRT microseconds
                   1190:         * to pass after it transmits a frame that requires a response;
                   1191:         * it waits at most SIFS + MART microseconds for the response.
                   1192:         * Surely this is not the ACK timeout?
                   1193:         */
                   1194:        ATW_WRITE(sc, ATW_RSPT, LSHIFT(0xffff, ATW_RSPT_MART_MASK) |
                   1195:            LSHIFT(0xff, ATW_RSPT_MIRT_MASK));
                   1196: }
                   1197:
                   1198: /* Set up the MMI read/write addresses for the baseband. The Tx/Rx
                   1199:  * engines read and write baseband registers after Rx and before
                   1200:  * Tx, respectively.
                   1201:  */
                   1202: void
                   1203: atw_bbp_io_init(struct atw_softc *sc)
                   1204: {
                   1205:        uint32_t mmiraddr2;
                   1206:
                   1207:        /* XXX The reference driver does this, but is it *really*
                   1208:         * necessary?
                   1209:         */
                   1210:        switch (sc->sc_rev) {
                   1211:        case ATW_REVISION_AB:
                   1212:        case ATW_REVISION_AF:
                   1213:                mmiraddr2 = 0x0;
                   1214:                break;
                   1215:        default:
                   1216:                mmiraddr2 = ATW_READ(sc, ATW_MMIRADDR2);
                   1217:                mmiraddr2 &=
                   1218:                    ~(ATW_MMIRADDR2_PROREXT|ATW_MMIRADDR2_PRORLEN_MASK);
                   1219:                break;
                   1220:        }
                   1221:
                   1222:        switch (sc->sc_bbptype) {
                   1223:        case ATW_BBPTYPE_INTERSIL:
                   1224:                ATW_WRITE(sc, ATW_MMIWADDR, ATW_MMIWADDR_INTERSIL);
                   1225:                ATW_WRITE(sc, ATW_MMIRADDR1, ATW_MMIRADDR1_INTERSIL);
                   1226:                mmiraddr2 |= ATW_MMIRADDR2_INTERSIL;
                   1227:                break;
                   1228:        case ATW_BBPTYPE_MARVEL:
                   1229:                /* TBD find out the Marvel settings. */
                   1230:                break;
                   1231:        case ATW_BBPTYPE_RFMD:
                   1232:        default:
                   1233:                ATW_WRITE(sc, ATW_MMIWADDR, ATW_MMIWADDR_RFMD);
                   1234:                ATW_WRITE(sc, ATW_MMIRADDR1, ATW_MMIRADDR1_RFMD);
                   1235:                mmiraddr2 |= ATW_MMIRADDR2_RFMD;
                   1236:                break;
                   1237:        }
                   1238:        ATW_WRITE(sc, ATW_MMIRADDR2, mmiraddr2);
                   1239:
                   1240:        atw_si4126_init(sc);
                   1241:
                   1242:        ATW_WRITE(sc, ATW_MACTEST, ATW_MACTEST_MMI_USETXCLK);
                   1243: }
                   1244:
                   1245: void
                   1246: atw_si4126_init(struct atw_softc *sc)
                   1247: {
                   1248:        switch (sc->sc_rftype) {
                   1249:        case ATW_RFTYPE_RFMD:
                   1250:                if (sc->sc_rev >= ATW_REVISION_BA) {
                   1251:                        atw_si4126_write(sc, 0x1f, 0x00000);
                   1252:                        atw_si4126_write(sc, 0x0c, 0x3001f);
                   1253:                        atw_si4126_write(sc, SI4126_GAIN, 0x29c03);
                   1254:                        atw_si4126_write(sc, SI4126_RF1N, 0x1ff6f);
                   1255:                        atw_si4126_write(sc, SI4126_RF2N, 0x29403);
                   1256:                        atw_si4126_write(sc, SI4126_RF2R, 0x1456f);
                   1257:                        atw_si4126_write(sc, 0x09, 0x10050);
                   1258:                        atw_si4126_write(sc, SI4126_IFR, 0x3fff8);
                   1259:                }
                   1260:                break;
                   1261:        default:
                   1262:                break;
                   1263:        }
                   1264: }
                   1265:
                   1266: /*
                   1267:  * atw_init:           [ ifnet interface function ]
                   1268:  *
                   1269:  *     Initialize the interface.  Must be called at splnet().
                   1270:  */
                   1271: int
                   1272: atw_init(struct ifnet *ifp)
                   1273: {
                   1274:        struct atw_softc *sc = ifp->if_softc;
                   1275:        struct ieee80211com *ic = &sc->sc_ic;
                   1276:        struct atw_txsoft *txs;
                   1277:        struct atw_rxsoft *rxs;
                   1278:        int i, error = 0;
                   1279:
                   1280:        if ((error = atw_enable(sc)) != 0)
                   1281:                goto out;
                   1282:
                   1283:        /*
                   1284:         * Cancel any pending I/O. This also resets.
                   1285:         */
                   1286:        atw_stop(ifp, 0);
                   1287:
                   1288:        ic->ic_bss->ni_chan = ic->ic_ibss_chan;
                   1289:        DPRINTF(sc, ("%s: channel %d freq %d flags 0x%04x\n",
                   1290:            __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
                   1291:            ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
                   1292:
                   1293:        atw_wcsr_init(sc);
                   1294:
                   1295:        atw_cmdr_init(sc);
                   1296:
                   1297:        /* Set data rate for PLCP Signal field, 1Mbps = 10 x 100Kb/s.
                   1298:         *
                   1299:         * XXX Set transmit power for ATIM, RTS, Beacon.
                   1300:         */
                   1301:        ATW_WRITE(sc, ATW_PLCPHD, LSHIFT(10, ATW_PLCPHD_SIGNAL_MASK) |
                   1302:            LSHIFT(0xb0, ATW_PLCPHD_SERVICE_MASK));
                   1303:
                   1304:        atw_tofs2_init(sc);
                   1305:
                   1306:        atw_nar_init(sc);
                   1307:
                   1308:        atw_txlmt_init(sc);
                   1309:
                   1310:        atw_test1_init(sc);
                   1311:
                   1312:        atw_rf_reset(sc);
                   1313:
                   1314:        atw_cfp_init(sc);
                   1315:
                   1316:        atw_tofs0_init(sc);
                   1317:
                   1318:        atw_ifs_init(sc);
                   1319:
                   1320:        /* XXX Fall asleep after one second of inactivity.
                   1321:         * XXX A frame may only dribble in for 65536us.
                   1322:         */
                   1323:        ATW_WRITE(sc, ATW_RMD,
                   1324:            LSHIFT(1, ATW_RMD_PCNT) | LSHIFT(0xffff, ATW_RMD_RMRD_MASK));
                   1325:
                   1326:        atw_response_times_init(sc);
                   1327:
                   1328:        atw_bbp_io_init(sc);
                   1329:
                   1330:        ATW_WRITE(sc, ATW_STSR, 0xffffffff);
                   1331:
                   1332:        if ((error = atw_rf3000_init(sc)) != 0)
                   1333:                goto out;
                   1334:
                   1335:        ATW_WRITE(sc, ATW_PAR, sc->sc_busmode);
                   1336:        DPRINTF(sc, ("%s: ATW_PAR %08x busmode %08x\n", sc->sc_dev.dv_xname,
                   1337:            ATW_READ(sc, ATW_PAR), sc->sc_busmode));
                   1338:
                   1339:        /*
                   1340:         * Initialize the transmit descriptor ring.
                   1341:         */
                   1342:        memset(sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
                   1343:        for (i = 0; i < ATW_NTXDESC; i++) {
                   1344:                sc->sc_txdescs[i].at_ctl = 0;
                   1345:                /* no transmit chaining */
                   1346:                sc->sc_txdescs[i].at_flags = 0 /* ATW_TXFLAG_TCH */;
                   1347:                sc->sc_txdescs[i].at_buf2 =
                   1348:                    htole32(ATW_CDTXADDR(sc, ATW_NEXTTX(i)));
                   1349:        }
                   1350:        /* use ring mode */
                   1351:        sc->sc_txdescs[ATW_NTXDESC - 1].at_flags |= htole32(ATW_TXFLAG_TER);
                   1352:        ATW_CDTXSYNC(sc, 0, ATW_NTXDESC,
                   1353:            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1354:        sc->sc_txfree = ATW_NTXDESC;
                   1355:        sc->sc_txnext = 0;
                   1356:
                   1357:        /*
                   1358:         * Initialize the transmit job descriptors.
                   1359:         */
                   1360:        SIMPLEQ_INIT(&sc->sc_txfreeq);
                   1361:        SIMPLEQ_INIT(&sc->sc_txdirtyq);
                   1362:        for (i = 0; i < ATW_TXQUEUELEN; i++) {
                   1363:                txs = &sc->sc_txsoft[i];
                   1364:                txs->txs_mbuf = NULL;
                   1365:                SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
                   1366:        }
                   1367:
                   1368:        /*
                   1369:         * Initialize the receive descriptor and receive job
                   1370:         * descriptor rings.
                   1371:         */
                   1372:        for (i = 0; i < ATW_NRXDESC; i++) {
                   1373:                rxs = &sc->sc_rxsoft[i];
                   1374:                if (rxs->rxs_mbuf == NULL) {
                   1375:                        if ((error = atw_add_rxbuf(sc, i)) != 0) {
                   1376:                                printf("%s: unable to allocate or map rx "
                   1377:                                    "buffer %d, error = %d\n",
                   1378:                                    sc->sc_dev.dv_xname, i, error);
                   1379:                                /*
                   1380:                                 * XXX Should attempt to run with fewer receive
                   1381:                                 * XXX buffers instead of just failing.
                   1382:                                 */
                   1383:                                atw_rxdrain(sc);
                   1384:                                goto out;
                   1385:                        }
                   1386:                } else
                   1387:                        ATW_INIT_RXDESC(sc, i);
                   1388:        }
                   1389:        sc->sc_rxptr = 0;
                   1390:
                   1391:        /*
                   1392:         * Initialize the interrupt mask and enable interrupts.
                   1393:         */
                   1394:        /* normal interrupts */
                   1395:        sc->sc_inten =  ATW_INTR_TCI | ATW_INTR_TDU | ATW_INTR_RCI |
                   1396:            ATW_INTR_NISS | ATW_INTR_LINKON | ATW_INTR_BCNTC;
                   1397:
                   1398:        /* abnormal interrupts */
                   1399:        sc->sc_inten |= ATW_INTR_TPS | ATW_INTR_TLT | ATW_INTR_TRT |
                   1400:            ATW_INTR_TUF | ATW_INTR_RDU | ATW_INTR_RPS | ATW_INTR_AISS |
                   1401:            ATW_INTR_FBE | ATW_INTR_LINKOFF | ATW_INTR_TSFTF | ATW_INTR_TSCZ;
                   1402:
                   1403:        sc->sc_linkint_mask = ATW_INTR_LINKON | ATW_INTR_LINKOFF |
                   1404:            ATW_INTR_BCNTC | ATW_INTR_TSFTF | ATW_INTR_TSCZ;
                   1405:        sc->sc_rxint_mask = ATW_INTR_RCI | ATW_INTR_RDU;
                   1406:        sc->sc_txint_mask = ATW_INTR_TCI | ATW_INTR_TUF | ATW_INTR_TLT |
                   1407:            ATW_INTR_TRT;
                   1408:
                   1409:        sc->sc_linkint_mask &= sc->sc_inten;
                   1410:        sc->sc_rxint_mask &= sc->sc_inten;
                   1411:        sc->sc_txint_mask &= sc->sc_inten;
                   1412:
                   1413:        ATW_WRITE(sc, ATW_IER, sc->sc_inten);
                   1414:        ATW_WRITE(sc, ATW_STSR, 0xffffffff);
                   1415:
                   1416:        DPRINTF(sc, ("%s: ATW_IER %08x, inten %08x\n",
                   1417:            sc->sc_dev.dv_xname, ATW_READ(sc, ATW_IER), sc->sc_inten));
                   1418:
                   1419:        /*
                   1420:         * Give the transmit and receive rings to the ADM8211.
                   1421:         */
                   1422:        ATW_WRITE(sc, ATW_RDB, ATW_CDRXADDR(sc, sc->sc_rxptr));
                   1423:        ATW_WRITE(sc, ATW_TDBD, ATW_CDTXADDR(sc, sc->sc_txnext));
                   1424:
                   1425:        sc->sc_txthresh = 0;
                   1426:        sc->sc_opmode = ATW_NAR_SR | ATW_NAR_ST |
                   1427:            sc->sc_txth[sc->sc_txthresh].txth_opmode;
                   1428:
                   1429:        /* common 802.11 configuration */
                   1430:        ic->ic_flags &= ~IEEE80211_F_IBSSON;
                   1431:        switch (ic->ic_opmode) {
                   1432:        case IEEE80211_M_STA:
                   1433:                break;
                   1434:        case IEEE80211_M_AHDEMO: /* XXX */
                   1435:        case IEEE80211_M_IBSS:
                   1436:                ic->ic_flags |= IEEE80211_F_IBSSON;
                   1437:                /*FALLTHROUGH*/
                   1438:        case IEEE80211_M_HOSTAP: /* XXX */
                   1439:                break;
                   1440:        case IEEE80211_M_MONITOR: /* XXX */
                   1441:                break;
                   1442:        }
                   1443:
                   1444:        switch (ic->ic_opmode) {
                   1445:        case IEEE80211_M_AHDEMO:
                   1446:        case IEEE80211_M_HOSTAP:
                   1447:                ic->ic_bss->ni_intval = ic->ic_lintval;
                   1448:                ic->ic_bss->ni_rssi = 0;
                   1449:                ic->ic_bss->ni_rstamp = 0;
                   1450:                break;
                   1451:        default:                                        /* XXX */
                   1452:                break;
                   1453:        }
                   1454:
                   1455:        sc->sc_wepctl = 0;
                   1456:
                   1457:        atw_write_ssid(sc);
                   1458:        atw_write_sup_rates(sc);
                   1459:        if (ic->ic_caps & IEEE80211_C_WEP)
                   1460:                atw_write_wep(sc);
                   1461:
                   1462:        ic->ic_state = IEEE80211_S_INIT;
                   1463:
                   1464:        /*
                   1465:         * Set the receive filter.  This will start the transmit and
                   1466:         * receive processes.
                   1467:         */
                   1468:        atw_filter_setup(sc);
                   1469:
                   1470:        /*
                   1471:         * Start the receive process.
                   1472:         */
                   1473:        ATW_WRITE(sc, ATW_RDR, 0x1);
                   1474:
                   1475:        /*
                   1476:         * Note that the interface is now running.
                   1477:         */
                   1478:        ifp->if_flags |= IFF_RUNNING;
                   1479:        ifp->if_flags &= ~IFF_OACTIVE;
                   1480:
                   1481:        /* send no beacons, yet. */
                   1482:        atw_start_beacon(sc, 0);
                   1483:
                   1484:        if (ic->ic_opmode == IEEE80211_M_MONITOR)
                   1485:                error = ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   1486:        else
                   1487:                error = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                   1488:  out:
                   1489:        if (error) {
                   1490:                ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   1491:                ifp->if_timer = 0;
                   1492:                printf("%s: interface not running\n", sc->sc_dev.dv_xname);
                   1493:        }
                   1494: #ifdef ATW_DEBUG
                   1495:        atw_print_regs(sc, "end of init");
                   1496: #endif /* ATW_DEBUG */
                   1497:
                   1498:        return (error);
                   1499: }
                   1500:
                   1501: /* enable == 1: host control of RF3000/Si4126 through ATW_SYNCTL.
                   1502:  *           0: MAC control of RF3000/Si4126.
                   1503:  *
                   1504:  * Applies power, or selects RF front-end? Sets reset condition.
                   1505:  *
                   1506:  * TBD support non-RFMD BBP, non-SiLabs synth.
                   1507:  */
                   1508: void
                   1509: atw_bbp_io_enable(struct atw_softc *sc, int enable)
                   1510: {
                   1511:        if (enable) {
                   1512:                ATW_WRITE(sc, ATW_SYNRF,
                   1513:                    ATW_SYNRF_SELRF|ATW_SYNRF_PE1|ATW_SYNRF_PHYRST);
                   1514:                DELAY(atw_bbp_io_enable_delay);
                   1515:        } else {
                   1516:                ATW_WRITE(sc, ATW_SYNRF, 0);
                   1517:                DELAY(atw_bbp_io_disable_delay); /* shorter for some reason */
                   1518:        }
                   1519: }
                   1520:
                   1521: int
                   1522: atw_tune(struct atw_softc *sc)
                   1523: {
                   1524:        int rc;
                   1525:        u_int chan;
                   1526:        struct ieee80211com *ic = &sc->sc_ic;
                   1527:
                   1528:        chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                   1529:        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
                   1530:                return 0;
                   1531:
                   1532:        if (chan == sc->sc_cur_chan)
                   1533:                return 0;
                   1534:
                   1535:        DPRINTF(sc, ("%s: chan %d -> %d\n", sc->sc_dev.dv_xname,
                   1536:            sc->sc_cur_chan, chan));
                   1537:
                   1538:        atw_idle(sc, ATW_NAR_SR|ATW_NAR_ST);
                   1539:
                   1540:        atw_si4126_tune(sc, chan);
                   1541:        if ((rc = atw_rf3000_tune(sc, chan)) != 0)
                   1542:                printf("%s: failed to tune channel %d\n", sc->sc_dev.dv_xname,
                   1543:                    chan);
                   1544:
                   1545:        ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
                   1546:        DELAY(20 * 1000);
                   1547:        ATW_WRITE(sc, ATW_RDR, 0x1);
                   1548:
                   1549:        if (rc == 0)
                   1550:                sc->sc_cur_chan = chan;
                   1551:
                   1552:        return rc;
                   1553: }
                   1554:
                   1555: #ifdef ATW_SYNDEBUG
                   1556: void
                   1557: atw_si4126_print(struct atw_softc *sc)
                   1558: {
                   1559:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   1560:        u_int addr, val;
                   1561:
                   1562:        if (atw_debug < 3 || (ifp->if_flags & IFF_DEBUG) == 0)
                   1563:                return;
                   1564:
                   1565:        for (addr = 0; addr <= 8; addr++) {
                   1566:                printf("%s: synth[%d] = ", sc->sc_dev.dv_xname, addr);
                   1567:                if (atw_si4126_read(sc, addr, &val) == 0) {
                   1568:                        printf("<unknown> (quitting print-out)\n");
                   1569:                        break;
                   1570:                }
                   1571:                printf("%05x\n", val);
                   1572:        }
                   1573: }
                   1574: #endif /* ATW_SYNDEBUG */
                   1575:
                   1576: /* Tune to channel chan by adjusting the Si4126 RF/IF synthesizer.
                   1577:  *
                   1578:  * The RF/IF synthesizer produces two reference frequencies for
                   1579:  * the RF2948B transceiver.  The first frequency the RF2948B requires
                   1580:  * is two times the so-called "intermediate frequency" (IF). Since
                   1581:  * a SAW filter on the radio fixes the IF at 374MHz, I program the
                   1582:  * Si4126 to generate IF LO = 374MHz x 2 = 748MHz.  The second
                   1583:  * frequency required by the transceiver is the radio frequency
                   1584:  * (RF). This is a superheterodyne transceiver; for f(chan) the
                   1585:  * center frequency of the channel we are tuning, RF = f(chan) -
                   1586:  * IF.
                   1587:  *
                   1588:  * XXX I am told by SiLabs that the Si4126 will accept a broader range
                   1589:  * of XIN than the 2-25MHz mentioned by the datasheet, even *without*
                   1590:  * XINDIV2 = 1.  I've tried this (it is necessary to double R) and it
                   1591:  * works, but I have still programmed for XINDIV2 = 1 to be safe.
                   1592:  */
                   1593: void
                   1594: atw_si4126_tune(struct atw_softc *sc, u_int chan)
                   1595: {
                   1596:        u_int mhz;
                   1597:        u_int R;
                   1598:        u_int32_t gpio;
                   1599:        u_int16_t gain;
                   1600:
                   1601: #ifdef ATW_SYNDEBUG
                   1602:        atw_si4126_print(sc);
                   1603: #endif /* ATW_SYNDEBUG */
                   1604:
                   1605:        if (sc->sc_rev >= ATW_REVISION_BA) {
                   1606:                atw_si4126_write(sc, SI4126_MAIN, 0x04007);
                   1607:                atw_si4126_write(sc, SI4126_POWER, 0x00033);
                   1608:                atw_si4126_write(sc, SI4126_IFN,
                   1609:                    atw_rfmd2958_ifn[chan - 1]);
                   1610:                atw_si4126_write(sc, SI4126_RF1R,
                   1611:                    atw_rfmd2958_rf1r[chan - 1]);
                   1612: #ifdef NOTYET
                   1613:                /* set TX POWER? */
                   1614:                atw_si4126_write(sc, 0x0a,
                   1615:                    (sc->sc_srom[ATW_SR_CSR20] & mask) |
                   1616:                    power << 9);
                   1617: #endif
                   1618:                /* set TX GAIN */
                   1619:                atw_si4126_write(sc, 0x09, 0x00050 |
                   1620:                    sc->sc_srom[ATW_SR_TXPOWER(chan - 1)]);
                   1621:                /* wait 100us from power-up for RF, IF to settle */
                   1622:                DELAY(100);
                   1623:
                   1624:                return;
                   1625:        }
                   1626:
                   1627:        if (chan == 14)
                   1628:                mhz = 2484;
                   1629:        else
                   1630:                mhz = 2412 + 5 * (chan - 1);
                   1631:
                   1632:        /* Tune IF to 748MHz to suit the IF LO input of the
                   1633:         * RF2494B, which is 2 x IF. No need to set an IF divider
                   1634:          * because an IF in 526MHz - 952MHz is allowed.
                   1635:         *
                   1636:         * XIN is 44.000MHz, so divide it by two to get allowable
                   1637:         * range of 2-25MHz. SiLabs tells me that this is not
                   1638:         * strictly necessary.
                   1639:         */
                   1640:
                   1641:        if (atw_xindiv2)
                   1642:                R = 44;
                   1643:        else
                   1644:                R = 88;
                   1645:
                   1646:        /* Power-up RF, IF synthesizers. */
                   1647:        atw_si4126_write(sc, SI4126_POWER,
                   1648:            SI4126_POWER_PDIB|SI4126_POWER_PDRB);
                   1649:
                   1650:        /* set LPWR, too? */
                   1651:        atw_si4126_write(sc, SI4126_MAIN,
                   1652:            (atw_xindiv2) ? SI4126_MAIN_XINDIV2 : 0);
                   1653:
                   1654:        /* Set the phase-locked loop gain.  If RF2 N > 2047, then
                   1655:         * set KP2 to 1.
                   1656:         *
                   1657:         * REFDIF This is different from the reference driver, which
                   1658:         * always sets SI4126_GAIN to 0.
                   1659:         */
                   1660:        gain = LSHIFT(((mhz - 374) > 2047) ? 1 : 0, SI4126_GAIN_KP2_MASK);
                   1661:
                   1662:        atw_si4126_write(sc, SI4126_GAIN, gain);
                   1663:
                   1664:        /* XIN = 44MHz.
                   1665:         *
                   1666:         * If XINDIV2 = 1, IF = N/(2 * R) * XIN.  I choose N = 1496,
                   1667:         * R = 44 so that 1496/(2 * 44) * 44MHz = 748MHz.
                   1668:         *
                   1669:         * If XINDIV2 = 0, IF = N/R * XIN.  I choose N = 1496, R = 88
                   1670:         * so that 1496/88 * 44MHz = 748MHz.
                   1671:         */
                   1672:        atw_si4126_write(sc, SI4126_IFN, 1496);
                   1673:
                   1674:        atw_si4126_write(sc, SI4126_IFR, R);
                   1675:
                   1676: #ifndef ATW_REFSLAVE
                   1677:        /* Set RF1 arbitrarily. DO NOT configure RF1 after RF2, because
                   1678:         * then RF1 becomes the active RF synthesizer, even on the Si4126,
                   1679:         * which has no RF1!
                   1680:         */
                   1681:        atw_si4126_write(sc, SI4126_RF1R, R);
                   1682:
                   1683:        atw_si4126_write(sc, SI4126_RF1N, mhz - 374);
                   1684: #endif
                   1685:
                   1686:        /* N/R * XIN = RF. XIN = 44MHz. We desire RF = mhz - IF,
                   1687:         * where IF = 374MHz.  Let's divide XIN to 1MHz. So R = 44.
                   1688:         * Now let's multiply it to mhz. So mhz - IF = N.
                   1689:         */
                   1690:        atw_si4126_write(sc, SI4126_RF2R, R);
                   1691:
                   1692:        atw_si4126_write(sc, SI4126_RF2N, mhz - 374);
                   1693:
                   1694:        /* wait 100us from power-up for RF, IF to settle */
                   1695:        DELAY(100);
                   1696:
                   1697:        gpio = ATW_READ(sc, ATW_GPIO);
                   1698:        gpio &= ~(ATW_GPIO_EN_MASK|ATW_GPIO_O_MASK|ATW_GPIO_I_MASK);
                   1699:        gpio |= LSHIFT(1, ATW_GPIO_EN_MASK);
                   1700:
                   1701:        if ((sc->sc_if.if_flags & IFF_LINK1) != 0 && chan != 14) {
                   1702:                /* Set a Prism RF front-end to a special mode for channel 14?
                   1703:                 *
                   1704:                 * Apparently the SMC2635W needs this, although I don't think
                   1705:                 * it has a Prism RF.
                   1706:                 */
                   1707:                gpio |= LSHIFT(1, ATW_GPIO_O_MASK);
                   1708:        }
                   1709:        ATW_WRITE(sc, ATW_GPIO, gpio);
                   1710:
                   1711: #ifdef ATW_SYNDEBUG
                   1712:        atw_si4126_print(sc);
                   1713: #endif /* ATW_SYNDEBUG */
                   1714: }
                   1715:
                   1716: /* Baseline initialization of RF3000 BBP: set CCA mode and enable antenna
                   1717:  * diversity.
                   1718:  *
                   1719:  * !!!
                   1720:  * !!! Call this w/ Tx/Rx suspended, atw_idle(, ATW_NAR_ST|ATW_NAR_SR).
                   1721:  * !!!
                   1722:  */
                   1723: int
                   1724: atw_rf3000_init(struct atw_softc *sc)
                   1725: {
                   1726:        int rc = 0;
                   1727:
                   1728:        atw_bbp_io_enable(sc, 1);
                   1729:
                   1730:        /* CCA is acquisition sensitive */
                   1731:        rc = atw_rf3000_write(sc, RF3000_CCACTL,
                   1732:            LSHIFT(RF3000_CCACTL_MODE_BOTH, RF3000_CCACTL_MODE_MASK));
                   1733:
                   1734:        if (rc != 0)
                   1735:                goto out;
                   1736:
                   1737:        /* enable diversity */
                   1738:        rc = atw_rf3000_write(sc, RF3000_DIVCTL, RF3000_DIVCTL_ENABLE);
                   1739:
                   1740:        if (rc != 0)
                   1741:                goto out;
                   1742:
                   1743:        /* sensible setting from a binary-only driver */
                   1744:        rc = atw_rf3000_write(sc, RF3000_GAINCTL,
                   1745:            LSHIFT(0x1d, RF3000_GAINCTL_TXVGC_MASK));
                   1746:
                   1747:        if (rc != 0)
                   1748:                goto out;
                   1749:
                   1750:        /* magic from a binary-only driver */
                   1751:        rc = atw_rf3000_write(sc, RF3000_LOGAINCAL,
                   1752:            LSHIFT(0x38, RF3000_LOGAINCAL_CAL_MASK));
                   1753:
                   1754:        if (rc != 0)
                   1755:                goto out;
                   1756:
                   1757:        rc = atw_rf3000_write(sc, RF3000_HIGAINCAL, RF3000_HIGAINCAL_DSSSPAD);
                   1758:
                   1759:        if (rc != 0)
                   1760:                goto out;
                   1761:
                   1762:        /*
                   1763:         * XXX Reference driver remarks that Abocom sets this to 50.
                   1764:         * Meaning 0x50, I think....  50 = 0x32, which would set a bit
                   1765:         * in the "reserved" area of register RF3000_OPTIONS1.
                   1766:         */
                   1767:        rc = atw_rf3000_write(sc, RF3000_OPTIONS1, sc->sc_rf3000_options1);
                   1768:
                   1769:        if (rc != 0)
                   1770:                goto out;
                   1771:
                   1772:        rc = atw_rf3000_write(sc, RF3000_OPTIONS2, sc->sc_rf3000_options2);
                   1773:
                   1774:        if (rc != 0)
                   1775:                goto out;
                   1776:
                   1777: out:
                   1778:        atw_bbp_io_enable(sc, 0);
                   1779:        return rc;
                   1780: }
                   1781:
                   1782: #ifdef ATW_BBPDEBUG
                   1783: void
                   1784: atw_rf3000_print(struct atw_softc *sc)
                   1785: {
                   1786:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   1787:        u_int addr, val;
                   1788:
                   1789:        if (atw_debug < 3 || (ifp->if_flags & IFF_DEBUG) == 0)
                   1790:                return;
                   1791:
                   1792:        for (addr = 0x01; addr <= 0x15; addr++) {
                   1793:                printf("%s: bbp[%d] = \n", sc->sc_dev.dv_xname, addr);
                   1794:                if (atw_rf3000_read(sc, addr, &val) != 0) {
                   1795:                        printf("<unknown> (quitting print-out)\n");
                   1796:                        break;
                   1797:                }
                   1798:                printf("%08x\n", val);
                   1799:        }
                   1800: }
                   1801: #endif /* ATW_BBPDEBUG */
                   1802:
                   1803: /* Set the power settings on the BBP for channel `chan'. */
                   1804: int
                   1805: atw_rf3000_tune(struct atw_softc *sc, u_int chan)
                   1806: {
                   1807:        int rc = 0;
                   1808:        u_int32_t reg;
                   1809:        u_int16_t txpower, lpf_cutoff, lna_gs_thresh;
                   1810:
                   1811:        txpower = sc->sc_srom[ATW_SR_TXPOWER(chan)];
                   1812:        lpf_cutoff = sc->sc_srom[ATW_SR_LPF_CUTOFF(chan)];
                   1813:        lna_gs_thresh = sc->sc_srom[ATW_SR_LNA_GS_THRESH(chan)];
                   1814:
                   1815:        /* odd channels: LSB, even channels: MSB */
                   1816:        if (chan % 2 == 1) {
                   1817:                txpower &= 0xFF;
                   1818:                lpf_cutoff &= 0xFF;
                   1819:                lna_gs_thresh &= 0xFF;
                   1820:        } else {
                   1821:                txpower >>= 8;
                   1822:                lpf_cutoff >>= 8;
                   1823:                lna_gs_thresh >>= 8;
                   1824:        }
                   1825:
                   1826: #ifdef ATW_BBPDEBUG
                   1827:        atw_rf3000_print(sc);
                   1828: #endif /* ATW_BBPDEBUG */
                   1829:
                   1830:        DPRINTF(sc, ("%s: chan %d txpower %02x, lpf_cutoff %02x, "
                   1831:            "lna_gs_thresh %02x\n",
                   1832:            sc->sc_dev.dv_xname, chan, txpower, lpf_cutoff, lna_gs_thresh));
                   1833:
                   1834:        atw_bbp_io_enable(sc, 1);
                   1835:
                   1836:        if ((rc = atw_rf3000_write(sc, RF3000_GAINCTL,
                   1837:            LSHIFT(txpower, RF3000_GAINCTL_TXVGC_MASK))) != 0)
                   1838:                goto out;
                   1839:
                   1840:        if ((rc = atw_rf3000_write(sc, RF3000_LOGAINCAL, lpf_cutoff)) != 0)
                   1841:                goto out;
                   1842:
                   1843:        if ((rc = atw_rf3000_write(sc, RF3000_HIGAINCAL, lna_gs_thresh)) != 0)
                   1844:                goto out;
                   1845:
                   1846:        if ((rc = atw_rf3000_write(sc, RF3000_OPTIONS1, 0x0)) != 0)
                   1847:                goto out;
                   1848:
                   1849:        rc = atw_rf3000_write(sc, RF3000_OPTIONS2, RF3000_OPTIONS2_LNAGS_DELAY);
                   1850:        if (rc != 0)
                   1851:                goto out;
                   1852:
                   1853: #ifdef ATW_BBPDEBUG
                   1854:        atw_rf3000_print(sc);
                   1855: #endif /* ATW_BBPDEBUG */
                   1856:
                   1857: out:
                   1858:        atw_bbp_io_enable(sc, 0);
                   1859:
                   1860:        /* set beacon, rts, atim transmit power */
                   1861:        reg = ATW_READ(sc, ATW_PLCPHD);
                   1862:        reg &= ~ATW_PLCPHD_SERVICE_MASK;
                   1863:        reg |= LSHIFT(LSHIFT(txpower, RF3000_GAINCTL_TXVGC_MASK),
                   1864:            ATW_PLCPHD_SERVICE_MASK);
                   1865:        ATW_WRITE(sc, ATW_PLCPHD, reg);
                   1866:        DELAY(2 * 1000);
                   1867:
                   1868:        return rc;
                   1869: }
                   1870:
                   1871: /* Write a register on the RF3000 baseband processor using the
                   1872:  * registers provided by the ADM8211 for this purpose.
                   1873:  *
                   1874:  * Return 0 on success.
                   1875:  */
                   1876: int
                   1877: atw_rf3000_write(struct atw_softc *sc, u_int addr, u_int val)
                   1878: {
                   1879:        u_int32_t reg;
                   1880:        int i;
                   1881:
                   1882:        reg = sc->sc_bbpctl_wr |
                   1883:             LSHIFT(val & 0xff, ATW_BBPCTL_DATA_MASK) |
                   1884:             LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
                   1885:
                   1886:        for (i = 10; --i >= 0; ) {
                   1887:                ATW_WRITE(sc, ATW_BBPCTL, reg);
                   1888:                DELAY(2000);
                   1889:                if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_WR) == 0)
                   1890:                        break;
                   1891:        }
                   1892:
                   1893:        if (i < 0) {
                   1894:                printf("%s: BBPCTL still busy\n", sc->sc_dev.dv_xname);
                   1895:                return ETIMEDOUT;
                   1896:        }
                   1897:        return 0;
                   1898: }
                   1899:
                   1900: /* Read a register on the RF3000 baseband processor using the registers
                   1901:  * the ADM8211 provides for this purpose.
                   1902:  *
                   1903:  * The 7-bit register address is addr.  Record the 8-bit data in the register
                   1904:  * in *val.
                   1905:  *
                   1906:  * Return 0 on success.
                   1907:  *
                   1908:  * XXX This does not seem to work. The ADM8211 must require more or
                   1909:  * different magic to read the chip than to write it. Possibly some
                   1910:  * of the magic I have derived from a binary-only driver concerns
                   1911:  * the "chip address" (see the RF3000 manual).
                   1912:  */
                   1913: #ifdef ATW_BBPDEBUG
                   1914: int
                   1915: atw_rf3000_read(struct atw_softc *sc, u_int addr, u_int *val)
                   1916: {
                   1917:        u_int32_t reg;
                   1918:        int i;
                   1919:
                   1920:        for (i = 1000; --i >= 0; ) {
                   1921:                if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD|ATW_BBPCTL_WR) == 0)
                   1922:                        break;
                   1923:                DELAY(100);
                   1924:        }
                   1925:
                   1926:        if (i < 0) {
                   1927:                printf("%s: start atw_rf3000_read, BBPCTL busy\n",
                   1928:                    sc->sc_dev.dv_xname);
                   1929:                return ETIMEDOUT;
                   1930:        }
                   1931:
                   1932:        reg = sc->sc_bbpctl_rd | LSHIFT(addr & 0x7f, ATW_BBPCTL_ADDR_MASK);
                   1933:
                   1934:        ATW_WRITE(sc, ATW_BBPCTL, reg);
                   1935:
                   1936:        for (i = 1000; --i >= 0; ) {
                   1937:                DELAY(100);
                   1938:                if (ATW_ISSET(sc, ATW_BBPCTL, ATW_BBPCTL_RD) == 0)
                   1939:                        break;
                   1940:        }
                   1941:
                   1942:        ATW_CLR(sc, ATW_BBPCTL, ATW_BBPCTL_RD);
                   1943:
                   1944:        if (i < 0) {
                   1945:                printf("%s: atw_rf3000_read wrote %08x; BBPCTL still busy\n",
                   1946:                    sc->sc_dev.dv_xname, reg);
                   1947:                return ETIMEDOUT;
                   1948:        }
                   1949:        if (val != NULL)
                   1950:                *val = MASK_AND_RSHIFT(reg, ATW_BBPCTL_DATA_MASK);
                   1951:        return 0;
                   1952: }
                   1953: #endif /* ATW_BBPDEBUG */
                   1954:
                   1955: /* Write a register on the Si4126 RF/IF synthesizer using the registers
                   1956:  * provided by the ADM8211 for that purpose.
                   1957:  *
                   1958:  * val is 18 bits of data, and val is the 4-bit address of the register.
                   1959:  *
                   1960:  * Return 0 on success.
                   1961:  */
                   1962: void
                   1963: atw_si4126_write(struct atw_softc *sc, u_int addr, u_int val)
                   1964: {
                   1965:        uint32_t bits, mask, reg;
                   1966:        int nbits;
                   1967:
                   1968:        if (sc->sc_rev >= ATW_REVISION_BA) {
                   1969:                nbits = 24;
                   1970:
                   1971:                val &= 0x3ffff;
                   1972:                addr &= 0x1f;
                   1973:                bits = val | (addr << 18);
                   1974:        } else {
                   1975:                nbits = 22;
                   1976:
                   1977:                KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
                   1978:                KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
                   1979:
                   1980:                bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
                   1981:                    LSHIFT(addr, SI4126_TWI_ADDR_MASK);
                   1982:        }
                   1983:
                   1984:        reg = ATW_SYNRF_SELSYN;
                   1985:        /* reference driver: reset Si4126 serial bus to initial
                   1986:         * conditions?
                   1987:         */
                   1988:        ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_LEIF);
                   1989:        ATW_WRITE(sc, ATW_SYNRF, reg);
                   1990:
                   1991:        for (mask = BIT(nbits - 1); mask != 0; mask >>= 1) {
                   1992:                if ((bits & mask) != 0)
                   1993:                        reg |= ATW_SYNRF_SYNDATA;
                   1994:                else
                   1995:                        reg &= ~ATW_SYNRF_SYNDATA;
                   1996:                ATW_WRITE(sc, ATW_SYNRF, reg);
                   1997:                ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_SYNCLK);
                   1998:                ATW_WRITE(sc, ATW_SYNRF, reg);
                   1999:        }
                   2000:        ATW_WRITE(sc, ATW_SYNRF, reg | ATW_SYNRF_LEIF);
                   2001:        ATW_WRITE(sc, ATW_SYNRF, 0x0);
                   2002: }
                   2003:
                   2004: /* Read 18-bit data from the 4-bit address addr in Si4126
                   2005:  * RF synthesizer and write the data to *val. Return 0 on success.
                   2006:  *
                   2007:  * XXX This does not seem to work. The ADM8211 must require more or
                   2008:  * different magic to read the chip than to write it.
                   2009:  */
                   2010: #ifdef ATW_SYNDEBUG
                   2011: int
                   2012: atw_si4126_read(struct atw_softc *sc, u_int addr, u_int *val)
                   2013: {
                   2014:        u_int32_t reg;
                   2015:        int i;
                   2016:
                   2017:        KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
                   2018:
                   2019:        for (i = 1000; --i >= 0; ) {
                   2020:                if (ATW_ISSET(sc, ATW_SYNCTL, ATW_SYNCTL_RD|ATW_SYNCTL_WR) == 0)
                   2021:                        break;
                   2022:                DELAY(100);
                   2023:        }
                   2024:
                   2025:        if (i < 0) {
                   2026:                printf("%s: start atw_si4126_read, SYNCTL busy\n",
                   2027:                    sc->sc_dev.dv_xname);
                   2028:                return ETIMEDOUT;
                   2029:        }
                   2030:
                   2031:        reg = sc->sc_synctl_rd | LSHIFT(addr, ATW_SYNCTL_DATA_MASK);
                   2032:
                   2033:        ATW_WRITE(sc, ATW_SYNCTL, reg);
                   2034:
                   2035:        for (i = 1000; --i >= 0; ) {
                   2036:                DELAY(100);
                   2037:                if (ATW_ISSET(sc, ATW_SYNCTL, ATW_SYNCTL_RD) == 0)
                   2038:                        break;
                   2039:        }
                   2040:
                   2041:        ATW_CLR(sc, ATW_SYNCTL, ATW_SYNCTL_RD);
                   2042:
                   2043:        if (i < 0) {
                   2044:                printf("%s: atw_si4126_read wrote %#08x, SYNCTL still busy\n",
                   2045:                    sc->sc_dev.dv_xname, reg);
                   2046:                return ETIMEDOUT;
                   2047:        }
                   2048:        if (val != NULL)
                   2049:                *val = MASK_AND_RSHIFT(ATW_READ(sc, ATW_SYNCTL),
                   2050:                                       ATW_SYNCTL_DATA_MASK);
                   2051:        return 0;
                   2052: }
                   2053: #endif /* ATW_SYNDEBUG */
                   2054:
                   2055: /* XXX is the endianness correct? test. */
                   2056: #define        atw_calchash(addr) \
                   2057:        (ether_crc32_le((addr), IEEE80211_ADDR_LEN) & BITS(5, 0))
                   2058:
                   2059: /*
                   2060:  * atw_filter_setup:
                   2061:  *
                   2062:  *     Set the ADM8211's receive filter.
                   2063:  */
                   2064: void
                   2065: atw_filter_setup(struct atw_softc *sc)
                   2066: {
                   2067:        struct ieee80211com *ic = &sc->sc_ic;
                   2068: #if defined(__OpenBSD__)
                   2069:        struct arpcom *ec = &ic->ic_ac;
                   2070: #else
                   2071:        struct ethercom *ec = &ic->ic_ec;
                   2072: #endif
                   2073:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   2074:        int hash;
                   2075:        u_int32_t hashes[2];
                   2076:        struct ether_multi *enm;
                   2077:        struct ether_multistep step;
                   2078:
                   2079:        /* According to comments in tlp_al981_filter_setup
                   2080:         * (dev/ic/tulip.c) the ADMtek AL981 does not like for its
                   2081:         * multicast filter to be set while it is running.  Hopefully
                   2082:         * the ADM8211 is not the same!
                   2083:         */
                   2084:        if ((ifp->if_flags & IFF_RUNNING) != 0)
                   2085:                atw_idle(sc, ATW_NAR_SR);
                   2086:
                   2087:        sc->sc_opmode &= ~(ATW_NAR_PR|ATW_NAR_MM);
                   2088:
                   2089:        /* XXX in scan mode, do not filter packets.  Maybe this is
                   2090:         * unnecessary.
                   2091:         */
                   2092:        if (ic->ic_state == IEEE80211_S_SCAN ||
                   2093:            (ifp->if_flags & IFF_PROMISC) != 0) {
                   2094:                sc->sc_opmode |= ATW_NAR_PR;
                   2095:                goto allmulti;
                   2096:        }
                   2097:
                   2098:        hashes[0] = hashes[1] = 0x0;
                   2099:
                   2100:        /*
                   2101:         * Program the 64-bit multicast hash filter.
                   2102:         */
                   2103:        ETHER_FIRST_MULTI(step, ec, enm);
                   2104:        while (enm != NULL) {
                   2105:                if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
                   2106:                    ETHER_ADDR_LEN) != 0)
                   2107:                        goto allmulti;
                   2108:
                   2109:                hash = atw_calchash(enm->enm_addrlo);
                   2110:                hashes[hash >> 5] |= 1 << (hash & 0x1f);
                   2111:                ETHER_NEXT_MULTI(step, enm);
                   2112:                sc->sc_opmode |= ATW_NAR_MM;
                   2113:        }
                   2114:        ifp->if_flags &= ~IFF_ALLMULTI;
                   2115:        goto setit;
                   2116:
                   2117: allmulti:
                   2118:        sc->sc_opmode |= ATW_NAR_MM;
                   2119:        ifp->if_flags |= IFF_ALLMULTI;
                   2120:        hashes[0] = hashes[1] = 0xffffffff;
                   2121:
                   2122: setit:
                   2123:        ATW_WRITE(sc, ATW_MAR0, hashes[0]);
                   2124:        ATW_WRITE(sc, ATW_MAR1, hashes[1]);
                   2125:        ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
                   2126:        DELAY(20 * 1000);
                   2127:        ATW_WRITE(sc, ATW_RDR, 0x1);
                   2128:
                   2129:        DPRINTF(sc, ("%s: ATW_NAR %08x opmode %08x\n", sc->sc_dev.dv_xname,
                   2130:            ATW_READ(sc, ATW_NAR), sc->sc_opmode));
                   2131: }
                   2132:
                   2133: /* Tell the ADM8211 our preferred BSSID. The ADM8211 must match
                   2134:  * a beacon's BSSID and SSID against the preferred BSSID and SSID
                   2135:  * before it will raise ATW_INTR_LINKON. When the ADM8211 receives
                   2136:  * no beacon with the preferred BSSID and SSID in the number of
                   2137:  * beacon intervals given in ATW_BPLI, then it raises ATW_INTR_LINKOFF.
                   2138:  */
                   2139: void
                   2140: atw_write_bssid(struct atw_softc *sc)
                   2141: {
                   2142:        struct ieee80211com *ic = &sc->sc_ic;
                   2143:        u_int8_t *bssid;
                   2144:
                   2145:        bssid = ic->ic_bss->ni_bssid;
                   2146:
                   2147:        ATW_WRITE(sc, ATW_BSSID0,
                   2148:            LSHIFT(bssid[0], ATW_BSSID0_BSSIDB0_MASK) |
                   2149:            LSHIFT(bssid[1], ATW_BSSID0_BSSIDB1_MASK) |
                   2150:            LSHIFT(bssid[2], ATW_BSSID0_BSSIDB2_MASK) |
                   2151:            LSHIFT(bssid[3], ATW_BSSID0_BSSIDB3_MASK));
                   2152:
                   2153:        ATW_WRITE(sc, ATW_ABDA1,
                   2154:            (ATW_READ(sc, ATW_ABDA1) &
                   2155:            ~(ATW_ABDA1_BSSIDB4_MASK|ATW_ABDA1_BSSIDB5_MASK)) |
                   2156:            LSHIFT(bssid[4], ATW_ABDA1_BSSIDB4_MASK) |
                   2157:            LSHIFT(bssid[5], ATW_ABDA1_BSSIDB5_MASK));
                   2158:
                   2159:        DPRINTF(sc, ("%s: BSSID %s -> ", sc->sc_dev.dv_xname,
                   2160:            ether_sprintf(sc->sc_bssid)));
                   2161:        DPRINTF(sc, ("%s\n", ether_sprintf(bssid)));
                   2162:
                   2163:        memcpy(sc->sc_bssid, bssid, sizeof(sc->sc_bssid));
                   2164: }
                   2165:
                   2166: /* Write buflen bytes from buf to SRAM starting at the SRAM's ofs'th
                   2167:  * 16-bit word.
                   2168:  */
                   2169: void
                   2170: atw_write_sram(struct atw_softc *sc, u_int ofs, u_int8_t *buf, u_int buflen)
                   2171: {
                   2172:        u_int i;
                   2173:        u_int8_t *ptr;
                   2174:
                   2175:        memcpy(&sc->sc_sram[ofs], buf, buflen);
                   2176:
                   2177:        KASSERT(ofs % 2 == 0 && buflen % 2 == 0);
                   2178:
                   2179:        KASSERT(buflen + ofs <= sc->sc_sramlen);
                   2180:
                   2181:        ptr = &sc->sc_sram[ofs];
                   2182:
                   2183:        for (i = 0; i < buflen; i += 2) {
                   2184:                ATW_WRITE(sc, ATW_WEPCTL, ATW_WEPCTL_WR |
                   2185:                    LSHIFT((ofs + i) / 2, ATW_WEPCTL_TBLADD_MASK));
                   2186:                DELAY(atw_writewep_delay);
                   2187:
                   2188:                ATW_WRITE(sc, ATW_WESK,
                   2189:                    LSHIFT((ptr[i + 1] << 8) | ptr[i], ATW_WESK_DATA_MASK));
                   2190:                DELAY(atw_writewep_delay);
                   2191:        }
                   2192:        ATW_WRITE(sc, ATW_WEPCTL, sc->sc_wepctl); /* restore WEP condition */
                   2193:
                   2194:        if (sc->sc_if.if_flags & IFF_DEBUG) {
                   2195:                int n_octets = 0;
                   2196:                printf("%s: wrote %d bytes at 0x%x wepctl 0x%08x\n",
                   2197:                    sc->sc_dev.dv_xname, buflen, ofs, sc->sc_wepctl);
                   2198:                for (i = 0; i < buflen; i++) {
                   2199:                        printf(" %02x", ptr[i]);
                   2200:                        if (++n_octets % 24 == 0)
                   2201:                                printf("\n");
                   2202:                }
                   2203:                if (n_octets % 24 != 0)
                   2204:                        printf("\n");
                   2205:        }
                   2206: }
                   2207:
                   2208: /* Write WEP keys from the ieee80211com to the ADM8211's SRAM. */
                   2209: void
                   2210: atw_write_wep(struct atw_softc *sc)
                   2211: {
                   2212:        struct ieee80211com *ic = &sc->sc_ic;
                   2213: #if 0
                   2214:        u_int32_t reg;
                   2215:        int i;
                   2216: #endif
                   2217:        /* SRAM shared-key record format: key0 flags key1 ... key12 */
                   2218:        u_int8_t buf[IEEE80211_WEP_NKID]
                   2219:                    [1 /* key[0] */ + 1 /* flags */ + 12 /* key[1 .. 12] */];
                   2220:
                   2221:        sc->sc_wepctl = 0;
                   2222:        ATW_WRITE(sc, ATW_WEPCTL, sc->sc_wepctl);
                   2223:
                   2224:        if ((ic->ic_flags & IEEE80211_F_WEPON) == 0)
                   2225:                return;
                   2226:
                   2227:        memset(&buf[0][0], 0, sizeof(buf));
                   2228:
                   2229: #if 0
                   2230:        for (i = 0; i < IEEE80211_WEP_NKID; i++) {
                   2231:                if (ic->ic_nw_keys[i].k_len > 5) {
                   2232:                        buf[i][1] = ATW_WEP_ENABLED | ATW_WEP_104BIT;
                   2233:                } else if (ic->ic_nw_keys[i].k_len != 0) {
                   2234:                        buf[i][1] = ATW_WEP_ENABLED;
                   2235:                } else {
                   2236:                        buf[i][1] = 0;
                   2237:                        continue;
                   2238:                }
                   2239:                buf[i][0] = ic->ic_nw_keys[i].k_key[0];
                   2240:                memcpy(&buf[i][2], &ic->ic_nw_keys[i].k_key[1],
                   2241:                    ic->ic_nw_keys[i].k_len - 1);
                   2242:        }
                   2243:
                   2244:        reg = ATW_READ(sc, ATW_MACTEST);
                   2245:        reg |= ATW_MACTEST_MMI_USETXCLK | ATW_MACTEST_FORCE_KEYID;
                   2246:        reg &= ~ATW_MACTEST_KEYID_MASK;
                   2247:        reg |= LSHIFT(ic->ic_wep_txkey, ATW_MACTEST_KEYID_MASK);
                   2248:        ATW_WRITE(sc, ATW_MACTEST, reg);
                   2249:
                   2250:        sc->sc_wepctl = ATW_WEPCTL_WEPENABLE;
                   2251:
                   2252:        switch (sc->sc_rev) {
                   2253:        case ATW_REVISION_AB:
                   2254:        case ATW_REVISION_AF:
                   2255:                /* Bypass WEP on Rx. */
                   2256:                sc->sc_wepctl |= ATW_WEPCTL_WEPRXBYP;
                   2257:                break;
                   2258:        default:
                   2259:                break;
                   2260:        }
                   2261: #endif
                   2262:
                   2263:        atw_write_sram(sc, ATW_SRAM_ADDR_SHARED_KEY, (u_int8_t*)&buf[0][0],
                   2264:            sizeof(buf));
                   2265: }
                   2266:
                   2267: void
                   2268: atw_change_ibss(struct atw_softc *sc)
                   2269: {
                   2270:        atw_predict_beacon(sc);
                   2271:        atw_write_bssid(sc);
                   2272:        atw_start_beacon(sc, 1);
                   2273: }
                   2274:
                   2275: void
                   2276: atw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
                   2277:     struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
                   2278: {
                   2279:        struct atw_softc *sc = (struct atw_softc*)ic->ic_softc;
                   2280:
                   2281:        /* The ADM8211A answers probe requests. */
                   2282:        if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ &&
                   2283:            sc->sc_rev < ATW_REVISION_BA)
                   2284:                return;
                   2285:
                   2286:        (*sc->sc_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
                   2287:
                   2288:        switch (subtype) {
                   2289:        case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
                   2290:        case IEEE80211_FC0_SUBTYPE_BEACON:
                   2291:                if (ic->ic_opmode != IEEE80211_M_IBSS ||
                   2292:                    ic->ic_state != IEEE80211_S_RUN)
                   2293:                        break;
                   2294:                if (ieee80211_ibss_merge(ic, ni, atw_get_tsft(sc)) == ENETRESET)
                   2295:                        atw_change_ibss(sc);
                   2296:                break;
                   2297:        default:
                   2298:                break;
                   2299:        }
                   2300:        return;
                   2301: }
                   2302:
                   2303: /* Write the SSID in the ieee80211com to the SRAM on the ADM8211.
                   2304:  * In ad hoc mode, the SSID is written to the beacons sent by the
                   2305:  * ADM8211. In both ad hoc and infrastructure mode, beacons received
                   2306:  * with matching SSID affect ATW_INTR_LINKON/ATW_INTR_LINKOFF
                   2307:  * indications.
                   2308:  */
                   2309: void
                   2310: atw_write_ssid(struct atw_softc *sc)
                   2311: {
                   2312:        struct ieee80211com *ic = &sc->sc_ic;
                   2313:        /* 34 bytes are reserved in ADM8211 SRAM for the SSID, but
                   2314:         * it only expects the element length, not its ID.
                   2315:         */
                   2316:        u_int8_t buf[roundup(1 /* length */ + IEEE80211_NWID_LEN, 2)];
                   2317:
                   2318:        memset(buf, 0, sizeof(buf));
                   2319:        buf[0] = ic->ic_bss->ni_esslen;
                   2320:        memcpy(&buf[1], ic->ic_bss->ni_essid, ic->ic_bss->ni_esslen);
                   2321:
                   2322:        atw_write_sram(sc, ATW_SRAM_ADDR_SSID, buf,
                   2323:            roundup(1 + ic->ic_bss->ni_esslen, 2));
                   2324: }
                   2325:
                   2326: /* Write the supported rates in the ieee80211com to the SRAM of the ADM8211.
                   2327:  * In ad hoc mode, the supported rates are written to beacons sent by the
                   2328:  * ADM8211.
                   2329:  */
                   2330: void
                   2331: atw_write_sup_rates(struct atw_softc *sc)
                   2332: {
                   2333:        struct ieee80211com *ic = &sc->sc_ic;
                   2334:        /* 14 bytes are probably (XXX) reserved in the ADM8211 SRAM for
                   2335:         * supported rates
                   2336:         */
                   2337:        u_int8_t buf[roundup(1 /* length */ + IEEE80211_RATE_SIZE, 2)];
                   2338:
                   2339:        memset(buf, 0, sizeof(buf));
                   2340:        buf[0] = ic->ic_bss->ni_rates.rs_nrates;
                   2341:        memcpy(&buf[1], ic->ic_bss->ni_rates.rs_rates,
                   2342:            ic->ic_bss->ni_rates.rs_nrates);
                   2343:
                   2344:        /* XXX deal with rev BA bug linux driver talks of? */
                   2345:
                   2346:        atw_write_sram(sc, ATW_SRAM_ADDR_SUPRATES, buf, sizeof(buf));
                   2347: }
                   2348:
                   2349: /* Start/stop sending beacons. */
                   2350: void
                   2351: atw_start_beacon(struct atw_softc *sc, int start)
                   2352: {
                   2353:        struct ieee80211com *ic = &sc->sc_ic;
                   2354:        uint16_t chan;
                   2355:        uint32_t bcnt, bpli, cap0, cap1, capinfo;
                   2356:        size_t len;
                   2357:
                   2358:        if (ATW_IS_ENABLED(sc) == 0)
                   2359:                return;
                   2360:
                   2361:        /* start beacons */
                   2362:        len = sizeof(struct ieee80211_frame) +
                   2363:            8 /* timestamp */ + 2 /* beacon interval */ +
                   2364:            2 /* capability info */ +
                   2365:            2 + ic->ic_bss->ni_esslen /* SSID element */ +
                   2366:            2 + ic->ic_bss->ni_rates.rs_nrates /* rates element */ +
                   2367:            3 /* DS parameters */ +
                   2368:            IEEE80211_CRC_LEN;
                   2369:
                   2370:        bcnt = ATW_READ(sc, ATW_BCNT) & ~ATW_BCNT_BCNT_MASK;
                   2371:        cap0 = ATW_READ(sc, ATW_CAP0) & ~ATW_CAP0_CHN_MASK;
                   2372:        cap1 = ATW_READ(sc, ATW_CAP1) & ~ATW_CAP1_CAPI_MASK;
                   2373:
                   2374:        ATW_WRITE(sc, ATW_BCNT, bcnt);
                   2375:        ATW_WRITE(sc, ATW_CAP1, cap1);
                   2376:
                   2377:        if (!start)
                   2378:                return;
                   2379:
                   2380:        /* TBD use ni_capinfo */
                   2381:
                   2382:        capinfo = 0;
                   2383:        if (sc->sc_flags & ATWF_SHORT_PREAMBLE)
                   2384:                capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
                   2385:        if (ic->ic_flags & IEEE80211_F_WEPON)
                   2386:                capinfo |= IEEE80211_CAPINFO_PRIVACY;
                   2387:
                   2388:        switch (ic->ic_opmode) {
                   2389:        case IEEE80211_M_IBSS:
                   2390:                len += 4; /* IBSS parameters */
                   2391:                capinfo |= IEEE80211_CAPINFO_IBSS;
                   2392:                break;
                   2393:        case IEEE80211_M_HOSTAP:
                   2394:                /* XXX 6-byte minimum TIM */
                   2395:                len += atw_beacon_len_adjust;
                   2396:                capinfo |= IEEE80211_CAPINFO_ESS;
                   2397:                break;
                   2398:        default:
                   2399:                return;
                   2400:        }
                   2401:
                   2402:        /* set listen interval
                   2403:         * XXX do software units agree w/ hardware?
                   2404:         */
                   2405:        bpli = LSHIFT(ic->ic_bss->ni_intval, ATW_BPLI_BP_MASK) |
                   2406:            LSHIFT(ic->ic_lintval / ic->ic_bss->ni_intval, ATW_BPLI_LI_MASK);
                   2407:
                   2408:        chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                   2409:
                   2410:        bcnt |= LSHIFT(len, ATW_BCNT_BCNT_MASK);
                   2411:        cap0 |= LSHIFT(chan, ATW_CAP0_CHN_MASK);
                   2412:        cap1 |= LSHIFT(capinfo, ATW_CAP1_CAPI_MASK);
                   2413:
                   2414:        ATW_WRITE(sc, ATW_BCNT, bcnt);
                   2415:        ATW_WRITE(sc, ATW_BPLI, bpli);
                   2416:        ATW_WRITE(sc, ATW_CAP0, cap0);
                   2417:        ATW_WRITE(sc, ATW_CAP1, cap1);
                   2418:
                   2419:        DPRINTF(sc, ("%s: atw_start_beacon reg[ATW_BCNT] = %08x\n",
                   2420:            sc->sc_dev.dv_xname, bcnt));
                   2421:        DPRINTF(sc, ("%s: atw_start_beacon reg[ATW_CAP1] = %08x\n",
                   2422:            sc->sc_dev.dv_xname, cap1));
                   2423: }
                   2424:
                   2425: /* Return the 32 lsb of the last TSFT divisible by ival. */
                   2426: static __inline uint32_t
                   2427: atw_last_even_tsft(uint32_t tsfth, uint32_t tsftl, uint32_t ival)
                   2428: {
                   2429:        /* Following the reference driver's lead, I compute
                   2430:         *
                   2431:         *   (uint32_t)((((uint64_t)tsfth << 32) | tsftl) % ival)
                   2432:         *
                   2433:         * without using 64-bit arithmetic, using the following
                   2434:         * relationship:
                   2435:         *
                   2436:         *     (0x100000000 * H + L) % m
                   2437:         *   = ((0x100000000 % m) * H + L) % m
                   2438:         *   = (((0xffffffff + 1) % m) * H + L) % m
                   2439:         *   = ((0xffffffff % m + 1 % m) * H + L) % m
                   2440:         *   = ((0xffffffff % m + 1) * H + L) % m
                   2441:         */
                   2442:        return ((0xFFFFFFFF % ival + 1) * tsfth + tsftl) % ival;
                   2443: }
                   2444:
                   2445: uint64_t
                   2446: atw_get_tsft(struct atw_softc *sc)
                   2447: {
                   2448:        int i;
                   2449:        uint32_t tsfth, tsftl;
                   2450:        for (i = 0; i < 2; i++) {
                   2451:                tsfth = ATW_READ(sc, ATW_TSFTH);
                   2452:                tsftl = ATW_READ(sc, ATW_TSFTL);
                   2453:                if (ATW_READ(sc, ATW_TSFTH) == tsfth)
                   2454:                        break;
                   2455:        }
                   2456:        return ((uint64_t)tsfth << 32) | tsftl;
                   2457: }
                   2458:
                   2459: /* If we've created an IBSS, write the TSF time in the ADM8211 to
                   2460:  * the ieee80211com.
                   2461:  *
                   2462:  * Predict the next target beacon transmission time (TBTT) and
                   2463:  * write it to the ADM8211.
                   2464:  */
                   2465: void
                   2466: atw_predict_beacon(struct atw_softc *sc)
                   2467: {
                   2468: #define TBTTOFS 20 /* TU */
                   2469:
                   2470:        struct ieee80211com *ic = &sc->sc_ic;
                   2471:        uint64_t tsft;
                   2472:        uint32_t ival, past_even, tbtt, tsfth, tsftl;
                   2473:        union {
                   2474:                uint64_t        word;
                   2475:                uint8_t         tstamp[8];
                   2476:        } u;
                   2477:
                   2478:        if ((ic->ic_opmode == IEEE80211_M_HOSTAP) ||
                   2479:            ((ic->ic_opmode == IEEE80211_M_IBSS) &&
                   2480:             (ic->ic_flags & IEEE80211_F_SIBSS))) {
                   2481:                tsft = atw_get_tsft(sc);
                   2482:                u.word = htole64(tsft);
                   2483:                (void)memcpy(&ic->ic_bss->ni_tstamp[0], &u.tstamp[0],
                   2484:                    sizeof(ic->ic_bss->ni_tstamp));
                   2485:        } else {
                   2486:                (void)memcpy(&u, &ic->ic_bss->ni_tstamp[0], sizeof(u));
                   2487:                tsft = letoh64(u.word);
                   2488:        }
                   2489:
                   2490:        ival = ic->ic_bss->ni_intval * IEEE80211_DUR_TU;
                   2491:
                   2492:        tsftl = tsft & 0xFFFFFFFF;
                   2493:        tsfth = tsft >> 32;
                   2494:
                   2495:        /* We sent/received the last beacon `past' microseconds
                   2496:         * after the interval divided the TSF timer.
                   2497:         */
                   2498:        past_even = tsftl - atw_last_even_tsft(tsfth, tsftl, ival);
                   2499:
                   2500:        /* Skip ten beacons so that the TBTT cannot pass before
                   2501:         * we've programmed it.  Ten is an arbitrary number.
                   2502:         */
                   2503:        tbtt = past_even + ival * 10;
                   2504:
                   2505:        ATW_WRITE(sc, ATW_TOFS1,
                   2506:            LSHIFT(1, ATW_TOFS1_TSFTOFSR_MASK) |
                   2507:            LSHIFT(TBTTOFS, ATW_TOFS1_TBTTOFS_MASK) |
                   2508:            LSHIFT(MASK_AND_RSHIFT(tbtt - TBTTOFS * IEEE80211_DUR_TU,
                   2509:                ATW_TBTTPRE_MASK), ATW_TOFS1_TBTTPRE_MASK));
                   2510: #undef TBTTOFS
                   2511: }
                   2512:
                   2513: void
                   2514: atw_next_scan(void *arg)
                   2515: {
                   2516:        struct atw_softc *sc = arg;
                   2517:        struct ieee80211com *ic = &sc->sc_ic;
                   2518:        struct ifnet *ifp = &ic->ic_if;
                   2519:        int s;
                   2520:
                   2521:        /* don't call atw_start w/o network interrupts blocked */
                   2522:        s = splnet();
                   2523:        if (ic->ic_state == IEEE80211_S_SCAN)
                   2524:                ieee80211_next_scan(ifp);
                   2525:        splx(s);
                   2526: }
                   2527:
                   2528: /* Synchronize the hardware state with the software state. */
                   2529: int
                   2530: atw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                   2531: {
                   2532:        struct ifnet *ifp = &ic->ic_if;
                   2533:        struct atw_softc *sc = ifp->if_softc;
                   2534:        enum ieee80211_state ostate = ic->ic_state;
                   2535:        int error;
                   2536:
                   2537:        if (nstate == IEEE80211_S_INIT) {
                   2538:                timeout_del(&sc->sc_scan_to);
                   2539:                sc->sc_cur_chan = IEEE80211_CHAN_ANY;
                   2540:                atw_start_beacon(sc, 0);
                   2541:                return (*sc->sc_newstate)(ic, nstate, arg);
                   2542:        }
                   2543:
                   2544:        if ((error = atw_tune(sc)) != 0)
                   2545:                return error;
                   2546:
                   2547:        switch (nstate) {
                   2548:        case IEEE80211_S_ASSOC:
                   2549:                break;
                   2550:        case IEEE80211_S_INIT:
                   2551:                panic("%s: unexpected state IEEE80211_S_INIT", __func__);
                   2552:                break;
                   2553:        case IEEE80211_S_SCAN:
                   2554:                timeout_add(&sc->sc_scan_to, atw_dwelltime * hz / 1000);
                   2555:                break;
                   2556:        case IEEE80211_S_RUN:
                   2557:                if (ic->ic_opmode == IEEE80211_M_STA)
                   2558:                        break;
                   2559:                /*FALLTHROUGH*/
                   2560:        case IEEE80211_S_AUTH:
                   2561:                atw_write_bssid(sc);
                   2562:                atw_write_ssid(sc);
                   2563:                atw_write_sup_rates(sc);
                   2564:
                   2565:                if (ic->ic_opmode == IEEE80211_M_AHDEMO ||
                   2566:                    ic->ic_opmode == IEEE80211_M_MONITOR)
                   2567:                        break;
                   2568:
                   2569:                /* set listen interval
                   2570:                 * XXX do software units agree w/ hardware?
                   2571:                 */
                   2572:                ATW_WRITE(sc, ATW_BPLI,
                   2573:                    LSHIFT(ic->ic_bss->ni_intval, ATW_BPLI_BP_MASK) |
                   2574:                    LSHIFT(ic->ic_lintval / ic->ic_bss->ni_intval,
                   2575:                           ATW_BPLI_LI_MASK));
                   2576:
                   2577:                DPRINTF(sc, ("%s: reg[ATW_BPLI] = %08x\n",
                   2578:                    sc->sc_dev.dv_xname, ATW_READ(sc, ATW_BPLI)));
                   2579:
                   2580:                atw_predict_beacon(sc);
                   2581:                break;
                   2582:        }
                   2583:
                   2584:        if (nstate != IEEE80211_S_SCAN)
                   2585:                timeout_del(&sc->sc_scan_to);
                   2586:
                   2587:        if (nstate == IEEE80211_S_RUN &&
                   2588:            (ic->ic_opmode == IEEE80211_M_HOSTAP ||
                   2589:             ic->ic_opmode == IEEE80211_M_IBSS))
                   2590:                atw_start_beacon(sc, 1);
                   2591:        else
                   2592:                atw_start_beacon(sc, 0);
                   2593:
                   2594:        error = (*sc->sc_newstate)(ic, nstate, arg);
                   2595:
                   2596:        if (ostate == IEEE80211_S_INIT && nstate == IEEE80211_S_SCAN)
                   2597:                atw_write_bssid(sc);
                   2598:
                   2599:        return error;
                   2600: }
                   2601:
                   2602: /*
                   2603:  * atw_add_rxbuf:
                   2604:  *
                   2605:  *     Add a receive buffer to the indicated descriptor.
                   2606:  */
                   2607: int
                   2608: atw_add_rxbuf(struct atw_softc *sc, int idx)
                   2609: {
                   2610:        struct atw_rxsoft *rxs = &sc->sc_rxsoft[idx];
                   2611:        struct mbuf *m;
                   2612:        int error;
                   2613:
                   2614:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   2615:        if (m == NULL)
                   2616:                return (ENOBUFS);
                   2617:
                   2618:        MCLGET(m, M_DONTWAIT);
                   2619:        if ((m->m_flags & M_EXT) == 0) {
                   2620:                m_freem(m);
                   2621:                return (ENOBUFS);
                   2622:        }
                   2623:
                   2624:        if (rxs->rxs_mbuf != NULL)
                   2625:                bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
                   2626:
                   2627:        rxs->rxs_mbuf = m;
                   2628:
                   2629:        error = bus_dmamap_load(sc->sc_dmat, rxs->rxs_dmamap,
                   2630:            m->m_ext.ext_buf, m->m_ext.ext_size, NULL,
                   2631:            BUS_DMA_READ|BUS_DMA_NOWAIT);
                   2632:        if (error) {
                   2633:                printf("%s: can't load rx DMA map %d, error = %d\n",
                   2634:                    sc->sc_dev.dv_xname, idx, error);
                   2635:                panic("atw_add_rxbuf"); /* XXX */
                   2636:        }
                   2637:
                   2638:        bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   2639:            rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   2640:
                   2641:        ATW_INIT_RXDESC(sc, idx);
                   2642:
                   2643:        return (0);
                   2644: }
                   2645:
                   2646: /*
                   2647:  * Release any queued transmit buffers.
                   2648:  */
                   2649: void
                   2650: atw_txdrain(struct atw_softc *sc)
                   2651: {
                   2652:        struct atw_txsoft *txs;
                   2653:
                   2654:        while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
                   2655:                SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
                   2656:                if (txs->txs_mbuf != NULL) {
                   2657:                        bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
                   2658:                        m_freem(txs->txs_mbuf);
                   2659:                        txs->txs_mbuf = NULL;
                   2660:                }
                   2661:                SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
                   2662:        }
                   2663:        sc->sc_tx_timer = 0;
                   2664: }
                   2665:
                   2666: /*
                   2667:  * atw_stop:           [ ifnet interface function ]
                   2668:  *
                   2669:  *     Stop transmission on the interface.
                   2670:  */
                   2671: void
                   2672: atw_stop(struct ifnet *ifp, int disable)
                   2673: {
                   2674:        struct atw_softc *sc = ifp->if_softc;
                   2675:        struct ieee80211com *ic = &sc->sc_ic;
                   2676:
                   2677:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
                   2678:
                   2679:        /*
                   2680:         * Mark the interface down and cancel the watchdog timer.
                   2681:        */
                   2682:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   2683:        ifp->if_timer = 0;
                   2684:
                   2685:        /* Disable interrupts. */
                   2686:        ATW_WRITE(sc, ATW_IER, 0);
                   2687:
                   2688:        /* Stop the transmit and receive processes. */
                   2689:        sc->sc_opmode = 0;
                   2690:        ATW_WRITE(sc, ATW_NAR, 0);
                   2691:        DELAY(20 * 1000);
                   2692:        ATW_WRITE(sc, ATW_TDBD, 0);
                   2693:        ATW_WRITE(sc, ATW_TDBP, 0);
                   2694:        ATW_WRITE(sc, ATW_RDB, 0);
                   2695:
                   2696:        atw_txdrain(sc);
                   2697:
                   2698:        if (disable) {
                   2699:                atw_rxdrain(sc);
                   2700:                atw_disable(sc);
                   2701:        }
                   2702:
                   2703:        if (!disable)
                   2704:                atw_reset(sc);
                   2705: }
                   2706:
                   2707: /*
                   2708:  * atw_rxdrain:
                   2709:  *
                   2710:  *     Drain the receive queue.
                   2711:  */
                   2712: void
                   2713: atw_rxdrain(struct atw_softc *sc)
                   2714: {
                   2715:        struct atw_rxsoft *rxs;
                   2716:        int i;
                   2717:
                   2718:        for (i = 0; i < ATW_NRXDESC; i++) {
                   2719:                rxs = &sc->sc_rxsoft[i];
                   2720:                if (rxs->rxs_mbuf == NULL)
                   2721:                        continue;
                   2722:                bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
                   2723:                m_freem(rxs->rxs_mbuf);
                   2724:                rxs->rxs_mbuf = NULL;
                   2725:        }
                   2726: }
                   2727:
                   2728: /*
                   2729:  * atw_detach:
                   2730:  *
                   2731:  *     Detach an ADM8211 interface.
                   2732:  */
                   2733: int
                   2734: atw_detach(struct atw_softc *sc)
                   2735: {
                   2736:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   2737:        struct atw_rxsoft *rxs;
                   2738:        struct atw_txsoft *txs;
                   2739:        int i;
                   2740:
                   2741:        /*
                   2742:         * Succeed now if there isn't any work to do.
                   2743:         */
                   2744:        if ((sc->sc_flags & ATWF_ATTACHED) == 0)
                   2745:                return (0);
                   2746:
                   2747:        timeout_del(&sc->sc_scan_to);
                   2748:
                   2749:        ieee80211_ifdetach(ifp);
                   2750:        if_detach(ifp);
                   2751:
                   2752:        for (i = 0; i < ATW_NRXDESC; i++) {
                   2753:                rxs = &sc->sc_rxsoft[i];
                   2754:                if (rxs->rxs_mbuf != NULL) {
                   2755:                        bus_dmamap_unload(sc->sc_dmat, rxs->rxs_dmamap);
                   2756:                        m_freem(rxs->rxs_mbuf);
                   2757:                        rxs->rxs_mbuf = NULL;
                   2758:                }
                   2759:                bus_dmamap_destroy(sc->sc_dmat, rxs->rxs_dmamap);
                   2760:        }
                   2761:        for (i = 0; i < ATW_TXQUEUELEN; i++) {
                   2762:                txs = &sc->sc_txsoft[i];
                   2763:                if (txs->txs_mbuf != NULL) {
                   2764:                        bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
                   2765:                        m_freem(txs->txs_mbuf);
                   2766:                        txs->txs_mbuf = NULL;
                   2767:                }
                   2768:                bus_dmamap_destroy(sc->sc_dmat, txs->txs_dmamap);
                   2769:        }
                   2770:        bus_dmamap_unload(sc->sc_dmat, sc->sc_cddmamap);
                   2771:        bus_dmamap_destroy(sc->sc_dmat, sc->sc_cddmamap);
                   2772:        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_control_data,
                   2773:            sizeof(struct atw_control_data));
                   2774:        bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_cdnseg);
                   2775:
                   2776:        if (sc->sc_sdhook != NULL)
                   2777:                shutdownhook_disestablish(sc->sc_sdhook);
                   2778:        if (sc->sc_powerhook != NULL)
                   2779:                powerhook_disestablish(sc->sc_powerhook);
                   2780:
                   2781:        if (sc->sc_srom)
                   2782:                free(sc->sc_srom, M_DEVBUF);
                   2783:
                   2784:        return (0);
                   2785: }
                   2786:
                   2787: /* atw_shutdown: make sure the interface is stopped at reboot time. */
                   2788: void
                   2789: atw_shutdown(void *arg)
                   2790: {
                   2791:        struct atw_softc *sc = arg;
                   2792:
                   2793:        atw_stop(&sc->sc_ic.ic_if, 1);
                   2794: }
                   2795:
                   2796: int
                   2797: atw_intr(void *arg)
                   2798: {
                   2799:        struct atw_softc *sc = arg;
                   2800:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   2801:        u_int32_t status, rxstatus, txstatus, linkstatus;
                   2802:        int handled = 0, txthresh;
                   2803:
                   2804: #ifdef DEBUG
                   2805:        if (ATW_IS_ENABLED(sc) == 0)
                   2806:                panic("%s: atw_intr: not enabled", sc->sc_dev.dv_xname);
                   2807: #endif
                   2808:
                   2809:        /*
                   2810:         * If the interface isn't running, the interrupt couldn't
                   2811:         * possibly have come from us.
                   2812:         */
                   2813:        if ((ifp->if_flags & IFF_RUNNING) == 0 ||
                   2814:            (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
                   2815:                return (0);
                   2816:
                   2817:        for (;;) {
                   2818:                status = ATW_READ(sc, ATW_STSR);
                   2819:
                   2820:                if (status)
                   2821:                        ATW_WRITE(sc, ATW_STSR, status);
                   2822:
                   2823: #ifdef ATW_DEBUG
                   2824: #define PRINTINTR(flag) do { \
                   2825:        if ((status & flag) != 0) { \
                   2826:                printf("%s" #flag, delim); \
                   2827:                delim = ","; \
                   2828:        } \
                   2829: } while (0)
                   2830:
                   2831:                if (atw_debug > 1 && status) {
                   2832:                        const char *delim = "<";
                   2833:
                   2834:                        printf("%s: reg[STSR] = %x",
                   2835:                            sc->sc_dev.dv_xname, status);
                   2836:
                   2837:                        PRINTINTR(ATW_INTR_FBE);
                   2838:                        PRINTINTR(ATW_INTR_LINKOFF);
                   2839:                        PRINTINTR(ATW_INTR_LINKON);
                   2840:                        PRINTINTR(ATW_INTR_RCI);
                   2841:                        PRINTINTR(ATW_INTR_RDU);
                   2842:                        PRINTINTR(ATW_INTR_REIS);
                   2843:                        PRINTINTR(ATW_INTR_RPS);
                   2844:                        PRINTINTR(ATW_INTR_TCI);
                   2845:                        PRINTINTR(ATW_INTR_TDU);
                   2846:                        PRINTINTR(ATW_INTR_TLT);
                   2847:                        PRINTINTR(ATW_INTR_TPS);
                   2848:                        PRINTINTR(ATW_INTR_TRT);
                   2849:                        PRINTINTR(ATW_INTR_TUF);
                   2850:                        PRINTINTR(ATW_INTR_BCNTC);
                   2851:                        PRINTINTR(ATW_INTR_ATIME);
                   2852:                        PRINTINTR(ATW_INTR_TBTT);
                   2853:                        PRINTINTR(ATW_INTR_TSCZ);
                   2854:                        PRINTINTR(ATW_INTR_TSFTF);
                   2855:                        printf(">\n");
                   2856:                }
                   2857: #undef PRINTINTR
                   2858: #endif /* ATW_DEBUG */
                   2859:
                   2860:                if ((status & sc->sc_inten) == 0)
                   2861:                        break;
                   2862:
                   2863:                handled = 1;
                   2864:
                   2865:                rxstatus = status & sc->sc_rxint_mask;
                   2866:                txstatus = status & sc->sc_txint_mask;
                   2867:                linkstatus = status & sc->sc_linkint_mask;
                   2868:
                   2869:                if (linkstatus) {
                   2870:                        atw_linkintr(sc, linkstatus);
                   2871:                }
                   2872:
                   2873:                if (rxstatus) {
                   2874:                        /* Grab any new packets. */
                   2875:                        atw_rxintr(sc);
                   2876:
                   2877:                        if (rxstatus & ATW_INTR_RDU) {
                   2878:                                printf("%s: receive ring overrun\n",
                   2879:                                    sc->sc_dev.dv_xname);
                   2880:                                /* Get the receive process going again. */
                   2881:                                ATW_WRITE(sc, ATW_RDR, 0x1);
                   2882:                                break;
                   2883:                        }
                   2884:                }
                   2885:
                   2886:                if (txstatus) {
                   2887:                        /* Sweep up transmit descriptors. */
                   2888:                        atw_txintr(sc);
                   2889:
                   2890:                        if (txstatus & ATW_INTR_TLT)
                   2891:                                DPRINTF(sc, ("%s: tx lifetime exceeded\n",
                   2892:                                    sc->sc_dev.dv_xname));
                   2893:
                   2894:                        if (txstatus & ATW_INTR_TRT)
                   2895:                                DPRINTF(sc, ("%s: tx retry limit exceeded\n",
                   2896:                                    sc->sc_dev.dv_xname));
                   2897:
                   2898:                        /* If Tx under-run, increase our transmit threshold
                   2899:                         * if another is available.
                   2900:                         */
                   2901:                        txthresh = sc->sc_txthresh + 1;
                   2902:                        if ((txstatus & ATW_INTR_TUF) &&
                   2903:                            sc->sc_txth[txthresh].txth_name != NULL) {
                   2904:                                /* Idle the transmit process. */
                   2905:                                atw_idle(sc, ATW_NAR_ST);
                   2906:
                   2907:                                sc->sc_txthresh = txthresh;
                   2908:                                sc->sc_opmode &= ~(ATW_NAR_TR_MASK|ATW_NAR_SF);
                   2909:                                sc->sc_opmode |=
                   2910:                                    sc->sc_txth[txthresh].txth_opmode;
                   2911:                                printf("%s: transmit underrun; new "
                   2912:                                    "threshold: %s\n", sc->sc_dev.dv_xname,
                   2913:                                    sc->sc_txth[txthresh].txth_name);
                   2914:
                   2915:                                /* Set the new threshold and restart
                   2916:                                 * the transmit process.
                   2917:                                 */
                   2918:                                ATW_WRITE(sc, ATW_NAR, sc->sc_opmode);
                   2919:                                DELAY(20 * 1000);
                   2920:                                ATW_WRITE(sc, ATW_RDR, 0x1);
                   2921:                                /* XXX Log every Nth underrun from
                   2922:                                 * XXX now on?
                   2923:                                 */
                   2924:                        }
                   2925:                }
                   2926:
                   2927:                if (status & (ATW_INTR_TPS|ATW_INTR_RPS)) {
                   2928:                        if (status & ATW_INTR_TPS)
                   2929:                                printf("%s: transmit process stopped\n",
                   2930:                                    sc->sc_dev.dv_xname);
                   2931:                        if (status & ATW_INTR_RPS)
                   2932:                                printf("%s: receive process stopped\n",
                   2933:                                    sc->sc_dev.dv_xname);
                   2934:                        (void)atw_init(ifp);
                   2935:                        break;
                   2936:                }
                   2937:
                   2938:                if (status & ATW_INTR_FBE) {
                   2939:                        printf("%s: fatal bus error\n", sc->sc_dev.dv_xname);
                   2940:                        (void)atw_init(ifp);
                   2941:                        break;
                   2942:                }
                   2943:
                   2944:                /*
                   2945:                 * Not handled:
                   2946:                 *
                   2947:                 *      Transmit buffer unavailable -- normal
                   2948:                 *      condition, nothing to do, really.
                   2949:                 *
                   2950:                 *      Early receive interrupt -- not available on
                   2951:                 *      all chips, we just use RI.  We also only
                   2952:                 *      use single-segment receive DMA, so this
                   2953:                 *      is mostly useless.
                   2954:                 *
                   2955:                 *      TBD others
                   2956:                 */
                   2957:        }
                   2958:
                   2959:        /* Try to get more packets going. */
                   2960:        atw_start(ifp);
                   2961:
                   2962:        return (handled);
                   2963: }
                   2964:
                   2965: /*
                   2966:  * atw_idle:
                   2967:  *
                   2968:  *     Cause the transmit and/or receive processes to go idle.
                   2969:  *
                   2970:  *      XXX It seems that the ADM8211 will not signal the end of the Rx/Tx
                   2971:  *     process in STSR if I clear SR or ST after the process has already
                   2972:  *     ceased. Fair enough. But the Rx process status bits in ATW_TEST0
                   2973:  *      do not seem to be too reliable. Perhaps I have the sense of the
                   2974:  *     Rx bits switched with the Tx bits?
                   2975:  */
                   2976: void
                   2977: atw_idle(struct atw_softc *sc, u_int32_t bits)
                   2978: {
                   2979:        u_int32_t ackmask = 0, opmode, stsr, test0;
                   2980:        int i, s;
                   2981:
                   2982:        s = splnet();
                   2983:
                   2984:        opmode = sc->sc_opmode & ~bits;
                   2985:
                   2986:        if (bits & ATW_NAR_SR)
                   2987:                ackmask |= ATW_INTR_RPS;
                   2988:
                   2989:        if (bits & ATW_NAR_ST) {
                   2990:                ackmask |= ATW_INTR_TPS;
                   2991:                /* set ATW_NAR_HF to flush TX FIFO. */
                   2992:                opmode |= ATW_NAR_HF;
                   2993:        }
                   2994:
                   2995:        ATW_WRITE(sc, ATW_NAR, opmode);
                   2996:        DELAY(20 * 1000);
                   2997:
                   2998:        for (i = 0; i < 10; i++) {
                   2999:                stsr = ATW_READ(sc, ATW_STSR);
                   3000:                if ((stsr & ackmask) == ackmask)
                   3001:                        break;
                   3002:                DELAY(1000);
                   3003:        }
                   3004:
                   3005:        ATW_WRITE(sc, ATW_STSR, stsr & ackmask);
                   3006:
                   3007:        if ((stsr & ackmask) == ackmask)
                   3008:                goto out;
                   3009:
                   3010:        test0 = ATW_READ(sc, ATW_TEST0);
                   3011:
                   3012:        if ((bits & ATW_NAR_ST) != 0 && (stsr & ATW_INTR_TPS) == 0 &&
                   3013:            (test0 & ATW_TEST0_TS_MASK) != ATW_TEST0_TS_STOPPED) {
                   3014:                DPRINTF2(sc, ("%s: transmit process not idle [%s]\n",
                   3015:                    sc->sc_dev.dv_xname,
                   3016:                    atw_tx_state[MASK_AND_RSHIFT(test0, ATW_TEST0_TS_MASK)]));
                   3017:                DPRINTF2(sc, ("%s: bits %08x test0 %08x stsr %08x\n",
                   3018:                    sc->sc_dev.dv_xname, bits, test0, stsr));
                   3019:        }
                   3020:
                   3021:        if ((bits & ATW_NAR_SR) != 0 && (stsr & ATW_INTR_RPS) == 0 &&
                   3022:            (test0 & ATW_TEST0_RS_MASK) != ATW_TEST0_RS_STOPPED) {
                   3023:                DPRINTF2(sc, ("%s: receive process not idle [%s]\n",
                   3024:                    sc->sc_dev.dv_xname,
                   3025:                    atw_rx_state[MASK_AND_RSHIFT(test0, ATW_TEST0_RS_MASK)]));
                   3026:                DPRINTF2(sc, ("%s: bits %08x test0 %08x stsr %08x\n",
                   3027:                    sc->sc_dev.dv_xname, bits, test0, stsr));
                   3028:        }
                   3029: out:
                   3030:        if ((bits & ATW_NAR_ST) != 0)
                   3031:                atw_txdrain(sc);
                   3032:        splx(s);
                   3033:        return;
                   3034: }
                   3035:
                   3036: /*
                   3037:  * atw_linkintr:
                   3038:  *
                   3039:  *     Helper; handle link-status interrupts.
                   3040:  */
                   3041: void
                   3042: atw_linkintr(struct atw_softc *sc, u_int32_t linkstatus)
                   3043: {
                   3044:        struct ieee80211com *ic = &sc->sc_ic;
                   3045:
                   3046:        if (ic->ic_state != IEEE80211_S_RUN)
                   3047:                return;
                   3048:
                   3049:        if (linkstatus & ATW_INTR_LINKON) {
                   3050:                DPRINTF(sc, ("%s: link on\n", sc->sc_dev.dv_xname));
                   3051:                sc->sc_rescan_timer = 0;
                   3052:        } else if (linkstatus & ATW_INTR_LINKOFF) {
                   3053:                DPRINTF(sc, ("%s: link off\n", sc->sc_dev.dv_xname));
                   3054:                if (ic->ic_opmode != IEEE80211_M_STA)
                   3055:                        return;
                   3056:                sc->sc_rescan_timer = 3;
                   3057:                ic->ic_if.if_timer = 1;
                   3058:        }
                   3059: }
                   3060:
                   3061: static __inline int
                   3062: atw_hw_decrypted(struct atw_softc *sc, struct ieee80211_frame *wh)
                   3063: {
                   3064:        if ((sc->sc_ic.ic_flags & IEEE80211_F_WEPON) == 0)
                   3065:                return 0;
                   3066:        if ((wh->i_fc[1] & IEEE80211_FC1_WEP) == 0)
                   3067:                return 0;
                   3068:        return (sc->sc_wepctl & ATW_WEPCTL_WEPRXBYP) == 0;
                   3069: }
                   3070:
                   3071: /*
                   3072:  * atw_rxintr:
                   3073:  *
                   3074:  *     Helper; handle receive interrupts.
                   3075:  */
                   3076: void
                   3077: atw_rxintr(struct atw_softc *sc)
                   3078: {
                   3079:        static int rate_tbl[] = {2, 4, 11, 22, 44};
                   3080:        struct ieee80211com *ic = &sc->sc_ic;
                   3081:        struct ieee80211_node *ni;
                   3082:        struct ieee80211_frame *wh;
                   3083:        struct ifnet *ifp = &ic->ic_if;
                   3084:        struct atw_rxsoft *rxs;
                   3085:        struct mbuf *m;
                   3086:        u_int32_t rxstat;
                   3087:        int i, len, rate, rate0;
                   3088:        u_int32_t rssi, rssi0;
                   3089:
                   3090:        for (i = sc->sc_rxptr;; i = ATW_NEXTRX(i)) {
                   3091:                rxs = &sc->sc_rxsoft[i];
                   3092:
                   3093:                ATW_CDRXSYNC(sc, i, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   3094:
                   3095:                rxstat = letoh32(sc->sc_rxdescs[i].ar_stat);
                   3096:                rssi0 = letoh32(sc->sc_rxdescs[i].ar_rssi);
                   3097:                rate0 = MASK_AND_RSHIFT(rxstat, ATW_RXSTAT_RXDR_MASK);
                   3098:
                   3099:                if (rxstat & ATW_RXSTAT_OWN)
                   3100:                        break; /* We have processed all receive buffers. */
                   3101:
                   3102:                DPRINTF3(sc,
                   3103:                    ("%s: rx stat %08x rssi0 %08x buf1 %08x buf2 %08x\n",
                   3104:                    sc->sc_dev.dv_xname,
                   3105:                    rxstat, rssi0,
                   3106:                    letoh32(sc->sc_rxdescs[i].ar_buf1),
                   3107:                    letoh32(sc->sc_rxdescs[i].ar_buf2)));
                   3108:
                   3109:                /*
                   3110:                 * Make sure the packet fits in one buffer.  This should
                   3111:                 * always be the case.
                   3112:                 */
                   3113:                if ((rxstat & (ATW_RXSTAT_FS|ATW_RXSTAT_LS)) !=
                   3114:                    (ATW_RXSTAT_FS|ATW_RXSTAT_LS)) {
                   3115:                        printf("%s: incoming packet spilled, resetting\n",
                   3116:                            sc->sc_dev.dv_xname);
                   3117:                        (void)atw_init(ifp);
                   3118:                        return;
                   3119:                }
                   3120:
                   3121:                /*
                   3122:                 * If an error occurred, update stats, clear the status
                   3123:                 * word, and leave the packet buffer in place.  It will
                   3124:                 * simply be reused the next time the ring comes around.
                   3125:                 * If 802.1Q VLAN MTU is enabled, ignore the Frame Too Long
                   3126:                 * error.
                   3127:                 */
                   3128:
                   3129:                if ((rxstat & ATW_RXSTAT_ES) != 0 &&
                   3130: #if defined(__OpenBSD__)
                   3131:                    ((sc->sc_ic.ic_if.if_capabilities & IFCAP_VLAN_MTU) == 0 ||
                   3132: #else
                   3133:                    ((sc->sc_ic.ic_ec.ec_capenable & ETHERCAP_VLAN_MTU) == 0 ||
                   3134: #endif
                   3135:                     (rxstat & (ATW_RXSTAT_DE | ATW_RXSTAT_SFDE |
                   3136:                                ATW_RXSTAT_SIGE | ATW_RXSTAT_CRC16E |
                   3137:                                ATW_RXSTAT_RXTOE | ATW_RXSTAT_CRC32E |
                   3138:                                ATW_RXSTAT_ICVE)) != 0)) {
                   3139: #define        PRINTERR(bit, str)                                              \
                   3140:                        if (rxstat & (bit))                             \
                   3141:                                printf("%s: receive error: %s\n",       \
                   3142:                                    sc->sc_dev.dv_xname, str)
                   3143:                        ifp->if_ierrors++;
                   3144:                        PRINTERR(ATW_RXSTAT_DE, "descriptor error");
                   3145:                        PRINTERR(ATW_RXSTAT_SFDE, "PLCP SFD error");
                   3146:                        PRINTERR(ATW_RXSTAT_SIGE, "PLCP signal error");
                   3147:                        PRINTERR(ATW_RXSTAT_CRC16E, "PLCP CRC16 error");
                   3148:                        PRINTERR(ATW_RXSTAT_RXTOE, "time-out");
                   3149:                        PRINTERR(ATW_RXSTAT_CRC32E, "FCS error");
                   3150:                        PRINTERR(ATW_RXSTAT_ICVE, "WEP ICV error");
                   3151: #undef PRINTERR
                   3152:                        ATW_INIT_RXDESC(sc, i);
                   3153:                        continue;
                   3154:                }
                   3155:
                   3156:                bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   3157:                    rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   3158:
                   3159:                /*
                   3160:                 * No errors; receive the packet.  Note the ADM8211
                   3161:                 * includes the CRC in promiscuous mode.
                   3162:                 */
                   3163:                len = MASK_AND_RSHIFT(rxstat, ATW_RXSTAT_FL_MASK);
                   3164:
                   3165:                /*
                   3166:                 * Allocate a new mbuf cluster.  If that fails, we are
                   3167:                 * out of memory, and must drop the packet and recycle
                   3168:                 * the buffer that's already attached to this descriptor.
                   3169:                 */
                   3170:                m = rxs->rxs_mbuf;
                   3171:                if (atw_add_rxbuf(sc, i) != 0) {
                   3172:                        ifp->if_ierrors++;
                   3173:                        ATW_INIT_RXDESC(sc, i);
                   3174:                        bus_dmamap_sync(sc->sc_dmat, rxs->rxs_dmamap, 0,
                   3175:                            rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   3176:                        continue;
                   3177:                }
                   3178:
                   3179:                ifp->if_ipackets++;
                   3180:                if (sc->sc_opmode & ATW_NAR_PR)
                   3181:                        len -= IEEE80211_CRC_LEN;
                   3182:                m->m_pkthdr.rcvif = ifp;
                   3183:                m->m_pkthdr.len = m->m_len = MIN(m->m_ext.ext_size, len);
                   3184:
                   3185:                if (rate0 >= sizeof(rate_tbl) / sizeof(rate_tbl[0]))
                   3186:                        rate = 0;
                   3187:                else
                   3188:                        rate = rate_tbl[rate0];
                   3189:
                   3190:                /* The RSSI comes straight from a register in the
                   3191:                 * baseband processor.  I know that for the RF3000,
                   3192:                 * the RSSI register also contains the antenna-selection
                   3193:                 * bits.  Mask those off.
                   3194:                 *
                   3195:                 * TBD Treat other basebands.
                   3196:                 */
                   3197:                if (sc->sc_bbptype == ATW_BBPTYPE_RFMD)
                   3198:                        rssi = rssi0 & RF3000_RSSI_MASK;
                   3199:                else
                   3200:                        rssi = rssi0;
                   3201:
                   3202: #if NBPFILTER > 0
                   3203:                /* Pass this up to any BPF listeners. */
                   3204:                if (sc->sc_radiobpf != NULL) {
                   3205:                        struct mbuf mb;
                   3206:
                   3207:                        struct atw_rx_radiotap_header *tap = &sc->sc_rxtap;
                   3208:
                   3209:                        tap->ar_rate = rate;
                   3210:                        tap->ar_chan_freq = ic->ic_bss->ni_chan->ic_freq;
                   3211:                        tap->ar_chan_flags = ic->ic_bss->ni_chan->ic_flags;
                   3212:
                   3213:                        /* TBD verify units are dB */
                   3214:                        tap->ar_antsignal = (int)rssi;
                   3215:                        /* TBD tap->ar_flags */
                   3216:
                   3217:                        mb.m_data = (caddr_t)tap;
                   3218:                        mb.m_len = tap->ar_ihdr.it_len;
                   3219:                        mb.m_next = m;
                   3220:                        mb.m_nextpkt = NULL;
                   3221:                        mb.m_type = 0;
                   3222:                        mb.m_flags = 0;
                   3223:                        bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
                   3224:                }
                   3225: #endif /* NPBFILTER > 0 */
                   3226:
                   3227:                wh = mtod(m, struct ieee80211_frame *);
                   3228:                ni = ieee80211_find_rxnode(ic, wh);
                   3229: #if 0
                   3230:                if (atw_hw_decrypted(sc, wh))
                   3231:                        wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
                   3232: #endif
                   3233:                ieee80211_input(ifp, m, ni, (int)rssi, 0);
                   3234:                /*
                   3235:                 * The frame may have caused the node to be marked for
                   3236:                 * reclamation (e.g. in response to a DEAUTH message)
                   3237:                 * so use release_node here instead of unref_node.
                   3238:                 */
                   3239:                ieee80211_release_node(ic, ni);
                   3240:        }
                   3241:
                   3242:        /* Update the receive pointer. */
                   3243:        sc->sc_rxptr = i;
                   3244: }
                   3245:
                   3246: /*
                   3247:  * atw_txintr:
                   3248:  *
                   3249:  *     Helper; handle transmit interrupts.
                   3250:  */
                   3251: void
                   3252: atw_txintr(struct atw_softc *sc)
                   3253: {
                   3254: #define TXSTAT_ERRMASK (ATW_TXSTAT_TUF | ATW_TXSTAT_TLT | ATW_TXSTAT_TRT | \
                   3255:     ATW_TXSTAT_TRO | ATW_TXSTAT_SOFBR)
                   3256: #define TXSTAT_FMT "\20\31ATW_TXSTAT_SOFBR\32ATW_TXSTAT_TRO\33ATW_TXSTAT_TUF" \
                   3257:     "\34ATW_TXSTAT_TRT\35ATW_TXSTAT_TLT"
                   3258:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   3259:        struct atw_txsoft *txs;
                   3260:        u_int32_t txstat;
                   3261:
                   3262:        DPRINTF3(sc, ("%s: atw_txintr: sc_flags 0x%08x\n",
                   3263:            sc->sc_dev.dv_xname, sc->sc_flags));
                   3264:
                   3265:        ifp->if_flags &= ~IFF_OACTIVE;
                   3266:
                   3267:        /*
                   3268:         * Go through our Tx list and free mbufs for those
                   3269:         * frames that have been transmitted.
                   3270:         */
                   3271:        while ((txs = SIMPLEQ_FIRST(&sc->sc_txdirtyq)) != NULL) {
                   3272:                ATW_CDTXSYNC(sc, txs->txs_lastdesc, 1,
                   3273:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   3274:
                   3275: #ifdef ATW_DEBUG
                   3276:                if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
                   3277:                        int i;
                   3278:                        printf("    txsoft %p transmit chain:\n", txs);
                   3279:                        ATW_CDTXSYNC(sc, txs->txs_firstdesc,
                   3280:                            txs->txs_ndescs - 1,
                   3281:                            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   3282:                        for (i = txs->txs_firstdesc;; i = ATW_NEXTTX(i)) {
                   3283:                                printf("     descriptor %d:\n", i);
                   3284:                                printf("       at_status:   0x%08x\n",
                   3285:                                    letoh32(sc->sc_txdescs[i].at_stat));
                   3286:                                printf("       at_flags:      0x%08x\n",
                   3287:                                    letoh32(sc->sc_txdescs[i].at_flags));
                   3288:                                printf("       at_buf1: 0x%08x\n",
                   3289:                                    letoh32(sc->sc_txdescs[i].at_buf1));
                   3290:                                printf("       at_buf2: 0x%08x\n",
                   3291:                                    letoh32(sc->sc_txdescs[i].at_buf2));
                   3292:                                if (i == txs->txs_lastdesc)
                   3293:                                        break;
                   3294:                        }
                   3295:                }
                   3296: #endif
                   3297:
                   3298:                txstat = letoh32(sc->sc_txdescs[txs->txs_lastdesc].at_stat);
                   3299:                if (txstat & ATW_TXSTAT_OWN)
                   3300:                        break;
                   3301:
                   3302:                SIMPLEQ_REMOVE_HEAD(&sc->sc_txdirtyq, txs_q);
                   3303:
                   3304:                sc->sc_txfree += txs->txs_ndescs;
                   3305:
                   3306:                bus_dmamap_sync(sc->sc_dmat, txs->txs_dmamap,
                   3307:                    0, txs->txs_dmamap->dm_mapsize,
                   3308:                    BUS_DMASYNC_POSTWRITE);
                   3309:                bus_dmamap_unload(sc->sc_dmat, txs->txs_dmamap);
                   3310:                m_freem(txs->txs_mbuf);
                   3311:                txs->txs_mbuf = NULL;
                   3312:
                   3313:                SIMPLEQ_INSERT_TAIL(&sc->sc_txfreeq, txs, txs_q);
                   3314:
                   3315:                if ((ifp->if_flags & IFF_DEBUG) != 0 &&
                   3316:                    (txstat & TXSTAT_ERRMASK) != 0) {
                   3317: #if defined(__OpenBSD__)
                   3318:                        printf("%s: txstat %b %d\n", sc->sc_dev.dv_xname,
                   3319:                            txstat & TXSTAT_ERRMASK, TXSTAT_FMT,
                   3320:                            MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK));
                   3321: #else
                   3322:                        static char txstat_buf[sizeof("ffffffff<>" TXSTAT_FMT)];
                   3323:                        bitmask_snprintf(txstat & TXSTAT_ERRMASK, TXSTAT_FMT,
                   3324:                            txstat_buf, sizeof(txstat_buf));
                   3325:                        printf("%s: txstat %s %d\n", sc->sc_dev.dv_xname,
                   3326:                            txstat_buf,
                   3327:                            MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK));
                   3328: #endif
                   3329:                }
                   3330:
                   3331:                /*
                   3332:                 * Check for errors and collisions.
                   3333:                 */
                   3334:                if (txstat & ATW_TXSTAT_TUF)
                   3335:                        sc->sc_stats.ts_tx_tuf++;
                   3336:                if (txstat & ATW_TXSTAT_TLT)
                   3337:                        sc->sc_stats.ts_tx_tlt++;
                   3338:                if (txstat & ATW_TXSTAT_TRT)
                   3339:                        sc->sc_stats.ts_tx_trt++;
                   3340:                if (txstat & ATW_TXSTAT_TRO)
                   3341:                        sc->sc_stats.ts_tx_tro++;
                   3342:                if (txstat & ATW_TXSTAT_SOFBR) {
                   3343:                        sc->sc_stats.ts_tx_sofbr++;
                   3344:                }
                   3345:
                   3346:                if ((txstat & ATW_TXSTAT_ES) == 0)
                   3347:                        ifp->if_collisions +=
                   3348:                            MASK_AND_RSHIFT(txstat, ATW_TXSTAT_ARC_MASK);
                   3349:                else
                   3350:                        ifp->if_oerrors++;
                   3351:
                   3352:                ifp->if_opackets++;
                   3353:        }
                   3354:
                   3355:        /*
                   3356:         * If there are no more pending transmissions, cancel the watchdog
                   3357:         * timer.
                   3358:         */
                   3359:        if (txs == NULL)
                   3360:                sc->sc_tx_timer = 0;
                   3361: #undef TXSTAT_ERRMASK
                   3362: #undef TXSTAT_FMT
                   3363: }
                   3364:
                   3365: /*
                   3366:  * atw_watchdog:       [ifnet interface function]
                   3367:  *
                   3368:  *     Watchdog timer handler.
                   3369:  */
                   3370: void
                   3371: atw_watchdog(struct ifnet *ifp)
                   3372: {
                   3373:        struct atw_softc *sc = ifp->if_softc;
                   3374:        struct ieee80211com *ic = &sc->sc_ic;
                   3375:        uint32_t test1, rra, rwa;
                   3376:
                   3377:        ifp->if_timer = 0;
                   3378:        if (ATW_IS_ENABLED(sc) == 0)
                   3379:                return;
                   3380:
                   3381:        if (sc->sc_rescan_timer) {
                   3382:                if (--sc->sc_rescan_timer == 0)
                   3383:                        (void)ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                   3384:        }
                   3385:        if (sc->sc_tx_timer) {
                   3386:                if (--sc->sc_tx_timer == 0 &&
                   3387:                    !SIMPLEQ_EMPTY(&sc->sc_txdirtyq)) {
                   3388:                        printf("%s: transmit timeout\n", ifp->if_xname);
                   3389:                        ifp->if_oerrors++;
                   3390:                        (void)atw_init(ifp);
                   3391:                        atw_start(ifp);
                   3392:                }
                   3393:        }
                   3394:        if (sc->sc_tx_timer != 0 || sc->sc_rescan_timer != 0)
                   3395:                ifp->if_timer = 1;
                   3396:
                   3397:        /*
                   3398:         * ADM8211B seems to stall every so often, check for this.
                   3399:         * These bits are what the Linux driver checks, they don't
                   3400:         * seem to be documented by ADMTek/Infineon?
                   3401:         */
                   3402:        if (sc->sc_rev == ATW_REVISION_BA) {
                   3403:                test1 = ATW_READ(sc, ATW_TEST1);
                   3404:                rra = (test1 >> 12) & 0x1ff;
                   3405:                rwa = (test1 >> 2) & 0x1ff;
                   3406:
                   3407:                if ((rra != rwa) && !(test1 & 0x2)) {
                   3408:                        atw_init(ifp);
                   3409:                        atw_start(ifp);
                   3410:                }
                   3411:        }
                   3412:
                   3413:        ieee80211_watchdog(ifp);
                   3414: }
                   3415:
                   3416: /*
                   3417:  * Arguments in:
                   3418:  *
                   3419:  * paylen:  payload length (no FCS, no WEP header)
                   3420:  *
                   3421:  * hdrlen:  header length
                   3422:  *
                   3423:  * rate:    MSDU speed, units 500kb/s
                   3424:  *
                   3425:  * flags:   IEEE80211_F_SHPREAMBLE (use short preamble),
                   3426:  *          IEEE80211_F_SHSLOT (use short slot length)
                   3427:  *
                   3428:  * Arguments out:
                   3429:  *
                   3430:  * d:       802.11 Duration field for RTS,
                   3431:  *          802.11 Duration field for data frame,
                   3432:  *          PLCP Length for data frame,
                   3433:  *          residual octets at end of data slot
                   3434:  */
                   3435: int
                   3436: atw_compute_duration1(int len, int use_ack, uint32_t flags, int rate,
                   3437:     struct atw_duration *d)
                   3438: {
                   3439:        int pre, ctsrate;
                   3440:        int ack, bitlen, data_dur, remainder;
                   3441:
                   3442:        /* RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK
                   3443:         * DATA reserves medium for SIFS | ACK
                   3444:         *
                   3445:         * XXXMYC: no ACK on multicast/broadcast or control packets
                   3446:         */
                   3447:
                   3448:        bitlen = len * 8;
                   3449:
                   3450:        pre = IEEE80211_DUR_DS_SIFS;
                   3451:        if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
                   3452:                pre += IEEE80211_DUR_DS_SHORT_PREAMBLE +
                   3453:                    IEEE80211_DUR_DS_FAST_PLCPHDR;
                   3454:        else
                   3455:                pre += IEEE80211_DUR_DS_LONG_PREAMBLE +
                   3456:                    IEEE80211_DUR_DS_SLOW_PLCPHDR;
                   3457:
                   3458:        d->d_residue = 0;
                   3459:        data_dur = (bitlen * 2) / rate;
                   3460:        remainder = (bitlen * 2) % rate;
                   3461:        if (remainder != 0) {
                   3462:                d->d_residue = (rate - remainder) / 16;
                   3463:                data_dur++;
                   3464:        }
                   3465:
                   3466:        switch (rate) {
                   3467:        case 2:         /* 1 Mb/s */
                   3468:        case 4:         /* 2 Mb/s */
                   3469:                /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */
                   3470:                ctsrate = 2;
                   3471:                break;
                   3472:        case 11:        /* 5.5 Mb/s */
                   3473:        case 22:        /* 11  Mb/s */
                   3474:        case 44:        /* 22  Mb/s */
                   3475:                /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */
                   3476:                ctsrate = 4;
                   3477:                break;
                   3478:        default:
                   3479:                /* TBD */
                   3480:                return -1;
                   3481:        }
                   3482:
                   3483:        d->d_plcp_len = data_dur;
                   3484:
                   3485:        ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
                   3486:
                   3487:        d->d_rts_dur =
                   3488:            pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
                   3489:            pre + data_dur +
                   3490:            ack;
                   3491:
                   3492:        d->d_data_dur = ack;
                   3493:
                   3494:        return 0;
                   3495: }
                   3496:
                   3497: /*
                   3498:  * Arguments in:
                   3499:  *
                   3500:  * wh:      802.11 header
                   3501:  *
                   3502:  * len: packet length
                   3503:  *
                   3504:  * rate:    MSDU speed, units 500kb/s
                   3505:  *
                   3506:  * fraglen: fragment length, set to maximum (or higher) for no
                   3507:  *          fragmentation
                   3508:  *
                   3509:  * flags:   IEEE80211_F_WEPON (hardware adds WEP),
                   3510:  *          IEEE80211_F_SHPREAMBLE (use short preamble),
                   3511:  *          IEEE80211_F_SHSLOT (use short slot length)
                   3512:  *
                   3513:  * Arguments out:
                   3514:  *
                   3515:  * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
                   3516:  *     of first/only fragment
                   3517:  *
                   3518:  * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
                   3519:  *     of first/only fragment
                   3520:  */
                   3521: int
                   3522: atw_compute_duration(struct ieee80211_frame *wh, int len, uint32_t flags,
                   3523:     int fraglen, int rate, struct atw_duration *d0, struct atw_duration *dn,
                   3524:     int *npktp, int debug)
                   3525: {
                   3526:        int ack, rc;
                   3527:        int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
                   3528:
                   3529:        if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
                   3530:                hdrlen = sizeof(struct ieee80211_frame_addr4);
                   3531:        else
                   3532:                hdrlen = sizeof(struct ieee80211_frame);
                   3533:
                   3534:        paylen = len - hdrlen;
                   3535:
                   3536:        if ((flags & IEEE80211_F_WEPON) != 0)
                   3537:                overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
                   3538:        else
                   3539:                overlen = IEEE80211_CRC_LEN;
                   3540:
                   3541:        npkt = paylen / fraglen;
                   3542:        lastlen0 = paylen % fraglen;
                   3543:
                   3544:        if (npkt == 0)                  /* no fragments */
                   3545:                lastlen = paylen + overlen;
                   3546:        else if (lastlen0 != 0) {       /* a short "tail" fragment */
                   3547:                lastlen = lastlen0 + overlen;
                   3548:                npkt++;
                   3549:        } else                          /* full-length "tail" fragment */
                   3550:                lastlen = fraglen + overlen;
                   3551:
                   3552:        if (npktp != NULL)
                   3553:                *npktp = npkt;
                   3554:
                   3555:        if (npkt > 1)
                   3556:                firstlen = fraglen + overlen;
                   3557:        else
                   3558:                firstlen = paylen + overlen;
                   3559:
                   3560:        if (debug) {
                   3561:                printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
                   3562:                    "fraglen %d overlen %d len %d rate %d flags %08x\n",
                   3563:                    __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
                   3564:                    overlen, len, rate, flags);
                   3565:        }
                   3566:
                   3567:        ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
                   3568:            (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL;
                   3569:
                   3570:        rc = atw_compute_duration1(firstlen + hdrlen, ack, flags, rate, d0);
                   3571:        if (rc == -1)
                   3572:                return rc;
                   3573:
                   3574:        if (npkt <= 1) {
                   3575:                *dn = *d0;
                   3576:                return 0;
                   3577:        }
                   3578:        return atw_compute_duration1(lastlen + hdrlen, ack, flags, rate, dn);
                   3579: }
                   3580:
                   3581: #ifdef ATW_DEBUG
                   3582: void
                   3583: atw_dump_pkt(struct ifnet *ifp, struct mbuf *m0)
                   3584: {
                   3585:        struct atw_softc *sc = ifp->if_softc;
                   3586:        struct mbuf *m;
                   3587:        int i, noctets = 0;
                   3588:
                   3589:        printf("%s: %d-byte packet\n", sc->sc_dev.dv_xname,
                   3590:            m0->m_pkthdr.len);
                   3591:
                   3592:        for (m = m0; m; m = m->m_next) {
                   3593:                if (m->m_len == 0)
                   3594:                        continue;
                   3595:                for (i = 0; i < m->m_len; i++) {
                   3596:                        printf(" %02x", ((u_int8_t*)m->m_data)[i]);
                   3597:                        if (++noctets % 24 == 0)
                   3598:                                printf("\n");
                   3599:                }
                   3600:        }
                   3601:        printf("%s%s: %d bytes emitted\n",
                   3602:            (noctets % 24 != 0) ? "\n" : "", sc->sc_dev.dv_xname, noctets);
                   3603: }
                   3604: #endif /* ATW_DEBUG */
                   3605:
                   3606: /*
                   3607:  * atw_start:          [ifnet interface function]
                   3608:  *
                   3609:  *     Start packet transmission on the interface.
                   3610:  */
                   3611: void
                   3612: atw_start(struct ifnet *ifp)
                   3613: {
                   3614:        struct atw_softc *sc = ifp->if_softc;
                   3615:        struct ieee80211com *ic = &sc->sc_ic;
                   3616:        struct ieee80211_node *ni;
                   3617:        struct ieee80211_frame *wh;
                   3618:        struct atw_frame *hh;
                   3619:        struct mbuf *m0, *m;
                   3620:        struct atw_txsoft *txs, *last_txs;
                   3621:        struct atw_txdesc *txd;
                   3622:        int do_encrypt, npkt, rate;
                   3623:        bus_dmamap_t dmamap;
                   3624:        int ctl, error, firsttx, nexttx, lasttx = -1, first, ofree, seg;
                   3625:
                   3626:        DPRINTF2(sc, ("%s: atw_start: sc_flags 0x%08x, if_flags 0x%08x\n",
                   3627:            sc->sc_dev.dv_xname, sc->sc_flags, ifp->if_flags));
                   3628:
                   3629:        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
                   3630:                return;
                   3631:
                   3632:        /*
                   3633:         * Remember the previous number of free descriptors and
                   3634:         * the first descriptor we'll use.
                   3635:         */
                   3636:        ofree = sc->sc_txfree;
                   3637:        firsttx = sc->sc_txnext;
                   3638:
                   3639:        DPRINTF2(sc, ("%s: atw_start: txfree %d, txnext %d\n",
                   3640:            sc->sc_dev.dv_xname, ofree, firsttx));
                   3641:
                   3642:        /*
                   3643:         * Loop through the send queue, setting up transmit descriptors
                   3644:         * until we drain the queue, or use up all available transmit
                   3645:         * descriptors.
                   3646:         */
                   3647:        while ((txs = SIMPLEQ_FIRST(&sc->sc_txfreeq)) != NULL &&
                   3648:               sc->sc_txfree != 0) {
                   3649:
                   3650:                /*
                   3651:                 * Grab a packet off the management queue, if it
                   3652:                 * is not empty. Otherwise, from the data queue.
                   3653:                 */
                   3654:                IF_DEQUEUE(&ic->ic_mgtq, m0);
                   3655:                if (m0 != NULL) {
                   3656:                        ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
                   3657:                        m0->m_pkthdr.rcvif = NULL;
                   3658:                } else {
                   3659:                        /* send no data packets until we are associated */
                   3660:                        if (ic->ic_state != IEEE80211_S_RUN)
                   3661:                                break;
                   3662:                        IFQ_DEQUEUE(&ifp->if_snd, m0);
                   3663:                        if (m0 == NULL)
                   3664:                                break;
                   3665: #if NBPFILTER > 0
                   3666:                        if (ifp->if_bpf != NULL)
                   3667:                                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   3668: #endif /* NBPFILTER > 0 */
                   3669:                        if ((m0 = ieee80211_encap(ifp, m0, &ni)) == NULL) {
                   3670:                                ifp->if_oerrors++;
                   3671:                                break;
                   3672:                        }
                   3673:
                   3674:                        if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
                   3675:                                if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL) {
                   3676:                                        ifp->if_oerrors++;
                   3677:                                        break;
                   3678:                                }
                   3679:                        }
                   3680:                }
                   3681:
                   3682:                wh = mtod(m0, struct ieee80211_frame *);
                   3683:
                   3684:                /* XXX do real rate control */
                   3685:                if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
                   3686:                    IEEE80211_FC0_TYPE_MGT)
                   3687:                        rate = 2;
                   3688:                else
                   3689:                        rate = MAX(2, ieee80211_get_rate(ic));
                   3690:
                   3691:                if (atw_compute_duration(wh, m0->m_pkthdr.len,
                   3692:                    ic->ic_flags & ~IEEE80211_F_WEPON, ic->ic_fragthreshold,
                   3693:                    rate, &txs->txs_d0, &txs->txs_dn, &npkt,
                   3694:                    (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
                   3695:                    (IFF_DEBUG|IFF_LINK2)) == -1) {
                   3696:                        DPRINTF2(sc, ("%s: fail compute duration\n", __func__));
                   3697:                        m_freem(m0);
                   3698:                        break;
                   3699:                }
                   3700:
                   3701:                /*
                   3702:                 * XXX Misleading if fragmentation is enabled.  Better
                   3703:                 * to fragment in software?
                   3704:                 */
                   3705:                *(uint16_t *)wh->i_dur = htole16(txs->txs_d0.d_rts_dur);
                   3706:
                   3707: #if NBPFILTER > 0
                   3708:                /*
                   3709:                 * Pass the packet to any BPF listeners.
                   3710:                 */
                   3711:                if (ic->ic_rawbpf != NULL)
                   3712:                        bpf_mtap(ic->ic_rawbpf, m0, BPF_DIRECTION_OUT);
                   3713:
                   3714:                if (sc->sc_radiobpf != NULL) {
                   3715:                        struct mbuf mb;
                   3716:                        struct atw_tx_radiotap_header *tap = &sc->sc_txtap;
                   3717:
                   3718:                        tap->at_rate = rate;
                   3719:                        tap->at_chan_freq = ic->ic_bss->ni_chan->ic_freq;
                   3720:                        tap->at_chan_flags = ic->ic_bss->ni_chan->ic_flags;
                   3721:
                   3722:                        /* TBD tap->at_flags */
                   3723:
                   3724:                        mb.m_data = (caddr_t)tap;
                   3725:                        mb.m_len = tap->at_ihdr.it_len;
                   3726:                        mb.m_next = m0;
                   3727:                        mb.m_nextpkt = NULL;
                   3728:                        mb.m_type = 0;
                   3729:                        mb.m_flags = 0;
                   3730:                        bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
                   3731:                }
                   3732: #endif /* NBPFILTER > 0 */
                   3733:
                   3734:                M_PREPEND(m0, offsetof(struct atw_frame, atw_ihdr), M_DONTWAIT);
                   3735:
                   3736:                if (ni != NULL)
                   3737:                        ieee80211_release_node(ic, ni);
                   3738:
                   3739:                if (m0 == NULL) {
                   3740:                        ifp->if_oerrors++;
                   3741:                        break;
                   3742:                }
                   3743:
                   3744:                /* just to make sure. */
                   3745:                m0 = m_pullup(m0, sizeof(struct atw_frame));
                   3746:
                   3747:                if (m0 == NULL) {
                   3748:                        ifp->if_oerrors++;
                   3749:                        break;
                   3750:                }
                   3751:
                   3752:                hh = mtod(m0, struct atw_frame *);
                   3753:                wh = &hh->atw_ihdr;
                   3754:
                   3755:                do_encrypt = ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0) ? 1 : 0;
                   3756:
                   3757:                /* Copy everything we need from the 802.11 header:
                   3758:                 * Frame Control; address 1, address 3, or addresses
                   3759:                 * 3 and 4. NIC fills in BSSID, SA.
                   3760:                 */
                   3761:                if (wh->i_fc[1] & IEEE80211_FC1_DIR_TODS) {
                   3762:                        if (wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS)
                   3763:                                panic("%s: illegal WDS frame",
                   3764:                                    sc->sc_dev.dv_xname);
                   3765:                        memcpy(hh->atw_dst, wh->i_addr3, IEEE80211_ADDR_LEN);
                   3766:                } else
                   3767:                        memcpy(hh->atw_dst, wh->i_addr1, IEEE80211_ADDR_LEN);
                   3768:
                   3769:                *(u_int16_t*)hh->atw_fc = *(u_int16_t*)wh->i_fc;
                   3770:
                   3771:                /* initialize remaining Tx parameters */
                   3772:                memset(&hh->u, 0, sizeof(hh->u));
                   3773:
                   3774:                hh->atw_rate = rate * 5;
                   3775:                /* XXX this could be incorrect if M_FCS. _encap should
                   3776:                 * probably strip FCS just in case it sticks around in
                   3777:                 * bridged packets.
                   3778:                 */
                   3779:                hh->atw_service = IEEE80211_PLCP_SERVICE; /* XXX guess */
                   3780:                hh->atw_paylen = htole16(m0->m_pkthdr.len -
                   3781:                    sizeof(struct atw_frame));
                   3782:
                   3783:                hh->atw_fragthr = htole16(ATW_FRAGTHR_FRAGTHR_MASK);
                   3784:                hh->atw_rtylmt = 3;
                   3785:                hh->atw_hdrctl = htole16(ATW_HDRCTL_UNKNOWN1);
                   3786: #if 0
                   3787:                if (do_encrypt) {
                   3788:                        hh->atw_hdrctl |= htole16(ATW_HDRCTL_WEP);
                   3789:                        hh->atw_keyid = ic->ic_wep_txkey;
                   3790:                }
                   3791: #endif
                   3792:
                   3793:                hh->atw_head_plcplen = htole16(txs->txs_d0.d_plcp_len);
                   3794:                hh->atw_tail_plcplen = htole16(txs->txs_dn.d_plcp_len);
                   3795:                if (txs->txs_d0.d_residue)
                   3796:                        hh->atw_head_plcplen |= htole16(0x8000);
                   3797:                if (txs->txs_dn.d_residue)
                   3798:                        hh->atw_tail_plcplen |= htole16(0x8000);
                   3799:                hh->atw_head_dur = htole16(txs->txs_d0.d_rts_dur);
                   3800:                hh->atw_tail_dur = htole16(txs->txs_dn.d_rts_dur);
                   3801:
                   3802:                /* never fragment multicast frames */
                   3803:                if (IEEE80211_IS_MULTICAST(hh->atw_dst)) {
                   3804:                        hh->atw_fragthr = htole16(ATW_FRAGTHR_FRAGTHR_MASK);
                   3805:                } else if (sc->sc_flags & ATWF_RTSCTS) {
                   3806:                        hh->atw_hdrctl |= htole16(ATW_HDRCTL_RTSCTS);
                   3807:                }
                   3808:
                   3809: #ifdef ATW_DEBUG
                   3810:                hh->atw_fragnum = 0;
                   3811:
                   3812:                if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
                   3813:                        printf("%s: dst = %s, rate = 0x%02x, "
                   3814:                            "service = 0x%02x, paylen = 0x%04x\n",
                   3815:                            sc->sc_dev.dv_xname, ether_sprintf(hh->atw_dst),
                   3816:                            hh->atw_rate, hh->atw_service, hh->atw_paylen);
                   3817:
                   3818:                        printf("%s: fc[0] = 0x%02x, fc[1] = 0x%02x, "
                   3819:                            "dur1 = 0x%04x, dur2 = 0x%04x, "
                   3820:                            "dur3 = 0x%04x, rts_dur = 0x%04x\n",
                   3821:                            sc->sc_dev.dv_xname, hh->atw_fc[0], hh->atw_fc[1],
                   3822:                            hh->atw_tail_plcplen, hh->atw_head_plcplen,
                   3823:                            hh->atw_tail_dur, hh->atw_head_dur);
                   3824:
                   3825:                        printf("%s: hdrctl = 0x%04x, fragthr = 0x%04x, "
                   3826:                            "fragnum = 0x%02x, rtylmt = 0x%04x\n",
                   3827:                            sc->sc_dev.dv_xname, hh->atw_hdrctl,
                   3828:                            hh->atw_fragthr, hh->atw_fragnum, hh->atw_rtylmt);
                   3829:
                   3830:                        printf("%s: keyid = %d\n",
                   3831:                            sc->sc_dev.dv_xname, hh->atw_keyid);
                   3832:
                   3833:                        atw_dump_pkt(ifp, m0);
                   3834:                }
                   3835: #endif /* ATW_DEBUG */
                   3836:
                   3837:                dmamap = txs->txs_dmamap;
                   3838:
                   3839:                /*
                   3840:                 * Load the DMA map.  Copy and try (once) again if the packet
                   3841:                 * didn't fit in the alloted number of segments.
                   3842:                 */
                   3843:                for (first = 1;
                   3844:                     (error = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0,
                   3845:                                  BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 && first;
                   3846:                     first = 0) {
                   3847:                        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   3848:                        if (m == NULL) {
                   3849:                                printf("%s: unable to allocate Tx mbuf\n",
                   3850:                                    sc->sc_dev.dv_xname);
                   3851:                                break;
                   3852:                        }
                   3853:                        if (m0->m_pkthdr.len > MHLEN) {
                   3854:                                MCLGET(m, M_DONTWAIT);
                   3855:                                if ((m->m_flags & M_EXT) == 0) {
                   3856:                                        printf("%s: unable to allocate Tx "
                   3857:                                            "cluster\n", sc->sc_dev.dv_xname);
                   3858:                                        m_freem(m);
                   3859:                                        break;
                   3860:                                }
                   3861:                        }
                   3862:                        m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
                   3863:                        m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
                   3864:                        m_freem(m0);
                   3865:                        m0 = m;
                   3866:                        m = NULL;
                   3867:                }
                   3868:                if (error != 0) {
                   3869:                        printf("%s: unable to load Tx buffer, "
                   3870:                            "error = %d\n", sc->sc_dev.dv_xname, error);
                   3871:                        m_freem(m0);
                   3872:                        break;
                   3873:                }
                   3874:
                   3875:                /*
                   3876:                 * Ensure we have enough descriptors free to describe
                   3877:                 * the packet.
                   3878:                 */
                   3879:                if (dmamap->dm_nsegs > sc->sc_txfree) {
                   3880:                        /*
                   3881:                         * Not enough free descriptors to transmit
                   3882:                         * this packet.  Unload the DMA map and
                   3883:                         * drop the packet.  Notify the upper layer
                   3884:                         * that there are no more slots left.
                   3885:                         *
                   3886:                         * XXX We could allocate an mbuf and copy, but
                   3887:                         * XXX it is worth it?
                   3888:                         */
                   3889:                        ifp->if_flags |= IFF_OACTIVE;
                   3890:                        bus_dmamap_unload(sc->sc_dmat, dmamap);
                   3891:                        m_freem(m0);
                   3892:                        break;
                   3893:                }
                   3894:
                   3895:                /*
                   3896:                 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET.
                   3897:                 */
                   3898:
                   3899:                /* Sync the DMA map. */
                   3900:                bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize,
                   3901:                    BUS_DMASYNC_PREWRITE);
                   3902:
                   3903:                /* XXX arbitrary retry limit; 8 because I have seen it in
                   3904:                 * use already and maybe 0 means "no tries" !
                   3905:                 */
                   3906:                ctl = htole32(LSHIFT(8, ATW_TXCTL_TL_MASK));
                   3907:
                   3908:                DPRINTF2(sc, ("%s: TXDR <- max(10, %d)\n",
                   3909:                    sc->sc_dev.dv_xname, rate * 5));
                   3910:                ctl |= htole32(LSHIFT(MAX(10, rate * 5), ATW_TXCTL_TXDR_MASK));
                   3911:
                   3912:                /*
                   3913:                 * Initialize the transmit descriptors.
                   3914:                 */
                   3915:                for (nexttx = sc->sc_txnext, seg = 0;
                   3916:                     seg < dmamap->dm_nsegs;
                   3917:                     seg++, nexttx = ATW_NEXTTX(nexttx)) {
                   3918:                        /*
                   3919:                         * If this is the first descriptor we're
                   3920:                         * enqueueing, don't set the OWN bit just
                   3921:                         * yet.  That could cause a race condition.
                   3922:                         * We'll do it below.
                   3923:                         */
                   3924:                        txd = &sc->sc_txdescs[nexttx];
                   3925:                        txd->at_ctl = ctl |
                   3926:                            ((nexttx == firsttx) ? 0 : htole32(ATW_TXCTL_OWN));
                   3927:
                   3928:                        txd->at_buf1 = htole32(dmamap->dm_segs[seg].ds_addr);
                   3929:                        txd->at_flags =
                   3930:                            htole32(LSHIFT(dmamap->dm_segs[seg].ds_len,
                   3931:                                           ATW_TXFLAG_TBS1_MASK)) |
                   3932:                            ((nexttx == (ATW_NTXDESC - 1))
                   3933:                                ? htole32(ATW_TXFLAG_TER) : 0);
                   3934:                        lasttx = nexttx;
                   3935:                }
                   3936:
                   3937:                if (lasttx == -1)
                   3938:                        panic("%s: bad lastx", ifp->if_xname);
                   3939:                /* Set `first segment' and `last segment' appropriately. */
                   3940:                sc->sc_txdescs[sc->sc_txnext].at_flags |=
                   3941:                    htole32(ATW_TXFLAG_FS);
                   3942:                sc->sc_txdescs[lasttx].at_flags |= htole32(ATW_TXFLAG_LS);
                   3943:
                   3944: #ifdef ATW_DEBUG
                   3945:                if ((ifp->if_flags & IFF_DEBUG) != 0 && atw_debug > 2) {
                   3946:                        printf("     txsoft %p transmit chain:\n", txs);
                   3947:                        for (seg = sc->sc_txnext;; seg = ATW_NEXTTX(seg)) {
                   3948:                                printf("     descriptor %d:\n", seg);
                   3949:                                printf("       at_ctl:   0x%08x\n",
                   3950:                                    letoh32(sc->sc_txdescs[seg].at_ctl));
                   3951:                                printf("       at_flags:      0x%08x\n",
                   3952:                                    letoh32(sc->sc_txdescs[seg].at_flags));
                   3953:                                printf("       at_buf1: 0x%08x\n",
                   3954:                                    letoh32(sc->sc_txdescs[seg].at_buf1));
                   3955:                                printf("       at_buf2: 0x%08x\n",
                   3956:                                    letoh32(sc->sc_txdescs[seg].at_buf2));
                   3957:                                if (seg == lasttx)
                   3958:                                        break;
                   3959:                        }
                   3960:                }
                   3961: #endif
                   3962:
                   3963:                /* Sync the descriptors we're using. */
                   3964:                ATW_CDTXSYNC(sc, sc->sc_txnext, dmamap->dm_nsegs,
                   3965:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   3966:
                   3967:                /*
                   3968:                 * Store a pointer to the packet so we can free it later,
                   3969:                 * and remember what txdirty will be once the packet is
                   3970:                 * done.
                   3971:                 */
                   3972:                txs->txs_mbuf = m0;
                   3973:                txs->txs_firstdesc = sc->sc_txnext;
                   3974:                txs->txs_lastdesc = lasttx;
                   3975:                txs->txs_ndescs = dmamap->dm_nsegs;
                   3976:
                   3977:                /* Advance the tx pointer. */
                   3978:                sc->sc_txfree -= dmamap->dm_nsegs;
                   3979:                sc->sc_txnext = nexttx;
                   3980:
                   3981:                SIMPLEQ_REMOVE_HEAD(&sc->sc_txfreeq, txs_q);
                   3982:                SIMPLEQ_INSERT_TAIL(&sc->sc_txdirtyq, txs, txs_q);
                   3983:
                   3984:                last_txs = txs;
                   3985:        }
                   3986:
                   3987:        if (txs == NULL || sc->sc_txfree == 0) {
                   3988:                /* No more slots left; notify upper layer. */
                   3989:                ifp->if_flags |= IFF_OACTIVE;
                   3990:        }
                   3991:
                   3992:        if (sc->sc_txfree != ofree) {
                   3993:                DPRINTF2(sc, ("%s: packets enqueued, IC on %d, OWN on %d\n",
                   3994:                    sc->sc_dev.dv_xname, lasttx, firsttx));
                   3995:                /*
                   3996:                 * Cause a transmit interrupt to happen on the
                   3997:                 * last packet we enqueued.
                   3998:                 */
                   3999:                sc->sc_txdescs[lasttx].at_flags |= htole32(ATW_TXFLAG_IC);
                   4000:                ATW_CDTXSYNC(sc, lasttx, 1,
                   4001:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   4002:
                   4003:                /*
                   4004:                 * The entire packet chain is set up.  Give the
                   4005:                 * first descriptor to the chip now.
                   4006:                 */
                   4007:                sc->sc_txdescs[firsttx].at_ctl |= htole32(ATW_TXCTL_OWN);
                   4008:                ATW_CDTXSYNC(sc, firsttx, 1,
                   4009:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   4010:
                   4011:                /* Wake up the transmitter. */
                   4012:                ATW_WRITE(sc, ATW_TDR, 0x1);
                   4013:
                   4014:                /* Set a watchdog timer in case the chip flakes out. */
                   4015:                sc->sc_tx_timer = 5;
                   4016:                ifp->if_timer = 1;
                   4017:        }
                   4018: }
                   4019:
                   4020: /*
                   4021:  * atw_power:
                   4022:  *
                   4023:  *     Power management (suspend/resume) hook.
                   4024:  */
                   4025: void
                   4026: atw_power(int why, void *arg)
                   4027: {
                   4028:        struct atw_softc *sc = arg;
                   4029:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   4030:        int s;
                   4031:
                   4032:        DPRINTF(sc, ("%s: atw_power(%d,)\n", sc->sc_dev.dv_xname, why));
                   4033:
                   4034:        s = splnet();
                   4035:        switch (why) {
                   4036:        case PWR_STANDBY:
                   4037:                /* XXX do nothing. */
                   4038:                break;
                   4039:        case PWR_SUSPEND:
                   4040:                atw_stop(ifp, 1);
                   4041:                if (sc->sc_power != NULL)
                   4042:                        (*sc->sc_power)(sc, why);
                   4043:                break;
                   4044:        case PWR_RESUME:
                   4045:                if (ifp->if_flags & IFF_UP) {
                   4046:                        if (sc->sc_power != NULL)
                   4047:                                (*sc->sc_power)(sc, why);
                   4048:                        atw_init(ifp);
                   4049:                }
                   4050:                break;
                   4051: #if !defined(__OpenBSD__)
                   4052:        case PWR_SOFTSUSPEND:
                   4053:        case PWR_SOFTSTANDBY:
                   4054:        case PWR_SOFTRESUME:
                   4055:                break;
                   4056: #endif
                   4057:        }
                   4058:        splx(s);
                   4059: }
                   4060:
                   4061: /*
                   4062:  * atw_ioctl:          [ifnet interface function]
                   4063:  *
                   4064:  *     Handle control requests from the operator.
                   4065:  */
                   4066: int
                   4067: atw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                   4068: {
                   4069:        struct atw_softc *sc = ifp->if_softc;
                   4070:        struct ieee80211com *ic = &sc->sc_ic;
                   4071:        struct ifreq *ifr = (struct ifreq *)data;
                   4072:        struct ifaddr *ifa = (struct ifaddr *)data;
                   4073:        int s, error = 0;
                   4074:
                   4075:        /* XXX monkey see, monkey do. comes from wi_ioctl. */
                   4076:        if ((sc->sc_dev.dv_flags & DVF_ACTIVE) == 0)
                   4077:                return ENXIO;
                   4078:
                   4079:        s = splnet();
                   4080:
                   4081:        switch (cmd) {
                   4082:         case SIOCSIFMTU:
                   4083:                 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
                   4084:                         error = EINVAL;
                   4085:                 } else if (ifp->if_mtu != ifr->ifr_mtu) {
                   4086:                         ifp->if_mtu = ifr->ifr_mtu;
                   4087:                 }
                   4088:                 break;
                   4089:         case SIOCSIFADDR:
                   4090:                 ifp->if_flags |= IFF_UP;
                   4091: #ifdef INET
                   4092:                 if (ifa->ifa_addr->sa_family == AF_INET) {
                   4093:                         arp_ifinit(&ic->ic_ac, ifa);
                   4094:                 }
                   4095: #endif  /* INET */
                   4096:                /* FALLTHROUGH */
                   4097:        case SIOCSIFFLAGS:
                   4098:                if (ifp->if_flags & IFF_UP) {
                   4099:                        if (ATW_IS_ENABLED(sc)) {
                   4100:                                /*
                   4101:                                 * To avoid rescanning another access point,
                   4102:                                 * do not call atw_init() here.  Instead,
                   4103:                                 * only reflect media settings.
                   4104:                                 */
                   4105:                                atw_filter_setup(sc);
                   4106:                        } else
                   4107:                                error = atw_init(ifp);
                   4108:                } else if (ATW_IS_ENABLED(sc))
                   4109:                        atw_stop(ifp, 1);
                   4110:                break;
                   4111:        case SIOCADDMULTI:
                   4112:        case SIOCDELMULTI:
                   4113:                error = (cmd == SIOCADDMULTI) ?
                   4114: #if defined(__OpenBSD__)
                   4115:                    ether_addmulti(ifr, &sc->sc_ic.ic_ac) :
                   4116:                    ether_delmulti(ifr, &sc->sc_ic.ic_ac);
                   4117: #else
                   4118:                    ether_addmulti(ifr, &sc->sc_ic.ic_ec) :
                   4119:                    ether_delmulti(ifr, &sc->sc_ic.ic_ec);
                   4120: #endif
                   4121:
                   4122:                if (error == ENETRESET) {
                   4123:                        if (ifp->if_flags & IFF_RUNNING)
                   4124:                                atw_filter_setup(sc); /* do not rescan */
                   4125:                        error = 0;
                   4126:                }
                   4127:                break;
                   4128:        default:
                   4129:                error = ieee80211_ioctl(ifp, cmd, data);
                   4130:                if (error == ENETRESET) {
                   4131:                        if (ATW_IS_ENABLED(sc))
                   4132:                                error = atw_init(ifp);
                   4133:                        else
                   4134:                                error = 0;
                   4135:                }
                   4136:                break;
                   4137:        }
                   4138:
                   4139:        /* Try to get more packets going. */
                   4140:        if (ATW_IS_ENABLED(sc))
                   4141:                atw_start(ifp);
                   4142:
                   4143:        splx(s);
                   4144:        return (error);
                   4145: }
                   4146:
                   4147: int
                   4148: atw_media_change(struct ifnet *ifp)
                   4149: {
                   4150:        int error;
                   4151:
                   4152:        error = ieee80211_media_change(ifp);
                   4153:        if (error == ENETRESET) {
                   4154:                if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
                   4155:                    (IFF_RUNNING|IFF_UP))
                   4156:                        atw_init(ifp);          /* XXX lose error */
                   4157:                error = 0;
                   4158:        }
                   4159:        return error;
                   4160: }
                   4161:
                   4162: void
                   4163: atw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
                   4164: {
                   4165:        struct atw_softc *sc = ifp->if_softc;
                   4166:
                   4167:        if (ATW_IS_ENABLED(sc) == 0) {
                   4168:                imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
                   4169:                imr->ifm_status = 0;
                   4170:                return;
                   4171:        }
                   4172:        ieee80211_media_status(ifp, imr);
                   4173: }

CVSweb