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

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

1.1       nbrk        1: /*     $OpenBSD: rtw.c,v 1.61 2007/06/07 20:20:15 damien Exp $ */
                      2: /*     $NetBSD: rtw.c,v 1.29 2004/12/27 19:49:16 dyoung Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2004, 2005 David Young.  All rights reserved.
                      6:  *
                      7:  * Programmed for NetBSD by David Young.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. The name of David Young may not be used to endorse or promote
                     18:  *    products derived from this software without specific prior
                     19:  *    written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
                     22:  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
                     23:  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
                     24:  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
                     25:  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     26:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
                     27:  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
                     29:  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
                     30:  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
                     32:  * OF SUCH DAMAGE.
                     33:  */
                     34: /*
                     35:  * Device driver for the Realtek RTL8180 802.11 MAC/BBP.
                     36:  */
                     37:
                     38: #include <sys/cdefs.h>
                     39: #include "bpfilter.h"
                     40:
                     41: #include <sys/param.h>
                     42: #include <sys/systm.h>
                     43: #include <sys/mbuf.h>
                     44: #include <sys/malloc.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/ioctl.h>
                     47: #include <sys/socket.h>
                     48: #include <sys/time.h>
                     49: #include <sys/types.h>
                     50:
                     51: #include <machine/endian.h>
                     52: #include <machine/bus.h>
                     53: #include <machine/intr.h>      /* splnet */
                     54:
                     55: #include <uvm/uvm_extern.h>
                     56:
                     57: #include <net/if.h>
                     58: #include <net/if_media.h>
                     59:
                     60: #if NBPFILTER > 0
                     61: #include <net/bpf.h>
                     62: #endif
                     63:
                     64: #ifdef INET
                     65: #include <netinet/in.h>
                     66: #include <netinet/if_ether.h>
                     67: #endif
                     68:
                     69: #include <net80211/ieee80211_var.h>
                     70: #include <net80211/ieee80211_radiotap.h>
                     71:
                     72: #include <dev/ic/rtwreg.h>
                     73: #include <dev/ic/rtwvar.h>
                     74: #include <dev/ic/max2820reg.h>
                     75: #include <dev/ic/sa2400reg.h>
                     76: #include <dev/ic/si4136reg.h>
                     77: #include <dev/ic/rtl8225reg.h>
                     78: #include <dev/ic/smc93cx6var.h>
                     79:
                     80: int rtw_rfprog_fallback = 0;
                     81: int rtw_do_chip_reset = 0;
                     82: int rtw_dwelltime = 200;       /* milliseconds per channel */
                     83: int rtw_macbangbits_timeout = 100;
                     84:
                     85: #ifdef RTW_DEBUG
                     86: int rtw_debug = 0;
                     87: int rtw_rxbufs_limit = RTW_RXQLEN;
                     88: #endif /* RTW_DEBUG */
                     89:
                     90: void    rtw_start(struct ifnet *);
                     91: void    rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *);
                     92: void    rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *);
                     93: void    rtw_txdesc_blk_init(struct rtw_txdesc_blk *);
                     94: void    rtw_txdescs_sync(struct rtw_txdesc_blk *, u_int, u_int, int);
                     95: u_int   rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *);
                     96: void    rtw_txring_fixup(struct rtw_softc *);
                     97: void    rtw_rxbufs_release(bus_dma_tag_t, struct rtw_rxsoft *);
                     98: void    rtw_rxdesc_init(struct rtw_rxdesc_blk *, struct rtw_rxsoft *, int, int);
                     99: void    rtw_rxring_fixup(struct rtw_softc *);
                    100: void    rtw_io_enable(struct rtw_regs *, u_int8_t, int);
                    101: void    rtw_intr_rx(struct rtw_softc *, u_int16_t);
                    102: void    rtw_intr_beacon(struct rtw_softc *, u_int16_t);
                    103: void    rtw_intr_atim(struct rtw_softc *);
                    104: void    rtw_transmit_config(struct rtw_softc *);
                    105: void    rtw_pktfilt_load(struct rtw_softc *);
                    106: void    rtw_start(struct ifnet *);
                    107: void    rtw_watchdog(struct ifnet *);
                    108: void    rtw_next_scan(void *);
                    109: void    rtw_recv_mgmt(struct ieee80211com *, struct mbuf *,
                    110:            struct ieee80211_node *, int, int, u_int32_t);
                    111: struct ieee80211_node *rtw_node_alloc(struct ieee80211com *);
                    112: void    rtw_node_free(struct ieee80211com *, struct ieee80211_node *);
                    113: void    rtw_media_status(struct ifnet *, struct ifmediareq *);
                    114: void    rtw_txsoft_blk_cleanup_all(struct rtw_softc *);
                    115: void    rtw_txdesc_blk_setup(struct rtw_txdesc_blk *, struct rtw_txdesc *,
                    116:            u_int, bus_addr_t, bus_addr_t);
                    117: void    rtw_txdesc_blk_setup_all(struct rtw_softc *);
                    118: void    rtw_intr_tx(struct rtw_softc *, u_int16_t);
                    119: void    rtw_intr_ioerror(struct rtw_softc *, u_int16_t);
                    120: void    rtw_intr_timeout(struct rtw_softc *);
                    121: void    rtw_stop(struct ifnet *, int);
                    122: void    rtw_maxim_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
                    123: void    rtw_philips_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
                    124: void    rtw_rtl_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
                    125: void    rtw_pwrstate0(struct rtw_softc *, enum rtw_pwrstate, int, int);
                    126: void    rtw_join_bss(struct rtw_softc *, u_int8_t *, u_int16_t);
                    127: void    rtw_set_access1(struct rtw_regs *, enum rtw_access);
                    128: int     rtw_srom_parse(struct rtw_softc *);
                    129: int     rtw_srom_read(struct rtw_regs *, u_int32_t, struct rtw_srom *,
                    130:            const char *);
                    131: void    rtw_set_rfprog(struct rtw_regs *, int, const char *);
                    132: u_int8_t rtw_chan2txpower(struct rtw_srom *, struct ieee80211com *,
                    133:            struct ieee80211_channel *);
                    134: int     rtw_txsoft_blk_init(struct rtw_txsoft_blk *);
                    135: int     rtw_rxsoft_init_all(bus_dma_tag_t, struct rtw_rxsoft *,
                    136:            int *, const char *);
                    137: void    rtw_txsoft_release(bus_dma_tag_t, struct ieee80211com *,
                    138:            struct rtw_txsoft *);
                    139: void    rtw_txsofts_release(bus_dma_tag_t, struct ieee80211com *,
                    140:            struct rtw_txsoft_blk *);
                    141: void    rtw_hwring_setup(struct rtw_softc *);
                    142: int     rtw_swring_setup(struct rtw_softc *);
                    143: void    rtw_txdescs_reset(struct rtw_softc *);
                    144: void    rtw_rfmd_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
                    145: int     rtw_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
                    146: int     rtw_tune(struct rtw_softc *);
                    147: void    rtw_set_nettype(struct rtw_softc *, enum ieee80211_opmode);
                    148: int     rtw_compute_duration1(int, int, uint32_t, int, struct rtw_duration *);
                    149: int     rtw_compute_duration(struct ieee80211_frame *, int, uint32_t, int,
                    150:            int, struct rtw_duration *, struct rtw_duration *, int *, int);
                    151: int     rtw_init(struct ifnet *);
                    152: int     rtw_ioctl(struct ifnet *, u_long, caddr_t);
                    153: int     rtw_seg_too_short(bus_dmamap_t);
                    154: struct mbuf *rtw_dmamap_load_txbuf(bus_dma_tag_t, bus_dmamap_t, struct mbuf *,
                    155:            u_int, short *, const char *);
                    156: int     rtw_newstate(struct ieee80211com *, enum ieee80211_state, int);
                    157: int     rtw_media_change(struct ifnet *);
                    158: int     rtw_txsoft_blk_setup_all(struct rtw_softc *);
                    159: int     rtw_rf_attach(struct rtw_softc *, int);
                    160: u_int8_t rtw_check_phydelay(struct rtw_regs *, u_int32_t);
                    161: int     rtw_chip_reset1(struct rtw_regs *, const char *);
                    162: int     rtw_chip_reset(struct rtw_regs *, const char *);
                    163: int     rtw_recall_eeprom(struct rtw_regs *, const char *);
                    164: int     rtw_reset(struct rtw_softc *);
                    165: void    rtw_reset_oactive(struct rtw_softc *);
                    166: int     rtw_txdesc_dmamaps_create(bus_dma_tag_t, struct rtw_txsoft *, u_int);
                    167: int     rtw_rxdesc_dmamaps_create(bus_dma_tag_t, struct rtw_rxsoft *, u_int);
                    168: void    rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t, struct rtw_rxsoft *, u_int);
                    169: void    rtw_txdesc_dmamaps_destroy(bus_dma_tag_t, struct rtw_txsoft *, u_int);
                    170: void    rtw_init_channels(enum rtw_locale, struct ieee80211_channel (*)[],
                    171:            const char*);
                    172: void    rtw_identify_country(struct rtw_regs *, enum rtw_locale *);
                    173: int     rtw_identify_sta(struct rtw_regs *, u_int8_t (*)[], const char *);
                    174: void    rtw_rxdescs_sync(struct rtw_rxdesc_blk *, int, int, int);
                    175: int     rtw_rxsoft_alloc(bus_dma_tag_t, struct rtw_rxsoft *);
                    176: void    rtw_collect_txpkt(struct rtw_softc *, struct rtw_txdesc_blk *,
                    177:            struct rtw_txsoft *, int);
                    178: void    rtw_collect_txring(struct rtw_softc *, struct rtw_txsoft_blk *,
                    179:            struct rtw_txdesc_blk *, int);
                    180: void    rtw_suspend_ticks(struct rtw_softc *);
                    181: void    rtw_resume_ticks(struct rtw_softc *);
                    182: void    rtw_enable_interrupts(struct rtw_softc *);
                    183: int     rtw_dequeue(struct ifnet *, struct rtw_txsoft_blk **,
                    184:            struct rtw_txdesc_blk **, struct mbuf **,
                    185:            struct ieee80211_node **);
                    186: void    rtw_establish_hooks(struct rtw_hooks *, const char *, void *);
                    187: void    rtw_disestablish_hooks(struct rtw_hooks *, const char *, void *);
                    188: int     rtw_txsoft_blk_setup(struct rtw_txsoft_blk *, u_int);
                    189: void    rtw_rxdesc_init_all(struct rtw_rxdesc_blk *, struct rtw_rxsoft *,
                    190:            int);
                    191: int     rtw_txring_choose(struct rtw_softc *, struct rtw_txsoft_blk **,
                    192:            struct rtw_txdesc_blk **, int);
                    193: u_int   rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *);
                    194: struct mbuf *rtw_80211_dequeue(struct rtw_softc *, struct ifqueue *, int,
                    195:            struct rtw_txsoft_blk **, struct rtw_txdesc_blk **,
                    196:            struct ieee80211_node **, short *);
                    197: uint64_t rtw_tsf_extend(struct rtw_regs *, u_int32_t);
                    198: void    rtw_ibss_merge(struct rtw_softc *, struct ieee80211_node *,
                    199:            u_int32_t);
                    200: void    rtw_idle(struct rtw_regs *);
                    201: void    rtw_led_attach(struct rtw_led_state *, void *);
                    202: void    rtw_led_init(struct rtw_regs *);
                    203: void    rtw_led_slowblink(void *);
                    204: void    rtw_led_fastblink(void *);
                    205: void    rtw_led_set(struct rtw_led_state *, struct rtw_regs *, u_int);
                    206: void    rtw_led_newstate(struct rtw_softc *, enum ieee80211_state);
                    207:
                    208: int     rtw_phy_init(struct rtw_softc *);
                    209: int     rtw_bbp_preinit(struct rtw_regs *, u_int, int, u_int);
                    210: int     rtw_bbp_init(struct rtw_regs *, struct rtw_bbpset *, int,
                    211:            int, u_int8_t, u_int);
                    212: void    rtw_verify_syna(u_int, u_int32_t);
                    213: int     rtw_sa2400_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
                    214: int     rtw_sa2400_txpower(struct rtw_softc *, u_int8_t);
                    215: int     rtw_sa2400_tune(struct rtw_softc *, u_int);
                    216: int     rtw_sa2400_vcocal_start(struct rtw_softc *, int);
                    217: int     rtw_sa2400_vco_calibration(struct rtw_softc *);
                    218: int     rtw_sa2400_filter_calibration(struct rtw_softc *);
                    219: int     rtw_sa2400_dc_calibration(struct rtw_softc *);
                    220: int     rtw_sa2400_calibrate(struct rtw_softc *, u_int);
                    221: int     rtw_sa2400_init(struct rtw_softc *, u_int, u_int8_t,
                    222:            enum rtw_pwrstate);
                    223: int     rtw_max2820_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
                    224: int     rtw_max2820_init(struct rtw_softc *, u_int, u_int8_t,
                    225:            enum rtw_pwrstate);
                    226: int     rtw_max2820_txpower(struct rtw_softc *, u_int8_t);
                    227: int     rtw_max2820_tune(struct rtw_softc *, u_int);
                    228: int     rtw_rtl8225_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
                    229: int     rtw_rtl8225_init(struct rtw_softc *, u_int, u_int8_t,
                    230:            enum rtw_pwrstate);
                    231: int     rtw_rtl8225_txpower(struct rtw_softc *, u_int8_t);
                    232: int     rtw_rtl8225_tune(struct rtw_softc *, u_int);
                    233: int     rtw_rtl8255_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
                    234: int     rtw_rtl8255_init(struct rtw_softc *, u_int, u_int8_t,
                    235:            enum rtw_pwrstate);
                    236: int     rtw_rtl8255_txpower(struct rtw_softc *, u_int8_t);
                    237: int     rtw_rtl8255_tune(struct rtw_softc *, u_int);
                    238: int     rtw_grf5101_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
                    239: int     rtw_grf5101_init(struct rtw_softc *, u_int, u_int8_t,
                    240:            enum rtw_pwrstate);
                    241: int     rtw_grf5101_txpower(struct rtw_softc *, u_int8_t);
                    242: int     rtw_grf5101_tune(struct rtw_softc *, u_int);
                    243: int     rtw_rf_hostwrite(struct rtw_softc *, u_int, u_int32_t);
                    244: int     rtw_rf_macwrite(struct rtw_softc *, u_int, u_int32_t);
                    245: int     rtw_bbp_write(struct rtw_regs *, u_int, u_int);
                    246: u_int32_t rtw_grf5101_host_crypt(u_int, u_int32_t);
                    247: u_int32_t rtw_maxim_swizzle(u_int, uint32_t);
                    248: u_int32_t rtw_grf5101_mac_crypt(u_int, u_int32_t);
                    249: void    rtw_rf_hostbangbits(struct rtw_regs *, u_int32_t, int, u_int);
                    250: void    rtw_rf_rtl8225_hostbangbits(struct rtw_regs *, u_int32_t, int, u_int);
                    251: int     rtw_rf_macbangbits(struct rtw_regs *, u_int32_t);
                    252:
                    253: u_int8_t rtw_read8(void *, u_int32_t);
                    254: u_int16_t rtw_read16(void *, u_int32_t);
                    255: u_int32_t rtw_read32(void *, u_int32_t);
                    256: void    rtw_write8(void *, u_int32_t, u_int8_t);
                    257: void    rtw_write16(void *, u_int32_t, u_int16_t);
                    258: void    rtw_write32(void *, u_int32_t, u_int32_t);
                    259: void    rtw_barrier(void *, u_int32_t, u_int32_t, int);
                    260:
                    261: #ifdef RTW_DEBUG
                    262: void    rtw_print_txdesc(struct rtw_softc *, const char *,
                    263:            struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
                    264: const char *rtw_access_string(enum rtw_access);
                    265: void    rtw_dump_rings(struct rtw_softc *);
                    266: void    rtw_print_txdesc(struct rtw_softc *, const char *,
                    267:            struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
                    268: #endif
                    269:
                    270: struct cfdriver rtw_cd = {
                    271:        NULL, "rtw", DV_IFNET
                    272: };
                    273:
                    274: void
                    275: rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
                    276: {
                    277:        struct rtw_regs *regs = &sc->sc_regs;
                    278:
                    279:        u_int32_t tcr;
                    280:        tcr = RTW_READ(regs, RTW_TCR);
                    281:        tcr &= ~RTW_TCR_LBK_MASK;
                    282:        if (enable)
                    283:                tcr |= RTW_TCR_LBK_CONT;
                    284:        else
                    285:                tcr |= RTW_TCR_LBK_NORMAL;
                    286:        RTW_WRITE(regs, RTW_TCR, tcr);
                    287:        RTW_SYNC(regs, RTW_TCR, RTW_TCR);
                    288:        rtw_set_access(regs, RTW_ACCESS_ANAPARM);
                    289:        rtw_txdac_enable(sc, !enable);
                    290:        rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */
                    291:        rtw_set_access(regs, RTW_ACCESS_NONE);
                    292: }
                    293:
                    294: #ifdef RTW_DEBUG
                    295: const char *
                    296: rtw_access_string(enum rtw_access access)
                    297: {
                    298:        switch (access) {
                    299:        case RTW_ACCESS_NONE:
                    300:                return "none";
                    301:        case RTW_ACCESS_CONFIG:
                    302:                return "config";
                    303:        case RTW_ACCESS_ANAPARM:
                    304:                return "anaparm";
                    305:        default:
                    306:                return "unknown";
                    307:        }
                    308: }
                    309: #endif
                    310:
                    311: void
                    312: rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess)
                    313: {
                    314:        KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM);
                    315:        KASSERT(regs->r_access >= RTW_ACCESS_NONE &&
                    316:            regs->r_access <= RTW_ACCESS_ANAPARM);
                    317:
                    318:        if (naccess == regs->r_access)
                    319:                return;
                    320:
                    321:        switch (naccess) {
                    322:        case RTW_ACCESS_NONE:
                    323:                switch (regs->r_access) {
                    324:                case RTW_ACCESS_ANAPARM:
                    325:                        rtw_anaparm_enable(regs, 0);
                    326:                        /*FALLTHROUGH*/
                    327:                case RTW_ACCESS_CONFIG:
                    328:                        rtw_config0123_enable(regs, 0);
                    329:                        /*FALLTHROUGH*/
                    330:                case RTW_ACCESS_NONE:
                    331:                        break;
                    332:                }
                    333:                break;
                    334:        case RTW_ACCESS_CONFIG:
                    335:                switch (regs->r_access) {
                    336:                case RTW_ACCESS_NONE:
                    337:                        rtw_config0123_enable(regs, 1);
                    338:                        /*FALLTHROUGH*/
                    339:                case RTW_ACCESS_CONFIG:
                    340:                        break;
                    341:                case RTW_ACCESS_ANAPARM:
                    342:                        rtw_anaparm_enable(regs, 0);
                    343:                        break;
                    344:                }
                    345:                break;
                    346:        case RTW_ACCESS_ANAPARM:
                    347:                switch (regs->r_access) {
                    348:                case RTW_ACCESS_NONE:
                    349:                        rtw_config0123_enable(regs, 1);
                    350:                        /*FALLTHROUGH*/
                    351:                case RTW_ACCESS_CONFIG:
                    352:                        rtw_anaparm_enable(regs, 1);
                    353:                        /*FALLTHROUGH*/
                    354:                case RTW_ACCESS_ANAPARM:
                    355:                        break;
                    356:                }
                    357:                break;
                    358:        }
                    359: }
                    360:
                    361: void
                    362: rtw_set_access(struct rtw_regs *regs, enum rtw_access access)
                    363: {
                    364:        rtw_set_access1(regs, access);
                    365:        RTW_DPRINTF(RTW_DEBUG_ACCESS,
                    366:            ("%s: access %s -> %s\n",__func__,
                    367:            rtw_access_string(regs->r_access),
                    368:            rtw_access_string(access)));
                    369:        regs->r_access = access;
                    370: }
                    371:
                    372: /*
                    373:  * Enable registers, switch register banks.
                    374:  */
                    375: void
                    376: rtw_config0123_enable(struct rtw_regs *regs, int enable)
                    377: {
                    378:        u_int8_t ecr;
                    379:        ecr = RTW_READ8(regs, RTW_9346CR);
                    380:        ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
                    381:        if (enable)
                    382:                ecr |= RTW_9346CR_EEM_CONFIG;
                    383:        else {
                    384:                RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
                    385:                ecr |= RTW_9346CR_EEM_NORMAL;
                    386:        }
                    387:        RTW_WRITE8(regs, RTW_9346CR, ecr);
                    388:        RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
                    389: }
                    390:
                    391: /* requires rtw_config0123_enable(, 1) */
                    392: void
                    393: rtw_anaparm_enable(struct rtw_regs *regs, int enable)
                    394: {
                    395:        u_int8_t cfg3;
                    396:
                    397:        cfg3 = RTW_READ8(regs, RTW_CONFIG3);
                    398:        cfg3 |= RTW_CONFIG3_CLKRUNEN;
                    399:        if (enable)
                    400:                cfg3 |= RTW_CONFIG3_PARMEN;
                    401:        else
                    402:                cfg3 &= ~RTW_CONFIG3_PARMEN;
                    403:        RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
                    404:        RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
                    405: }
                    406:
                    407: /* requires rtw_anaparm_enable(, 1) */
                    408: void
                    409: rtw_txdac_enable(struct rtw_softc *sc, int enable)
                    410: {
                    411:        u_int32_t anaparm;
                    412:        struct rtw_regs *regs = &sc->sc_regs;
                    413:
                    414:        anaparm = RTW_READ(regs, RTW_ANAPARM_0);
                    415:        if (enable)
                    416:                anaparm &= ~RTW_ANAPARM_TXDACOFF;
                    417:        else
                    418:                anaparm |= RTW_ANAPARM_TXDACOFF;
                    419:        RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
                    420:        RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
                    421: }
                    422:
                    423: int
                    424: rtw_chip_reset1(struct rtw_regs *regs, const char *dvname)
                    425: {
                    426:        u_int8_t cr;
                    427:        int i;
                    428:
                    429:        RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
                    430:
                    431:        RTW_WBR(regs, RTW_CR, RTW_CR);
                    432:
                    433:        for (i = 0; i < 1000; i++) {
                    434:                if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
                    435:                        RTW_DPRINTF(RTW_DEBUG_RESET,
                    436:                            ("%s: reset in %dus\n", dvname, i));
                    437:                        return 0;
                    438:                }
                    439:                RTW_RBR(regs, RTW_CR, RTW_CR);
                    440:                DELAY(10); /* 10us */
                    441:        }
                    442:
                    443:        printf("\n%s: reset failed\n", dvname);
                    444:        return ETIMEDOUT;
                    445: }
                    446:
                    447: int
                    448: rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
                    449: {
                    450:        uint32_t tcr;
                    451:
                    452:        /* from Linux driver */
                    453:        tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
                    454:            LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK);
                    455:
                    456:        RTW_WRITE(regs, RTW_TCR, tcr);
                    457:
                    458:        RTW_WBW(regs, RTW_CR, RTW_TCR);
                    459:
                    460:        return rtw_chip_reset1(regs, dvname);
                    461: }
                    462:
                    463: int
                    464: rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname)
                    465: {
                    466:        int i;
                    467:        u_int8_t ecr;
                    468:
                    469:        ecr = RTW_READ8(regs, RTW_9346CR);
                    470:        ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
                    471:        RTW_WRITE8(regs, RTW_9346CR, ecr);
                    472:
                    473:        RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
                    474:
                    475:        /* wait 10ms for completion */
                    476:        for (i = 0; i < 50; i++) {
                    477:                ecr = RTW_READ8(regs, RTW_9346CR);
                    478:                if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
                    479:                        RTW_DPRINTF(RTW_DEBUG_RESET,
                    480:                            ("%s: recall EEPROM in %dus\n", dvname, i * 200));
                    481:                        return (0);
                    482:                }
                    483:                RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
                    484:                DELAY(200);
                    485:        }
                    486:
                    487:        printf("\n%s: could not recall EEPROM in %dus\n", dvname, i * 200);
                    488:
                    489:        return (ETIMEDOUT);
                    490: }
                    491:
                    492: int
                    493: rtw_reset(struct rtw_softc *sc)
                    494: {
                    495:        int rc;
                    496:        uint8_t config1;
                    497:
                    498:        if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
                    499:                return rc;
                    500:
                    501:        if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
                    502:                ;
                    503:
                    504:        config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
                    505:        RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
                    506:        /* TBD turn off maximum power saving? */
                    507:
                    508:        return 0;
                    509: }
                    510:
                    511: int
                    512: rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
                    513:     u_int ndescs)
                    514: {
                    515:        int i, rc = 0;
                    516:        for (i = 0; i < ndescs; i++) {
                    517:                rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
                    518:                    0, 0, &descs[i].ts_dmamap);
                    519:                if (rc != 0)
                    520:                        break;
                    521:        }
                    522:        return rc;
                    523: }
                    524:
                    525: int
                    526: rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
                    527:     u_int ndescs)
                    528: {
                    529:        int i, rc = 0;
                    530:        for (i = 0; i < ndescs; i++) {
                    531:                rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
                    532:                    &descs[i].rs_dmamap);
                    533:                if (rc != 0)
                    534:                        break;
                    535:        }
                    536:        return rc;
                    537: }
                    538:
                    539: void
                    540: rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
                    541:     u_int ndescs)
                    542: {
                    543:        int i;
                    544:        for (i = 0; i < ndescs; i++) {
                    545:                if (descs[i].rs_dmamap != NULL)
                    546:                        bus_dmamap_destroy(dmat, descs[i].rs_dmamap);
                    547:        }
                    548: }
                    549:
                    550: void
                    551: rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
                    552:     u_int ndescs)
                    553: {
                    554:        int i;
                    555:        for (i = 0; i < ndescs; i++) {
                    556:                if (descs[i].ts_dmamap != NULL)
                    557:                        bus_dmamap_destroy(dmat, descs[i].ts_dmamap);
                    558:        }
                    559: }
                    560:
                    561: int
                    562: rtw_srom_parse(struct rtw_softc *sc)
                    563: {
                    564:        int i;
                    565:        struct rtw_srom *sr = &sc->sc_srom;
                    566:        u_int32_t *flags = &sc->sc_flags;
                    567:        u_int8_t *cs_threshold = &sc->sc_csthr;
                    568:        int *rfchipid = &sc->sc_rfchipid;
                    569:        u_int32_t *rcr = &sc->sc_rcr;
                    570:        enum rtw_locale *locale = &sc->sc_locale;
                    571:        u_int16_t version;
                    572:        u_int8_t mac[IEEE80211_ADDR_LEN];
                    573:
                    574:        *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
                    575:        *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
                    576:
                    577:        version = RTW_SR_GET16(sr, RTW_SR_VERSION);
                    578:        RTW_DPRINTF(RTW_DEBUG_ATTACH,
                    579:            ("%s: SROM %d.%d\n", sc->sc_dev.dv_xname, version >> 8,
                    580:            version & 0xff));
                    581:
                    582:        if (version <= 0x0101) {
                    583:                printf(" is not understood, limping along with defaults ");
                    584:                *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
                    585:                *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
                    586:                *rcr |= RTW_RCR_ENCS1;
                    587:                *rfchipid = RTW_RFCHIPID_PHILIPS;
                    588:                return 0;
                    589:        }
                    590:
                    591:        for (i = 0; i < IEEE80211_ADDR_LEN; i++)
                    592:                mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
                    593:
                    594:        RTW_DPRINTF(RTW_DEBUG_ATTACH,
                    595:            ("%s: EEPROM MAC %s\n", sc->sc_dev.dv_xname, ether_sprintf(mac)));
                    596:
                    597:        *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
                    598:
                    599:        if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW8180_CONFIG2_ANT) != 0)
                    600:                *flags |= RTW_F_ANTDIV;
                    601:
                    602:        /* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems
                    603:         * to be reversed.
                    604:         */
                    605:        if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
                    606:                *flags |= RTW_F_DIGPHY;
                    607:        if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
                    608:                *flags |= RTW_F_DFLANTB;
                    609:
                    610:        *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM),
                    611:            RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
                    612:
                    613:        *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
                    614:
                    615:        if (sc->sc_flags & RTW_F_RTL8185) {
                    616:                *locale = RTW_LOCALE_UNKNOWN;
                    617:                return (0);
                    618:        }
                    619:
                    620:        switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW8180_CONFIG0_GL_MASK) {
                    621:        case RTW8180_CONFIG0_GL_USA:
                    622:                *locale = RTW_LOCALE_USA;
                    623:                break;
                    624:        case RTW8180_CONFIG0_GL_EUROPE:
                    625:                *locale = RTW_LOCALE_EUROPE;
                    626:                break;
                    627:        case RTW8180_CONFIG0_GL_JAPAN:
                    628:        case RTW8180_CONFIG0_GL_JAPAN2:
                    629:                *locale = RTW_LOCALE_JAPAN;
                    630:                break;
                    631:        default:
                    632:                *locale = RTW_LOCALE_UNKNOWN;
                    633:                break;
                    634:        }
                    635:        return 0;
                    636: }
                    637:
                    638: /* Returns -1 on failure. */
                    639: int
                    640: rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr,
                    641:     const char *dvname)
                    642: {
                    643:        int rc;
                    644:        struct seeprom_descriptor sd;
                    645:        u_int8_t ecr;
                    646:
                    647:        bzero(&sd, sizeof(sd));
                    648:
                    649:        ecr = RTW_READ8(regs, RTW_9346CR);
                    650:
                    651:        if ((flags & RTW_F_9356SROM) != 0) {
                    652:                RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname));
                    653:                sr->sr_size = 256;
                    654:                sd.sd_chip = C56_66;
                    655:        } else {
                    656:                RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname));
                    657:                sr->sr_size = 128;
                    658:                sd.sd_chip = C46;
                    659:        }
                    660:
                    661:        ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
                    662:            RTW_9346CR_EEM_MASK | RTW_9346CR_EECS);
                    663:        ecr |= RTW_9346CR_EEM_PROGRAM;
                    664:
                    665:        RTW_WRITE8(regs, RTW_9346CR, ecr);
                    666:
                    667:        sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
                    668:
                    669:        if (sr->sr_content == NULL) {
                    670:                printf("%s: unable to allocate SROM buffer\n", dvname);
                    671:                return ENOMEM;
                    672:        }
                    673:
                    674:        bzero(sr->sr_content, sr->sr_size);
                    675:
                    676:        /* RTL8180 has a single 8-bit register for controlling the
                    677:         * 93cx6 SROM.  There is no "ready" bit. The RTL8180
                    678:         * input/output sense is the reverse of read_seeprom's.
                    679:         */
                    680:        sd.sd_tag = regs->r_bt;
                    681:        sd.sd_bsh = regs->r_bh;
                    682:        sd.sd_regsize = 1;
                    683:        sd.sd_control_offset = RTW_9346CR;
                    684:        sd.sd_status_offset = RTW_9346CR;
                    685:        sd.sd_dataout_offset = RTW_9346CR;
                    686:        sd.sd_CK = RTW_9346CR_EESK;
                    687:        sd.sd_CS = RTW_9346CR_EECS;
                    688:        sd.sd_DI = RTW_9346CR_EEDO;
                    689:        sd.sd_DO = RTW_9346CR_EEDI;
                    690:        /* make read_seeprom enter EEPROM read/write mode */
                    691:        sd.sd_MS = ecr;
                    692:        sd.sd_RDY = 0;
                    693:
                    694:        /* TBD bus barriers */
                    695:        if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
                    696:                printf("\n%s: could not read SROM\n", dvname);
                    697:                free(sr->sr_content, M_DEVBUF);
                    698:                sr->sr_content = NULL;
                    699:                return -1;      /* XXX */
                    700:        }
                    701:
                    702:        /* end EEPROM read/write mode */
                    703:        RTW_WRITE8(regs, RTW_9346CR,
                    704:            (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
                    705:        RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
                    706:
                    707:        if ((rc = rtw_recall_eeprom(regs, dvname)) != 0)
                    708:                return rc;
                    709:
                    710: #ifdef RTW_DEBUG
                    711:        {
                    712:                int i;
                    713:                RTW_DPRINTF(RTW_DEBUG_ATTACH,
                    714:                    ("\n%s: serial ROM:\n\t", dvname));
                    715:                for (i = 0; i < sr->sr_size/2; i++) {
                    716:                        if (((i % 8) == 0) && (i != 0))
                    717:                                RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t"));
                    718:                        RTW_DPRINTF(RTW_DEBUG_ATTACH,
                    719:                            (" %04x", sr->sr_content[i]));
                    720:                }
                    721:                RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n"));
                    722:        }
                    723: #endif /* RTW_DEBUG */
                    724:        return 0;
                    725: }
                    726:
                    727: void
                    728: rtw_set_rfprog(struct rtw_regs *regs, int rfchipid,
                    729:     const char *dvname)
                    730: {
                    731:        u_int8_t cfg4;
                    732:        const char *method;
                    733:
                    734:        cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
                    735:
                    736:        switch (rfchipid) {
                    737:        default:
                    738:                cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
                    739:                method = "fallback";
                    740:                break;
                    741:        case RTW_RFCHIPID_INTERSIL:
                    742:                cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
                    743:                method = "Intersil";
                    744:                break;
                    745:        case RTW_RFCHIPID_PHILIPS:
                    746:                cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
                    747:                method = "Philips";
                    748:                break;
                    749:        case RTW_RFCHIPID_RFMD2948:
                    750:                cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
                    751:                method = "RFMD";
                    752:                break;
                    753:        }
                    754:
                    755:        RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
                    756:
                    757:        RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
                    758:
                    759:        RTW_DPRINTF(RTW_DEBUG_INIT,
                    760:            ("%s: %s RF programming method, %#02x\n", dvname, method,
                    761:            RTW_READ8(regs, RTW_CONFIG4)));
                    762: }
                    763:
                    764: void
                    765: rtw_init_channels(enum rtw_locale locale,
                    766:     struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1],
                    767:     const char *dvname)
                    768: {
                    769:        int i;
                    770:        const char *name = NULL;
                    771: #define ADD_CHANNEL(_chans, _chan) do {                        \
                    772:        (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B;           \
                    773:        (*_chans)[_chan].ic_freq =                              \
                    774:            ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
                    775: } while (0)
                    776:
                    777:        switch (locale) {
                    778:        case RTW_LOCALE_USA:    /* 1-11 */
                    779:                name = "USA";
                    780:                for (i = 1; i <= 11; i++)
                    781:                        ADD_CHANNEL(chans, i);
                    782:                break;
                    783:        case RTW_LOCALE_JAPAN:  /* 1-14 */
                    784:                name = "Japan";
                    785:                ADD_CHANNEL(chans, 14);
                    786:                for (i = 1; i <= 14; i++)
                    787:                        ADD_CHANNEL(chans, i);
                    788:                break;
                    789:        case RTW_LOCALE_EUROPE: /* 1-13 */
                    790:                name = "Europe";
                    791:                for (i = 1; i <= 13; i++)
                    792:                        ADD_CHANNEL(chans, i);
                    793:                break;
                    794:        default:                        /* 10-11 allowed by most countries */
                    795:                name = "<unknown>";
                    796:                for (i = 10; i <= 11; i++)
                    797:                        ADD_CHANNEL(chans, i);
                    798:                break;
                    799:        }
                    800:        RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: Geographic Location %s\n",
                    801:            dvname, name));
                    802: #undef ADD_CHANNEL
                    803: }
                    804:
                    805: void
                    806: rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale)
                    807: {
                    808:        u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
                    809:
                    810:        switch (cfg0 & RTW8180_CONFIG0_GL_MASK) {
                    811:        case RTW8180_CONFIG0_GL_USA:
                    812:                *locale = RTW_LOCALE_USA;
                    813:                break;
                    814:        case RTW8180_CONFIG0_GL_JAPAN:
                    815:        case RTW8180_CONFIG0_GL_JAPAN2:
                    816:                *locale = RTW_LOCALE_JAPAN;
                    817:                break;
                    818:        case RTW8180_CONFIG0_GL_EUROPE:
                    819:                *locale = RTW_LOCALE_EUROPE;
                    820:                break;
                    821:        default:
                    822:                *locale = RTW_LOCALE_UNKNOWN;
                    823:                break;
                    824:        }
                    825: }
                    826:
                    827: int
                    828: rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN],
                    829:     const char *dvname)
                    830: {
                    831:        static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
                    832:                0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    833:        };
                    834:        u_int32_t idr0 = RTW_READ(regs, RTW_IDR0),
                    835:            idr1 = RTW_READ(regs, RTW_IDR1);
                    836:
                    837:        (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0,  7));
                    838:        (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8,  15));
                    839:        (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23));
                    840:        (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31));
                    841:
                    842:        (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0,  7));
                    843:        (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15));
                    844:
                    845:        if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
                    846:                printf("\n%s: could not get mac address, attach failed\n",
                    847:                    dvname);
                    848:                return ENXIO;
                    849:        }
                    850:
                    851:        printf("address %s\n", ether_sprintf(*addr));
                    852:
                    853:        return 0;
                    854: }
                    855:
                    856: u_int8_t
                    857: rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
                    858:     struct ieee80211_channel *chan)
                    859: {
                    860:        u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
                    861:        KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
                    862:            ("%s: channel %d out of range", __func__,
                    863:             idx - RTW_SR_TXPOWER1 + 1));
                    864:        return RTW_SR_GET(sr, idx);
                    865: }
                    866:
                    867: void
                    868: rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb)
                    869: {
                    870:        int pri;
                    871:        /* nfree: the number of free descriptors in each ring.
                    872:         * The beacon ring is a special case: I do not let the
                    873:         * driver use all of the descriptors on the beacon ring.
                    874:         * The reasons are two-fold:
                    875:         *
                    876:         * (1) A BEACON descriptor's OWN bit is (apparently) not
                    877:         * updated, so the driver cannot easily know if the descriptor
                    878:         * belongs to it, or if it is racing the NIC.  If the NIC
                    879:         * does not OWN every descriptor, then the driver can safely
                    880:         * update the descriptors when RTW_TBDA points at tdb_next.
                    881:         *
                    882:         * (2) I hope that the NIC will process more than one BEACON
                    883:         * descriptor in a single beacon interval, since that will
                    884:         * enable multiple-BSS support.  Since the NIC does not
                    885:         * clear the OWN bit, there is no natural place for it to
                    886:         * stop processing BEACON desciptors.  Maybe it will *not*
                    887:         * stop processing them!  I do not want to chance the NIC
                    888:         * looping around and around a saturated beacon ring, so
                    889:         * I will leave one descriptor unOWNed at all times.
                    890:         */
                    891:        u_int nfree[RTW_NTXPRI] =
                    892:            {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI,
                    893:             RTW_NTXDESCBCN - 1};
                    894:
                    895:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                    896:                tdb[pri].tdb_nfree = nfree[pri];
                    897:                tdb[pri].tdb_next = 0;
                    898:        }
                    899: }
                    900:
                    901: int
                    902: rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb)
                    903: {
                    904:        int i;
                    905:        struct rtw_txsoft *ts;
                    906:
                    907:        SIMPLEQ_INIT(&tsb->tsb_dirtyq);
                    908:        SIMPLEQ_INIT(&tsb->tsb_freeq);
                    909:        for (i = 0; i < tsb->tsb_ndesc; i++) {
                    910:                ts = &tsb->tsb_desc[i];
                    911:                ts->ts_mbuf = NULL;
                    912:                SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
                    913:        }
                    914:        tsb->tsb_tx_timer = 0;
                    915:        return 0;
                    916: }
                    917:
                    918: void
                    919: rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb)
                    920: {
                    921:        int pri;
                    922:        for (pri = 0; pri < RTW_NTXPRI; pri++)
                    923:                rtw_txsoft_blk_init(&tsb[pri]);
                    924: }
                    925:
                    926: void
                    927: rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops)
                    928: {
                    929:        KASSERT(nsync <= rdb->rdb_ndesc);
                    930:        /* sync to end of ring */
                    931:        if (desc0 + nsync > rdb->rdb_ndesc) {
                    932:                bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
                    933:                    offsetof(struct rtw_descs, hd_rx[desc0]),
                    934:                    sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops);
                    935:                nsync -= (rdb->rdb_ndesc - desc0);
                    936:                desc0 = 0;
                    937:        }
                    938:
                    939:        KASSERT(desc0 < rdb->rdb_ndesc);
                    940:        KASSERT(nsync <= rdb->rdb_ndesc);
                    941:        KASSERT(desc0 + nsync <= rdb->rdb_ndesc);
                    942:
                    943:        /* sync what remains */
                    944:        bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
                    945:            offsetof(struct rtw_descs, hd_rx[desc0]),
                    946:            sizeof(struct rtw_rxdesc) * nsync, ops);
                    947: }
                    948:
                    949: void
                    950: rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops)
                    951: {
                    952:        /* sync to end of ring */
                    953:        if (desc0 + nsync > tdb->tdb_ndesc) {
                    954:                bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
                    955:                    tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
                    956:                    sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0),
                    957:                    ops);
                    958:                nsync -= (tdb->tdb_ndesc - desc0);
                    959:                desc0 = 0;
                    960:        }
                    961:
                    962:        /* sync what remains */
                    963:        bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
                    964:            tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
                    965:            sizeof(struct rtw_txdesc) * nsync, ops);
                    966: }
                    967:
                    968: void
                    969: rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc)
                    970: {
                    971:        int i;
                    972:        struct rtw_rxsoft *rs;
                    973:
                    974:        for (i = 0; i < RTW_RXQLEN; i++) {
                    975:                rs = &desc[i];
                    976:                if (rs->rs_mbuf == NULL)
                    977:                        continue;
                    978:                bus_dmamap_sync(dmat, rs->rs_dmamap, 0,
                    979:                    rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                    980:                bus_dmamap_unload(dmat, rs->rs_dmamap);
                    981:                m_freem(rs->rs_mbuf);
                    982:                rs->rs_mbuf = NULL;
                    983:        }
                    984: }
                    985:
                    986: int
                    987: rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs)
                    988: {
                    989:        int rc;
                    990:        struct mbuf *m;
                    991:
                    992:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                    993:        if (m == NULL)
                    994:                return ENOBUFS;
                    995:
                    996:        MCLGET(m, M_DONTWAIT);
                    997:        if ((m->m_flags & M_EXT) == 0) {
                    998:                m_freem(m);
                    999:                return ENOBUFS;
                   1000:        }
                   1001:
                   1002:        m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
                   1003:
                   1004:        if (rs->rs_mbuf != NULL)
                   1005:                bus_dmamap_unload(dmat, rs->rs_dmamap);
                   1006:
                   1007:        rs->rs_mbuf = NULL;
                   1008:
                   1009:        rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT);
                   1010:        if (rc != 0) {
                   1011:                m_freem(m);
                   1012:                return -1;
                   1013:        }
                   1014:
                   1015:        rs->rs_mbuf = m;
                   1016:
                   1017:        return 0;
                   1018: }
                   1019:
                   1020: int
                   1021: rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc,
                   1022:     int *ndesc, const char *dvname)
                   1023: {
                   1024:        int i, rc = 0;
                   1025:        struct rtw_rxsoft *rs;
                   1026:
                   1027:        for (i = 0; i < RTW_RXQLEN; i++) {
                   1028:                rs = &desc[i];
                   1029:                /* we're in rtw_init, so there should be no mbufs allocated */
                   1030:                KASSERT(rs->rs_mbuf == NULL);
                   1031: #ifdef RTW_DEBUG
                   1032:                if (i == rtw_rxbufs_limit) {
                   1033:                        printf("%s: TEST hit %d-buffer limit\n", dvname, i);
                   1034:                        rc = ENOBUFS;
                   1035:                        break;
                   1036:                }
                   1037: #endif /* RTW_DEBUG */
                   1038:                if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) {
                   1039:                        printf("%s: rtw_rxsoft_alloc failed, %d buffers, "
                   1040:                            "rc %d\n", dvname, i, rc);
                   1041:                        break;
                   1042:                }
                   1043:        }
                   1044:        *ndesc = i;
                   1045:        return rc;
                   1046: }
                   1047:
                   1048: void
                   1049: rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs,
                   1050:     int idx, int kick)
                   1051: {
                   1052:        int is_last = (idx == rdb->rdb_ndesc - 1);
                   1053:        uint32_t ctl, octl, obuf;
                   1054:        struct rtw_rxdesc *rd = &rdb->rdb_desc[idx];
                   1055:
                   1056:        obuf = rd->rd_buf;
                   1057:        rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr);
                   1058:
                   1059:        ctl = LSHIFT(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
                   1060:            RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
                   1061:
                   1062:        if (is_last)
                   1063:                ctl |= RTW_RXCTL_EOR;
                   1064:
                   1065:        octl = rd->rd_ctl;
                   1066:        rd->rd_ctl = htole32(ctl);
                   1067:
                   1068:        RTW_DPRINTF(kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK)
                   1069:            : RTW_DEBUG_RECV_DESC,
                   1070:            ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd,
                   1071:            letoh32(obuf), letoh32(rd->rd_buf), letoh32(octl),
                   1072:            letoh32(rd->rd_ctl)));
                   1073:
                   1074:        /* sync the mbuf */
                   1075:        bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0,
                   1076:            rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
                   1077:
                   1078:        /* sync the descriptor */
                   1079:        bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
                   1080:            RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc),
                   1081:            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1082: }
                   1083:
                   1084: void
                   1085: rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl,
                   1086:     int kick)
                   1087: {
                   1088:        int i;
                   1089:        struct rtw_rxdesc *rd;
                   1090:        struct rtw_rxsoft *rs;
                   1091:
                   1092:        for (i = 0; i < rdb->rdb_ndesc; i++) {
                   1093:                rd = &rdb->rdb_desc[i];
                   1094:                rs = &ctl[i];
                   1095:                rtw_rxdesc_init(rdb, rs, i, kick);
                   1096:        }
                   1097: }
                   1098:
                   1099: void
                   1100: rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable)
                   1101: {
                   1102:        u_int8_t cr;
                   1103:
                   1104:        RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__,
                   1105:            enable ? "enable" : "disable", flags));
                   1106:
                   1107:        cr = RTW_READ8(regs, RTW_CR);
                   1108:
                   1109:        /* XXX reference source does not enable MULRW */
                   1110: #if 0
                   1111:        /* enable PCI Read/Write Multiple */
                   1112:        cr |= RTW_CR_MULRW;
                   1113: #endif
                   1114:
                   1115:        RTW_RBW(regs, RTW_CR, RTW_CR);  /* XXX paranoia? */
                   1116:        if (enable)
                   1117:                cr |= flags;
                   1118:        else
                   1119:                cr &= ~flags;
                   1120:        RTW_WRITE8(regs, RTW_CR, cr);
                   1121:        RTW_SYNC(regs, RTW_CR, RTW_CR);
                   1122: }
                   1123:
                   1124: void
                   1125: rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
                   1126: {
                   1127: #define        IS_BEACON(__fc0)                                                \
                   1128:     ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\
                   1129:      (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON))
                   1130:
                   1131:        static const int ratetbl[4] = {2, 4, 11, 22};   /* convert rates:
                   1132:                                                         * hardware -> net80211
                   1133:                                                         */
                   1134:        u_int next, nproc = 0;
                   1135:        int hwrate, len, rate, rssi, sq;
                   1136:        u_int32_t hrssi, hstat, htsfth, htsftl;
                   1137:        struct rtw_rxdesc *rd;
                   1138:        struct rtw_rxsoft *rs;
                   1139:        struct rtw_rxdesc_blk *rdb;
                   1140:        struct mbuf *m;
                   1141:
                   1142:        struct ieee80211_node *ni;
                   1143:        struct ieee80211_frame *wh;
                   1144:
                   1145:        rdb = &sc->sc_rxdesc_blk;
                   1146:
                   1147:        KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
                   1148:
                   1149:        for (next = rdb->rdb_next; ; next = (next + 1) % rdb->rdb_ndesc) {
                   1150:                rtw_rxdescs_sync(rdb, next, 1,
                   1151:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1152:                rd = &rdb->rdb_desc[next];
                   1153:                rs = &sc->sc_rxsoft[next];
                   1154:
                   1155:                hstat = letoh32(rd->rd_stat);
                   1156:                hrssi = letoh32(rd->rd_rssi);
                   1157:                htsfth = letoh32(rd->rd_tsfth);
                   1158:                htsftl = letoh32(rd->rd_tsftl);
                   1159:
                   1160:                RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
                   1161:                    ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n",
                   1162:                    __func__, next, hstat, hrssi, htsfth, htsftl));
                   1163:
                   1164:                ++nproc;
                   1165:
                   1166:                /* still belongs to NIC */
                   1167:                if ((hstat & RTW_RXSTAT_OWN) != 0) {
                   1168:                        if (nproc > 1)
                   1169:                                break;
                   1170:
                   1171:                        /* sometimes the NIC skips to the 0th descriptor */
                   1172:                        rtw_rxdescs_sync(rdb, 0, 1,
                   1173:                            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1174:                        rd = &rdb->rdb_desc[0];
                   1175:                        if ((rd->rd_stat & htole32(RTW_RXSTAT_OWN)) != 0)
                   1176:                                break;
                   1177:                        RTW_DPRINTF(RTW_DEBUG_BUGS,
                   1178:                            ("%s: NIC skipped from rxdesc[%u] to rxdesc[0]\n",
                   1179:                             sc->sc_dev.dv_xname, next));
                   1180:                        next = rdb->rdb_ndesc - 1;
                   1181:                        continue;
                   1182:                }
                   1183:
                   1184: #ifdef RTW_DEBUG
                   1185: #define PRINTSTAT(flag) do { \
                   1186:        if ((hstat & flag) != 0) { \
                   1187:                printf("%s" #flag, delim); \
                   1188:                delim = ","; \
                   1189:        } \
                   1190: } while (0)
                   1191:                if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) {
                   1192:                        const char *delim = "<";
                   1193:                        printf("%s: ", sc->sc_dev.dv_xname);
                   1194:                        if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
                   1195:                                printf("status %08x", hstat);
                   1196:                                PRINTSTAT(RTW_RXSTAT_SPLCP);
                   1197:                                PRINTSTAT(RTW_RXSTAT_MAR);
                   1198:                                PRINTSTAT(RTW_RXSTAT_PAR);
                   1199:                                PRINTSTAT(RTW_RXSTAT_BAR);
                   1200:                                PRINTSTAT(RTW_RXSTAT_PWRMGT);
                   1201:                                PRINTSTAT(RTW_RXSTAT_CRC32);
                   1202:                                PRINTSTAT(RTW_RXSTAT_ICV);
                   1203:                                printf(">, ");
                   1204:                        }
                   1205:                }
                   1206: #undef PRINTSTAT
                   1207: #endif /* RTW_DEBUG */
                   1208:
                   1209:                if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
                   1210:                        printf("%s: DMA error/FIFO overflow %08x, "
                   1211:                            "rx descriptor %d\n", sc->sc_dev.dv_xname,
                   1212:                            hstat & RTW_RXSTAT_IOERROR, next);
                   1213:                        sc->sc_if.if_ierrors++;
                   1214:                        goto next;
                   1215:                }
                   1216:
                   1217:                len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK);
                   1218:                if (len < IEEE80211_MIN_LEN) {
                   1219:                        sc->sc_ic.ic_stats.is_rx_tooshort++;
                   1220:                        goto next;
                   1221:                }
                   1222:
                   1223:                /* CRC is included with the packet; trim it off. */
                   1224:                len -= IEEE80211_CRC_LEN;
                   1225:
                   1226:                hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK);
                   1227:                if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) {
                   1228:                        printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname,
                   1229:                            MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK));
                   1230:                        sc->sc_if.if_ierrors++;
                   1231:                        goto next;
                   1232:                }
                   1233:                rate = ratetbl[hwrate];
                   1234:
                   1235: #ifdef RTW_DEBUG
                   1236:                RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
                   1237:                    ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10,
                   1238:                     (rate * 5) % 10, htsfth, htsftl));
                   1239: #endif /* RTW_DEBUG */
                   1240:
                   1241:                if ((hstat & RTW_RXSTAT_RES) != 0 &&
                   1242:                    sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
                   1243:                        goto next;
                   1244:
                   1245:                /* if bad flags, skip descriptor */
                   1246:                if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
                   1247:                        printf("%s: too many rx segments\n",
                   1248:                            sc->sc_dev.dv_xname);
                   1249:                        goto next;
                   1250:                }
                   1251:
                   1252:                bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0,
                   1253:                    rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
                   1254:
                   1255:                m = rs->rs_mbuf;
                   1256:
                   1257:                /* if temporarily out of memory, re-use mbuf */
                   1258:                switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) {
                   1259:                case 0:
                   1260:                        break;
                   1261:                case ENOBUFS:
                   1262:                        printf("%s: rtw_rxsoft_alloc(, %d) failed, "
                   1263:                            "dropping this packet\n", sc->sc_dev.dv_xname,
                   1264:                            next);
                   1265:                        goto next;
                   1266:                default:
                   1267:                        /* XXX shorten rx ring, instead? */
                   1268:                        panic("%s: could not load DMA map",
                   1269:                            sc->sc_dev.dv_xname);
                   1270:                }
                   1271:
                   1272:                if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
                   1273:                        rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI);
                   1274:                else {
                   1275:                        rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI);
                   1276:                        /* TBD find out each front-end's LNA gain in the
                   1277:                         * front-end's units
                   1278:                         */
                   1279:                        if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
                   1280:                                rssi |= 0x80;
                   1281:                }
                   1282:
                   1283:                sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ);
                   1284:
                   1285:                /*
                   1286:                 * Note well: now we cannot recycle the rs_mbuf unless
                   1287:                 * we restore its original length.
                   1288:                 */
                   1289:                m->m_pkthdr.rcvif = &sc->sc_if;
                   1290:                m->m_pkthdr.len = m->m_len = len;
                   1291:
                   1292:                wh = mtod(m, struct ieee80211_frame *);
                   1293:
                   1294:                if (!IS_BEACON(wh->i_fc[0]))
                   1295:                        sc->sc_led_state.ls_event |= RTW_LED_S_RX;
                   1296:                /* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
                   1297:                ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
                   1298:
                   1299:                sc->sc_tsfth = htsfth;
                   1300:
                   1301: #ifdef RTW_DEBUG
                   1302:                if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
                   1303:                    (IFF_DEBUG|IFF_LINK2)) {
                   1304:                        ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
                   1305:                            rate, rssi);
                   1306:                }
                   1307: #endif /* RTW_DEBUG */
                   1308:
                   1309: #if NBPFILTER > 0
                   1310:                if (sc->sc_radiobpf != NULL) {
                   1311:                        struct mbuf mb;
                   1312:                        struct ieee80211com *ic = &sc->sc_ic;
                   1313:                        struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
                   1314:
                   1315:                        rr->rr_tsft =
                   1316:                            htole64(((uint64_t)htsfth << 32) | htsftl);
                   1317:
                   1318:                        if ((hstat & RTW_RXSTAT_SPLCP) != 0)
                   1319:                                rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE;
                   1320:
                   1321:                        rr->rr_flags = 0;
                   1322:                        rr->rr_rate = rate;
                   1323:                        rr->rr_chan_freq =
                   1324:                            htole16(ic->ic_bss->ni_chan->ic_freq);
                   1325:                        rr->rr_chan_flags =
                   1326:                            htole16(ic->ic_bss->ni_chan->ic_flags);
                   1327:                        rr->rr_antsignal = rssi;
                   1328:                        rr->rr_barker_lock = htole16(sq);
                   1329:
                   1330:                        mb.m_data = (caddr_t)rr;
                   1331:                        mb.m_len = sizeof(sc->sc_rxtapu);
                   1332:                        mb.m_next = m;
                   1333:                        mb.m_nextpkt = NULL;
                   1334:                        mb.m_type = 0;
                   1335:                        mb.m_flags = 0;
                   1336:                        bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
                   1337:                }
                   1338: #endif /* NPBFILTER > 0 */
                   1339:
                   1340:                ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl);
                   1341:                ieee80211_release_node(&sc->sc_ic, ni);
                   1342: next:
                   1343:                rtw_rxdesc_init(rdb, rs, next, 0);
                   1344:        }
                   1345:        rdb->rdb_next = next;
                   1346:
                   1347:        KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
                   1348:
                   1349:        /*
                   1350:         * In HostAP mode, ieee80211_input() will enqueue packets in if_snd
                   1351:         * without calling if_start().
                   1352:         */
                   1353:        if (!IFQ_IS_EMPTY(&sc->sc_if.if_snd) &&
                   1354:            !(sc->sc_if.if_flags & IFF_OACTIVE))
                   1355:                (*sc->sc_if.if_start)(&sc->sc_if);
                   1356:
                   1357:        return;
                   1358: #undef IS_BEACON
                   1359: }
                   1360:
                   1361: void
                   1362: rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
                   1363:     struct rtw_txsoft *ts)
                   1364: {
                   1365:        struct mbuf *m;
                   1366:        struct ieee80211_node *ni;
                   1367:
                   1368:        m = ts->ts_mbuf;
                   1369:        ni = ts->ts_ni;
                   1370:        KASSERT(m != NULL);
                   1371:        KASSERT(ni != NULL);
                   1372:        ts->ts_mbuf = NULL;
                   1373:        ts->ts_ni = NULL;
                   1374:
                   1375:        bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize,
                   1376:            BUS_DMASYNC_POSTWRITE);
                   1377:        bus_dmamap_unload(dmat, ts->ts_dmamap);
                   1378:        m_freem(m);
                   1379:        ieee80211_release_node(ic, ni);
                   1380: }
                   1381:
                   1382: void
                   1383: rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
                   1384:     struct rtw_txsoft_blk *tsb)
                   1385: {
                   1386:        struct rtw_txsoft *ts;
                   1387:
                   1388:        while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
                   1389:                rtw_txsoft_release(dmat, ic, ts);
                   1390:                SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
                   1391:                SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
                   1392:        }
                   1393:        tsb->tsb_tx_timer = 0;
                   1394: }
                   1395:
                   1396: void
                   1397: rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb,
                   1398:     struct rtw_txsoft *ts, int ndesc)
                   1399: {
                   1400:        uint32_t hstat;
                   1401:        int data_retry, rts_retry;
                   1402:        struct rtw_txdesc *tdn;
                   1403:        const char *condstring;
                   1404:
                   1405:        rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts);
                   1406:
                   1407:        tdb->tdb_nfree += ndesc;
                   1408:
                   1409:        tdn = &tdb->tdb_desc[ts->ts_last];
                   1410:
                   1411:        hstat = letoh32(tdn->td_stat);
                   1412:        rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
                   1413:        data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK);
                   1414:
                   1415:        sc->sc_if.if_collisions += rts_retry + data_retry;
                   1416:
                   1417:        if ((hstat & RTW_TXSTAT_TOK) != 0)
                   1418:                condstring = "ok";
                   1419:        else {
                   1420:                sc->sc_if.if_oerrors++;
                   1421:                condstring = "error";
                   1422:        }
                   1423:
                   1424:        DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
                   1425:            ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n",
                   1426:            sc->sc_dev.dv_xname, ts, ts->ts_first, ts->ts_last,
                   1427:            condstring, rts_retry, data_retry));
                   1428: }
                   1429:
                   1430: void
                   1431: rtw_reset_oactive(struct rtw_softc *sc)
                   1432: {
                   1433:        short oflags;
                   1434:        int pri;
                   1435:        struct rtw_txsoft_blk *tsb;
                   1436:        struct rtw_txdesc_blk *tdb;
                   1437:        oflags = sc->sc_if.if_flags;
                   1438:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1439:                tsb = &sc->sc_txsoft_blk[pri];
                   1440:                tdb = &sc->sc_txdesc_blk[pri];
                   1441:                if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0)
                   1442:                        sc->sc_if.if_flags &= ~IFF_OACTIVE;
                   1443:        }
                   1444:        if (oflags != sc->sc_if.if_flags) {
                   1445:                DPRINTF(sc, RTW_DEBUG_OACTIVE,
                   1446:                    ("%s: reset OACTIVE\n", __func__));
                   1447:        }
                   1448: }
                   1449:
                   1450: /* Collect transmitted packets. */
                   1451: void
                   1452: rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb,
                   1453:     struct rtw_txdesc_blk *tdb, int force)
                   1454: {
                   1455:        int ndesc;
                   1456:        struct rtw_txsoft *ts;
                   1457:
                   1458:        while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
                   1459:                ndesc = 1 + ts->ts_last - ts->ts_first;
                   1460:                if (ts->ts_last < ts->ts_first)
                   1461:                        ndesc += tdb->tdb_ndesc;
                   1462:
                   1463:                KASSERT(ndesc > 0);
                   1464:
                   1465:                rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
                   1466:                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1467:
                   1468:                if (force) {
                   1469:                        int i;
                   1470:                        for (i = ts->ts_first; ; i = RTW_NEXT_IDX(tdb, i)) {
                   1471:                                tdb->tdb_desc[i].td_stat &=
                   1472:                                    ~htole32(RTW_TXSTAT_OWN);
                   1473:                                if (i == ts->ts_last)
                   1474:                                        break;
                   1475:                        }
                   1476:                        rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
                   1477:                            BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1478:                } else if ((tdb->tdb_desc[ts->ts_last].td_stat &
                   1479:                    htole32(RTW_TXSTAT_OWN)) != 0)
                   1480:                        break;
                   1481:
                   1482:                rtw_collect_txpkt(sc, tdb, ts, ndesc);
                   1483:                SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
                   1484:                SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
                   1485:        }
                   1486:        /* no more pending transmissions, cancel watchdog */
                   1487:        if (ts == NULL)
                   1488:                tsb->tsb_tx_timer = 0;
                   1489:        rtw_reset_oactive(sc);
                   1490: }
                   1491:
                   1492: void
                   1493: rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr)
                   1494: {
                   1495:        int pri;
                   1496:        struct rtw_txsoft_blk   *tsb;
                   1497:        struct rtw_txdesc_blk   *tdb;
                   1498:
                   1499:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1500:                tsb = &sc->sc_txsoft_blk[pri];
                   1501:                tdb = &sc->sc_txdesc_blk[pri];
                   1502:
                   1503:                rtw_collect_txring(sc, tsb, tdb, 0);
                   1504:
                   1505:        }
                   1506:
                   1507:        if ((isr & RTW_INTR_TX) != 0)
                   1508:                rtw_start(&sc->sc_if);
                   1509: }
                   1510:
                   1511: void
                   1512: rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr)
                   1513: {
                   1514:        u_int next;
                   1515:        uint32_t tsfth, tsftl;
                   1516:        struct ieee80211com *ic;
                   1517:        struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN];
                   1518:        struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN];
                   1519:        struct mbuf *m;
                   1520:
                   1521:        tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH);
                   1522:        tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
                   1523:
                   1524:        if ((isr & (RTW_INTR_TBDOK|RTW_INTR_TBDER)) != 0) {
                   1525:                next = rtw_txring_next(&sc->sc_regs, tdb);
                   1526:                RTW_DPRINTF(RTW_DEBUG_BEACON,
                   1527:                    ("%s: beacon ring %sprocessed, isr = %#04hx"
                   1528:                     ", next %u expected %u, %llu\n", __func__,
                   1529:                     (next == tdb->tdb_next) ? "" : "un", isr, next,
                   1530:                     tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl));
                   1531:                if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0){
                   1532:                        rtw_collect_txring(sc, tsb, tdb, 1);
                   1533:                        tdb->tdb_next = 0;
                   1534:                }
                   1535:        }
                   1536:        /* Start beacon transmission. */
                   1537:
                   1538:        if ((isr & RTW_INTR_BCNINT) != 0 &&
                   1539:            sc->sc_ic.ic_state == IEEE80211_S_RUN &&
                   1540:            SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) {
                   1541:                RTW_DPRINTF(RTW_DEBUG_BEACON,
                   1542:                    ("%s: beacon prep. time, isr = %#04hx"
                   1543:                     ", %16llu\n", __func__, isr,
                   1544:                     (uint64_t)tsfth << 32 | tsftl));
                   1545:                ic = &sc->sc_ic;
                   1546:                if ((m = ieee80211_beacon_alloc(ic, ic->ic_bss)) != NULL) {
                   1547:                        RTW_DPRINTF(RTW_DEBUG_BEACON,
                   1548:                            ("%s: m %p len %u\n", __func__, m, m->m_len));
                   1549:                }
                   1550:
                   1551:                if (m == NULL) {
                   1552:                        printf("%s: could not allocate beacon\n",
                   1553:                            sc->sc_dev.dv_xname);
                   1554:                        return;
                   1555:                }
                   1556:                m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ic->ic_bss);
                   1557:                IF_ENQUEUE(&sc->sc_beaconq, m);
                   1558:                rtw_start(&sc->sc_if);
                   1559:        }
                   1560: }
                   1561:
                   1562: void
                   1563: rtw_intr_atim(struct rtw_softc *sc)
                   1564: {
                   1565:        /* TBD */
                   1566:        return;
                   1567: }
                   1568:
                   1569: #ifdef RTW_DEBUG
                   1570: void
                   1571: rtw_dump_rings(struct rtw_softc *sc)
                   1572: {
                   1573:        struct rtw_txdesc_blk *tdb;
                   1574:        struct rtw_rxdesc *rd;
                   1575:        struct rtw_rxdesc_blk *rdb;
                   1576:        int desc, pri;
                   1577:
                   1578:        if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
                   1579:                return;
                   1580:
                   1581:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1582:                tdb = &sc->sc_txdesc_blk[pri];
                   1583:                printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
                   1584:                    tdb->tdb_ndesc, tdb->tdb_nfree);
                   1585:                for (desc = 0; desc < tdb->tdb_ndesc; desc++)
                   1586:                        rtw_print_txdesc(sc, ".", NULL, tdb, desc);
                   1587:        }
                   1588:
                   1589:        rdb = &sc->sc_rxdesc_blk;
                   1590:
                   1591:        for (desc = 0; desc < RTW_RXQLEN; desc++) {
                   1592:                rd = &rdb->rdb_desc[desc];
                   1593:                printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x "
                   1594:                    "rsvd1/tsfth %08x\n", __func__,
                   1595:                    (desc >= rdb->rdb_ndesc) ? "UNUSED " : "",
                   1596:                    letoh32(rd->rd_ctl), letoh32(rd->rd_rssi),
                   1597:                    letoh32(rd->rd_buf), letoh32(rd->rd_tsfth));
                   1598:        }
                   1599: }
                   1600: #endif /* RTW_DEBUG */
                   1601:
                   1602: void
                   1603: rtw_hwring_setup(struct rtw_softc *sc)
                   1604: {
                   1605:        int pri;
                   1606:        struct rtw_regs *regs = &sc->sc_regs;
                   1607:        struct rtw_txdesc_blk *tdb;
                   1608:
                   1609:        sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA;
                   1610:        sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo);
                   1611:        sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA;
                   1612:        sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd);
                   1613:        sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA;
                   1614:        sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi);
                   1615:        sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA;
                   1616:        sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn);
                   1617:
                   1618:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1619:                tdb = &sc->sc_txdesc_blk[pri];
                   1620:                RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base);
                   1621:                RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
                   1622:                    ("%s: reg[tdb->tdb_basereg] <- %lx\n", __func__,
                   1623:                     (u_int *)tdb->tdb_base));
                   1624:        }
                   1625:
                   1626:        RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
                   1627:
                   1628:        RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
                   1629:            ("%s: reg[RDSAR] <- %lx\n", __func__,
                   1630:             (u_int *)RTW_RING_BASE(sc, hd_rx)));
                   1631:
                   1632:        RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
                   1633: }
                   1634:
                   1635: int
                   1636: rtw_swring_setup(struct rtw_softc *sc)
                   1637: {
                   1638:        int rc, pri;
                   1639:        struct rtw_rxdesc_blk *rdb;
                   1640:        struct rtw_txdesc_blk *tdb;
                   1641:
                   1642:        rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
                   1643:
                   1644:        rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]);
                   1645:
                   1646:        rdb = &sc->sc_rxdesc_blk;
                   1647:        if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft,
                   1648:            &rdb->rdb_ndesc, sc->sc_dev.dv_xname)) != 0 &&
                   1649:            rdb->rdb_ndesc == 0) {
                   1650:                printf("%s: could not allocate rx buffers\n",
                   1651:                    sc->sc_dev.dv_xname);
                   1652:                return rc;
                   1653:        }
                   1654:
                   1655:        rdb = &sc->sc_rxdesc_blk;
                   1656:        rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc,
                   1657:            BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
                   1658:        rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1);
                   1659:        rdb->rdb_next = 0;
                   1660:
                   1661:        tdb = &sc->sc_txdesc_blk[0];
                   1662:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1663:                rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc,
                   1664:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   1665:        }
                   1666:        return 0;
                   1667: }
                   1668:
                   1669: void
                   1670: rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb)
                   1671: {
                   1672:        int i;
                   1673:
                   1674:        bzero(tdb->tdb_desc, sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
                   1675:        for (i = 0; i < tdb->tdb_ndesc; i++)
                   1676:                tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i));
                   1677: }
                   1678:
                   1679: u_int
                   1680: rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb)
                   1681: {
                   1682:        return (letoh32(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) /
                   1683:            sizeof(struct rtw_txdesc);
                   1684: }
                   1685:
                   1686: void
                   1687: rtw_txring_fixup(struct rtw_softc *sc)
                   1688: {
                   1689:        int pri;
                   1690:        u_int next;
                   1691:        struct rtw_txdesc_blk *tdb;
                   1692:        struct rtw_regs *regs = &sc->sc_regs;
                   1693:
                   1694:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1695:                tdb = &sc->sc_txdesc_blk[pri];
                   1696:                next = rtw_txring_next(regs, tdb);
                   1697:                if (tdb->tdb_next == next)
                   1698:                        continue;
                   1699:                RTW_DPRINTF(RTW_DEBUG_BUGS,
                   1700:                    ("%s: tx-ring %d expected next %u, read %u\n", __func__,
                   1701:                    pri, tdb->tdb_next, next));
                   1702:                tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1);
                   1703:        }
                   1704: }
                   1705:
                   1706: void
                   1707: rtw_rxring_fixup(struct rtw_softc *sc)
                   1708: {
                   1709:        u_int next;
                   1710:        uint32_t rdsar;
                   1711:        struct rtw_rxdesc_blk *rdb;
                   1712:
                   1713:        rdsar = letoh32(RTW_READ(&sc->sc_regs, RTW_RDSAR));
                   1714:        next = (rdsar - RTW_RING_BASE(sc, hd_rx)) / sizeof(struct rtw_rxdesc);
                   1715:
                   1716:        rdb = &sc->sc_rxdesc_blk;
                   1717:        if (rdb->rdb_next != next) {
                   1718:                RTW_DPRINTF(RTW_DEBUG_BUGS,
                   1719:                    ("%s: rx-ring expected next %u, read %u\n", __func__,
                   1720:                    rdb->rdb_next, next));
                   1721:                rdb->rdb_next = MIN(next, rdb->rdb_ndesc - 1);
                   1722:        }
                   1723: }
                   1724:
                   1725: void
                   1726: rtw_txdescs_reset(struct rtw_softc *sc)
                   1727: {
                   1728:        int pri;
                   1729:
                   1730:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1731:                rtw_collect_txring(sc, &sc->sc_txsoft_blk[pri],
                   1732:                    &sc->sc_txdesc_blk[pri], 1);
                   1733:        }
                   1734: }
                   1735:
                   1736: void
                   1737: rtw_intr_ioerror(struct rtw_softc *sc, u_int16_t isr)
                   1738: {
                   1739:        uint8_t cr = 0;
                   1740:        int xmtr = 0, rcvr = 0;
                   1741:        struct rtw_regs *regs = &sc->sc_regs;
                   1742:
                   1743:        if ((isr & RTW_INTR_TXFOVW) != 0) {
                   1744:                RTW_DPRINTF(RTW_DEBUG_BUGS,
                   1745:                    ("%s: tx fifo underflow\n", sc->sc_dev.dv_xname));
                   1746:                rcvr = xmtr = 1;
                   1747:                cr |= RTW_CR_TE | RTW_CR_RE;
                   1748:        }
                   1749:
                   1750:        if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) != 0) {
                   1751:                cr |= RTW_CR_RE;
                   1752:                rcvr = 1;
                   1753:        }
                   1754:
                   1755:        RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv, isr %hx"
                   1756:            "\n", sc->sc_dev.dv_xname, isr));
                   1757:
                   1758: #ifdef RTW_DEBUG
                   1759:        rtw_dump_rings(sc);
                   1760: #endif /* RTW_DEBUG */
                   1761:
                   1762:        rtw_io_enable(regs, cr, 0);
                   1763:
                   1764:        /* Collect rx'd packets.  Refresh rx buffers. */
                   1765:        if (rcvr)
                   1766:                rtw_intr_rx(sc, 0);
                   1767:        /* Collect tx'd packets.  XXX let's hope this stops the transmit
                   1768:         * timeouts.
                   1769:         */
                   1770:        if (xmtr)
                   1771:                rtw_txdescs_reset(sc);
                   1772:
                   1773:        RTW_WRITE16(regs, RTW_IMR, 0);
                   1774:        RTW_SYNC(regs, RTW_IMR, RTW_IMR);
                   1775:
                   1776:        if (rtw_do_chip_reset) {
                   1777:                rtw_chip_reset1(regs, sc->sc_dev.dv_xname);
                   1778:        }
                   1779:
                   1780:        rtw_rxdesc_init_all(&sc->sc_rxdesc_blk, &sc->sc_rxsoft[0], 1);
                   1781:
                   1782: #ifdef RTW_DEBUG
                   1783:        rtw_dump_rings(sc);
                   1784: #endif /* RTW_DEBUG */
                   1785:
                   1786:        RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
                   1787:        RTW_SYNC(regs, RTW_IMR, RTW_IMR);
                   1788:        if (rcvr)
                   1789:                rtw_rxring_fixup(sc);
                   1790:        rtw_io_enable(regs, cr, 1);
                   1791:        if (xmtr)
                   1792:                rtw_txring_fixup(sc);
                   1793: }
                   1794:
                   1795: void
                   1796: rtw_suspend_ticks(struct rtw_softc *sc)
                   1797: {
                   1798:        RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
                   1799:            ("%s: suspending ticks\n", sc->sc_dev.dv_xname));
                   1800:        sc->sc_do_tick = 0;
                   1801: }
                   1802:
                   1803: void
                   1804: rtw_resume_ticks(struct rtw_softc *sc)
                   1805: {
                   1806:        u_int32_t tsftrl0, tsftrl1, next_tick;
                   1807:
                   1808:        tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
                   1809:
                   1810:        tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
                   1811:        next_tick = tsftrl1 + 1000000;
                   1812:        RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick);
                   1813:
                   1814:        sc->sc_do_tick = 1;
                   1815:
                   1816:        RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
                   1817:            ("%s: resume ticks delta %#08x now %#08x next %#08x\n",
                   1818:            sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick));
                   1819: }
                   1820:
                   1821: void
                   1822: rtw_intr_timeout(struct rtw_softc *sc)
                   1823: {
                   1824:        RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname));
                   1825:        if (sc->sc_do_tick)
                   1826:                rtw_resume_ticks(sc);
                   1827:        return;
                   1828: }
                   1829:
                   1830: int
                   1831: rtw_intr(void *arg)
                   1832: {
                   1833:        int i;
                   1834:        struct rtw_softc *sc = arg;
                   1835:        struct rtw_regs *regs = &sc->sc_regs;
                   1836:        u_int16_t isr;
                   1837:
                   1838:        /*
                   1839:         * If the interface isn't running, the interrupt couldn't
                   1840:         * possibly have come from us.
                   1841:         */
                   1842:        if ((sc->sc_flags & RTW_F_ENABLED) == 0 ||
                   1843:            (sc->sc_if.if_flags & IFF_RUNNING) == 0 ||
                   1844:            (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
                   1845:                RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n",
                   1846:                     sc->sc_dev.dv_xname));
                   1847:                return (0);
                   1848:        }
                   1849:
                   1850:        for (i = 0; i < 10; i++) {
                   1851:                isr = RTW_READ16(regs, RTW_ISR);
                   1852:
                   1853:                RTW_WRITE16(regs, RTW_ISR, isr);
                   1854:                RTW_WBR(regs, RTW_ISR, RTW_ISR);
                   1855:
                   1856:                if (sc->sc_intr_ack != NULL)
                   1857:                        (*sc->sc_intr_ack)(regs);
                   1858:
                   1859:                if (isr == 0)
                   1860:                        break;
                   1861:
                   1862: #ifdef RTW_DEBUG
                   1863: #define PRINTINTR(flag) do { \
                   1864:        if ((isr & flag) != 0) { \
                   1865:                printf("%s" #flag, delim); \
                   1866:                delim = ","; \
                   1867:        } \
                   1868: } while (0)
                   1869:
                   1870:                if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
                   1871:                        const char *delim = "<";
                   1872:
                   1873:                        printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr);
                   1874:
                   1875:                        PRINTINTR(RTW_INTR_TXFOVW);
                   1876:                        PRINTINTR(RTW_INTR_TIMEOUT);
                   1877:                        PRINTINTR(RTW_INTR_BCNINT);
                   1878:                        PRINTINTR(RTW_INTR_ATIMINT);
                   1879:                        PRINTINTR(RTW_INTR_TBDER);
                   1880:                        PRINTINTR(RTW_INTR_TBDOK);
                   1881:                        PRINTINTR(RTW_INTR_THPDER);
                   1882:                        PRINTINTR(RTW_INTR_THPDOK);
                   1883:                        PRINTINTR(RTW_INTR_TNPDER);
                   1884:                        PRINTINTR(RTW_INTR_TNPDOK);
                   1885:                        PRINTINTR(RTW_INTR_RXFOVW);
                   1886:                        PRINTINTR(RTW_INTR_RDU);
                   1887:                        PRINTINTR(RTW_INTR_TLPDER);
                   1888:                        PRINTINTR(RTW_INTR_TLPDOK);
                   1889:                        PRINTINTR(RTW_INTR_RER);
                   1890:                        PRINTINTR(RTW_INTR_ROK);
                   1891:
                   1892:                        printf(">\n");
                   1893:                }
                   1894: #undef PRINTINTR
                   1895: #endif /* RTW_DEBUG */
                   1896:
                   1897:                if ((isr & RTW_INTR_RX) != 0)
                   1898:                        rtw_intr_rx(sc, isr & RTW_INTR_RX);
                   1899:                if ((isr & RTW_INTR_TX) != 0)
                   1900:                        rtw_intr_tx(sc, isr & RTW_INTR_TX);
                   1901:                if ((isr & RTW_INTR_BEACON) != 0)
                   1902:                        rtw_intr_beacon(sc, isr & RTW_INTR_BEACON);
                   1903:                if ((isr & RTW_INTR_ATIMINT) != 0)
                   1904:                        rtw_intr_atim(sc);
                   1905:                if ((isr & RTW_INTR_IOERROR) != 0)
                   1906:                        rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR);
                   1907:                if ((isr & RTW_INTR_TIMEOUT) != 0)
                   1908:                        rtw_intr_timeout(sc);
                   1909:        }
                   1910:
                   1911:        return 1;
                   1912: }
                   1913:
                   1914: /* Must be called at splnet. */
                   1915: void
                   1916: rtw_stop(struct ifnet *ifp, int disable)
                   1917: {
                   1918:        int pri;
                   1919:        struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
                   1920:        struct ieee80211com *ic = &sc->sc_ic;
                   1921:        struct rtw_regs *regs = &sc->sc_regs;
                   1922:
                   1923:        if ((sc->sc_flags & RTW_F_ENABLED) == 0)
                   1924:                return;
                   1925:
                   1926:        rtw_suspend_ticks(sc);
                   1927:
                   1928:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
                   1929:
                   1930:        if ((sc->sc_flags & RTW_F_INVALID) == 0) {
                   1931:                /* Disable interrupts. */
                   1932:                RTW_WRITE16(regs, RTW_IMR, 0);
                   1933:
                   1934:                RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
                   1935:
                   1936:                /* Stop the transmit and receive processes. First stop DMA,
                   1937:                 * then disable receiver and transmitter.
                   1938:                 */
                   1939:                RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
                   1940:
                   1941:                RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
                   1942:
                   1943:                rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0);
                   1944:        }
                   1945:
                   1946:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   1947:                rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic,
                   1948:                    &sc->sc_txsoft_blk[pri]);
                   1949:        }
                   1950:
                   1951:        rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]);
                   1952:
                   1953:        if (disable)
                   1954:                rtw_disable(sc);
                   1955:
                   1956:        /* Mark the interface as not running.  Cancel the watchdog timer. */
                   1957:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   1958:        ifp->if_timer = 0;
                   1959:
                   1960:        return;
                   1961: }
                   1962:
                   1963: #ifdef RTW_DEBUG
                   1964: const char *
                   1965: rtw_pwrstate_string(enum rtw_pwrstate power)
                   1966: {
                   1967:        switch (power) {
                   1968:        case RTW_ON:
                   1969:                return "on";
                   1970:        case RTW_SLEEP:
                   1971:                return "sleep";
                   1972:        case RTW_OFF:
                   1973:                return "off";
                   1974:        default:
                   1975:                return "unknown";
                   1976:        }
                   1977: }
                   1978: #endif
                   1979:
                   1980: /* XXX For Maxim, I am using the RFMD settings gleaned from the
                   1981:  * reference driver, plus a magic Maxim "ON" value that comes from
                   1982:  * the Realtek document "Windows PG for Rtl8180."
                   1983:  */
                   1984: void
                   1985: rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
                   1986:     int before_rf, int digphy)
                   1987: {
                   1988:        u_int32_t anaparm;
                   1989:
                   1990:        anaparm = RTW_READ(regs, RTW_ANAPARM_0);
                   1991:        anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
                   1992:
                   1993:        switch (power) {
                   1994:        case RTW_OFF:
                   1995:                if (before_rf)
                   1996:                        return;
                   1997:                anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
                   1998:                anaparm |= RTW_ANAPARM_TXDACOFF;
                   1999:                break;
                   2000:        case RTW_SLEEP:
                   2001:                if (!before_rf)
                   2002:                        return;
                   2003:                anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
                   2004:                anaparm |= RTW_ANAPARM_TXDACOFF;
                   2005:                break;
                   2006:        case RTW_ON:
                   2007:                if (!before_rf)
                   2008:                        return;
                   2009:                anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
                   2010:                break;
                   2011:        }
                   2012:        RTW_DPRINTF(RTW_DEBUG_PWR,
                   2013:            ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
                   2014:            __func__, rtw_pwrstate_string(power),
                   2015:            (before_rf) ? "before" : "after", anaparm));
                   2016:
                   2017:        RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
                   2018:        RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
                   2019: }
                   2020:
                   2021: /* XXX I am using the RFMD settings gleaned from the reference
                   2022:  * driver.  They agree
                   2023:  */
                   2024: void
                   2025: rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
                   2026:     int before_rf, int digphy)
                   2027: {
                   2028:        u_int32_t anaparm;
                   2029:
                   2030:        anaparm = RTW_READ(regs, RTW_ANAPARM_0);
                   2031:        anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
                   2032:
                   2033:        switch (power) {
                   2034:        case RTW_OFF:
                   2035:                if (before_rf)
                   2036:                        return;
                   2037:                anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
                   2038:                anaparm |= RTW_ANAPARM_TXDACOFF;
                   2039:                break;
                   2040:        case RTW_SLEEP:
                   2041:                if (!before_rf)
                   2042:                        return;
                   2043:                anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
                   2044:                anaparm |= RTW_ANAPARM_TXDACOFF;
                   2045:                break;
                   2046:        case RTW_ON:
                   2047:                if (!before_rf)
                   2048:                        return;
                   2049:                anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
                   2050:                break;
                   2051:        }
                   2052:        RTW_DPRINTF(RTW_DEBUG_PWR,
                   2053:            ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
                   2054:            __func__, rtw_pwrstate_string(power),
                   2055:            (before_rf) ? "before" : "after", anaparm));
                   2056:
                   2057:        RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
                   2058:        RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
                   2059: }
                   2060:
                   2061: void
                   2062: rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
                   2063:     int before_rf, int digphy)
                   2064: {
                   2065:        u_int32_t anaparm;
                   2066:
                   2067:        anaparm = RTW_READ(regs, RTW_ANAPARM_0);
                   2068:        anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
                   2069:
                   2070:        switch (power) {
                   2071:        case RTW_OFF:
                   2072:                if (before_rf)
                   2073:                        return;
                   2074:                anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
                   2075:                anaparm |= RTW_ANAPARM_TXDACOFF;
                   2076:                break;
                   2077:        case RTW_SLEEP:
                   2078:                if (!before_rf)
                   2079:                        return;
                   2080:                anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
                   2081:                anaparm |= RTW_ANAPARM_TXDACOFF;
                   2082:                break;
                   2083:        case RTW_ON:
                   2084:                if (!before_rf)
                   2085:                        return;
                   2086:                if (digphy) {
                   2087:                        anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
                   2088:                        /* XXX guess */
                   2089:                        anaparm |= RTW_ANAPARM_TXDACOFF;
                   2090:                } else
                   2091:                        anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
                   2092:                break;
                   2093:        }
                   2094:        RTW_DPRINTF(RTW_DEBUG_PWR,
                   2095:            ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
                   2096:            __func__, rtw_pwrstate_string(power),
                   2097:            (before_rf) ? "before" : "after", anaparm));
                   2098:
                   2099:        RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
                   2100:        RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
                   2101: }
                   2102:
                   2103: void
                   2104: rtw_rtl_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
                   2105:     int before_rf, int digphy)
                   2106: {
                   2107:        /* empty */
                   2108: }
                   2109:
                   2110: void
                   2111: rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
                   2112:     int digphy)
                   2113: {
                   2114:        struct rtw_regs *regs = &sc->sc_regs;
                   2115:
                   2116:        rtw_set_access(regs, RTW_ACCESS_ANAPARM);
                   2117:
                   2118:        (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
                   2119:
                   2120:        rtw_set_access(regs, RTW_ACCESS_NONE);
                   2121:
                   2122:        return;
                   2123: }
                   2124:
                   2125: int
                   2126: rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
                   2127: {
                   2128:        int rc;
                   2129:
                   2130:        RTW_DPRINTF(RTW_DEBUG_PWR,
                   2131:            ("%s: %s->%s\n", __func__,
                   2132:            rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
                   2133:
                   2134:        if (sc->sc_pwrstate == power)
                   2135:                return 0;
                   2136:
                   2137:        rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
                   2138:        rc = (*sc->sc_rf_pwrstate)(sc, power);
                   2139:        rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
                   2140:
                   2141:        switch (power) {
                   2142:        case RTW_ON:
                   2143:                /* TBD set LEDs */
                   2144:                break;
                   2145:        case RTW_SLEEP:
                   2146:                /* TBD */
                   2147:                break;
                   2148:        case RTW_OFF:
                   2149:                /* TBD */
                   2150:                break;
                   2151:        }
                   2152:        if (rc == 0)
                   2153:                sc->sc_pwrstate = power;
                   2154:        else
                   2155:                sc->sc_pwrstate = RTW_OFF;
                   2156:        return rc;
                   2157: }
                   2158:
                   2159: int
                   2160: rtw_tune(struct rtw_softc *sc)
                   2161: {
                   2162:        struct ieee80211com *ic = &sc->sc_ic;
                   2163:        u_int chan, idx;
                   2164:        u_int8_t txpower;
                   2165:        int rc;
                   2166:
                   2167:        KASSERT(ic->ic_bss->ni_chan != NULL);
                   2168:
                   2169:        chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                   2170:        if (chan == 0 || chan == IEEE80211_CHAN_ANY)
                   2171:                return 0;
                   2172:
                   2173:        if (chan == sc->sc_cur_chan) {
                   2174:                RTW_DPRINTF(RTW_DEBUG_TUNE,
                   2175:                    ("%s: already tuned chan #%d\n", __func__, chan));
                   2176:                return 0;
                   2177:        }
                   2178:
                   2179:        rtw_suspend_ticks(sc);
                   2180:
                   2181:        rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0);
                   2182:
                   2183:        /* TBD wait for Tx to complete */
                   2184:
                   2185:        KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0);
                   2186:
                   2187:        idx = RTW_SR_TXPOWER1 +
                   2188:            ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan) - 1;
                   2189:        KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
                   2190:            ("%s: channel %d out of range", __func__,
                   2191:             idx - RTW_SR_TXPOWER1 + 1));
                   2192:        txpower =  RTW_SR_GET(&sc->sc_srom, idx);
                   2193:
                   2194:        if ((rc = rtw_phy_init(sc)) != 0) {
                   2195:                /* XXX condition on powersaving */
                   2196:                printf("%s: phy init failed\n", sc->sc_dev.dv_xname);
                   2197:        }
                   2198:
                   2199:        sc->sc_cur_chan = chan;
                   2200:
                   2201:        rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1);
                   2202:
                   2203:        rtw_resume_ticks(sc);
                   2204:
                   2205:        return rc;
                   2206: }
                   2207:
                   2208: void
                   2209: rtw_disable(struct rtw_softc *sc)
                   2210: {
                   2211:        int rc;
                   2212:
                   2213:        if ((sc->sc_flags & RTW_F_ENABLED) == 0)
                   2214:                return;
                   2215:
                   2216:        /* turn off PHY */
                   2217:        if ((sc->sc_flags & RTW_F_INVALID) == 0 &&
                   2218:            (rc = rtw_pwrstate(sc, RTW_OFF)) != 0) {
                   2219:                printf("%s: failed to turn off PHY (%d)\n",
                   2220:                    sc->sc_dev.dv_xname, rc);
                   2221:        }
                   2222:
                   2223:        if (sc->sc_disable != NULL)
                   2224:                (*sc->sc_disable)(sc);
                   2225:
                   2226:        sc->sc_flags &= ~RTW_F_ENABLED;
                   2227: }
                   2228:
                   2229: int
                   2230: rtw_enable(struct rtw_softc *sc)
                   2231: {
                   2232:        if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
                   2233:                if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
                   2234:                        printf("%s: device enable failed\n",
                   2235:                            sc->sc_dev.dv_xname);
                   2236:                        return (EIO);
                   2237:                }
                   2238:                sc->sc_flags |= RTW_F_ENABLED;
                   2239:        }
                   2240:        return (0);
                   2241: }
                   2242:
                   2243: void
                   2244: rtw_transmit_config(struct rtw_softc *sc)
                   2245: {
                   2246:        struct rtw_regs *regs = &sc->sc_regs;
                   2247:        u_int32_t tcr;
                   2248:
                   2249:        tcr = RTW_READ(regs, RTW_TCR);
                   2250:
                   2251:        tcr |= RTW_TCR_CWMIN;
                   2252:        tcr &= ~RTW_TCR_MXDMA_MASK;
                   2253:        tcr |= RTW_TCR_MXDMA_256;
                   2254:        if ((sc->sc_flags & RTW_F_RTL8185) == 0)
                   2255:                tcr |= RTW8180_TCR_SAT;         /* send ACK as fast as possible */
                   2256:        tcr &= ~RTW_TCR_LBK_MASK;
                   2257:        tcr |= RTW_TCR_LBK_NORMAL;      /* normal operating mode */
                   2258:
                   2259:        /* set short/long retry limits */
                   2260:        tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
                   2261:        tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK);
                   2262:
                   2263:        tcr &= ~RTW_TCR_CRC;    /* NIC appends CRC32 */
                   2264:
                   2265:        RTW_WRITE(regs, RTW_TCR, tcr);
                   2266:        RTW_SYNC(regs, RTW_TCR, RTW_TCR);
                   2267: }
                   2268:
                   2269: void
                   2270: rtw_enable_interrupts(struct rtw_softc *sc)
                   2271: {
                   2272:        struct rtw_regs *regs = &sc->sc_regs;
                   2273:
                   2274:        sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
                   2275:        sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
                   2276:
                   2277:        RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
                   2278:        RTW_WBW(regs, RTW_IMR, RTW_ISR);
                   2279:        RTW_WRITE16(regs, RTW_ISR, 0xffff);
                   2280:        RTW_SYNC(regs, RTW_IMR, RTW_ISR);
                   2281:
                   2282:        /* XXX necessary? */
                   2283:        if (sc->sc_intr_ack != NULL)
                   2284:                (*sc->sc_intr_ack)(regs);
                   2285: }
                   2286:
                   2287: void
                   2288: rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
                   2289: {
                   2290:        uint8_t msr;
                   2291:
                   2292:        /* I'm guessing that MSR is protected as CONFIG[0123] are. */
                   2293:        rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG);
                   2294:
                   2295:        msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
                   2296:
                   2297:        switch (opmode) {
                   2298:        case IEEE80211_M_AHDEMO:
                   2299:        case IEEE80211_M_IBSS:
                   2300:                msr |= RTW_MSR_NETYPE_ADHOC_OK;
                   2301:                break;
                   2302:        case IEEE80211_M_HOSTAP:
                   2303:                msr |= RTW_MSR_NETYPE_AP_OK;
                   2304:                break;
                   2305:        case IEEE80211_M_MONITOR:
                   2306:                /* XXX */
                   2307:                msr |= RTW_MSR_NETYPE_NOLINK;
                   2308:                break;
                   2309:        case IEEE80211_M_STA:
                   2310:                msr |= RTW_MSR_NETYPE_INFRA_OK;
                   2311:                break;
                   2312:        }
                   2313:        RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
                   2314:
                   2315:        rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE);
                   2316: }
                   2317:
                   2318: void
                   2319: rtw_pktfilt_load(struct rtw_softc *sc)
                   2320: {
                   2321:        struct rtw_regs *regs = &sc->sc_regs;
                   2322:        struct ieee80211com *ic = &sc->sc_ic;
                   2323:        struct arpcom *ec = &ic->ic_ac;
                   2324:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   2325:        int hash;
                   2326:        u_int32_t hashes[2] = { 0, 0 };
                   2327:        struct ether_multi *enm;
                   2328:        struct ether_multistep step;
                   2329:
                   2330:        /* XXX might be necessary to stop Rx/Tx engines while setting filters */
                   2331:
                   2332:        sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
                   2333:        sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW8180_RCR_RXFTH_MASK);
                   2334:
                   2335:        sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
                   2336:        /* MAC auto-reset PHY (huh?) */
                   2337:        sc->sc_rcr |= RTW_RCR_ENMARP;
                   2338:        /* DMA whole Rx packets, only.  Set Tx DMA burst size to 1024 bytes. */
                   2339:        sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW8180_RCR_RXFTH_WHOLE;
                   2340:
                   2341:        switch (ic->ic_opmode) {
                   2342:        case IEEE80211_M_MONITOR:
                   2343:                sc->sc_rcr |= RTW_RCR_MONITOR;
                   2344:                break;
                   2345:        case IEEE80211_M_AHDEMO:
                   2346:        case IEEE80211_M_IBSS:
                   2347:                /* receive broadcasts in our BSS */
                   2348:                sc->sc_rcr |= RTW_RCR_ADD3;
                   2349:                break;
                   2350:        default:
                   2351:                break;
                   2352:        }
                   2353:
                   2354:        ifp->if_flags &= ~IFF_ALLMULTI;
                   2355:
                   2356:        /* XXX accept all broadcast if scanning */
                   2357:        if ((ifp->if_flags & IFF_BROADCAST) != 0)
                   2358:                sc->sc_rcr |= RTW_RCR_AB;       /* accept all broadcast */
                   2359:
                   2360:        if (ifp->if_flags & IFF_PROMISC) {
                   2361:                sc->sc_rcr |= RTW_RCR_AB;       /* accept all broadcast */
                   2362: allmulti:
                   2363:                ifp->if_flags |= IFF_ALLMULTI;
                   2364:                goto setit;
                   2365:        }
                   2366:
                   2367:        /*
                   2368:         * Program the 64-bit multicast hash filter.
                   2369:         */
                   2370:        ETHER_FIRST_MULTI(step, ec, enm);
                   2371:        while (enm != NULL) {
                   2372:                /* XXX */
                   2373:                if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
                   2374:                    ETHER_ADDR_LEN) != 0)
                   2375:                        goto allmulti;
                   2376:
                   2377:                hash = ether_crc32_be((enm->enm_addrlo),
                   2378:                    IEEE80211_ADDR_LEN) >> 26;
                   2379:                hashes[hash >> 5] |= (1 << (hash & 0x1f));
                   2380:                sc->sc_rcr |= RTW_RCR_AM;
                   2381:                ETHER_NEXT_MULTI(step, enm);
                   2382:        }
                   2383:
                   2384:        /* all bits set => hash is useless */
                   2385:        if (~(hashes[0] & hashes[1]) == 0)
                   2386:                goto allmulti;
                   2387:
                   2388:  setit:
                   2389:        if (ifp->if_flags & IFF_ALLMULTI) {
                   2390:                sc->sc_rcr |= RTW_RCR_AM;       /* accept all multicast */
                   2391:                hashes[0] = hashes[1] = 0xffffffff;
                   2392:        }
                   2393:
                   2394:        RTW_WRITE(regs, RTW_MAR0, hashes[0]);
                   2395:        RTW_WRITE(regs, RTW_MAR1, hashes[1]);
                   2396:        RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
                   2397:        RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
                   2398:
                   2399:        DPRINTF(sc, RTW_DEBUG_PKTFILT,
                   2400:            ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
                   2401:            sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0),
                   2402:            RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
                   2403:
                   2404:        return;
                   2405: }
                   2406:
                   2407: /* Must be called at splnet. */
                   2408: int
                   2409: rtw_init(struct ifnet *ifp)
                   2410: {
                   2411:        struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
                   2412:        struct ieee80211com *ic = &sc->sc_ic;
                   2413:        struct rtw_regs *regs = &sc->sc_regs;
                   2414:        int rc = 0;
                   2415:
                   2416:        if ((rc = rtw_enable(sc)) != 0)
                   2417:                goto out;
                   2418:
                   2419:        /* Cancel pending I/O and reset. */
                   2420:        rtw_stop(ifp, 0);
                   2421:
                   2422:        ic->ic_bss->ni_chan = ic->ic_ibss_chan;
                   2423:        DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
                   2424:            __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
                   2425:            ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
                   2426:
                   2427:        if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
                   2428:                goto out;
                   2429:
                   2430:        if ((rc = rtw_swring_setup(sc)) != 0)
                   2431:                goto out;
                   2432:
                   2433:        rtw_transmit_config(sc);
                   2434:
                   2435:        rtw_set_access(regs, RTW_ACCESS_CONFIG);
                   2436:
                   2437:        RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */
                   2438:        RTW_WBW(regs, RTW_MSR, RTW_BRSR);
                   2439:
                   2440:        /* long PLCP header, 1Mb/2Mb basic rate */
                   2441:        if (sc->sc_flags & RTW_F_RTL8185)
                   2442:                RTW_WRITE16(regs, RTW_BRSR, RTW8185_BRSR_MBR_2MBPS);
                   2443:        else
                   2444:                RTW_WRITE16(regs, RTW_BRSR, RTW8180_BRSR_MBR_2MBPS);
                   2445:        RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
                   2446:
                   2447:        rtw_set_access(regs, RTW_ACCESS_ANAPARM);
                   2448:        rtw_set_access(regs, RTW_ACCESS_NONE);
                   2449:
                   2450:        /* XXX from reference sources */
                   2451:        RTW_WRITE(regs, RTW_FEMR, 0xffff);
                   2452:        RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
                   2453:
                   2454:        rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname);
                   2455:
                   2456:        RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
                   2457:        /* from Linux driver */
                   2458:        RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
                   2459:
                   2460:        RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
                   2461:
                   2462:        rtw_enable_interrupts(sc);
                   2463:
                   2464:        rtw_pktfilt_load(sc);
                   2465:
                   2466:        rtw_hwring_setup(sc);
                   2467:
                   2468:        rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1);
                   2469:
                   2470:        ifp->if_flags |= IFF_RUNNING;
                   2471:        ic->ic_state = IEEE80211_S_INIT;
                   2472:
                   2473:        RTW_WRITE16(regs, RTW_BSSID16, 0x0);
                   2474:        RTW_WRITE(regs, RTW_BSSID32, 0x0);
                   2475:
                   2476:        rtw_resume_ticks(sc);
                   2477:
                   2478:        rtw_set_nettype(sc, IEEE80211_M_MONITOR);
                   2479:
                   2480:        if (ic->ic_opmode == IEEE80211_M_MONITOR)
                   2481:                return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
                   2482:        else
                   2483:                return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
                   2484:
                   2485: out:
                   2486:        printf("%s: interface not running\n", sc->sc_dev.dv_xname);
                   2487:        return rc;
                   2488: }
                   2489:
                   2490: void
                   2491: rtw_led_init(struct rtw_regs *regs)
                   2492: {
                   2493:        u_int8_t cfg0, cfg1;
                   2494:
                   2495:        rtw_set_access(regs, RTW_ACCESS_CONFIG);
                   2496:
                   2497:        cfg0 = RTW_READ8(regs, RTW_CONFIG0);
                   2498:        cfg0 |= RTW8180_CONFIG0_LEDGPOEN;
                   2499:        RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
                   2500:
                   2501:        cfg1 = RTW_READ8(regs, RTW_CONFIG1);
                   2502:        RTW_DPRINTF(RTW_DEBUG_LED,
                   2503:            ("%s: read % from reg[CONFIG1]\n", __func__, cfg1));
                   2504:
                   2505:        cfg1 &= ~RTW_CONFIG1_LEDS_MASK;
                   2506:        cfg1 |= RTW_CONFIG1_LEDS_TX_RX;
                   2507:        RTW_WRITE8(regs, RTW_CONFIG1, cfg1);
                   2508:
                   2509:        rtw_set_access(regs, RTW_ACCESS_NONE);
                   2510: }
                   2511:
                   2512: /*
                   2513:  * IEEE80211_S_INIT:           LED1 off
                   2514:  *
                   2515:  * IEEE80211_S_AUTH,
                   2516:  * IEEE80211_S_ASSOC,
                   2517:  * IEEE80211_S_SCAN:           LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx
                   2518:  *
                   2519:  * IEEE80211_S_RUN:            LED1 on, blinks @ 5Hz for tx/rx
                   2520:  */
                   2521: void
                   2522: rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate)
                   2523: {
                   2524:        struct rtw_led_state *ls;
                   2525:
                   2526:        ls = &sc->sc_led_state;
                   2527:
                   2528:        switch (nstate) {
                   2529:        case IEEE80211_S_INIT:
                   2530:                rtw_led_init(&sc->sc_regs);
                   2531:                timeout_del(&ls->ls_slow_ch);
                   2532:                timeout_del(&ls->ls_fast_ch);
                   2533:                ls->ls_slowblink = 0;
                   2534:                ls->ls_actblink = 0;
                   2535:                ls->ls_default = 0;
                   2536:                break;
                   2537:        case IEEE80211_S_SCAN:
                   2538:                timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
                   2539:                timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
                   2540:                /*FALLTHROUGH*/
                   2541:        case IEEE80211_S_AUTH:
                   2542:        case IEEE80211_S_ASSOC:
                   2543:                ls->ls_default = RTW_LED1;
                   2544:                ls->ls_actblink = RTW_LED1;
                   2545:                ls->ls_slowblink = RTW_LED1;
                   2546:                break;
                   2547:        case IEEE80211_S_RUN:
                   2548:                ls->ls_slowblink = 0;
                   2549:                break;
                   2550:        }
                   2551:        rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
                   2552: }
                   2553:
                   2554: void
                   2555: rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, u_int hwverid)
                   2556: {
                   2557:        u_int8_t led_condition;
                   2558:        bus_size_t ofs;
                   2559:        u_int8_t mask, newval, val;
                   2560:
                   2561:        led_condition = ls->ls_default;
                   2562:
                   2563:        if (ls->ls_state & RTW_LED_S_SLOW)
                   2564:                led_condition ^= ls->ls_slowblink;
                   2565:        if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX))
                   2566:                led_condition ^= ls->ls_actblink;
                   2567:
                   2568:        RTW_DPRINTF(RTW_DEBUG_LED,
                   2569:            ("%s: LED condition %\n", __func__, led_condition));
                   2570:
                   2571:        switch (hwverid) {
                   2572:        default:
                   2573:        case RTW_TCR_HWVERID_RTL8180F:
                   2574:                ofs = RTW_PSR;
                   2575:                newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1;
                   2576:                if (led_condition & RTW_LED0)
                   2577:                        newval &= ~RTW_PSR_LEDGPO0;
                   2578:                if (led_condition & RTW_LED1)
                   2579:                        newval &= ~RTW_PSR_LEDGPO1;
                   2580:                break;
                   2581:        case RTW_TCR_HWVERID_RTL8180D:
                   2582:                ofs = RTW_9346CR;
                   2583:                mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS;
                   2584:                newval = RTW_9346CR_EEM_PROGRAM;
                   2585:                if (led_condition & RTW_LED0)
                   2586:                        newval |= RTW_9346CR_EEDI;
                   2587:                if (led_condition & RTW_LED1)
                   2588:                        newval |= RTW_9346CR_EECS;
                   2589:                break;
                   2590:        }
                   2591:        val = RTW_READ8(regs, ofs);
                   2592:        RTW_DPRINTF(RTW_DEBUG_LED,
                   2593:            ("%s: read % from reg[%#02]\n", __func__, val,
                   2594:             (u_int *)ofs));
                   2595:        val &= ~mask;
                   2596:        val |= newval;
                   2597:        RTW_WRITE8(regs, ofs, val);
                   2598:        RTW_DPRINTF(RTW_DEBUG_LED,
                   2599:            ("%s: wrote % to reg[%#02]\n", __func__, val,
                   2600:             (u_int *)ofs));
                   2601:        RTW_SYNC(regs, ofs, ofs);
                   2602: }
                   2603:
                   2604: void
                   2605: rtw_led_fastblink(void *arg)
                   2606: {
                   2607:        int ostate, s;
                   2608:        struct rtw_softc *sc = (struct rtw_softc *)arg;
                   2609:        struct rtw_led_state *ls = &sc->sc_led_state;
                   2610:
                   2611:        s = splnet();
                   2612:        ostate = ls->ls_state;
                   2613:        ls->ls_state ^= ls->ls_event;
                   2614:
                   2615:        if ((ls->ls_event & RTW_LED_S_TX) == 0)
                   2616:                ls->ls_state &= ~RTW_LED_S_TX;
                   2617:
                   2618:        if ((ls->ls_event & RTW_LED_S_RX) == 0)
                   2619:                ls->ls_state &= ~RTW_LED_S_RX;
                   2620:
                   2621:        ls->ls_event = 0;
                   2622:
                   2623:        if (ostate != ls->ls_state)
                   2624:                rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
                   2625:        splx(s);
                   2626:
                   2627:        timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
                   2628: }
                   2629:
                   2630: void
                   2631: rtw_led_slowblink(void *arg)
                   2632: {
                   2633:        int s;
                   2634:        struct rtw_softc *sc = (struct rtw_softc *)arg;
                   2635:        struct rtw_led_state *ls = &sc->sc_led_state;
                   2636:
                   2637:        s = splnet();
                   2638:        ls->ls_state ^= RTW_LED_S_SLOW;
                   2639:        rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
                   2640:        splx(s);
                   2641:        timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
                   2642: }
                   2643:
                   2644: void
                   2645: rtw_led_attach(struct rtw_led_state *ls, void *arg)
                   2646: {
                   2647:        timeout_set(&ls->ls_fast_ch, rtw_led_fastblink, arg);
                   2648:        timeout_set(&ls->ls_slow_ch, rtw_led_slowblink, arg);
                   2649: }
                   2650:
                   2651: int
                   2652: rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
                   2653: {
                   2654:        int rc = 0, s;
                   2655:        struct rtw_softc *sc = ifp->if_softc;
                   2656:        struct ieee80211com *ic = &sc->sc_ic;
                   2657:        struct ifreq *ifr = (struct ifreq *)data;
                   2658:        struct ifaddr *ifa = (struct ifaddr *)data;
                   2659:
                   2660:        s = splnet();
                   2661:        switch (cmd) {
                   2662:        case SIOCSIFMTU:
                   2663:                if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
                   2664:                        rc = EINVAL;
                   2665:                } else if (ifp->if_mtu != ifr->ifr_mtu) {
                   2666:                        ifp->if_mtu = ifr->ifr_mtu;
                   2667:                }
                   2668:                break;
                   2669:        case SIOCSIFADDR:
                   2670:                ifp->if_flags |= IFF_UP;
                   2671: #ifdef INET
                   2672:                if (ifa->ifa_addr->sa_family == AF_INET) {
                   2673:                        arp_ifinit(&ic->ic_ac, ifa);
                   2674:                }
                   2675: #endif  /* INET */
                   2676:                /* FALLTHROUGH */
                   2677:
                   2678:        case SIOCSIFFLAGS:
                   2679:                if ((ifp->if_flags & IFF_UP) != 0) {
                   2680:                        if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
                   2681:                                rtw_pktfilt_load(sc);
                   2682:                        } else
                   2683:                                rc = rtw_init(ifp);
                   2684:                } else if ((sc->sc_flags & RTW_F_ENABLED) != 0)
                   2685:                        rtw_stop(ifp, 1);
                   2686:                break;
                   2687:        case SIOCADDMULTI:
                   2688:        case SIOCDELMULTI:
                   2689:                if (cmd == SIOCADDMULTI)
                   2690:                        rc = ether_addmulti(ifr, &sc->sc_ic.ic_ac);
                   2691:                else
                   2692:                        rc = ether_delmulti(ifr, &sc->sc_ic.ic_ac);
                   2693:                if (rc != ENETRESET)
                   2694:                        break;
                   2695:                if (ifp->if_flags & IFF_RUNNING)
                   2696:                        rtw_pktfilt_load(sc);
                   2697:                rc = 0;
                   2698:                break;
                   2699:        default:
                   2700:                if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) {
                   2701:                        if ((sc->sc_flags & RTW_F_ENABLED) != 0)
                   2702:                                rc = rtw_init(ifp);
                   2703:                        else
                   2704:                                rc = 0;
                   2705:                }
                   2706:                break;
                   2707:        }
                   2708:        splx(s);
                   2709:        return rc;
                   2710: }
                   2711:
                   2712: /* Select a transmit ring with at least one h/w and s/w descriptor free.
                   2713:  * Return 0 on success, -1 on failure.
                   2714:  */
                   2715: int
                   2716: rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp,
                   2717:     struct rtw_txdesc_blk **tdbp, int pri)
                   2718: {
                   2719:        struct rtw_txsoft_blk *tsb;
                   2720:        struct rtw_txdesc_blk *tdb;
                   2721:
                   2722:        KASSERT(pri >= 0 && pri < RTW_NTXPRI);
                   2723:
                   2724:        tsb = &sc->sc_txsoft_blk[pri];
                   2725:        tdb = &sc->sc_txdesc_blk[pri];
                   2726:
                   2727:        if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) {
                   2728:                if (tsb->tsb_tx_timer == 0)
                   2729:                        tsb->tsb_tx_timer = 5;
                   2730:                *tsbp = NULL;
                   2731:                *tdbp = NULL;
                   2732:                return -1;
                   2733:        }
                   2734:        *tsbp = tsb;
                   2735:        *tdbp = tdb;
                   2736:        return 0;
                   2737: }
                   2738:
                   2739: struct mbuf *
                   2740: rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri,
                   2741:     struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp,
                   2742:     struct ieee80211_node **nip, short *if_flagsp)
                   2743: {
                   2744:        struct mbuf *m;
                   2745:
                   2746:        if (IF_IS_EMPTY(ifq))
                   2747:                return NULL;
                   2748:        if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
                   2749:                DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n",
                   2750:                    __func__, pri));
                   2751:                *if_flagsp |= IFF_OACTIVE;
                   2752:                sc->sc_if.if_timer = 1;
                   2753:                return NULL;
                   2754:        }
                   2755:        IF_DEQUEUE(ifq, m);
                   2756:        *nip = (struct ieee80211_node *)m->m_pkthdr.rcvif;
                   2757:        m->m_pkthdr.rcvif = NULL;
                   2758:        return m;
                   2759: }
                   2760:
                   2761: /* Point *mp at the next 802.11 frame to transmit.  Point *tsbp
                   2762:  * at the driver's selection of transmit control block for the packet.
                   2763:  */
                   2764: int
                   2765: rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
                   2766:     struct rtw_txdesc_blk **tdbp, struct mbuf **mp,
                   2767:     struct ieee80211_node **nip)
                   2768: {
                   2769:        struct mbuf *m0;
                   2770:        struct rtw_softc *sc;
                   2771:        short *if_flagsp;
                   2772:
                   2773:        sc = (struct rtw_softc *)ifp->if_softc;
                   2774:
                   2775:        DPRINTF(sc, RTW_DEBUG_XMIT,
                   2776:            ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
                   2777:
                   2778:        if_flagsp = &ifp->if_flags;
                   2779:
                   2780:        if (sc->sc_ic.ic_state == IEEE80211_S_RUN &&
                   2781:            (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp,
                   2782:            tdbp, nip, if_flagsp)) != NULL) {
                   2783:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n",
                   2784:                    __func__));
                   2785:                return 0;
                   2786:        }
                   2787:
                   2788:        if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp,
                   2789:            tdbp, nip, if_flagsp)) != NULL) {
                   2790:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n",
                   2791:                    __func__));
                   2792:                return 0;
                   2793:        }
                   2794:
                   2795:        if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
                   2796:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
                   2797:                return 0;
                   2798:        }
                   2799:
                   2800:        if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_pwrsaveq, RTW_TXPRIHI,
                   2801:            tsbp, tdbp, nip, if_flagsp)) != NULL) {
                   2802:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue pwrsave frame\n",
                   2803:                    __func__));
                   2804:                return 0;
                   2805:        }
                   2806:
                   2807:        if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
                   2808:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
                   2809:                return 0;
                   2810:        }
                   2811:
                   2812:        *mp = NULL;
                   2813:
                   2814:        IFQ_POLL(&ifp->if_snd, m0);
                   2815:        if (m0 == NULL) {
                   2816:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
                   2817:                    __func__));
                   2818:                return 0;
                   2819:        }
                   2820:
                   2821:        if (rtw_txring_choose(sc, tsbp, tdbp, RTW_TXPRIMD) == -1) {
                   2822:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no descriptor\n", __func__));
                   2823:                *if_flagsp |= IFF_OACTIVE;
                   2824:                sc->sc_if.if_timer = 1;
                   2825:                return 0;
                   2826:        }
                   2827:
                   2828:        IFQ_DEQUEUE(&ifp->if_snd, m0);
                   2829:        if (m0 == NULL) {
                   2830:                DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame/ring ready\n",
                   2831:                    __func__));
                   2832:                return 0;
                   2833:        }
                   2834:        DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__));
                   2835:        ifp->if_opackets++;
                   2836: #if NBPFILTER > 0
                   2837:        if (ifp->if_bpf)
                   2838:                bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
                   2839: #endif
                   2840:        if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) {
                   2841:                DPRINTF(sc, RTW_DEBUG_XMIT,
                   2842:                    ("%s: encap error\n", __func__));
                   2843:                ifp->if_oerrors++;
                   2844:                return -1;
                   2845:        }
                   2846:
                   2847:        /* XXX should do WEP in hardware */
                   2848:        if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
                   2849:                if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL)
                   2850:                        return -1;
                   2851:        }
                   2852:
                   2853:        DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
                   2854:        *mp = m0;
                   2855:        return 0;
                   2856: }
                   2857:
                   2858: int
                   2859: rtw_seg_too_short(bus_dmamap_t dmamap)
                   2860: {
                   2861:        int i;
                   2862:        for (i = 0; i < dmamap->dm_nsegs; i++) {
                   2863:                if (dmamap->dm_segs[i].ds_len < 4) {
                   2864:                        printf("%s: segment too short\n", __func__);
                   2865:                        return 1;
                   2866:                }
                   2867:        }
                   2868:        return 0;
                   2869: }
                   2870:
                   2871: /* TBD factor with atw_start */
                   2872: struct mbuf *
                   2873: rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
                   2874:     u_int ndescfree, short *ifflagsp, const char *dvname)
                   2875: {
                   2876:        int first, rc;
                   2877:        struct mbuf *m, *m0;
                   2878:
                   2879:        m0 = chain;
                   2880:
                   2881:        /*
                   2882:         * Load the DMA map.  Copy and try (once) again if the packet
                   2883:         * didn't fit in the alloted number of segments.
                   2884:         */
                   2885:        for (first = 1;
                   2886:             ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
                   2887:             BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
                   2888:             dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
                   2889:             first = 0) {
                   2890:                if (rc == 0)
                   2891:                        bus_dmamap_unload(dmat, dmam);
                   2892:                MGETHDR(m, M_DONTWAIT, MT_DATA);
                   2893:                if (m == NULL) {
                   2894:                        printf("%s: unable to allocate Tx mbuf\n",
                   2895:                            dvname);
                   2896:                        break;
                   2897:                }
                   2898:                if (m0->m_pkthdr.len > MHLEN) {
                   2899:                        MCLGET(m, M_DONTWAIT);
                   2900:                        if ((m->m_flags & M_EXT) == 0) {
                   2901:                                printf("%s: cannot allocate Tx cluster\n",
                   2902:                                    dvname);
                   2903:                                m_freem(m);
                   2904:                                break;
                   2905:                        }
                   2906:                }
                   2907:                m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
                   2908:                m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
                   2909:                m_freem(m0);
                   2910:                m0 = m;
                   2911:                m = NULL;
                   2912:        }
                   2913:        if (rc != 0) {
                   2914:                printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc);
                   2915:                m_freem(m0);
                   2916:                return NULL;
                   2917:        } else if (rtw_seg_too_short(dmam)) {
                   2918:                printf("%s: cannot load Tx buffer, segment too short\n",
                   2919:                    dvname);
                   2920:                bus_dmamap_unload(dmat, dmam);
                   2921:                m_freem(m0);
                   2922:                return NULL;
                   2923:        } else if (dmam->dm_nsegs > ndescfree) {
                   2924:                printf("%s: too many tx segments\n", dvname);
                   2925:                bus_dmamap_unload(dmat, dmam);
                   2926:                m_freem(m0);
                   2927:                return NULL;
                   2928:        }
                   2929:        return m0;
                   2930: }
                   2931:
                   2932:
                   2933: /*
                   2934:  * Arguments in:
                   2935:  *
                   2936:  * paylen:  payload length (no FCS, no WEP header)
                   2937:  *
                   2938:  * hdrlen:  header length
                   2939:  *
                   2940:  * rate:    MSDU speed, units 500kb/s
                   2941:  *
                   2942:  * flags:   IEEE80211_F_SHPREAMBLE (use short preamble),
                   2943:  *          IEEE80211_F_SHSLOT (use short slot length)
                   2944:  *
                   2945:  * Arguments out:
                   2946:  *
                   2947:  * d:       802.11 Duration field for RTS,
                   2948:  *          802.11 Duration field for data frame,
                   2949:  *          PLCP Length for data frame,
                   2950:  *          residual octets at end of data slot
                   2951:  */
                   2952: int
                   2953: rtw_compute_duration1(int len, int use_ack, uint32_t flags, int rate,
                   2954:     struct rtw_duration *d)
                   2955: {
                   2956:        int pre, ctsrate;
                   2957:        int ack, bitlen, data_dur, remainder;
                   2958:
                   2959:        /* RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK
                   2960:         * DATA reserves medium for SIFS | ACK
                   2961:         *
                   2962:         * XXXMYC: no ACK on multicast/broadcast or control packets
                   2963:         */
                   2964:
                   2965:        bitlen = len * 8;
                   2966:
                   2967:        pre = IEEE80211_DUR_DS_SIFS;
                   2968:        if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
                   2969:                pre += IEEE80211_DUR_DS_SHORT_PREAMBLE +
                   2970:                    IEEE80211_DUR_DS_FAST_PLCPHDR;
                   2971:        else
                   2972:                pre += IEEE80211_DUR_DS_LONG_PREAMBLE +
                   2973:                    IEEE80211_DUR_DS_SLOW_PLCPHDR;
                   2974:
                   2975:        d->d_residue = 0;
                   2976:        data_dur = (bitlen * 2) / rate;
                   2977:        remainder = (bitlen * 2) % rate;
                   2978:        if (remainder != 0) {
                   2979:                d->d_residue = (rate - remainder) / 16;
                   2980:                data_dur++;
                   2981:        }
                   2982:
                   2983:        switch (rate) {
                   2984:        case 2:         /* 1 Mb/s */
                   2985:        case 4:         /* 2 Mb/s */
                   2986:                /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */
                   2987:                ctsrate = 2;
                   2988:                break;
                   2989:        case 11:        /* 5.5 Mb/s */
                   2990:        case 22:        /* 11  Mb/s */
                   2991:        case 44:        /* 22  Mb/s */
                   2992:                /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */
                   2993:                ctsrate = 4;
                   2994:                break;
                   2995:        default:
                   2996:                /* TBD */
                   2997:                return -1;
                   2998:        }
                   2999:
                   3000:        d->d_plcp_len = data_dur;
                   3001:
                   3002:        ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
                   3003:
                   3004:        d->d_rts_dur =
                   3005:            pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
                   3006:            pre + data_dur +
                   3007:            ack;
                   3008:
                   3009:        d->d_data_dur = ack;
                   3010:
                   3011:        return 0;
                   3012: }
                   3013:
                   3014: /*
                   3015:  * Arguments in:
                   3016:  *
                   3017:  * wh:      802.11 header
                   3018:  *
                   3019:  * len: packet length
                   3020:  *
                   3021:  * rate:    MSDU speed, units 500kb/s
                   3022:  *
                   3023:  * fraglen: fragment length, set to maximum (or higher) for no
                   3024:  *          fragmentation
                   3025:  *
                   3026:  * flags:   IEEE80211_F_WEPON (hardware adds WEP),
                   3027:  *          IEEE80211_F_SHPREAMBLE (use short preamble),
                   3028:  *          IEEE80211_F_SHSLOT (use short slot length)
                   3029:  *
                   3030:  * Arguments out:
                   3031:  *
                   3032:  * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
                   3033:  *     of first/only fragment
                   3034:  *
                   3035:  * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
                   3036:  *     of first/only fragment
                   3037:  */
                   3038: int
                   3039: rtw_compute_duration(struct ieee80211_frame *wh, int len, uint32_t flags,
                   3040:     int fraglen, int rate, struct rtw_duration *d0, struct rtw_duration *dn,
                   3041:     int *npktp, int debug)
                   3042: {
                   3043:        int ack, rc;
                   3044:        int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
                   3045:
                   3046:        if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
                   3047:                hdrlen = sizeof(struct ieee80211_frame_addr4);
                   3048:        else
                   3049:                hdrlen = sizeof(struct ieee80211_frame);
                   3050:
                   3051:        paylen = len - hdrlen;
                   3052:
                   3053:        if ((flags & IEEE80211_F_WEPON) != 0)
                   3054:                overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
                   3055:        else
                   3056:                overlen = IEEE80211_CRC_LEN;
                   3057:
                   3058:        npkt = paylen / fraglen;
                   3059:        lastlen0 = paylen % fraglen;
                   3060:
                   3061:        if (npkt == 0)                  /* no fragments */
                   3062:                lastlen = paylen + overlen;
                   3063:        else if (lastlen0 != 0) {       /* a short "tail" fragment */
                   3064:                lastlen = lastlen0 + overlen;
                   3065:                npkt++;
                   3066:        } else                          /* full-length "tail" fragment */
                   3067:                lastlen = fraglen + overlen;
                   3068:
                   3069:        if (npktp != NULL)
                   3070:                *npktp = npkt;
                   3071:
                   3072:        if (npkt > 1)
                   3073:                firstlen = fraglen + overlen;
                   3074:        else
                   3075:                firstlen = paylen + overlen;
                   3076:
                   3077:        if (debug) {
                   3078:                printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
                   3079:                    "fraglen %d overlen %d len %d rate %d flags %08x\n",
                   3080:                    __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
                   3081:                    overlen, len, rate, flags);
                   3082:        }
                   3083:
                   3084:        ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
                   3085:            (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL;
                   3086:
                   3087:        rc = rtw_compute_duration1(firstlen + hdrlen, ack, flags, rate, d0);
                   3088:        if (rc == -1)
                   3089:                return rc;
                   3090:
                   3091:        if (npkt <= 1) {
                   3092:                *dn = *d0;
                   3093:                return 0;
                   3094:        }
                   3095:        return rtw_compute_duration1(lastlen + hdrlen, ack, flags, rate, dn);
                   3096: }
                   3097:
                   3098: #ifdef RTW_DEBUG
                   3099: void
                   3100: rtw_print_txdesc(struct rtw_softc *sc, const char *action,
                   3101:     struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc)
                   3102: {
                   3103:        struct rtw_txdesc *td = &tdb->tdb_desc[desc];
                   3104:        DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x "
                   3105:            "buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n",
                   3106:            sc->sc_dev.dv_xname, ts, action, desc,
                   3107:            letoh32(td->td_buf), letoh32(td->td_next),
                   3108:            letoh32(td->td_ctl0), letoh32(td->td_ctl1),
                   3109:            letoh32(td->td_len)));
                   3110: }
                   3111: #endif /* RTW_DEBUG */
                   3112:
                   3113: void
                   3114: rtw_start(struct ifnet *ifp)
                   3115: {
                   3116:        uint8_t tppoll;
                   3117:        int desc, i, lastdesc, npkt, rate;
                   3118:        uint32_t proto_ctl0, ctl0, ctl1;
                   3119:        bus_dmamap_t            dmamap;
                   3120:        struct ieee80211com     *ic;
                   3121:        struct ieee80211_frame  *wh;
                   3122:        struct ieee80211_node   *ni;
                   3123:        struct mbuf             *m0;
                   3124:        struct rtw_softc        *sc;
                   3125:        struct rtw_duration     *d0;
                   3126:        struct rtw_txsoft_blk   *tsb;
                   3127:        struct rtw_txdesc_blk   *tdb;
                   3128:        struct rtw_txsoft       *ts;
                   3129:        struct rtw_txdesc       *td;
                   3130:
                   3131:        sc = (struct rtw_softc *)ifp->if_softc;
                   3132:        ic = &sc->sc_ic;
                   3133:
                   3134:        DPRINTF(sc, RTW_DEBUG_XMIT,
                   3135:            ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
                   3136:
                   3137:        if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
                   3138:                goto out;
                   3139:
                   3140:        /* XXX do real rate control */
                   3141:        proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
                   3142:
                   3143:        if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
                   3144:                proto_ctl0 |= RTW_TXCTL0_SPLCP;
                   3145:
                   3146:        for (;;) {
                   3147:                if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1)
                   3148:                        continue;
                   3149:                if (m0 == NULL)
                   3150:                        break;
                   3151:                ts = SIMPLEQ_FIRST(&tsb->tsb_freeq);
                   3152:
                   3153:                dmamap = ts->ts_dmamap;
                   3154:
                   3155:                m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
                   3156:                    tdb->tdb_nfree, &ifp->if_flags, sc->sc_dev.dv_xname);
                   3157:
                   3158:                if (m0 == NULL || dmamap->dm_nsegs == 0) {
                   3159:                        DPRINTF(sc, RTW_DEBUG_XMIT,
                   3160:                            ("%s: fail dmamap load\n", __func__));
                   3161:                        goto post_dequeue_err;
                   3162:                }
                   3163:
                   3164:                wh = mtod(m0, struct ieee80211_frame *);
                   3165:
                   3166:                /* XXX do real rate control */
                   3167:                if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
                   3168:                    IEEE80211_FC0_TYPE_MGT)
                   3169:                        rate = 2;
                   3170:                else
                   3171:                        rate = MAX(2, ieee80211_get_rate(ic));
                   3172:
                   3173: #ifdef RTW_DEBUG
                   3174:                if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
                   3175:                    (IFF_DEBUG|IFF_LINK2)) {
                   3176:                        ieee80211_dump_pkt(mtod(m0, uint8_t *),
                   3177:                            (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
                   3178:                            : sizeof(wh), rate, 0);
                   3179:                }
                   3180: #endif /* RTW_DEBUG */
                   3181:                ctl0 = proto_ctl0 |
                   3182:                    LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
                   3183:
                   3184:                switch (rate) {
                   3185:                default:
                   3186:                case 2:
                   3187:                        ctl0 |= RTW_TXCTL0_RATE_1MBPS;
                   3188:                        break;
                   3189:                case 4:
                   3190:                        ctl0 |= RTW_TXCTL0_RATE_2MBPS;
                   3191:                        break;
                   3192:                case 11:
                   3193:                        ctl0 |= RTW_TXCTL0_RATE_5MBPS;
                   3194:                        break;
                   3195:                case 22:
                   3196:                        ctl0 |= RTW_TXCTL0_RATE_11MBPS;
                   3197:                        break;
                   3198:                }
                   3199:
                   3200:                /* XXX >= ? Compare after fragmentation? */
                   3201:                if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
                   3202:                        ctl0 |= RTW_TXCTL0_RTSEN;
                   3203:
                   3204:                if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
                   3205:                    IEEE80211_FC0_TYPE_MGT) {
                   3206:                        ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN);
                   3207:                        if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
                   3208:                            IEEE80211_FC0_SUBTYPE_BEACON)
                   3209:                                ctl0 |= RTW_TXCTL0_BEACON;
                   3210:                }
                   3211:
                   3212:                if (rtw_compute_duration(wh, m0->m_pkthdr.len,
                   3213:                    ic->ic_flags & ~IEEE80211_F_WEPON, ic->ic_fragthreshold,
                   3214:                    rate, &ts->ts_d0, &ts->ts_dn, &npkt,
                   3215:                    (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
                   3216:                    (IFF_DEBUG|IFF_LINK2)) == -1) {
                   3217:                        DPRINTF(sc, RTW_DEBUG_XMIT,
                   3218:                            ("%s: fail compute duration\n", __func__));
                   3219:                        goto post_load_err;
                   3220:                }
                   3221:
                   3222:                d0 = &ts->ts_d0;
                   3223:
                   3224:                *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
                   3225:
                   3226:                ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
                   3227:                    LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
                   3228:
                   3229:                if (d0->d_residue)
                   3230:                        ctl1 |= RTW_TXCTL1_LENGEXT;
                   3231:
                   3232:                /* TBD fragmentation */
                   3233:
                   3234:                ts->ts_first = tdb->tdb_next;
                   3235:
                   3236:                rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
                   3237:                    BUS_DMASYNC_PREWRITE);
                   3238:
                   3239:                KASSERT(ts->ts_first < tdb->tdb_ndesc);
                   3240:
                   3241: #if NBPFILTER > 0
                   3242:                if (ic->ic_rawbpf != NULL)
                   3243:                        bpf_mtap((caddr_t)ic->ic_rawbpf, m0,
                   3244:                            BPF_DIRECTION_OUT);
                   3245:
                   3246:                if (sc->sc_radiobpf != NULL) {
                   3247:                        struct mbuf mb;
                   3248:                        struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
                   3249:
                   3250:                        rt->rt_flags = 0;
                   3251:                        rt->rt_rate = rate;
                   3252:                        rt->rt_chan_freq =
                   3253:                            htole16(ic->ic_bss->ni_chan->ic_freq);
                   3254:                        rt->rt_chan_flags =
                   3255:                            htole16(ic->ic_bss->ni_chan->ic_flags);
                   3256:
                   3257:                        mb.m_data = (caddr_t)rt;
                   3258:                        mb.m_len = sizeof(sc->sc_txtapu);
                   3259:                        mb.m_next = m0;
                   3260:                        mb.m_nextpkt = NULL;
                   3261:                        mb.m_type = 0;
                   3262:                        mb.m_flags = 0;
                   3263:                        bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
                   3264:
                   3265:                }
                   3266: #endif /* NPBFILTER > 0 */
                   3267:
                   3268:                for (i = 0, lastdesc = desc = ts->ts_first;
                   3269:                     i < dmamap->dm_nsegs;
                   3270:                     i++, desc = RTW_NEXT_IDX(tdb, desc)) {
                   3271:                        if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
                   3272:                                DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
                   3273:                                    ("%s: seg too long\n", __func__));
                   3274:                                goto post_load_err;
                   3275:                        }
                   3276:                        td = &tdb->tdb_desc[desc];
                   3277:                        td->td_ctl0 = htole32(ctl0);
                   3278:                        if (i != 0)
                   3279:                                td->td_ctl0 |= htole32(RTW_TXCTL0_OWN);
                   3280:                        td->td_ctl1 = htole32(ctl1);
                   3281:                        td->td_buf = htole32(dmamap->dm_segs[i].ds_addr);
                   3282:                        td->td_len = htole32(dmamap->dm_segs[i].ds_len);
                   3283:                        lastdesc = desc;
                   3284: #ifdef RTW_DEBUG
                   3285:                        rtw_print_txdesc(sc, "load", ts, tdb, desc);
                   3286: #endif /* RTW_DEBUG */
                   3287:                }
                   3288:
                   3289:                KASSERT(desc < tdb->tdb_ndesc);
                   3290:
                   3291:                ts->ts_ni = ni;
                   3292:                ts->ts_mbuf = m0;
                   3293:                ts->ts_last = lastdesc;
                   3294:                tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS);
                   3295:                tdb->tdb_desc[ts->ts_first].td_ctl0 |=
                   3296:                    htole32(RTW_TXCTL0_FS);
                   3297:
                   3298: #ifdef RTW_DEBUG
                   3299:                rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first);
                   3300:                rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last);
                   3301: #endif /* RTW_DEBUG */
                   3302:
                   3303:                tdb->tdb_nfree -= dmamap->dm_nsegs;
                   3304:                tdb->tdb_next = desc;
                   3305:
                   3306:                rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
                   3307:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   3308:
                   3309:                tdb->tdb_desc[ts->ts_first].td_ctl0 |=
                   3310:                    htole32(RTW_TXCTL0_OWN);
                   3311:
                   3312: #ifdef RTW_DEBUG
                   3313:                rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first);
                   3314: #endif /* RTW_DEBUG */
                   3315:
                   3316:                rtw_txdescs_sync(tdb, ts->ts_first, 1,
                   3317:                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
                   3318:
                   3319:                SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q);
                   3320:                SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q);
                   3321:
                   3322:                if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN])
                   3323:                        sc->sc_led_state.ls_event |= RTW_LED_S_TX;
                   3324:                tsb->tsb_tx_timer = 5;
                   3325:                ifp->if_timer = 1;
                   3326:                tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
                   3327:                tppoll &= ~RTW_TPPOLL_SALL;
                   3328:                tppoll |= tsb->tsb_poll & RTW_TPPOLL_ALL;
                   3329:                RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll);
                   3330:                RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
                   3331:        }
                   3332: out:
                   3333:        DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
                   3334:        return;
                   3335: post_load_err:
                   3336:        bus_dmamap_unload(sc->sc_dmat, dmamap);
                   3337:        m_freem(m0);
                   3338: post_dequeue_err:
                   3339:        ieee80211_release_node(&sc->sc_ic, ni);
                   3340:        return;
                   3341: }
                   3342:
                   3343: void
                   3344: rtw_idle(struct rtw_regs *regs)
                   3345: {
                   3346:        int active;
                   3347:
                   3348:        /* request stop DMA; wait for packets to stop transmitting. */
                   3349:
                   3350:        RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
                   3351:        RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL);
                   3352:
                   3353:        for (active = 0; active < 300 &&
                   3354:             (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0; active++)
                   3355:                DELAY(10);
                   3356:        RTW_DPRINTF(RTW_DEBUG_BUGS,
                   3357:            ("%s: transmit DMA idle in %dus\n", __func__, active * 10));
                   3358: }
                   3359:
                   3360: void
                   3361: rtw_watchdog(struct ifnet *ifp)
                   3362: {
                   3363:        int pri, tx_timeouts = 0;
                   3364:        struct rtw_softc *sc;
                   3365:        struct rtw_txsoft_blk *tsb;
                   3366:
                   3367:        sc = ifp->if_softc;
                   3368:
                   3369:        ifp->if_timer = 0;
                   3370:
                   3371:        if ((sc->sc_flags & RTW_F_ENABLED) == 0)
                   3372:                return;
                   3373:
                   3374:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   3375:                tsb = &sc->sc_txsoft_blk[pri];
                   3376:
                   3377:                if (tsb->tsb_tx_timer == 0)
                   3378:                        continue;
                   3379:                else if (--tsb->tsb_tx_timer == 0) {
                   3380:                        if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
                   3381:                                continue;
                   3382:                        RTW_DPRINTF(RTW_DEBUG_BUGS,
                   3383:                            ("%s: transmit timeout, priority %d\n",
                   3384:                            ifp->if_xname, pri));
                   3385:                        ifp->if_oerrors++;
                   3386:                        tx_timeouts++;
                   3387:                } else
                   3388:                        ifp->if_timer = 1;
                   3389:        }
                   3390:
                   3391:        if (tx_timeouts > 0) {
                   3392:                /* Stop Tx DMA, disable xmtr, flush Tx rings, enable xmtr,
                   3393:                 * reset s/w tx-ring pointers, and start transmission.
                   3394:                 *
                   3395:                 * TBD Stop/restart just the broken rings?
                   3396:                 */
                   3397:                rtw_idle(&sc->sc_regs);
                   3398:                rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0);
                   3399:                rtw_txdescs_reset(sc);
                   3400:                rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1);
                   3401:                rtw_txring_fixup(sc);
                   3402:                rtw_start(ifp);
                   3403:        }
                   3404:        ieee80211_watchdog(ifp);
                   3405: }
                   3406:
                   3407: void
                   3408: rtw_next_scan(void *arg)
                   3409: {
                   3410:        struct rtw_softc *sc = arg;
                   3411:        struct ieee80211com *ic = &sc->sc_ic;
                   3412:        struct ifnet *ifp = &ic->ic_if;
                   3413:        int s;
                   3414:
                   3415:        /* don't call rtw_start w/o network interrupts blocked */
                   3416:        s = splnet();
                   3417:        if (ic->ic_state == IEEE80211_S_SCAN)
                   3418:                ieee80211_next_scan(ifp);
                   3419:        splx(s);
                   3420: }
                   3421:
                   3422: void
                   3423: rtw_join_bss(struct rtw_softc *sc, u_int8_t *bssid, u_int16_t intval0)
                   3424: {
                   3425:        uint16_t bcnitv, bintritv, intval;
                   3426:        int i;
                   3427:        struct rtw_regs *regs = &sc->sc_regs;
                   3428:
                   3429:        for (i = 0; i < IEEE80211_ADDR_LEN; i++)
                   3430:                RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
                   3431:
                   3432:        RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
                   3433:
                   3434:        rtw_set_access(regs, RTW_ACCESS_CONFIG);
                   3435:
                   3436:        intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK));
                   3437:
                   3438:        bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
                   3439:        bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK);
                   3440:        RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
                   3441:        /* interrupt host 1ms before the TBTT */
                   3442:        bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV;
                   3443:        bintritv |= LSHIFT(1000, RTW_BINTRITV_BINTRITV);
                   3444:        RTW_WRITE16(regs, RTW_BINTRITV, bintritv);
                   3445:        /* magic from Linux */
                   3446:        RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND));
                   3447:        RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV));
                   3448:        rtw_set_access(regs, RTW_ACCESS_NONE);
                   3449:
                   3450:        /* TBD WEP */
                   3451:        RTW_WRITE8(regs, RTW8180_SCR, 0);
                   3452:
                   3453:        rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
                   3454: }
                   3455:
                   3456: /* Synchronize the hardware state with the software state. */
                   3457: int
                   3458: rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                   3459: {
                   3460:        struct ifnet *ifp = &ic->ic_if;
                   3461:        struct rtw_softc *sc = ifp->if_softc;
                   3462:        enum ieee80211_state ostate;
                   3463:        int error;
                   3464:
                   3465:        ostate = ic->ic_state;
                   3466:
                   3467:        rtw_led_newstate(sc, nstate);
                   3468:
                   3469:        if (nstate == IEEE80211_S_INIT) {
                   3470:                timeout_del(&sc->sc_scan_to);
                   3471:                sc->sc_cur_chan = IEEE80211_CHAN_ANY;
                   3472:                return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
                   3473:        }
                   3474:
                   3475:        if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
                   3476:                rtw_pwrstate(sc, RTW_ON);
                   3477:
                   3478:        if ((error = rtw_tune(sc)) != 0)
                   3479:                return error;
                   3480:
                   3481:        switch (nstate) {
                   3482:        case IEEE80211_S_INIT:
                   3483:                panic("%s: unexpected state IEEE80211_S_INIT", __func__);
                   3484:                break;
                   3485:        case IEEE80211_S_SCAN:
                   3486:                if (ostate != IEEE80211_S_SCAN) {
                   3487:                        bzero(ic->ic_bss->ni_bssid, IEEE80211_ADDR_LEN);
                   3488:                        rtw_set_nettype(sc, IEEE80211_M_MONITOR);
                   3489:                }
                   3490:
                   3491:                timeout_add(&sc->sc_scan_to, rtw_dwelltime * hz / 1000);
                   3492:
                   3493:                break;
                   3494:        case IEEE80211_S_RUN:
                   3495:                switch (ic->ic_opmode) {
                   3496:                case IEEE80211_M_HOSTAP:
                   3497:                case IEEE80211_M_IBSS:
                   3498:                        rtw_set_nettype(sc, IEEE80211_M_MONITOR);
                   3499:                        /*FALLTHROUGH*/
                   3500:                case IEEE80211_M_AHDEMO:
                   3501:                case IEEE80211_M_STA:
                   3502:                        rtw_join_bss(sc, ic->ic_bss->ni_bssid,
                   3503:                            ic->ic_bss->ni_intval);
                   3504:                        break;
                   3505:                case IEEE80211_M_MONITOR:
                   3506:                        break;
                   3507:                }
                   3508:                rtw_set_nettype(sc, ic->ic_opmode);
                   3509:                break;
                   3510:        case IEEE80211_S_ASSOC:
                   3511:        case IEEE80211_S_AUTH:
                   3512:                break;
                   3513:        }
                   3514:
                   3515:        if (nstate != IEEE80211_S_SCAN)
                   3516:                timeout_del(&sc->sc_scan_to);
                   3517:
                   3518:        return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
                   3519: }
                   3520:
                   3521: /* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */
                   3522: uint64_t
                   3523: rtw_tsf_extend(struct rtw_regs *regs, u_int32_t rstamp)
                   3524: {
                   3525:        u_int32_t tsftl, tsfth;
                   3526:
                   3527:        tsfth = RTW_READ(regs, RTW_TSFTRH);
                   3528:        tsftl = RTW_READ(regs, RTW_TSFTRL);
                   3529:        if (tsftl < rstamp)     /* Compensate for rollover. */
                   3530:                tsfth--;
                   3531:        return ((u_int64_t)tsfth << 32) | rstamp;
                   3532: }
                   3533:
                   3534: void
                   3535: rtw_ibss_merge(struct rtw_softc *sc, struct ieee80211_node *ni,
                   3536:     u_int32_t rstamp)
                   3537: {
                   3538:        u_int8_t tppoll;
                   3539:        struct ieee80211com *ic = &sc->sc_ic;
                   3540:
                   3541:        if (ieee80211_ibss_merge(ic, ni,
                   3542:            rtw_tsf_extend(&sc->sc_regs, rstamp)) == ENETRESET) {
                   3543:                /* Stop beacon queue.  Kick state machine to synchronize
                   3544:                 * with the new IBSS.
                   3545:                 */
                   3546:                tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
                   3547:                tppoll |= RTW_TPPOLL_SBQ;
                   3548:                RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll);
                   3549:                (void)ieee80211_new_state(&sc->sc_ic, IEEE80211_S_RUN, -1);
                   3550:        }
                   3551:        return;
                   3552: }
                   3553:
                   3554: void
                   3555: rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
                   3556:     struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
                   3557: {
                   3558:        struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc;
                   3559:
                   3560:        (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
                   3561:
                   3562:        switch (subtype) {
                   3563:        case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
                   3564:        case IEEE80211_FC0_SUBTYPE_BEACON:
                   3565:                if (ic->ic_opmode != IEEE80211_M_IBSS ||
                   3566:                    ic->ic_state != IEEE80211_S_RUN)
                   3567:                        return;
                   3568:                rtw_ibss_merge(sc, ni, rstamp);
                   3569:                break;
                   3570:        default:
                   3571:                break;
                   3572:        }
                   3573:        return;
                   3574: }
                   3575:
                   3576: struct ieee80211_node *
                   3577: rtw_node_alloc(struct ieee80211com *ic)
                   3578: {
                   3579:        struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
                   3580:        struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic);
                   3581:
                   3582:        DPRINTF(sc, RTW_DEBUG_NODE,
                   3583:            ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
                   3584:        return ni;
                   3585: }
                   3586:
                   3587: void
                   3588: rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
                   3589: {
                   3590:        struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
                   3591:
                   3592:        DPRINTF(sc, RTW_DEBUG_NODE,
                   3593:            ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
                   3594:            ether_sprintf(ni->ni_bssid)));
                   3595:        (*sc->sc_mtbl.mt_node_free)(ic, ni);
                   3596: }
                   3597:
                   3598: int
                   3599: rtw_media_change(struct ifnet *ifp)
                   3600: {
                   3601:        int error;
                   3602:
                   3603:        error = ieee80211_media_change(ifp);
                   3604:        if (error == ENETRESET) {
                   3605:                if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
                   3606:                    (IFF_RUNNING|IFF_UP))
                   3607:                        rtw_init(ifp);          /* XXX lose error */
                   3608:                error = 0;
                   3609:        }
                   3610:        return error;
                   3611: }
                   3612:
                   3613: void
                   3614: rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
                   3615: {
                   3616:        struct rtw_softc *sc = ifp->if_softc;
                   3617:
                   3618:        if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
                   3619:                imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
                   3620:                imr->ifm_status = 0;
                   3621:                return;
                   3622:        }
                   3623:        ieee80211_media_status(ifp, imr);
                   3624: }
                   3625:
                   3626: void
                   3627: rtw_power(int why, void *arg)
                   3628: {
                   3629:        struct rtw_softc *sc = arg;
                   3630:        struct ifnet *ifp = &sc->sc_ic.ic_if;
                   3631:        int s;
                   3632:
                   3633:        DPRINTF(sc, RTW_DEBUG_PWR,
                   3634:            ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why));
                   3635:
                   3636:        s = splnet();
                   3637:        switch (why) {
                   3638:        case PWR_STANDBY:
                   3639:                /* XXX do nothing. */
                   3640:                break;
                   3641:        case PWR_SUSPEND:
                   3642:                rtw_stop(ifp, 1);
                   3643:                if (sc->sc_power != NULL)
                   3644:                        (*sc->sc_power)(sc, why);
                   3645:                break;
                   3646:        case PWR_RESUME:
                   3647:                if (ifp->if_flags & IFF_UP) {
                   3648:                        if (sc->sc_power != NULL)
                   3649:                                (*sc->sc_power)(sc, why);
                   3650:                        rtw_init(ifp);
                   3651:                }
                   3652:                break;
                   3653:        }
                   3654:        splx(s);
                   3655: }
                   3656:
                   3657: /* rtw_shutdown: make sure the interface is stopped at reboot time. */
                   3658: void
                   3659: rtw_shutdown(void *arg)
                   3660: {
                   3661:        struct rtw_softc *sc = arg;
                   3662:
                   3663:        rtw_stop(&sc->sc_ic.ic_if, 1);
                   3664: }
                   3665:
                   3666: void
                   3667: rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname,
                   3668:     void *arg)
                   3669: {
                   3670:        /*
                   3671:         * Make sure the interface is shutdown during reboot.
                   3672:         */
                   3673:        hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg);
                   3674:        if (hooks->rh_shutdown == NULL)
                   3675:                printf("%s: WARNING: unable to establish shutdown hook\n",
                   3676:                    dvname);
                   3677:
                   3678:        /*
                   3679:         * Add a suspend hook to make sure we come back up after a
                   3680:         * resume.
                   3681:         */
                   3682:        hooks->rh_power = powerhook_establish(rtw_power, arg);
                   3683:        if (hooks->rh_power == NULL)
                   3684:                printf("%s: WARNING: unable to establish power hook\n",
                   3685:                    dvname);
                   3686: }
                   3687:
                   3688: void
                   3689: rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
                   3690:     void *arg)
                   3691: {
                   3692:        if (hooks->rh_shutdown != NULL)
                   3693:                shutdownhook_disestablish(hooks->rh_shutdown);
                   3694:
                   3695:        if (hooks->rh_power != NULL)
                   3696:                powerhook_disestablish(hooks->rh_power);
                   3697: }
                   3698:
                   3699: int
                   3700: rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen)
                   3701: {
                   3702:        SIMPLEQ_INIT(&tsb->tsb_dirtyq);
                   3703:        SIMPLEQ_INIT(&tsb->tsb_freeq);
                   3704:        tsb->tsb_ndesc = qlen;
                   3705:        tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF,
                   3706:            M_NOWAIT);
                   3707:        if (tsb->tsb_desc == NULL)
                   3708:                return ENOMEM;
                   3709:        return 0;
                   3710: }
                   3711:
                   3712: void
                   3713: rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc)
                   3714: {
                   3715:        int pri;
                   3716:        struct rtw_txsoft_blk *tsb;
                   3717:
                   3718:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   3719:                tsb = &sc->sc_txsoft_blk[pri];
                   3720:                free(tsb->tsb_desc, M_DEVBUF);
                   3721:                tsb->tsb_desc = NULL;
                   3722:        }
                   3723: }
                   3724:
                   3725: int
                   3726: rtw_txsoft_blk_setup_all(struct rtw_softc *sc)
                   3727: {
                   3728:        int pri, rc = 0;
                   3729:        int qlen[RTW_NTXPRI] =
                   3730:             {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
                   3731:        struct rtw_txsoft_blk *tsbs;
                   3732:
                   3733:        tsbs = sc->sc_txsoft_blk;
                   3734:
                   3735:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   3736:                rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]);
                   3737:                if (rc != 0)
                   3738:                        break;
                   3739:        }
                   3740:        tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ;
                   3741:        tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ;
                   3742:        tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ;
                   3743:        tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ;
                   3744:        return rc;
                   3745: }
                   3746:
                   3747: void
                   3748: rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc,
                   3749:     u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
                   3750: {
                   3751:        tdb->tdb_ndesc = ndesc;
                   3752:        tdb->tdb_desc = desc;
                   3753:        tdb->tdb_physbase = physbase;
                   3754:        tdb->tdb_ofs = ofs;
                   3755:
                   3756:        bzero(tdb->tdb_desc, sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
                   3757:
                   3758:        rtw_txdesc_blk_init(tdb);
                   3759:        tdb->tdb_next = 0;
                   3760: }
                   3761:
                   3762: void
                   3763: rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
                   3764: {
                   3765:        rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
                   3766:            &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
                   3767:            RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
                   3768:
                   3769:        rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
                   3770:            &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
                   3771:            RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
                   3772:
                   3773:        rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
                   3774:            &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
                   3775:            RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
                   3776:
                   3777:        rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
                   3778:            &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
                   3779:            RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
                   3780: }
                   3781:
                   3782: int
                   3783: rtw_rf_attach(struct rtw_softc *sc, int rfchipid)
                   3784: {
                   3785:        struct rtw_bbpset *bb = &sc->sc_bbpset;
                   3786:        int notsup = 0;
                   3787:        const char *rfname, *paname = NULL;
                   3788:        char scratch[sizeof("unknown 0xXX")];
                   3789:
                   3790:        switch (rfchipid) {
                   3791:        case RTW_RFCHIPID_RTL8225:
                   3792:                rfname = "RTL8225";
                   3793:                sc->sc_pwrstate_cb = rtw_rtl_pwrstate;
                   3794:                sc->sc_rf_init = rtw_rtl8255_init;
                   3795:                sc->sc_rf_pwrstate = rtw_rtl8225_pwrstate;
                   3796:                sc->sc_rf_tune = rtw_rtl8225_tune;
                   3797:                sc->sc_rf_txpower = rtw_rtl8225_txpower;
                   3798:                break;
                   3799:        case RTW_RFCHIPID_RTL8255:
                   3800:                rfname = "RTL8255";
                   3801:                sc->sc_pwrstate_cb = rtw_rtl_pwrstate;
                   3802:                sc->sc_rf_init = rtw_rtl8255_init;
                   3803:                sc->sc_rf_pwrstate = rtw_rtl8255_pwrstate;
                   3804:                sc->sc_rf_tune = rtw_rtl8255_tune;
                   3805:                sc->sc_rf_txpower = rtw_rtl8255_txpower;
                   3806:                break;
                   3807:        case RTW_RFCHIPID_MAXIM2820:
                   3808:                rfname = "MAX2820";     /* guess */
                   3809:                paname = "MAX2422";     /* guess */
                   3810:                /* XXX magic */
                   3811:                bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC;
                   3812:                bb->bb_chestlim =       0x00;
                   3813:                bb->bb_chsqlim =        0x9f;
                   3814:                bb->bb_ifagcdet =       0x64;
                   3815:                bb->bb_ifagcini =       0x90;
                   3816:                bb->bb_ifagclimit =     0x1a;
                   3817:                bb->bb_lnadet =         0xf8;
                   3818:                bb->bb_sys1 =           0x88;
                   3819:                bb->bb_sys2 =           0x47;
                   3820:                bb->bb_sys3 =           0x9b;
                   3821:                bb->bb_trl =            0x88;
                   3822:                bb->bb_txagc =          0x08;
                   3823:                sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
                   3824:                sc->sc_rf_init = rtw_max2820_init;
                   3825:                sc->sc_rf_pwrstate = rtw_max2820_pwrstate;
                   3826:                sc->sc_rf_tune = rtw_max2820_tune;
                   3827:                sc->sc_rf_txpower = rtw_max2820_txpower;
                   3828:                break;
                   3829:        case RTW_RFCHIPID_PHILIPS:
                   3830:                rfname = "SA2400A";
                   3831:                paname = "SA2411";
                   3832:                /* XXX magic */
                   3833:                bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC;
                   3834:                bb->bb_chestlim =       0x00;
                   3835:                bb->bb_chsqlim =        0xa0;
                   3836:                bb->bb_ifagcdet =       0x64;
                   3837:                bb->bb_ifagcini =       0x90;
                   3838:                bb->bb_ifagclimit =     0x1a;
                   3839:                bb->bb_lnadet =         0xe0;
                   3840:                bb->bb_sys1 =           0x98;
                   3841:                bb->bb_sys2 =           0x47;
                   3842:                bb->bb_sys3 =           0x90;
                   3843:                bb->bb_trl =            0x88;
                   3844:                bb->bb_txagc =          0x38;
                   3845:                sc->sc_pwrstate_cb = rtw_philips_pwrstate;
                   3846:                sc->sc_rf_init = rtw_sa2400_init;
                   3847:                sc->sc_rf_pwrstate = rtw_sa2400_pwrstate;
                   3848:                sc->sc_rf_tune = rtw_sa2400_tune;
                   3849:                sc->sc_rf_txpower = rtw_sa2400_txpower;
                   3850:                break;
                   3851:        case RTW_RFCHIPID_RFMD2948:
                   3852:                /* this is the same front-end as an atw(4)! */
                   3853:                rfname = "RFMD RF2948B, "       /* mentioned in Realtek docs */
                   3854:                         "LNA: RFMD RF2494, "   /* mentioned in Realtek docs */
                   3855:                         "SYN: Silicon Labs Si4126";     /* inferred from
                   3856:                                                          * reference driver
                   3857:                                                          */
                   3858:                paname = "RF2189";              /* mentioned in Realtek docs */
                   3859:                /* XXX RFMD has no RF constructor */
                   3860:                sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
                   3861:                notsup =  1;
                   3862:                break;
                   3863:        case RTW_RFCHIPID_GCT:          /* this combo seen in the wild */
                   3864:                rfname = "GRF5101";
                   3865:                paname = "WS9901";
                   3866:                /* XXX magic */
                   3867:                bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC;
                   3868:                bb->bb_chestlim =       0x00;
                   3869:                bb->bb_chsqlim =        0xa0;
                   3870:                bb->bb_ifagcdet =       0x64;
                   3871:                bb->bb_ifagcini =       0x90;
                   3872:                bb->bb_ifagclimit =     0x1e;
                   3873:                bb->bb_lnadet =         0xc0;
                   3874:                bb->bb_sys1 =           0xa8;
                   3875:                bb->bb_sys2 =           0x47;
                   3876:                bb->bb_sys3 =           0x9b;
                   3877:                bb->bb_trl =            0x88;
                   3878:                bb->bb_txagc =          0x08;
                   3879:                sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
                   3880:                sc->sc_rf_init = rtw_grf5101_init;
                   3881:                sc->sc_rf_pwrstate = rtw_grf5101_pwrstate;
                   3882:                sc->sc_rf_tune = rtw_grf5101_tune;
                   3883:                sc->sc_rf_txpower = rtw_grf5101_txpower;
                   3884:                break;
                   3885:        case RTW_RFCHIPID_INTERSIL:
                   3886:                rfname = "HFA3873";     /* guess */
                   3887:                paname = "Intersil <unknown>";
                   3888:                notsup = 1;
                   3889:                break;
                   3890:        default:
                   3891:                snprintf(scratch, sizeof(scratch), "unknown 0x%02x", rfchipid);
                   3892:                rfname = scratch;
                   3893:                notsup = 1;
                   3894:        }
                   3895:
                   3896:        printf("radio %s, ", rfname);
                   3897:        if (paname != NULL)
                   3898:                printf("amp %s, ", paname);
                   3899:
                   3900:        return (notsup);
                   3901: }
                   3902:
                   3903: /* Revision C and later use a different PHY delay setting than
                   3904:  * revisions A and B.
                   3905:  */
                   3906: u_int8_t
                   3907: rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0)
                   3908: {
                   3909: #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
                   3910: #define REVC (REVAB | RTW8180_RCR_RXFTH_WHOLE)
                   3911:
                   3912:        u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
                   3913:
                   3914:        RTW_WRITE(regs, RTW_RCR, REVAB);
                   3915:        RTW_WBW(regs, RTW_RCR, RTW_RCR);
                   3916:        RTW_WRITE(regs, RTW_RCR, REVC);
                   3917:
                   3918:        RTW_WBR(regs, RTW_RCR, RTW_RCR);
                   3919:        if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
                   3920:                phydelay |= RTW_PHYDELAY_REVC_MAGIC;
                   3921:
                   3922:        RTW_WRITE(regs, RTW_RCR, rcr0); /* restore RCR */
                   3923:        RTW_SYNC(regs, RTW_RCR, RTW_RCR);
                   3924:
                   3925:        return phydelay;
                   3926: #undef REVC
                   3927: }
                   3928:
                   3929: void
                   3930: rtw_attach(struct rtw_softc *sc)
                   3931: {
                   3932:        struct ieee80211com *ic = &sc->sc_ic;
                   3933:        struct rtw_txsoft_blk *tsb;
                   3934:        struct rtw_mtbl *mtbl;
                   3935:        struct rtw_srom *sr;
                   3936:        const char *vername;
                   3937:        struct ifnet *ifp;
                   3938:        char scratch[sizeof("unknown 0xXXXXXXXX")];
                   3939:        int pri, rc;
                   3940:
                   3941:
                   3942:        /* Use default DMA memory access */
                   3943:        if (sc->sc_regs.r_read8 == NULL) {
                   3944:                sc->sc_regs.r_read8 = rtw_read8;
                   3945:                sc->sc_regs.r_read16 = rtw_read16;
                   3946:                sc->sc_regs.r_read32 = rtw_read32;
                   3947:                sc->sc_regs.r_write8 = rtw_write8;
                   3948:                sc->sc_regs.r_write16 = rtw_write16;
                   3949:                sc->sc_regs.r_write32 = rtw_write32;
                   3950:                sc->sc_regs.r_barrier = rtw_barrier;
                   3951:        }
                   3952:
                   3953:        sc->sc_hwverid = RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK;
                   3954:        switch (sc->sc_hwverid) {
                   3955:        case RTW_TCR_HWVERID_RTL8185:
                   3956:                vername = "RTL8185";
                   3957:                sc->sc_flags |= RTW_F_RTL8185;
                   3958:                break;
                   3959:        case RTW_TCR_HWVERID_RTL8180F:
                   3960:                vername = "RTL8180F";
                   3961:                break;
                   3962:        case RTW_TCR_HWVERID_RTL8180D:
                   3963:                vername = "RTL8180D";
                   3964:                break;
                   3965:        default:
                   3966:                snprintf(scratch, sizeof(scratch), "unknown 0x%08x",
                   3967:                    sc->sc_hwverid);
                   3968:                vername = scratch;
                   3969:                break;
                   3970:        }
                   3971:
                   3972:        printf("%s: ver %s, ", sc->sc_dev.dv_xname, vername);
                   3973:
                   3974:        rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
                   3975:            RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
                   3976:            0);
                   3977:
                   3978:        if (rc != 0) {
                   3979:                printf("\n%s: could not allocate hw descriptors, error %d\n",
                   3980:                     sc->sc_dev.dv_xname, rc);
                   3981:                goto fail0;
                   3982:        }
                   3983:
                   3984:        rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
                   3985:            sc->sc_desc_nsegs, sizeof(struct rtw_descs),
                   3986:            (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT);
                   3987:
                   3988:        if (rc != 0) {
                   3989:                printf("\n%s: could not map hw descriptors, error %d\n",
                   3990:                    sc->sc_dev.dv_xname, rc);
                   3991:                goto fail1;
                   3992:        }
                   3993:
                   3994:        rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
                   3995:            sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
                   3996:
                   3997:        if (rc != 0) {
                   3998:                printf("\n%s: could not create DMA map for hw descriptors, "
                   3999:                    "error %d\n", sc->sc_dev.dv_xname, rc);
                   4000:                goto fail2;
                   4001:        }
                   4002:
                   4003:        sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat;
                   4004:        sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap;
                   4005:
                   4006:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   4007:                sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat;
                   4008:                sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap;
                   4009:        }
                   4010:
                   4011:        rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
                   4012:            sizeof(struct rtw_descs), NULL, 0);
                   4013:
                   4014:        if (rc != 0) {
                   4015:                printf("\n%s: could not load DMA map for hw descriptors, "
                   4016:                    "error %d\n", sc->sc_dev.dv_xname, rc);
                   4017:                goto fail3;
                   4018:        }
                   4019:
                   4020:        if (rtw_txsoft_blk_setup_all(sc) != 0)
                   4021:                goto fail4;
                   4022:
                   4023:        rtw_txdesc_blk_setup_all(sc);
                   4024:
                   4025:        sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0];
                   4026:
                   4027:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   4028:                tsb = &sc->sc_txsoft_blk[pri];
                   4029:
                   4030:                if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
                   4031:                    &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) {
                   4032:                        printf("\n%s: could not load DMA map for "
                   4033:                            "hw tx descriptors, error %d\n",
                   4034:                            sc->sc_dev.dv_xname, rc);
                   4035:                        goto fail5;
                   4036:                }
                   4037:        }
                   4038:
                   4039:        if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0],
                   4040:            RTW_RXQLEN)) != 0) {
                   4041:                printf("\n%s: could not load DMA map for hw rx descriptors, "
                   4042:                    "error %d\n", sc->sc_dev.dv_xname, rc);
                   4043:                goto fail6;
                   4044:        }
                   4045:
                   4046:        /* Reset the chip to a known state. */
                   4047:        if (rtw_reset(sc) != 0)
                   4048:                goto fail7;
                   4049:
                   4050:        sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
                   4051:
                   4052:        if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
                   4053:                sc->sc_flags |= RTW_F_9356SROM;
                   4054:
                   4055:        if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
                   4056:            sc->sc_dev.dv_xname) != 0)
                   4057:                goto fail7;
                   4058:
                   4059:        if (rtw_srom_parse(sc) != 0) {
                   4060:                printf("\n%s: attach failed, malformed serial ROM\n",
                   4061:                    sc->sc_dev.dv_xname);
                   4062:                goto fail8;
                   4063:        }
                   4064:
                   4065:        RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: %s PHY\n", sc->sc_dev.dv_xname,
                   4066:            ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"));
                   4067:
                   4068:        RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: CS threshold %u\n",
                   4069:            sc->sc_dev.dv_xname, sc->sc_csthr));
                   4070:
                   4071:        if ((rtw_rf_attach(sc, sc->sc_rfchipid)) != 0) {
                   4072:                printf("\n%s: attach failed, could not attach RF\n",
                   4073:                    sc->sc_dev.dv_xname);
                   4074:                goto fail8;
                   4075:        }
                   4076:
                   4077:        sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
                   4078:
                   4079:        RTW_DPRINTF(RTW_DEBUG_ATTACH,
                   4080:            ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay));
                   4081:
                   4082:        if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
                   4083:                rtw_identify_country(&sc->sc_regs, &sc->sc_locale);
                   4084:
                   4085:        rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels,
                   4086:            sc->sc_dev.dv_xname);
                   4087:
                   4088:        if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
                   4089:            sc->sc_dev.dv_xname) != 0)
                   4090:                goto fail8;
                   4091:
                   4092:        ifp = &sc->sc_if;
                   4093:        (void)memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
                   4094:        ifp->if_softc = sc;
                   4095:        ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
                   4096:            IFF_NOTRAILERS;
                   4097:        ifp->if_ioctl = rtw_ioctl;
                   4098:        ifp->if_start = rtw_start;
                   4099:        ifp->if_watchdog = rtw_watchdog;
                   4100:
                   4101:        IFQ_SET_READY(&sc->sc_if.if_snd);
                   4102:
                   4103:        ic->ic_phytype = IEEE80211_T_DS;
                   4104:        ic->ic_opmode = IEEE80211_M_STA;
                   4105:        ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
                   4106:            IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
                   4107:
                   4108:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                   4109:
                   4110:        rtw_led_attach(&sc->sc_led_state, (void *)sc);
                   4111:
                   4112:        /*
                   4113:         * Call MI attach routines.
                   4114:         */
                   4115:        if_attach(&sc->sc_if);
                   4116:        ieee80211_ifattach(&sc->sc_if);
                   4117:
                   4118:        mtbl = &sc->sc_mtbl;
                   4119:        mtbl->mt_newstate = ic->ic_newstate;
                   4120:        ic->ic_newstate = rtw_newstate;
                   4121:
                   4122:        mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
                   4123:        ic->ic_recv_mgmt = rtw_recv_mgmt;
                   4124:
                   4125:        mtbl->mt_node_free = ic->ic_node_free;
                   4126:        ic->ic_node_free = rtw_node_free;
                   4127:
                   4128:        mtbl->mt_node_alloc = ic->ic_node_alloc;
                   4129:        ic->ic_node_alloc = rtw_node_alloc;
                   4130:
                   4131:        /* possibly we should fill in our own sc_send_prresp, since
                   4132:         * the RTL8180 is probably sending probe responses in ad hoc
                   4133:         * mode.
                   4134:         */
                   4135:
                   4136:        /* complete initialization */
                   4137:        ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status);
                   4138:        timeout_set(&sc->sc_scan_to, rtw_next_scan, sc);
                   4139:
                   4140: #if NBPFILTER > 0
                   4141:        bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu));
                   4142:        sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
                   4143:        sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT;
                   4144:
                   4145:        bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu));
                   4146:        sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
                   4147:        sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT;
                   4148:
                   4149:        bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
                   4150:            sizeof(struct ieee80211_frame) + 64);
                   4151: #endif
                   4152:
                   4153:        rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc);
                   4154:
                   4155:        return;
                   4156:
                   4157: fail8:
                   4158:        sr = &sc->sc_srom;
                   4159:        sr->sr_size = 0;
                   4160:        if (sr->sr_content != NULL) {
                   4161:                free(sr->sr_content, M_DEVBUF);
                   4162:                sr->sr_content = NULL;
                   4163:        }
                   4164:
                   4165: fail7:
                   4166:        rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0],
                   4167:            RTW_RXQLEN);
                   4168:
                   4169: fail6:
                   4170:        for (pri = 0; pri < RTW_NTXPRI; pri++) {
                   4171:                rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
                   4172:                    sc->sc_txsoft_blk[pri].tsb_desc,
                   4173:                    sc->sc_txsoft_blk[pri].tsb_ndesc);
                   4174:        }
                   4175:
                   4176: fail5:
                   4177:        rtw_txsoft_blk_cleanup_all(sc);
                   4178:
                   4179: fail4:
                   4180:        bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
                   4181: fail3:
                   4182:        bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
                   4183: fail2:
                   4184:        bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs,
                   4185:            sizeof(struct rtw_descs));
                   4186: fail1:
                   4187:        bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
                   4188:            sc->sc_desc_nsegs);
                   4189: fail0:
                   4190:        return;
                   4191: }
                   4192:
                   4193: int
                   4194: rtw_detach(struct rtw_softc *sc)
                   4195: {
                   4196:        sc->sc_flags |= RTW_F_INVALID;
                   4197:
                   4198:        rtw_stop(&sc->sc_if, 1);
                   4199:
                   4200:        rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname,
                   4201:            (void*)sc);
                   4202:        timeout_del(&sc->sc_scan_to);
                   4203:        ieee80211_ifdetach(&sc->sc_if);
                   4204:        if_detach(&sc->sc_if);
                   4205:
                   4206:        return 0;
                   4207: }
                   4208:
                   4209: /*
                   4210:  * PHY specific functions
                   4211:  */
                   4212:
                   4213: int
                   4214: rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb,
                   4215:     u_int freq)
                   4216: {
                   4217:        u_int antatten = antatten0;
                   4218:        if (dflantb)
                   4219:                antatten |= RTW_BBP_ANTATTEN_DFLANTB;
                   4220:        if (freq == 2484) /* channel 14 */
                   4221:                antatten |= RTW_BBP_ANTATTEN_CHAN14;
                   4222:        return rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten);
                   4223: }
                   4224:
                   4225: int
                   4226: rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv,
                   4227:     int dflantb, u_int8_t cs_threshold, u_int freq)
                   4228: {
                   4229:        int rc;
                   4230:        u_int32_t sys2, sys3;
                   4231:
                   4232:        sys2 = bb->bb_sys2;
                   4233:        if (antdiv)
                   4234:                sys2 |= RTW_BBP_SYS2_ANTDIV;
                   4235:        sys3 = bb->bb_sys3 |
                   4236:            LSHIFT(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK);
                   4237:
                   4238: #define        RTW_BBP_WRITE_OR_RETURN(reg, val) \
                   4239:        if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \
                   4240:                return rc;
                   4241:
                   4242:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1,           bb->bb_sys1);
                   4243:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC,          bb->bb_txagc);
                   4244:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET,         bb->bb_lnadet);
                   4245:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI,       bb->bb_ifagcini);
                   4246:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT,     bb->bb_ifagclimit);
                   4247:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET,       bb->bb_ifagcdet);
                   4248:
                   4249:        if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0)
                   4250:                return rc;
                   4251:
                   4252:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL,            bb->bb_trl);
                   4253:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2,           sys2);
                   4254:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3,           sys3);
                   4255:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM,       bb->bb_chestlim);
                   4256:        RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM,        bb->bb_chsqlim);
                   4257:        return 0;
                   4258: }
                   4259:
                   4260: int
                   4261: rtw_sa2400_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
                   4262: {
                   4263:        return rtw_rf_macwrite(sc, SA2400_TX, opaque_txpower);
                   4264: }
                   4265:
                   4266: /* make sure we're using the same settings as the reference driver */
                   4267: void
                   4268: rtw_verify_syna(u_int freq, u_int32_t val)
                   4269: {
                   4270:        u_int32_t expected_val = ~val;
                   4271:
                   4272:        switch (freq) {
                   4273:        case 2412:
                   4274:                expected_val = 0x0000096c; /* ch 1 */
                   4275:                break;
                   4276:        case 2417:
                   4277:                expected_val = 0x00080970; /* ch 2 */
                   4278:                break;
                   4279:        case 2422:
                   4280:                expected_val = 0x00100974; /* ch 3 */
                   4281:                break;
                   4282:        case 2427:
                   4283:                expected_val = 0x00180978; /* ch 4 */
                   4284:                break;
                   4285:        case 2432:
                   4286:                expected_val = 0x00000980; /* ch 5 */
                   4287:                break;
                   4288:        case 2437:
                   4289:                expected_val = 0x00080984; /* ch 6 */
                   4290:                break;
                   4291:        case 2442:
                   4292:                expected_val = 0x00100988; /* ch 7 */
                   4293:                break;
                   4294:        case 2447:
                   4295:                expected_val = 0x0018098c; /* ch 8 */
                   4296:                break;
                   4297:        case 2452:
                   4298:                expected_val = 0x00000994; /* ch 9 */
                   4299:                break;
                   4300:        case 2457:
                   4301:                expected_val = 0x00080998; /* ch 10 */
                   4302:                break;
                   4303:        case 2462:
                   4304:                expected_val = 0x0010099c; /* ch 11 */
                   4305:                break;
                   4306:        case 2467:
                   4307:                expected_val = 0x001809a0; /* ch 12 */
                   4308:                break;
                   4309:        case 2472:
                   4310:                expected_val = 0x000009a8; /* ch 13 */
                   4311:                break;
                   4312:        case 2484:
                   4313:                expected_val = 0x000009b4; /* ch 14 */
                   4314:                break;
                   4315:        }
                   4316:        KASSERT(val == expected_val);
                   4317: }
                   4318:
                   4319: /* freq is in MHz */
                   4320: int
                   4321: rtw_sa2400_tune(struct rtw_softc *sc, u_int freq)
                   4322: {
                   4323:        int rc;
                   4324:        u_int32_t syna, synb, sync;
                   4325:
                   4326:        /* XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz.
                   4327:         *
                   4328:         * The channel spacing (5MHz) is not divisible by 4MHz, so
                   4329:         * we set the fractional part of N to compensate.
                   4330:         */
                   4331:        int n = freq / 4, nf = (freq % 4) * 2;
                   4332:
                   4333:        syna = LSHIFT(nf, SA2400_SYNA_NF_MASK) | LSHIFT(n, SA2400_SYNA_N_MASK);
                   4334:        rtw_verify_syna(freq, syna);
                   4335:
                   4336:        /* Divide the 44MHz crystal down to 4MHz. Set the fractional
                   4337:         * compensation charge pump value to agree with the fractional
                   4338:         * modulus.
                   4339:         */
                   4340:        synb = LSHIFT(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL |
                   4341:            SA2400_SYNB_ON | SA2400_SYNB_ONE |
                   4342:            LSHIFT(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */
                   4343:
                   4344:        sync = SA2400_SYNC_CP_NORMAL;
                   4345:
                   4346:        if ((rc = rtw_rf_macwrite(sc, SA2400_SYNA, syna)) != 0)
                   4347:                return rc;
                   4348:        if ((rc = rtw_rf_macwrite(sc, SA2400_SYNB, synb)) != 0)
                   4349:                return rc;
                   4350:        if ((rc = rtw_rf_macwrite(sc, SA2400_SYNC, sync)) != 0)
                   4351:                return rc;
                   4352:        return rtw_rf_macwrite(sc, SA2400_SYND, 0x0);
                   4353: }
                   4354:
                   4355: int
                   4356: rtw_sa2400_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
                   4357: {
                   4358:        u_int32_t opmode;
                   4359:        opmode = SA2400_OPMODE_DEFAULTS;
                   4360:        switch (power) {
                   4361:        case RTW_ON:
                   4362:                opmode |= SA2400_OPMODE_MODE_TXRX;
                   4363:                break;
                   4364:        case RTW_SLEEP:
                   4365:                opmode |= SA2400_OPMODE_MODE_WAIT;
                   4366:                break;
                   4367:        case RTW_OFF:
                   4368:                opmode |= SA2400_OPMODE_MODE_SLEEP;
                   4369:                break;
                   4370:        }
                   4371:
                   4372:        if (sc->sc_flags & RTW_F_DIGPHY)
                   4373:                opmode |= SA2400_OPMODE_DIGIN;
                   4374:
                   4375:        return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode);
                   4376: }
                   4377:
                   4378: int
                   4379: rtw_sa2400_vcocal_start(struct rtw_softc *sc, int start)
                   4380: {
                   4381:        u_int32_t opmode;
                   4382:
                   4383:        opmode = SA2400_OPMODE_DEFAULTS;
                   4384:        if (start)
                   4385:                opmode |= SA2400_OPMODE_MODE_VCOCALIB;
                   4386:        else
                   4387:                opmode |= SA2400_OPMODE_MODE_SLEEP;
                   4388:
                   4389:        if (sc->sc_flags & RTW_F_DIGPHY)
                   4390:                opmode |= SA2400_OPMODE_DIGIN;
                   4391:
                   4392:        return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode);
                   4393: }
                   4394:
                   4395: int
                   4396: rtw_sa2400_vco_calibration(struct rtw_softc *sc)
                   4397: {
                   4398:        int rc;
                   4399:        /* calibrate VCO */
                   4400:        if ((rc = rtw_sa2400_vcocal_start(sc, 1)) != 0)
                   4401:                return rc;
                   4402:        DELAY(2200);    /* 2.2 milliseconds */
                   4403:        /* XXX superfluous: SA2400 automatically entered SLEEP mode. */
                   4404:        return rtw_sa2400_vcocal_start(sc, 0);
                   4405: }
                   4406:
                   4407: int
                   4408: rtw_sa2400_filter_calibration(struct rtw_softc *sc)
                   4409: {
                   4410:        u_int32_t opmode;
                   4411:
                   4412:        opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB;
                   4413:        if (sc->sc_flags & RTW_F_DIGPHY)
                   4414:                opmode |= SA2400_OPMODE_DIGIN;
                   4415:
                   4416:        return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode);
                   4417: }
                   4418:
                   4419: int
                   4420: rtw_sa2400_dc_calibration(struct rtw_softc *sc)
                   4421: {
                   4422:        int rc;
                   4423:        u_int32_t dccal;
                   4424:
                   4425:        rtw_continuous_tx_enable(sc, 1);
                   4426:
                   4427:        dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX;
                   4428:
                   4429:        rc = rtw_rf_macwrite(sc, SA2400_OPMODE, dccal);
                   4430:
                   4431:        if (rc != 0)
                   4432:                return rc;
                   4433:
                   4434:        DELAY(5);       /* DCALIB after being in Tx mode for 5
                   4435:                         * microseconds
                   4436:                         */
                   4437:
                   4438:        dccal &= ~SA2400_OPMODE_MODE_MASK;
                   4439:        dccal |= SA2400_OPMODE_MODE_DCALIB;
                   4440:
                   4441:        rc = rtw_rf_macwrite(sc, SA2400_OPMODE, dccal);
                   4442:        if (rc != 0)
                   4443:                return rc;
                   4444:
                   4445:        DELAY(20);      /* calibration takes at most 20 microseconds */
                   4446:
                   4447:        rtw_continuous_tx_enable(sc, 0);
                   4448:
                   4449:        return 0;
                   4450: }
                   4451:
                   4452: int
                   4453: rtw_sa2400_calibrate(struct rtw_softc *sc, u_int freq)
                   4454: {
                   4455:        int i, rc;
                   4456:
                   4457:        /* XXX reference driver calibrates VCO twice. Is it a bug? */
                   4458:        for (i = 0; i < 2; i++) {
                   4459:                if ((rc = rtw_sa2400_vco_calibration(sc)) != 0)
                   4460:                        return rc;
                   4461:        }
                   4462:        /* VCO calibration erases synthesizer registers, so re-tune */
                   4463:        if ((rc = rtw_sa2400_tune(sc, freq)) != 0)
                   4464:                return rc;
                   4465:        if ((rc = rtw_sa2400_filter_calibration(sc)) != 0)
                   4466:                return rc;
                   4467:        /* analog PHY needs DC calibration */
                   4468:        if (!(sc->sc_flags & RTW_F_DIGPHY))
                   4469:                return rtw_sa2400_dc_calibration(sc);
                   4470:        return 0;
                   4471: }
                   4472:
                   4473: int
                   4474: rtw_sa2400_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
                   4475:     enum rtw_pwrstate power)
                   4476: {
                   4477:        int rc;
                   4478:        u_int32_t agc, manrx;
                   4479:
                   4480:        if ((rc = rtw_sa2400_txpower(sc, opaque_txpower)) != 0)
                   4481:                return rc;
                   4482:
                   4483:        /* skip configuration if it's time to sleep or to power-down. */
                   4484:        if (power == RTW_SLEEP || power == RTW_OFF)
                   4485:                return rtw_sa2400_pwrstate(sc, power);
                   4486:
                   4487:        /* go to sleep for configuration */
                   4488:        if ((rc = rtw_sa2400_pwrstate(sc, RTW_SLEEP)) != 0)
                   4489:                return rc;
                   4490:
                   4491:        if ((rc = rtw_sa2400_tune(sc, freq)) != 0)
                   4492:                return rc;
                   4493:
                   4494:        agc = LSHIFT(25, SA2400_AGC_MAXGAIN_MASK);
                   4495:        agc |= LSHIFT(7, SA2400_AGC_BBPDELAY_MASK);
                   4496:        agc |= LSHIFT(15, SA2400_AGC_LNADELAY_MASK);
                   4497:        agc |= LSHIFT(27, SA2400_AGC_RXONDELAY_MASK);
                   4498:
                   4499:        if ((rc = rtw_rf_macwrite(sc, SA2400_AGC, agc)) != 0)
                   4500:                return rc;
                   4501:
                   4502:        /* XXX we are not supposed to be in RXMGC mode when we do this? */
                   4503:        manrx = SA2400_MANRX_AHSN;
                   4504:        manrx |= SA2400_MANRX_TEN;
                   4505:        manrx |= LSHIFT(1023, SA2400_MANRX_RXGAIN_MASK);
                   4506:
                   4507:        if ((rc = rtw_rf_macwrite(sc, SA2400_MANRX, manrx)) != 0)
                   4508:                return rc;
                   4509:
                   4510:        if ((rc = rtw_sa2400_calibrate(sc, freq)) != 0)
                   4511:                return rc;
                   4512:
                   4513:        /* enter Tx/Rx mode */
                   4514:        return rtw_sa2400_pwrstate(sc, power);
                   4515: }
                   4516:
                   4517: /* freq is in MHz */
                   4518: int
                   4519: rtw_max2820_tune(struct rtw_softc *sc, u_int freq)
                   4520: {
                   4521:        if (freq < 2400 || freq > 2499)
                   4522:                return -1;
                   4523:
                   4524:        return rtw_rf_hostwrite(sc, MAX2820_CHANNEL,
                   4525:            LSHIFT(freq - 2400, MAX2820_CHANNEL_CF_MASK));
                   4526: }
                   4527:
                   4528: int
                   4529: rtw_max2820_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
                   4530:     enum rtw_pwrstate power)
                   4531: {
                   4532:        int rc;
                   4533:
                   4534:        if ((rc = rtw_rf_hostwrite(sc, MAX2820_TEST,
                   4535:            MAX2820_TEST_DEFAULT)) != 0)
                   4536:                return rc;
                   4537:
                   4538:        if ((rc = rtw_rf_hostwrite(sc, MAX2820_ENABLE,
                   4539:            MAX2820_ENABLE_DEFAULT)) != 0)
                   4540:                return rc;
                   4541:
                   4542:        /* skip configuration if it's time to sleep or to power-down. */
                   4543:        if ((rc = rtw_max2820_pwrstate(sc, power)) != 0)
                   4544:                return rc;
                   4545:        else if (power == RTW_OFF || power == RTW_SLEEP)
                   4546:                return 0;
                   4547:
                   4548:        if ((rc = rtw_rf_hostwrite(sc, MAX2820_SYNTH,
                   4549:            MAX2820_SYNTH_R_44MHZ)) != 0)
                   4550:                return rc;
                   4551:
                   4552:        if ((rc = rtw_max2820_tune(sc, freq)) != 0)
                   4553:                return rc;
                   4554:
                   4555:        /* XXX The MAX2820 datasheet indicates that 1C and 2C should not
                   4556:         * be changed from 7, however, the reference driver sets them
                   4557:         * to 4 and 1, respectively.
                   4558:         */
                   4559:        if ((rc = rtw_rf_hostwrite(sc, MAX2820_RECEIVE,
                   4560:            MAX2820_RECEIVE_DL_DEFAULT |
                   4561:            LSHIFT(4, MAX2820A_RECEIVE_1C_MASK) |
                   4562:            LSHIFT(1, MAX2820A_RECEIVE_2C_MASK))) != 0)
                   4563:                return rc;
                   4564:
                   4565:        return rtw_rf_hostwrite(sc, MAX2820_TRANSMIT,
                   4566:            MAX2820_TRANSMIT_PA_DEFAULT);
                   4567: }
                   4568:
                   4569: int
                   4570: rtw_max2820_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
                   4571: {
                   4572:        /* TBD */
                   4573:        return 0;
                   4574: }
                   4575:
                   4576: int
                   4577: rtw_max2820_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
                   4578: {
                   4579:        uint32_t enable;
                   4580:
                   4581:        switch (power) {
                   4582:        case RTW_OFF:
                   4583:        case RTW_SLEEP:
                   4584:        default:
                   4585:                enable = 0x0;
                   4586:                break;
                   4587:        case RTW_ON:
                   4588:                enable = MAX2820_ENABLE_DEFAULT;
                   4589:                break;
                   4590:        }
                   4591:        return rtw_rf_hostwrite(sc, MAX2820_ENABLE, enable);
                   4592: }
                   4593:
                   4594: int
                   4595: rtw_grf5101_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
                   4596:     enum rtw_pwrstate power)
                   4597: {
                   4598:        int rc;
                   4599:
                   4600:        /*
                   4601:         * These values have been derived from the rtl8180-sa2400 Linux driver.
                   4602:         * It is unknown what they all do, GCT refuse to release any documentation
                   4603:         * so these are more than likely sub optimal settings
                   4604:         */
                   4605:
                   4606:        rtw_rf_macwrite(sc, 0x01, 0x1a23);
                   4607:        rtw_rf_macwrite(sc, 0x02, 0x4971);
                   4608:        rtw_rf_macwrite(sc, 0x03, 0x41de);
                   4609:        rtw_rf_macwrite(sc, 0x04, 0x2d80);
                   4610:
                   4611:        rtw_rf_macwrite(sc, 0x05, 0x61ff);
                   4612:
                   4613:        rtw_rf_macwrite(sc, 0x06, 0x0);
                   4614:
                   4615:        rtw_rf_macwrite(sc, 0x08, 0x7533);
                   4616:        rtw_rf_macwrite(sc, 0x09, 0xc401);
                   4617:        rtw_rf_macwrite(sc, 0x0a, 0x0);
                   4618:        rtw_rf_macwrite(sc, 0x0c, 0x1c7);
                   4619:        rtw_rf_macwrite(sc, 0x0d, 0x29d3);
                   4620:        rtw_rf_macwrite(sc, 0x0e, 0x2e8);
                   4621:        rtw_rf_macwrite(sc, 0x10, 0x192);
                   4622:        rtw_rf_macwrite(sc, 0x11, 0x248);
                   4623:        rtw_rf_macwrite(sc, 0x12, 0x0);
                   4624:        rtw_rf_macwrite(sc, 0x13, 0x20c4);
                   4625:        rtw_rf_macwrite(sc, 0x14, 0xf4fc);
                   4626:        rtw_rf_macwrite(sc, 0x15, 0x0);
                   4627:        rtw_rf_macwrite(sc, 0x16, 0x1500);
                   4628:
                   4629:        if ((rc = rtw_grf5101_txpower(sc, opaque_txpower)) != 0)
                   4630:                return rc;
                   4631:
                   4632:        if ((rc = rtw_grf5101_tune(sc, freq)) != 0)
                   4633:                return rc;
                   4634:
                   4635:        return (0);
                   4636: }
                   4637:
                   4638: int
                   4639: rtw_grf5101_tune(struct rtw_softc *sc, u_int freq)
                   4640: {
                   4641:        struct ieee80211com *ic = &sc->sc_ic;
                   4642:        u_int channel = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
                   4643:
                   4644:        /* set channel */
                   4645:        rtw_rf_macwrite(sc, 0x07, 0);
                   4646:        rtw_rf_macwrite(sc, 0x0b, channel - 1);
                   4647:        rtw_rf_macwrite(sc, 0x07, 0x1000);
                   4648:
                   4649:        return (0);
                   4650: }
                   4651:
                   4652: int
                   4653: rtw_grf5101_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
                   4654: {
                   4655:        rtw_rf_macwrite(sc, 0x15, 0);
                   4656:        rtw_rf_macwrite(sc, 0x06, opaque_txpower);
                   4657:        rtw_rf_macwrite(sc, 0x15, 0x10);
                   4658:        rtw_rf_macwrite(sc, 0x15, 0x00);
                   4659:
                   4660:        return (0);
                   4661: }
                   4662:
                   4663: int
                   4664: rtw_grf5101_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
                   4665: {
                   4666:        switch (power) {
                   4667:        case RTW_OFF:
                   4668:        case RTW_SLEEP:
                   4669:                rtw_rf_macwrite(sc, 0x07, 0x0000);
                   4670:                rtw_rf_macwrite(sc, 0x1f, 0x0045);
                   4671:                rtw_rf_macwrite(sc, 0x1f, 0x0005);
                   4672:                rtw_rf_macwrite(sc, 0x00, 0x08e4);
                   4673:        default:
                   4674:                break;
                   4675:        case RTW_ON:
                   4676:                rtw_rf_macwrite(sc, 0x1f, 0x0001);
                   4677:                DELAY(10);
                   4678:                rtw_rf_macwrite(sc, 0x1f, 0x0001);
                   4679:                DELAY(10);
                   4680:                rtw_rf_macwrite(sc, 0x1f, 0x0041);
                   4681:                DELAY(10);
                   4682:                rtw_rf_macwrite(sc, 0x1f, 0x0061);
                   4683:                DELAY(10);
                   4684:                rtw_rf_macwrite(sc, 0x00, 0x0ae4);
                   4685:                DELAY(10);
                   4686:                rtw_rf_macwrite(sc, 0x07, 0x1000);
                   4687:                DELAY(100);
                   4688:                break;
                   4689:        }
                   4690:
                   4691:        return 0;
                   4692: }
                   4693:
                   4694: int
                   4695: rtw_rtl8225_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
                   4696: {
                   4697:        return (0);
                   4698: }
                   4699:
                   4700: int
                   4701: rtw_rtl8225_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
                   4702:     enum rtw_pwrstate power)
                   4703: {
                   4704:        return (0);
                   4705: }
                   4706:
                   4707: int
                   4708: rtw_rtl8225_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
                   4709: {
                   4710:        return (0);
                   4711: }
                   4712:
                   4713: int
                   4714: rtw_rtl8225_tune(struct rtw_softc *sc, u_int freq)
                   4715: {
                   4716:        return (0);
                   4717: }
                   4718:
                   4719: int
                   4720: rtw_rtl8255_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
                   4721: {
                   4722:        return (0);
                   4723: }
                   4724:
                   4725: int
                   4726: rtw_rtl8255_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
                   4727:     enum rtw_pwrstate power)
                   4728: {
                   4729:        return (0);
                   4730: }
                   4731:
                   4732: int
                   4733: rtw_rtl8255_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
                   4734: {
                   4735:        return (0);
                   4736: }
                   4737:
                   4738: int
                   4739: rtw_rtl8255_tune(struct rtw_softc *sc, u_int freq)
                   4740: {
                   4741:        return (0);
                   4742: }
                   4743:
                   4744: int
                   4745: rtw_phy_init(struct rtw_softc *sc)
                   4746: {
                   4747:        int rc;
                   4748:        struct ieee80211com *ic = &sc->sc_ic;
                   4749:        struct rtw_regs *regs = &sc->sc_regs;
                   4750:        int antdiv = sc->sc_flags & RTW_F_ANTDIV;
                   4751:        int dflantb = sc->sc_flags & RTW_F_DFLANTB;
                   4752:        u_int freq = ic->ic_bss->ni_chan->ic_freq;      /* freq is in MHz */
                   4753:        u_int8_t opaque_txpower = rtw_chan2txpower(&sc->sc_srom, ic,
                   4754:            ic->ic_bss->ni_chan);
                   4755:        u_int8_t cs_threshold = sc->sc_csthr;
                   4756:        enum rtw_pwrstate power = RTW_ON;
                   4757:
                   4758:        RTW_DPRINTF(RTW_DEBUG_PHY,
                   4759:            ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u "
                   4760:             "pwrstate %s\n", __func__, opaque_txpower, cs_threshold, freq,
                   4761:             antdiv, dflantb, rtw_pwrstate_string(power)));
                   4762:
                   4763:        /* XXX is this really necessary? */
                   4764:        if ((rc = (*sc->sc_rf_txpower)(sc, opaque_txpower)) != 0)
                   4765:                return rc;
                   4766:        if ((rc = rtw_bbp_preinit(regs, sc->sc_bbpset.bb_antatten, dflantb,
                   4767:            freq)) != 0)
                   4768:                return rc;
                   4769:        if ((rc = (*sc->sc_rf_tune)(sc, freq)) != 0)
                   4770:                return rc;
                   4771:        /* initialize RF  */
                   4772:        if ((rc = (*sc->sc_rf_init)(sc, freq, opaque_txpower, power)) != 0)
                   4773:                return rc;
                   4774: #if 0  /* what is this redundant tx power setting here for? */
                   4775:        if ((rc = (*sc->sc_rf_txpower)(sc, opaque_txpower)) != 0)
                   4776:                return rc;
                   4777: #endif
                   4778:        return rtw_bbp_init(regs, &sc->sc_bbpset, antdiv, dflantb,
                   4779:            cs_threshold, freq);
                   4780: }
                   4781:
                   4782: /*
                   4783:  * Generic PHY I/O functions
                   4784:  */
                   4785:
                   4786: int
                   4787: rtw_bbp_write(struct rtw_regs *regs, u_int addr, u_int val)
                   4788: {
                   4789: #define        BBP_WRITE_ITERS 50
                   4790: #define        BBP_WRITE_DELAY 1
                   4791:        int i;
                   4792:        u_int32_t wrbbp, rdbbp;
                   4793:
                   4794:        RTW_DPRINTF(RTW_DEBUG_PHYIO,
                   4795:            ("%s: bbp[%u] <- %u\n", __func__, addr, val));
                   4796:
                   4797:        KASSERT((addr & ~PRESHIFT(RTW_BB_ADDR_MASK)) == 0);
                   4798:        KASSERT((val & ~PRESHIFT(RTW_BB_WR_MASK)) == 0);
                   4799:
                   4800:        wrbbp = LSHIFT(addr, RTW_BB_ADDR_MASK) | RTW_BB_WREN |
                   4801:            LSHIFT(val, RTW_BB_WR_MASK) | RTW_BB_RD_MASK,
                   4802:
                   4803:        rdbbp = LSHIFT(addr, RTW_BB_ADDR_MASK) |
                   4804:            RTW_BB_WR_MASK | RTW_BB_RD_MASK;
                   4805:
                   4806:        RTW_DPRINTF(RTW_DEBUG_PHYIO,
                   4807:            ("%s: rdbbp = %#08x, wrbbp = %#08x\n", __func__, rdbbp, wrbbp));
                   4808:
                   4809:        for (i = BBP_WRITE_ITERS; --i >= 0; ) {
                   4810:                RTW_RBW(regs, RTW_BB, RTW_BB);
                   4811:                RTW_WRITE(regs, RTW_BB, wrbbp);
                   4812:                RTW_SYNC(regs, RTW_BB, RTW_BB);
                   4813:                RTW_WRITE(regs, RTW_BB, rdbbp);
                   4814:                RTW_SYNC(regs, RTW_BB, RTW_BB);
                   4815:                delay(BBP_WRITE_DELAY); /* 1 microsecond */
                   4816:                if (MASK_AND_RSHIFT(RTW_READ(regs, RTW_BB),
                   4817:                    RTW_BB_RD_MASK) == val) {
                   4818:                        RTW_DPRINTF(RTW_DEBUG_PHYIO,
                   4819:                            ("%s: finished in %dus\n", __func__,
                   4820:                            BBP_WRITE_DELAY * (BBP_WRITE_ITERS - i)));
                   4821:                        return 0;
                   4822:                }
                   4823:                delay(BBP_WRITE_DELAY); /* again */
                   4824:        }
                   4825:        printf("%s: timeout\n", __func__);
                   4826:        return -1;
                   4827: }
                   4828:
                   4829: /* Help rtw_rf_hostwrite bang bits to RF over 3-wire interface. */
                   4830: void
                   4831: rtw_rf_hostbangbits(struct rtw_regs *regs, u_int32_t bits, int lo_to_hi,
                   4832:     u_int nbits)
                   4833: {
                   4834:        int i;
                   4835:        u_int32_t mask, reg;
                   4836:
                   4837:        KASSERT(nbits <= 32);
                   4838:
                   4839:        RTW_DPRINTF(RTW_DEBUG_PHYIO,
                   4840:            ("%s: %u bits, %#08x, %s\n", __func__, nbits, bits,
                   4841:            (lo_to_hi) ? "lo to hi" : "hi to lo"));
                   4842:
                   4843:        reg = RTW8180_PHYCFG_HST;
                   4844:        RTW_WRITE(regs, RTW8180_PHYCFG, reg);
                   4845:        RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4846:
                   4847:        if (lo_to_hi)
                   4848:                mask = 0x1;
                   4849:        else
                   4850:                mask = 1 << (nbits - 1);
                   4851:
                   4852:        for (i = 0; i < nbits; i++) {
                   4853:                RTW_DPRINTF(RTW_DEBUG_PHYBITIO,
                   4854:                    ("%s: bits %#08x mask %#08x -> bit %#08x\n",
                   4855:                    __func__, bits, mask, bits & mask));
                   4856:
                   4857:                if ((bits & mask) != 0)
                   4858:                        reg |= RTW8180_PHYCFG_HST_DATA;
                   4859:                else
                   4860:                        reg &= ~RTW8180_PHYCFG_HST_DATA;
                   4861:
                   4862:                reg |= RTW8180_PHYCFG_HST_CLK;
                   4863:                RTW_WRITE(regs, RTW8180_PHYCFG, reg);
                   4864:                RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4865:
                   4866:                DELAY(2);       /* arbitrary delay */
                   4867:
                   4868:                reg &= ~RTW8180_PHYCFG_HST_CLK;
                   4869:                RTW_WRITE(regs, RTW8180_PHYCFG, reg);
                   4870:                RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4871:
                   4872:                if (lo_to_hi)
                   4873:                        mask <<= 1;
                   4874:                else
                   4875:                        mask >>= 1;
                   4876:        }
                   4877:
                   4878:        reg |= RTW8180_PHYCFG_HST_EN;
                   4879:        KASSERT((reg & RTW8180_PHYCFG_HST_CLK) == 0);
                   4880:        RTW_WRITE(regs, RTW8180_PHYCFG, reg);
                   4881:        RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4882: }
                   4883:
                   4884: #if 0
                   4885: void
                   4886: rtw_rf_rtl8225_hostbangbits(struct rtw_regs *regs, u_int32_t bits, int lo_to_hi,
                   4887:     u_int nbits)
                   4888: {
                   4889:        int i;
                   4890:        u_int8_t page;
                   4891:        u_int16_t reg0, reg1, reg2;
                   4892:        u_int32_t mask;
                   4893:
                   4894:        /* enable page 0 */
                   4895:        page = RTW_READ8(regs, RTW_PSR);
                   4896:        RTW_WRITE8(regs, RTW_PSR, page & ~RTW_PSR_PSEN);
                   4897:
                   4898:        /* enable RF access */
                   4899:        reg0 = RTW_READ16(regs, RTW8185_RFPINSOUTPUT) &
                   4900:            RTW8185_RFPINSOUTPUT_MASK;
                   4901:        reg1 = RTW_READ16(regs, RTW8185_RFPINSENABLE);
                   4902:        RTW_WRITE16(regs, RTW8185_RFPINSENABLE,
                   4903:            RTW8185_RFPINSENABLE_ENABLE | reg0);
                   4904:        reg2 = RTW_READ16(regs, RTW8185_RFPINSSELECT);
                   4905:        RTW_WRITE16(regs, RTW8185_RFPINSSELECT,
                   4906:            RTW8185_RFPINSSELECT_ENABLE | reg1 /* XXX | SW_GPIO_CTL */);
                   4907:        DELAY(10);
                   4908:
                   4909:        RTW_WRITE16(regs, RTW8185_RFPINSOUTPUT, reg0);
                   4910:        DELAY(10);
                   4911:
                   4912:        if (lo_to_hi)
                   4913:                mask = 0x1;
                   4914:        else
                   4915:                mask = 1 << (nbits - 1);
                   4916:
                   4917:        for (i = 0; i < nbits; i++) {
                   4918:                RTW_DPRINTF(RTW_DEBUG_PHYBITIO,
                   4919:                    ("%s: bits %#08x mask %#08x -> bit %#08x\n",
                   4920:                    __func__, bits, mask, bits & mask));
                   4921:
                   4922:                if ((bits & mask) != 0)
                   4923:                        reg |= RTW8180_PHYCFG_HST_DATA;
                   4924:                else
                   4925:                        reg &= ~RTW8180_PHYCFG_HST_DATA;
                   4926:
                   4927:                reg |= RTW8180_PHYCFG_HST_CLK;
                   4928:                RTW_WRITE(regs, RTW8180_PHYCFG, reg);
                   4929:                RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4930:
                   4931:                DELAY(2);       /* arbitrary delay */
                   4932:
                   4933:                reg &= ~RTW8180_PHYCFG_HST_CLK;
                   4934:                RTW_WRITE(regs, RTW8180_PHYCFG, reg);
                   4935:                RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4936:
                   4937:                if (lo_to_hi)
                   4938:                        mask <<= 1;
                   4939:                else
                   4940:                        mask >>= 1;
                   4941:        }
                   4942:
                   4943:        /* reset the page */
                   4944:        RTW_WRITE8(regs, RTW_PSR, page);
                   4945: }
                   4946: #endif
                   4947:
                   4948: /* Help rtw_rf_macwrite: tell MAC to bang bits to RF over the 3-wire
                   4949:  * interface.
                   4950:  */
                   4951: int
                   4952: rtw_rf_macbangbits(struct rtw_regs *regs, u_int32_t reg)
                   4953: {
                   4954:        int i;
                   4955:
                   4956:        RTW_DPRINTF(RTW_DEBUG_PHY, ("%s: %#08x\n", __func__, reg));
                   4957:
                   4958:        RTW_WRITE(regs, RTW8180_PHYCFG, RTW8180_PHYCFG_MAC_POLL | reg);
                   4959:
                   4960:        RTW_WBR(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4961:
                   4962:        for (i = rtw_macbangbits_timeout; --i >= 0; delay(1)) {
                   4963:                if ((RTW_READ(regs, RTW8180_PHYCFG) &
                   4964:                    RTW8180_PHYCFG_MAC_POLL) == 0) {
                   4965:                        RTW_DPRINTF(RTW_DEBUG_PHY,
                   4966:                            ("%s: finished in %dus\n", __func__,
                   4967:                            rtw_macbangbits_timeout - i));
                   4968:                        return 0;
                   4969:                }
                   4970:                RTW_RBR(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
                   4971:        }
                   4972:
                   4973:        printf("%s: RTW8180_PHYCFG_MAC_POLL still set.\n", __func__);
                   4974:        return -1;
                   4975: }
                   4976:
                   4977: u_int32_t
                   4978: rtw_grf5101_host_crypt(u_int addr, u_int32_t val)
                   4979: {
                   4980:        /* TBD */
                   4981:        return 0;
                   4982: }
                   4983:
                   4984: u_int32_t
                   4985: rtw_grf5101_mac_crypt(u_int addr, u_int32_t val)
                   4986: {
                   4987:        u_int32_t data_and_addr;
                   4988: #define EXTRACT_NIBBLE(d, which) (((d) >> (4 * (which))) & 0xf)
                   4989:        static u_int8_t caesar[16] = {
                   4990:                0x0, 0x8, 0x4, 0xc,
                   4991:                0x2, 0xa, 0x6, 0xe,
                   4992:                0x1, 0x9, 0x5, 0xd,
                   4993:                0x3, 0xb, 0x7, 0xf
                   4994:        };
                   4995:        data_and_addr =
                   4996:            caesar[EXTRACT_NIBBLE(val, 2)] |
                   4997:            (caesar[EXTRACT_NIBBLE(val, 1)] <<  4) |
                   4998:            (caesar[EXTRACT_NIBBLE(val, 0)] <<  8) |
                   4999:            (caesar[(addr >> 1) & 0xf]      << 12) |
                   5000:            ((addr & 0x1)                   << 16) |
                   5001:            (caesar[EXTRACT_NIBBLE(val, 3)] << 24);
                   5002:        return LSHIFT(data_and_addr, RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK |
                   5003:            RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK);
                   5004: #undef EXTRACT_NIBBLE
                   5005: }
                   5006:
                   5007: /* Bang bits over the 3-wire interface. */
                   5008: int
                   5009: rtw_rf_hostwrite(struct rtw_softc *sc, u_int addr, u_int32_t val)
                   5010: {
                   5011:        u_int nbits;
                   5012:        int lo_to_hi;
                   5013:        u_int32_t bits;
                   5014:        void(*rf_bangbits)(struct rtw_regs *, u_int32_t, int, u_int) =
                   5015:            rtw_rf_hostbangbits;
                   5016:
                   5017:        RTW_DPRINTF(RTW_DEBUG_PHYIO, ("%s: [%u] <- %#08x\n", __func__,
                   5018:            addr, val));
                   5019:
                   5020:        switch (sc->sc_rfchipid) {
                   5021:        case RTW_RFCHIPID_MAXIM2820:
                   5022:                nbits = 16;
                   5023:                lo_to_hi = 0;
                   5024:                bits = LSHIFT(val, MAX2820_TWI_DATA_MASK) |
                   5025:                    LSHIFT(addr, MAX2820_TWI_ADDR_MASK);
                   5026:                break;
                   5027:        case RTW_RFCHIPID_PHILIPS:
                   5028:                KASSERT((addr & ~PRESHIFT(SA2400_TWI_ADDR_MASK)) == 0);
                   5029:                KASSERT((val & ~PRESHIFT(SA2400_TWI_DATA_MASK)) == 0);
                   5030:                bits = LSHIFT(val, SA2400_TWI_DATA_MASK) |
                   5031:                    LSHIFT(addr, SA2400_TWI_ADDR_MASK) | SA2400_TWI_WREN;
                   5032:                nbits = 32;
                   5033:                lo_to_hi = 1;
                   5034:                break;
                   5035:        case RTW_RFCHIPID_GCT:
                   5036:                KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
                   5037:                KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
                   5038:                bits = rtw_grf5101_host_crypt(addr, val);
                   5039:                nbits = 21;
                   5040:                lo_to_hi = 1;
                   5041:                break;
                   5042:        case RTW_RFCHIPID_RFMD2948:
                   5043:                KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
                   5044:                KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
                   5045:                bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
                   5046:                    LSHIFT(addr, SI4126_TWI_ADDR_MASK);
                   5047:                nbits = 22;
                   5048:                lo_to_hi = 0;
                   5049:                break;
                   5050:        case RTW_RFCHIPID_RTL8225:
                   5051:        case RTW_RFCHIPID_RTL8255:
                   5052:                nbits = 16;
                   5053:                lo_to_hi = 0;
                   5054:                bits = LSHIFT(val, RTL8225_TWI_DATA_MASK) |
                   5055:                    LSHIFT(addr, RTL8225_TWI_ADDR_MASK);
                   5056:
                   5057:                /* the RTL8225 uses a slightly modified RF interface */
                   5058:                rf_bangbits = rtw_rf_hostbangbits;
                   5059:                break;
                   5060:        case RTW_RFCHIPID_INTERSIL:
                   5061:        default:
                   5062:                printf("%s: unknown rfchipid %d\n", __func__, sc->sc_rfchipid);
                   5063:                return -1;
                   5064:        }
                   5065:
                   5066:        (*rf_bangbits)(&sc->sc_regs, bits, lo_to_hi, nbits);
                   5067:
                   5068:        return 0;
                   5069: }
                   5070:
                   5071: u_int32_t
                   5072: rtw_maxim_swizzle(u_int addr, u_int32_t val)
                   5073: {
                   5074:        u_int32_t hidata, lodata;
                   5075:
                   5076:        KASSERT((val & ~(RTW_MAXIM_LODATA_MASK|RTW_MAXIM_HIDATA_MASK)) == 0);
                   5077:        lodata = MASK_AND_RSHIFT(val, RTW_MAXIM_LODATA_MASK);
                   5078:        hidata = MASK_AND_RSHIFT(val, RTW_MAXIM_HIDATA_MASK);
                   5079:        return LSHIFT(lodata, RTW8180_PHYCFG_MAC_MAXIM_LODATA_MASK) |
                   5080:            LSHIFT(hidata, RTW8180_PHYCFG_MAC_MAXIM_HIDATA_MASK) |
                   5081:            LSHIFT(addr, RTW8180_PHYCFG_MAC_MAXIM_ADDR_MASK);
                   5082: }
                   5083:
                   5084: /* Tell the MAC what to bang over the 3-wire interface. */
                   5085: int
                   5086: rtw_rf_macwrite(struct rtw_softc *sc, u_int addr, u_int32_t val)
                   5087: {
                   5088:        u_int32_t reg;
                   5089:
                   5090:        RTW_DPRINTF(RTW_DEBUG_PHYIO, ("%s: %s[%u] <- %#08x\n", __func__,
                   5091:            addr, val));
                   5092:
                   5093:        switch (sc->sc_rfchipid) {
                   5094:        case RTW_RFCHIPID_GCT:
                   5095:                reg = rtw_grf5101_mac_crypt(addr, val);
                   5096:                break;
                   5097:        case RTW_RFCHIPID_MAXIM2820:
                   5098:                reg = rtw_maxim_swizzle(addr, val);
                   5099:                break;
                   5100:        default:                /* XXX */
                   5101:        case RTW_RFCHIPID_PHILIPS:
                   5102:                KASSERT((addr &
                   5103:                    ~PRESHIFT(RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK)) == 0);
                   5104:                KASSERT((val &
                   5105:                    ~PRESHIFT(RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK)) == 0);
                   5106:
                   5107:                reg = LSHIFT(addr, RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK) |
                   5108:                    LSHIFT(val, RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK);
                   5109:        }
                   5110:
                   5111:        switch (sc->sc_rfchipid) {
                   5112:        case RTW_RFCHIPID_GCT:
                   5113:        case RTW_RFCHIPID_MAXIM2820:
                   5114:        case RTW_RFCHIPID_RFMD2948:
                   5115:                reg |= RTW8180_PHYCFG_MAC_RFTYPE_RFMD;
                   5116:                break;
                   5117:        case RTW_RFCHIPID_INTERSIL:
                   5118:                reg |= RTW8180_PHYCFG_MAC_RFTYPE_INTERSIL;
                   5119:                break;
                   5120:        case RTW_RFCHIPID_PHILIPS:
                   5121:                reg |= RTW8180_PHYCFG_MAC_RFTYPE_PHILIPS;
                   5122:                break;
                   5123:        default:
                   5124:                printf("%s: unknown rfchipid %d\n", __func__, sc->sc_rfchipid);
                   5125:                return -1;
                   5126:        }
                   5127:
                   5128:        return rtw_rf_macbangbits(&sc->sc_regs, reg);
                   5129: }
                   5130:
                   5131:
                   5132: u_int8_t
                   5133: rtw_read8(void *arg, u_int32_t off)
                   5134: {
                   5135:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5136:        return (bus_space_read_1(regs->r_bt, regs->r_bh, off));
                   5137: }
                   5138:
                   5139: u_int16_t
                   5140: rtw_read16(void *arg, u_int32_t off)
                   5141: {
                   5142:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5143:        return (bus_space_read_2(regs->r_bt, regs->r_bh, off));
                   5144: }
                   5145:
                   5146: u_int32_t
                   5147: rtw_read32(void *arg, u_int32_t off)
                   5148: {
                   5149:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5150:        return (bus_space_read_4(regs->r_bt, regs->r_bh, off));
                   5151: }
                   5152:
                   5153: void
                   5154: rtw_write8(void *arg, u_int32_t off, u_int8_t val)
                   5155: {
                   5156:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5157:        bus_space_write_1(regs->r_bt, regs->r_bh, off, val);
                   5158: }
                   5159:
                   5160: void
                   5161: rtw_write16(void *arg, u_int32_t off, u_int16_t val)
                   5162: {
                   5163:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5164:        bus_space_write_2(regs->r_bt, regs->r_bh, off, val);
                   5165: }
                   5166:
                   5167: void
                   5168: rtw_write32(void *arg, u_int32_t off, u_int32_t val)
                   5169: {
                   5170:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5171:        bus_space_write_4(regs->r_bt, regs->r_bh, off, val);
                   5172: }
                   5173:
                   5174: void
                   5175: rtw_barrier(void *arg, u_int32_t reg0, u_int32_t reg1, int flags)
                   5176: {
                   5177:        struct rtw_regs *regs = (struct rtw_regs *)arg;
                   5178:        bus_space_barrier(regs->r_bt, regs->r_bh, MIN(reg0, reg1),
                   5179:            MAX(reg0, reg1) - MIN(reg0, reg1) + 4, flags);
                   5180: }

CVSweb