[BACK]Return to if_urtwn.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / usb

Annotation of src/sys/dev/usb/if_urtwn.c, Revision 1.26

1.26    ! christos    1: /*     $NetBSD: if_urtwn.c,v 1.25 2013/08/10 21:15:26 jnemeth Exp $    */
1.1       nonaka      2: /*     $OpenBSD: if_urtwn.c,v 1.20 2011/11/26 06:39:33 ckuethe Exp $   */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
1.8       christos   20: /*-
1.1       nonaka     21:  * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188RU/RTL8192CU.
                     22:  */
                     23:
                     24: #include <sys/cdefs.h>
1.26    ! christos   25: __KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.25 2013/08/10 21:15:26 jnemeth Exp $");
1.11      jmcneill   26:
                     27: #ifdef _KERNEL_OPT
                     28: #include "opt_inet.h"
                     29: #endif
1.1       nonaka     30:
                     31: #include <sys/param.h>
                     32: #include <sys/sockio.h>
                     33: #include <sys/sysctl.h>
                     34: #include <sys/mbuf.h>
                     35: #include <sys/kernel.h>
                     36: #include <sys/socket.h>
                     37: #include <sys/systm.h>
                     38: #include <sys/malloc.h>
                     39: #include <sys/module.h>
                     40: #include <sys/conf.h>
                     41: #include <sys/device.h>
                     42:
                     43: #include <sys/bus.h>
                     44: #include <machine/endian.h>
                     45: #include <sys/intr.h>
                     46:
                     47: #include <net/bpf.h>
                     48: #include <net/if.h>
                     49: #include <net/if_arp.h>
                     50: #include <net/if_dl.h>
                     51: #include <net/if_ether.h>
                     52: #include <net/if_media.h>
                     53: #include <net/if_types.h>
                     54:
                     55: #include <netinet/in.h>
                     56: #include <netinet/in_systm.h>
                     57: #include <netinet/in_var.h>
                     58: #include <netinet/ip.h>
1.11      jmcneill   59: #include <netinet/if_inarp.h>
1.1       nonaka     60:
                     61: #include <net80211/ieee80211_netbsd.h>
                     62: #include <net80211/ieee80211_var.h>
                     63: #include <net80211/ieee80211_radiotap.h>
                     64:
                     65: #include <dev/firmload.h>
                     66:
                     67: #include <dev/usb/usb.h>
                     68: #include <dev/usb/usbdi.h>
                     69: #include <dev/usb/usbdivar.h>
                     70: #include <dev/usb/usbdi_util.h>
                     71: #include <dev/usb/usbdevs.h>
                     72:
                     73: #include <dev/usb/if_urtwnreg.h>
                     74: #include <dev/usb/if_urtwnvar.h>
                     75: #include <dev/usb/if_urtwn_data.h>
                     76:
1.12      christos   77: /*
                     78:  * The sc_write_mtx locking is to prevent sequences of writes from
                     79:  * being intermingled with each other.  I don't know if this is really
                     80:  * needed.  I have added it just to be on the safe side.
                     81:  */
                     82:
1.1       nonaka     83: #ifdef URTWN_DEBUG
                     84: #define        DBG_INIT        __BIT(0)
                     85: #define        DBG_FN          __BIT(1)
                     86: #define        DBG_TX          __BIT(2)
                     87: #define        DBG_RX          __BIT(3)
                     88: #define        DBG_STM         __BIT(4)
                     89: #define        DBG_RF          __BIT(5)
                     90: #define        DBG_REG         __BIT(6)
                     91: #define        DBG_ALL         0xffffffffU
1.10      jmcneill   92: u_int urtwn_debug = 0;
1.1       nonaka     93: #define DPRINTFN(n, s) \
                     94:        do { if (urtwn_debug & (n)) printf s; } while (/*CONSTCOND*/0)
                     95: #else
                     96: #define DPRINTFN(n, s)
                     97: #endif
                     98:
                     99: static const struct usb_devno urtwn_devs[] = {
                    100:        { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_RTL8188CU_1 },
                    101:        { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_RTL8188CU_2 },
                    102:        { USB_VENDOR_ABOCOM,    USB_PRODUCT_ABOCOM_RTL8192CU },
1.3       nonaka    103:        { USB_VENDOR_ASUSTEK,   USB_PRODUCT_ASUSTEK_RTL8192CU },
1.1       nonaka    104:        { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1 },
                    105:        { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2 },
1.3       nonaka    106:        { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU },
1.1       nonaka    107:        { USB_VENDOR_BELKIN,    USB_PRODUCT_BELKIN_RTL8188CU },
1.3       nonaka    108:        { USB_VENDOR_BELKIN,    USB_PRODUCT_BELKIN_RTL8192CU },
                    109:        { USB_VENDOR_CHICONY,   USB_PRODUCT_CHICONY_RTL8188CUS_1 },
                    110:        { USB_VENDOR_CHICONY,   USB_PRODUCT_CHICONY_RTL8188CUS_2 },
                    111:        { USB_VENDOR_CHICONY,   USB_PRODUCT_CHICONY_RTL8188CUS_3 },
                    112:        { USB_VENDOR_CHICONY,   USB_PRODUCT_CHICONY_RTL8188CUS_4 },
                    113:        { USB_VENDOR_CHICONY,   USB_PRODUCT_CHICONY_RTL8188CUS_5 },
1.1       nonaka    114:        { USB_VENDOR_COREGA,    USB_PRODUCT_COREGA_RTL8192CU },
                    115:        { USB_VENDOR_DLINK,     USB_PRODUCT_DLINK_RTL8188CU },
                    116:        { USB_VENDOR_DLINK,     USB_PRODUCT_DLINK_RTL8192CU_1 },
                    117:        { USB_VENDOR_DLINK,     USB_PRODUCT_DLINK_RTL8192CU_2 },
                    118:        { USB_VENDOR_DLINK,     USB_PRODUCT_DLINK_RTL8192CU_3 },
                    119:        { USB_VENDOR_EDIMAX,    USB_PRODUCT_EDIMAX_RTL8188CU },
                    120:        { USB_VENDOR_EDIMAX,    USB_PRODUCT_EDIMAX_RTL8192CU },
                    121:        { USB_VENDOR_FEIXUN,    USB_PRODUCT_FEIXUN_RTL8188CU },
                    122:        { USB_VENDOR_FEIXUN,    USB_PRODUCT_FEIXUN_RTL8192CU },
                    123:        { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150 },
1.3       nonaka    124:        { USB_VENDOR_HAWKING,   USB_PRODUCT_HAWKING_RTL8192CU },
1.1       nonaka    125:        { USB_VENDOR_HP3,       USB_PRODUCT_HP3_RTL8188CU },
                    126:        { USB_VENDOR_NETGEAR,   USB_PRODUCT_NETGEAR_WNA1000M },
1.3       nonaka    127:        { USB_VENDOR_NETGEAR,   USB_PRODUCT_NETGEAR_RTL8192CU },
                    128:        { USB_VENDOR_NETGEAR4,  USB_PRODUCT_NETGEAR4_RTL8188CU },
1.1       nonaka    129:        { USB_VENDOR_NOVATECH,  USB_PRODUCT_NOVATECH_RTL8188CU },
                    130:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_RTL8188CU_1 },
                    131:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_RTL8188CU_2 },
                    132:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_RTL8192CU },
1.3       nonaka    133:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_RTL8188CU_3 },
                    134:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_RTL8188CU_4 },
                    135:        { USB_VENDOR_PLANEX2,   USB_PRODUCT_PLANEX2_RTL8188CUS },
1.1       nonaka    136:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CE_0 },
                    137:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CE_1 },
1.3       nonaka    138:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CTV },
1.1       nonaka    139:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CU_0 },
                    140:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CU_1 },
                    141:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CU_2 },
1.3       nonaka    142:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CU_COMBO },
                    143:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188CUS },
1.1       nonaka    144:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188RU },
1.3       nonaka    145:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8188RU_2 },
1.1       nonaka    146:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8191CU },
                    147:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8192CE },
                    148:        { USB_VENDOR_REALTEK,   USB_PRODUCT_REALTEK_RTL8192CU },
                    149:        { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU },
1.3       nonaka    150:        { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2 },
                    151:        { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU },
1.25      jnemeth   152:        { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CUR2 },
1.1       nonaka    153:        { USB_VENDOR_TRENDNET,  USB_PRODUCT_TRENDNET_RTL8188CU },
1.3       nonaka    154:        { USB_VENDOR_TRENDNET,  USB_PRODUCT_TRENDNET_RTL8192CU },
1.1       nonaka    155:        { USB_VENDOR_ZYXEL,     USB_PRODUCT_ZYXEL_RTL8192CU }
                    156: };
                    157:
                    158: static int     urtwn_match(device_t, cfdata_t, void *);
                    159: static void    urtwn_attach(device_t, device_t, void *);
                    160: static int     urtwn_detach(device_t, int);
                    161: static int     urtwn_activate(device_t, enum devact);
                    162:
                    163: CFATTACH_DECL_NEW(urtwn, sizeof(struct urtwn_softc), urtwn_match,
                    164:     urtwn_attach, urtwn_detach, urtwn_activate);
                    165:
                    166: static int     urtwn_open_pipes(struct urtwn_softc *);
                    167: static void    urtwn_close_pipes(struct urtwn_softc *);
                    168: static int     urtwn_alloc_rx_list(struct urtwn_softc *);
                    169: static void    urtwn_free_rx_list(struct urtwn_softc *);
                    170: static int     urtwn_alloc_tx_list(struct urtwn_softc *);
                    171: static void    urtwn_free_tx_list(struct urtwn_softc *);
                    172: static void    urtwn_task(void *);
                    173: static void    urtwn_do_async(struct urtwn_softc *,
                    174:                    void (*)(struct urtwn_softc *, void *), void *, int);
                    175: static void    urtwn_wait_async(struct urtwn_softc *);
                    176: static int     urtwn_write_region_1(struct urtwn_softc *, uint16_t, uint8_t *,
                    177:                    int);
1.12      christos  178: static void    urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
                    179: static void    urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
                    180: static void    urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
                    181: static int     urtwn_write_region(struct urtwn_softc *, uint16_t, uint8_t *,
                    182:                    int);
1.1       nonaka    183: static int     urtwn_read_region_1(struct urtwn_softc *, uint16_t, uint8_t *,
                    184:                    int);
1.12      christos  185: static uint8_t urtwn_read_1(struct urtwn_softc *, uint16_t);
                    186: static uint16_t        urtwn_read_2(struct urtwn_softc *, uint16_t);
                    187: static uint32_t        urtwn_read_4(struct urtwn_softc *, uint16_t);
1.1       nonaka    188: static int     urtwn_fw_cmd(struct urtwn_softc *, uint8_t, const void *, int);
1.12      christos  189: static void    urtwn_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t);
1.1       nonaka    190: static uint32_t        urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
                    191: static int     urtwn_llt_write(struct urtwn_softc *, uint32_t, uint32_t);
                    192: static uint8_t urtwn_efuse_read_1(struct urtwn_softc *, uint16_t);
                    193: static void    urtwn_efuse_read(struct urtwn_softc *);
                    194: static int     urtwn_read_chipid(struct urtwn_softc *);
1.12      christos  195: #ifdef URTWN_DEBUG
                    196: static void    urtwn_dump_rom(struct urtwn_softc *, struct r92c_rom *);
                    197: #endif
1.1       nonaka    198: static void    urtwn_read_rom(struct urtwn_softc *);
                    199: static int     urtwn_media_change(struct ifnet *);
                    200: static int     urtwn_ra_init(struct urtwn_softc *);
1.12      christos  201: static int     urtwn_get_nettype(struct urtwn_softc *);
                    202: static void    urtwn_set_nettype0_msr(struct urtwn_softc *, uint8_t);
1.1       nonaka    203: static void    urtwn_tsf_sync_enable(struct urtwn_softc *);
                    204: static void    urtwn_set_led(struct urtwn_softc *, int, int);
                    205: static void    urtwn_calib_to(void *);
                    206: static void    urtwn_calib_to_cb(struct urtwn_softc *, void *);
                    207: static void    urtwn_next_scan(void *);
                    208: static int     urtwn_newstate(struct ieee80211com *, enum ieee80211_state,
                    209:                    int);
                    210: static void    urtwn_newstate_cb(struct urtwn_softc *, void *);
                    211: static int     urtwn_wme_update(struct ieee80211com *);
                    212: static void    urtwn_wme_update_cb(struct urtwn_softc *, void *);
                    213: static void    urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t);
                    214: static int8_t  urtwn_get_rssi(struct urtwn_softc *, int, void *);
                    215: static void    urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int);
                    216: static void    urtwn_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    217: static void    urtwn_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status);
                    218: static int     urtwn_tx(struct urtwn_softc *, struct mbuf *,
1.12      christos  219:                    struct ieee80211_node *, struct urtwn_tx_data *);
1.1       nonaka    220: static void    urtwn_start(struct ifnet *);
                    221: static void    urtwn_watchdog(struct ifnet *);
                    222: static int     urtwn_ioctl(struct ifnet *, u_long, void *);
                    223: static int     urtwn_power_on(struct urtwn_softc *);
                    224: static int     urtwn_llt_init(struct urtwn_softc *);
                    225: static void    urtwn_fw_reset(struct urtwn_softc *);
                    226: static int     urtwn_fw_loadpage(struct urtwn_softc *, int, uint8_t *, int);
                    227: static int     urtwn_load_firmware(struct urtwn_softc *);
                    228: static int     urtwn_dma_init(struct urtwn_softc *);
                    229: static void    urtwn_mac_init(struct urtwn_softc *);
                    230: static void    urtwn_bb_init(struct urtwn_softc *);
                    231: static void    urtwn_rf_init(struct urtwn_softc *);
                    232: static void    urtwn_cam_init(struct urtwn_softc *);
                    233: static void    urtwn_pa_bias_init(struct urtwn_softc *);
                    234: static void    urtwn_rxfilter_init(struct urtwn_softc *);
                    235: static void    urtwn_edca_init(struct urtwn_softc *);
                    236: static void    urtwn_write_txpower(struct urtwn_softc *, int, uint16_t[]);
1.22      christos  237: static void    urtwn_get_txpower(struct urtwn_softc *, size_t, u_int, u_int,
1.1       nonaka    238:                    uint16_t[]);
                    239: static void    urtwn_set_txpower(struct urtwn_softc *, u_int, u_int);
                    240: static void    urtwn_set_chan(struct urtwn_softc *, struct ieee80211_channel *,
                    241:                    u_int);
                    242: static void    urtwn_iq_calib(struct urtwn_softc *, bool);
                    243: static void    urtwn_lc_calib(struct urtwn_softc *);
                    244: static void    urtwn_temp_calib(struct urtwn_softc *);
                    245: static int     urtwn_init(struct ifnet *);
                    246: static void    urtwn_stop(struct ifnet *, int);
1.16      jmcneill  247: static int     urtwn_reset(struct ifnet *);
1.1       nonaka    248: static void    urtwn_chip_stop(struct urtwn_softc *);
1.26    ! christos  249: static void    urtwn_newassoc(struct ieee80211_node *, int);
1.1       nonaka    250:
                    251: /* Aliases. */
                    252: #define        urtwn_bb_write  urtwn_write_4
                    253: #define        urtwn_bb_read   urtwn_read_4
                    254:
                    255: static int
                    256: urtwn_match(device_t parent, cfdata_t match, void *aux)
                    257: {
                    258:        struct usb_attach_arg *uaa = aux;
                    259:
                    260:        return ((usb_lookup(urtwn_devs, uaa->vendor, uaa->product) != NULL) ?
                    261:            UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
                    262: }
                    263:
                    264: static void
                    265: urtwn_attach(device_t parent, device_t self, void *aux)
                    266: {
                    267:        struct urtwn_softc *sc = device_private(self);
                    268:        struct ieee80211com *ic = &sc->sc_ic;
                    269:        struct ifnet *ifp = &sc->sc_if;
                    270:        struct usb_attach_arg *uaa = aux;
                    271:        char *devinfop;
1.22      christos  272:        size_t i;
                    273:        int error;
1.1       nonaka    274:
                    275:        sc->sc_dev = self;
                    276:        sc->sc_udev = uaa->device;
                    277:
                    278:        aprint_naive("\n");
                    279:        aprint_normal("\n");
                    280:
1.12      christos  281:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    282:
1.1       nonaka    283:        devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
                    284:        aprint_normal_dev(self, "%s\n", devinfop);
                    285:        usbd_devinfo_free(devinfop);
                    286:
                    287:        mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET);
1.12      christos  288:        mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE);
1.1       nonaka    289:        mutex_init(&sc->sc_fwcmd_mtx, MUTEX_DEFAULT, IPL_NONE);
1.12      christos  290:        mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
1.1       nonaka    291:
1.18      jmcneill  292:        usb_init_task(&sc->sc_task, urtwn_task, sc, 0);
1.1       nonaka    293:
                    294:        callout_init(&sc->sc_scan_to, 0);
                    295:        callout_setfunc(&sc->sc_scan_to, urtwn_next_scan, sc);
                    296:        callout_init(&sc->sc_calib_to, 0);
                    297:        callout_setfunc(&sc->sc_calib_to, urtwn_calib_to, sc);
                    298:
1.6       skrll     299:        error = usbd_set_config_no(sc->sc_udev, 1, 0);
                    300:        if (error != 0) {
                    301:                aprint_error_dev(self, "failed to set configuration"
                    302:                    ", err=%s\n", usbd_errstr(error));
1.1       nonaka    303:                goto fail;
                    304:        }
                    305:
                    306:        /* Get the first interface handle. */
                    307:        error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
                    308:        if (error != 0) {
                    309:                aprint_error_dev(self, "could not get interface handle\n");
                    310:                goto fail;
                    311:        }
                    312:
                    313:        error = urtwn_read_chipid(sc);
                    314:        if (error != 0) {
                    315:                aprint_error_dev(self, "unsupported test chip\n");
                    316:                goto fail;
                    317:        }
                    318:
                    319:        /* Determine number of Tx/Rx chains. */
                    320:        if (sc->chip & URTWN_CHIP_92C) {
                    321:                sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2;
                    322:                sc->nrxchains = 2;
                    323:        } else {
                    324:                sc->ntxchains = 1;
                    325:                sc->nrxchains = 1;
                    326:        }
                    327:        urtwn_read_rom(sc);
                    328:
1.22      christos  329:        aprint_normal_dev(self, "MAC/BB RTL%s, RF 6052 %zdT%zdR, address %s\n",
1.1       nonaka    330:            (sc->chip & URTWN_CHIP_92C) ? "8192CU" :
                    331:            (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
                    332:            (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" :
                    333:            "8188CUS", sc->ntxchains, sc->nrxchains,
                    334:            ether_sprintf(ic->ic_myaddr));
                    335:
                    336:        error = urtwn_open_pipes(sc);
                    337:        if (error != 0) {
                    338:                aprint_error_dev(sc->sc_dev, "could not open pipes\n");
                    339:                goto fail;
                    340:        }
                    341:        aprint_normal_dev(self, "%d rx pipe%s, %d tx pipe%s\n",
                    342:            sc->rx_npipe, sc->rx_npipe > 1 ? "s" : "",
                    343:            sc->tx_npipe, sc->tx_npipe > 1 ? "s" : "");
                    344:
                    345:        /*
                    346:         * Setup the 802.11 device.
                    347:         */
                    348:        ic->ic_ifp = ifp;
                    349:        ic->ic_phytype = IEEE80211_T_OFDM;      /* Not only, but not used. */
                    350:        ic->ic_opmode = IEEE80211_M_STA;        /* Default to BSS mode. */
                    351:        ic->ic_state = IEEE80211_S_INIT;
                    352:
                    353:        /* Set device capabilities. */
                    354:        ic->ic_caps =
                    355:            IEEE80211_C_MONITOR |       /* Monitor mode supported. */
1.26    ! christos  356:            IEEE80211_C_IBSS |          /* IBSS mode supported */
        !           357:            IEEE80211_C_HOSTAP |        /* HostAp mode supported */
1.1       nonaka    358:            IEEE80211_C_SHPREAMBLE |    /* Short preamble supported. */
                    359:            IEEE80211_C_SHSLOT |        /* Short slot time supported. */
                    360:            IEEE80211_C_WME |           /* 802.11e */
                    361:            IEEE80211_C_WPA;            /* 802.11i */
                    362:
                    363:        /* Set supported .11b and .11g rates. */
                    364:        ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
                    365:        ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
                    366:
                    367:        /* Set supported .11b and .11g channels (1 through 14). */
                    368:        for (i = 1; i <= 14; i++) {
                    369:                ic->ic_channels[i].ic_freq =
                    370:                    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
                    371:                ic->ic_channels[i].ic_flags =
                    372:                    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
                    373:                    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
                    374:        }
                    375:
                    376:        ifp->if_softc = sc;
                    377:        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
                    378:        ifp->if_init = urtwn_init;
                    379:        ifp->if_ioctl = urtwn_ioctl;
                    380:        ifp->if_start = urtwn_start;
                    381:        ifp->if_watchdog = urtwn_watchdog;
                    382:        IFQ_SET_READY(&ifp->if_snd);
                    383:        memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
                    384:
                    385:        if_attach(ifp);
                    386:        ieee80211_ifattach(ic);
1.16      jmcneill  387:
1.1       nonaka    388:        /* override default methods */
1.26    ! christos  389:        ic->ic_newassoc = urtwn_newassoc;
1.16      jmcneill  390:        ic->ic_reset = urtwn_reset;
1.1       nonaka    391:        ic->ic_wme.wme_update = urtwn_wme_update;
                    392:
                    393:        /* Override state transition machine. */
                    394:        sc->sc_newstate = ic->ic_newstate;
                    395:        ic->ic_newstate = urtwn_newstate;
                    396:        ieee80211_media_init(ic, urtwn_media_change, ieee80211_media_status);
                    397:
                    398:        bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
                    399:            sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
                    400:            &sc->sc_drvbpf);
                    401:
                    402:        sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
                    403:        sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
                    404:        sc->sc_rxtap.wr_ihdr.it_present = htole32(URTWN_RX_RADIOTAP_PRESENT);
                    405:
                    406:        sc->sc_txtap_len = sizeof(sc->sc_txtapu);
                    407:        sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
                    408:        sc->sc_txtap.wt_ihdr.it_present = htole32(URTWN_TX_RADIOTAP_PRESENT);
                    409:
                    410:        ieee80211_announce(ic);
                    411:
                    412:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
                    413:
                    414:        SET(sc->sc_flags, URTWN_FLAG_ATTACHED);
                    415:        return;
                    416:
                    417:  fail:
                    418:        sc->sc_dying = 1;
                    419:        aprint_error_dev(self, "attach failed\n");
                    420: }
                    421:
                    422: static int
                    423: urtwn_detach(device_t self, int flags)
                    424: {
                    425:        struct urtwn_softc *sc = device_private(self);
                    426:        struct ifnet *ifp = &sc->sc_if;
                    427:        int s;
                    428:
                    429:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    430:
                    431:        s = splusb();
                    432:
                    433:        sc->sc_dying = 1;
                    434:
                    435:        callout_stop(&sc->sc_scan_to);
                    436:        callout_stop(&sc->sc_calib_to);
                    437:
                    438:        if (ISSET(sc->sc_flags, URTWN_FLAG_ATTACHED)) {
                    439:                usb_rem_task(sc->sc_udev, &sc->sc_task);
                    440:                urtwn_stop(ifp, 0);
                    441:
                    442:                ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                    443:                bpf_detach(ifp);
                    444:                ieee80211_ifdetach(&sc->sc_ic);
                    445:                if_detach(ifp);
                    446:
                    447:                /* Abort and close Tx/Rx pipes. */
                    448:                urtwn_close_pipes(sc);
                    449:        }
                    450:
                    451:        splx(s);
                    452:
                    453:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
                    454:
                    455:        callout_destroy(&sc->sc_scan_to);
                    456:        callout_destroy(&sc->sc_calib_to);
1.12      christos  457:
                    458:        mutex_destroy(&sc->sc_write_mtx);
1.1       nonaka    459:        mutex_destroy(&sc->sc_fwcmd_mtx);
                    460:        mutex_destroy(&sc->sc_tx_mtx);
                    461:        mutex_destroy(&sc->sc_task_mtx);
                    462:
                    463:        return (0);
                    464: }
                    465:
                    466: static int
                    467: urtwn_activate(device_t self, enum devact act)
                    468: {
                    469:        struct urtwn_softc *sc = device_private(self);
                    470:
                    471:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    472:
                    473:        switch (act) {
                    474:        case DVACT_DEACTIVATE:
                    475:                if_deactivate(sc->sc_ic.ic_ifp);
                    476:                return (0);
                    477:        default:
                    478:                return (EOPNOTSUPP);
                    479:        }
                    480: }
                    481:
                    482: static int
                    483: urtwn_open_pipes(struct urtwn_softc *sc)
                    484: {
                    485:        /* Bulk-out endpoints addresses (from highest to lowest prio). */
                    486:        static const uint8_t epaddr[] = { 0x02, 0x03, 0x05 };
                    487:        usb_interface_descriptor_t *id;
                    488:        usb_endpoint_descriptor_t *ed;
1.22      christos  489:        size_t i, ntx = 0;
                    490:        int error;
1.1       nonaka    491:
                    492:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    493:
                    494:        /* Determine the number of bulk-out pipes. */
                    495:        id = usbd_get_interface_descriptor(sc->sc_iface);
                    496:        for (i = 0; i < id->bNumEndpoints; i++) {
                    497:                ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
                    498:                if (ed != NULL &&
                    499:                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
                    500:                    UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
                    501:                        ntx++;
                    502:        }
1.22      christos  503:        DPRINTFN(DBG_INIT, ("%s: %s: found %zd bulk-out pipes\n",
1.1       nonaka    504:            device_xname(sc->sc_dev), __func__, ntx));
                    505:        if (ntx == 0 || ntx > R92C_MAX_EPOUT) {
                    506:                aprint_error_dev(sc->sc_dev,
1.22      christos  507:                    "%zd: invalid number of Tx bulk pipes\n", ntx);
1.1       nonaka    508:                return (EIO);
                    509:        }
                    510:        sc->rx_npipe = 1;
                    511:        sc->tx_npipe = ntx;
                    512:
                    513:        /* Open bulk-in pipe at address 0x81. */
                    514:        error = usbd_open_pipe(sc->sc_iface, 0x81, USBD_EXCLUSIVE_USE,
                    515:            &sc->rx_pipe);
                    516:        if (error != 0) {
1.12      christos  517:                aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe"
                    518:                    ": %d\n", error);
1.1       nonaka    519:                goto fail;
                    520:        }
                    521:
                    522:        /* Open bulk-out pipes (up to 3). */
                    523:        for (i = 0; i < ntx; i++) {
                    524:                error = usbd_open_pipe(sc->sc_iface, epaddr[i],
                    525:                    USBD_EXCLUSIVE_USE, &sc->tx_pipe[i]);
                    526:                if (error != 0) {
                    527:                        aprint_error_dev(sc->sc_dev,
1.12      christos  528:                            "could not open Tx bulk pipe 0x%02x: %d\n",
                    529:                            epaddr[i], error);
1.1       nonaka    530:                        goto fail;
                    531:                }
                    532:        }
                    533:
                    534:        /* Map 802.11 access categories to USB pipes. */
                    535:        sc->ac2idx[WME_AC_BK] =
                    536:        sc->ac2idx[WME_AC_BE] = (ntx == 3) ? 2 : ((ntx == 2) ? 1 : 0);
                    537:        sc->ac2idx[WME_AC_VI] = (ntx == 3) ? 1 : 0;
                    538:        sc->ac2idx[WME_AC_VO] = 0;      /* Always use highest prio. */
                    539:
                    540:  fail:
                    541:        if (error != 0)
                    542:                urtwn_close_pipes(sc);
                    543:        return (error);
                    544: }
                    545:
                    546: static void
                    547: urtwn_close_pipes(struct urtwn_softc *sc)
                    548: {
1.22      christos  549:        usbd_pipe_handle pipe;
                    550:        size_t i;
1.1       nonaka    551:
                    552:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    553:
                    554:        /* Close Rx pipe. */
1.22      christos  555:        CTASSERT(sizeof(pipe) == sizeof(void *));
                    556:        pipe = atomic_swap_ptr(&sc->rx_pipe, NULL);
                    557:        if (pipe != NULL) {
                    558:                usbd_abort_pipe(pipe);
                    559:                usbd_close_pipe(pipe);
1.1       nonaka    560:        }
                    561:        /* Close Tx pipes. */
                    562:        for (i = 0; i < R92C_MAX_EPOUT; i++) {
1.22      christos  563:                pipe = atomic_swap_ptr(&sc->tx_pipe[i], NULL);
                    564:                if (pipe != NULL) {
                    565:                        usbd_abort_pipe(pipe);
                    566:                        usbd_close_pipe(pipe);
                    567:                }
1.1       nonaka    568:        }
                    569: }
                    570:
                    571: static int
                    572: urtwn_alloc_rx_list(struct urtwn_softc *sc)
                    573: {
                    574:        struct urtwn_rx_data *data;
1.22      christos  575:        size_t i;
                    576:        int error = 0;
1.1       nonaka    577:
                    578:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    579:
                    580:        for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
                    581:                data = &sc->rx_data[i];
                    582:
                    583:                data->sc = sc;  /* Backpointer for callbacks. */
                    584:
                    585:                data->xfer = usbd_alloc_xfer(sc->sc_udev);
                    586:                if (data->xfer == NULL) {
                    587:                        aprint_error_dev(sc->sc_dev,
                    588:                            "could not allocate xfer\n");
                    589:                        error = ENOMEM;
                    590:                        break;
                    591:                }
                    592:
                    593:                data->buf = usbd_alloc_buffer(data->xfer, URTWN_RXBUFSZ);
                    594:                if (data->buf == NULL) {
                    595:                        aprint_error_dev(sc->sc_dev,
                    596:                            "could not allocate xfer buffer\n");
                    597:                        error = ENOMEM;
                    598:                        break;
                    599:                }
                    600:        }
                    601:        if (error != 0)
                    602:                urtwn_free_rx_list(sc);
                    603:        return (error);
                    604: }
                    605:
                    606: static void
                    607: urtwn_free_rx_list(struct urtwn_softc *sc)
                    608: {
1.22      christos  609:        usbd_xfer_handle xfer;
                    610:        size_t i;
1.1       nonaka    611:
                    612:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    613:
                    614:        /* NB: Caller must abort pipe first. */
                    615:        for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
1.22      christos  616:                CTASSERT(sizeof(xfer) == sizeof(void *));
1.24      nonaka    617:                xfer = atomic_swap_ptr(&sc->rx_data[i].xfer, NULL);
1.22      christos  618:                if (xfer != NULL)
                    619:                        usbd_free_xfer(xfer);
1.1       nonaka    620:        }
                    621: }
                    622:
                    623: static int
                    624: urtwn_alloc_tx_list(struct urtwn_softc *sc)
                    625: {
                    626:        struct urtwn_tx_data *data;
1.22      christos  627:        size_t i;
                    628:        int error = 0;
1.1       nonaka    629:
                    630:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    631:
1.12      christos  632:        mutex_enter(&sc->sc_tx_mtx);
1.1       nonaka    633:        TAILQ_INIT(&sc->tx_free_list);
                    634:        for (i = 0; i < URTWN_TX_LIST_COUNT; i++) {
                    635:                data = &sc->tx_data[i];
                    636:
                    637:                data->sc = sc;  /* Backpointer for callbacks. */
                    638:
                    639:                data->xfer = usbd_alloc_xfer(sc->sc_udev);
                    640:                if (data->xfer == NULL) {
                    641:                        aprint_error_dev(sc->sc_dev,
                    642:                            "could not allocate xfer\n");
                    643:                        error = ENOMEM;
                    644:                        goto fail;
                    645:                }
                    646:
                    647:                data->buf = usbd_alloc_buffer(data->xfer, URTWN_TXBUFSZ);
                    648:                if (data->buf == NULL) {
                    649:                        aprint_error_dev(sc->sc_dev,
                    650:                            "could not allocate xfer buffer\n");
                    651:                        error = ENOMEM;
                    652:                        goto fail;
                    653:                }
                    654:
                    655:                /* Append this Tx buffer to our free list. */
                    656:                TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
                    657:        }
1.12      christos  658:        mutex_exit(&sc->sc_tx_mtx);
1.1       nonaka    659:        return (0);
                    660:
                    661:  fail:
                    662:        urtwn_free_tx_list(sc);
1.12      christos  663:        mutex_exit(&sc->sc_tx_mtx);
1.1       nonaka    664:        return (error);
                    665: }
                    666:
                    667: static void
                    668: urtwn_free_tx_list(struct urtwn_softc *sc)
                    669: {
1.22      christos  670:        usbd_xfer_handle xfer;
                    671:        size_t i;
1.1       nonaka    672:
                    673:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    674:
                    675:        /* NB: Caller must abort pipe first. */
                    676:        for (i = 0; i < URTWN_TX_LIST_COUNT; i++) {
1.22      christos  677:                CTASSERT(sizeof(xfer) == sizeof(void *));
                    678:                xfer = atomic_swap_ptr(&sc->tx_data[i].xfer, NULL);
                    679:                if (xfer != NULL)
                    680:                        usbd_free_xfer(xfer);
1.1       nonaka    681:        }
                    682: }
                    683:
                    684: static void
                    685: urtwn_task(void *arg)
                    686: {
                    687:        struct urtwn_softc *sc = arg;
                    688:        struct urtwn_host_cmd_ring *ring = &sc->cmdq;
                    689:        struct urtwn_host_cmd *cmd;
                    690:        int s;
                    691:
                    692:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    693:
                    694:        /* Process host commands. */
                    695:        s = splusb();
                    696:        mutex_spin_enter(&sc->sc_task_mtx);
                    697:        while (ring->next != ring->cur) {
                    698:                cmd = &ring->cmd[ring->next];
                    699:                mutex_spin_exit(&sc->sc_task_mtx);
                    700:                splx(s);
1.16      jmcneill  701:                /* Invoke callback with kernel lock held. */
1.1       nonaka    702:                cmd->cb(sc, cmd->data);
                    703:                s = splusb();
                    704:                mutex_spin_enter(&sc->sc_task_mtx);
                    705:                ring->queued--;
                    706:                ring->next = (ring->next + 1) % URTWN_HOST_CMD_RING_COUNT;
                    707:        }
                    708:        mutex_spin_exit(&sc->sc_task_mtx);
                    709:        wakeup(&sc->cmdq);
                    710:        splx(s);
                    711: }
                    712:
                    713: static void
                    714: urtwn_do_async(struct urtwn_softc *sc, void (*cb)(struct urtwn_softc *, void *),
                    715:     void *arg, int len)
                    716: {
                    717:        struct urtwn_host_cmd_ring *ring = &sc->cmdq;
                    718:        struct urtwn_host_cmd *cmd;
                    719:        int s;
                    720:
                    721:        DPRINTFN(DBG_FN, ("%s: %s: cb=%p, arg=%p, len=%d\n",
                    722:            device_xname(sc->sc_dev), __func__, cb, arg, len));
                    723:
                    724:        s = splusb();
                    725:        mutex_spin_enter(&sc->sc_task_mtx);
                    726:        cmd = &ring->cmd[ring->cur];
                    727:        cmd->cb = cb;
                    728:        KASSERT(len <= sizeof(cmd->data));
                    729:        memcpy(cmd->data, arg, len);
                    730:        ring->cur = (ring->cur + 1) % URTWN_HOST_CMD_RING_COUNT;
                    731:
                    732:        /* If there is no pending command already, schedule a task. */
                    733:        if (!sc->sc_dying && ++ring->queued == 1) {
                    734:                mutex_spin_exit(&sc->sc_task_mtx);
                    735:                usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
                    736:        } else
                    737:                mutex_spin_exit(&sc->sc_task_mtx);
                    738:        splx(s);
                    739: }
                    740:
                    741: static void
                    742: urtwn_wait_async(struct urtwn_softc *sc)
                    743: {
                    744:
                    745:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                    746:
                    747:        /* Wait for all queued asynchronous commands to complete. */
                    748:        while (sc->cmdq.queued > 0)
                    749:                tsleep(&sc->cmdq, 0, "endtask", 0);
                    750: }
                    751:
                    752: static int
                    753: urtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
                    754:     int len)
                    755: {
                    756:        usb_device_request_t req;
                    757:        usbd_status error;
                    758:
1.12      christos  759:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                    760:
1.1       nonaka    761:        req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
                    762:        req.bRequest = R92C_REQ_REGS;
                    763:        USETW(req.wValue, addr);
                    764:        USETW(req.wIndex, 0);
                    765:        USETW(req.wLength, len);
                    766:        error = usbd_do_request(sc->sc_udev, &req, buf);
                    767:        if (error != USBD_NORMAL_COMPLETION) {
                    768:                DPRINTFN(DBG_REG, ("%s: %s: error=%d: addr=0x%x, len=%d\n",
                    769:                    device_xname(sc->sc_dev), __func__, error, addr, len));
                    770:        }
                    771:        return (error);
                    772: }
                    773:
                    774: static void
                    775: urtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val)
                    776: {
                    777:
                    778:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n",
                    779:            device_xname(sc->sc_dev), __func__, addr, val));
                    780:
                    781:        urtwn_write_region_1(sc, addr, &val, 1);
                    782: }
                    783:
                    784: static void
                    785: urtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val)
                    786: {
                    787:        uint8_t buf[2];
                    788:
                    789:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n",
                    790:            device_xname(sc->sc_dev), __func__, addr, val));
                    791:
                    792:        buf[0] = (uint8_t)val;
                    793:        buf[1] = (uint8_t)(val >> 8);
                    794:        urtwn_write_region_1(sc, addr, buf, 2);
                    795: }
                    796:
                    797: static void
                    798: urtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val)
                    799: {
                    800:        uint8_t buf[4];
                    801:
                    802:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n",
                    803:            device_xname(sc->sc_dev), __func__, addr, val));
                    804:
                    805:        buf[0] = (uint8_t)val;
                    806:        buf[1] = (uint8_t)(val >> 8);
                    807:        buf[2] = (uint8_t)(val >> 16);
                    808:        buf[3] = (uint8_t)(val >> 24);
                    809:        urtwn_write_region_1(sc, addr, buf, 4);
                    810: }
                    811:
                    812: static int
                    813: urtwn_write_region(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, int len)
                    814: {
                    815:
                    816:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, len=0x%x\n",
                    817:            device_xname(sc->sc_dev), __func__, addr, len));
                    818:
                    819:        return urtwn_write_region_1(sc, addr, buf, len);
                    820: }
                    821:
                    822: static int
                    823: urtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
                    824:     int len)
                    825: {
                    826:        usb_device_request_t req;
                    827:        usbd_status error;
                    828:
                    829:        req.bmRequestType = UT_READ_VENDOR_DEVICE;
                    830:        req.bRequest = R92C_REQ_REGS;
                    831:        USETW(req.wValue, addr);
                    832:        USETW(req.wIndex, 0);
                    833:        USETW(req.wLength, len);
                    834:        error = usbd_do_request(sc->sc_udev, &req, buf);
                    835:        if (error != USBD_NORMAL_COMPLETION) {
                    836:                DPRINTFN(DBG_REG, ("%s: %s: error=%d: addr=0x%x, len=%d\n",
                    837:                    device_xname(sc->sc_dev), __func__, error, addr, len));
                    838:        }
                    839:        return (error);
                    840: }
                    841:
                    842: static uint8_t
                    843: urtwn_read_1(struct urtwn_softc *sc, uint16_t addr)
                    844: {
                    845:        uint8_t val;
                    846:
                    847:        if (urtwn_read_region_1(sc, addr, &val, 1) != USBD_NORMAL_COMPLETION)
                    848:                return (0xff);
                    849:
                    850:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n",
                    851:            device_xname(sc->sc_dev), __func__, addr, val));
                    852:        return (val);
                    853: }
                    854:
                    855: static uint16_t
                    856: urtwn_read_2(struct urtwn_softc *sc, uint16_t addr)
                    857: {
                    858:        uint8_t buf[2];
                    859:        uint16_t val;
                    860:
                    861:        if (urtwn_read_region_1(sc, addr, buf, 2) != USBD_NORMAL_COMPLETION)
                    862:                return (0xffff);
                    863:
                    864:        val = LE_READ_2(&buf[0]);
                    865:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n",
                    866:            device_xname(sc->sc_dev), __func__, addr, val));
                    867:        return (val);
                    868: }
                    869:
                    870: static uint32_t
                    871: urtwn_read_4(struct urtwn_softc *sc, uint16_t addr)
                    872: {
                    873:        uint8_t buf[4];
                    874:        uint32_t val;
                    875:
                    876:        if (urtwn_read_region_1(sc, addr, buf, 4) != USBD_NORMAL_COMPLETION)
                    877:                return (0xffffffff);
                    878:
                    879:        val = LE_READ_4(&buf[0]);
                    880:        DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n",
                    881:            device_xname(sc->sc_dev), __func__, addr, val));
                    882:        return (val);
                    883: }
                    884:
                    885: static int
                    886: urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len)
                    887: {
                    888:        struct r92c_fw_cmd cmd;
                    889:        uint8_t *cp;
                    890:        int fwcur;
                    891:        int ntries;
                    892:
                    893:        DPRINTFN(DBG_REG, ("%s: %s: id=%d, buf=%p, len=%d\n",
                    894:            device_xname(sc->sc_dev), __func__, id, buf, len));
                    895:
1.12      christos  896:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                    897:
1.1       nonaka    898:        mutex_enter(&sc->sc_fwcmd_mtx);
                    899:        fwcur = sc->fwcur;
                    900:        sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
                    901:        mutex_exit(&sc->sc_fwcmd_mtx);
                    902:
                    903:        /* Wait for current FW box to be empty. */
                    904:        for (ntries = 0; ntries < 100; ntries++) {
                    905:                if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << fwcur)))
                    906:                        break;
                    907:                DELAY(1);
                    908:        }
                    909:        if (ntries == 100) {
                    910:                aprint_error_dev(sc->sc_dev,
                    911:                    "could not send firmware command %d\n", id);
                    912:                return (ETIMEDOUT);
                    913:        }
                    914:
                    915:        memset(&cmd, 0, sizeof(cmd));
                    916:        KASSERT(len <= sizeof(cmd.msg));
                    917:        memcpy(cmd.msg, buf, len);
                    918:
                    919:        /* Write the first word last since that will trigger the FW. */
                    920:        cp = (uint8_t *)&cmd;
                    921:        if (len >= 4) {
                    922:                cmd.id = id | R92C_CMD_FLAG_EXT;
                    923:                urtwn_write_region(sc, R92C_HMEBOX_EXT(fwcur), &cp[1], 2);
                    924:                urtwn_write_4(sc, R92C_HMEBOX(fwcur),
                    925:                    cp[0] + (cp[3] << 8) + (cp[4] << 16) + (cp[5] << 24));
                    926:        } else {
                    927:                cmd.id = id;
                    928:                urtwn_write_region(sc, R92C_HMEBOX(fwcur), cp, len);
                    929:        }
                    930:
                    931:        return (0);
                    932: }
                    933:
                    934: static void
                    935: urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
                    936: {
                    937:
                    938:        urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
                    939:            SM(R92C_LSSI_PARAM_ADDR, addr) | SM(R92C_LSSI_PARAM_DATA, val));
                    940: }
                    941:
                    942: static uint32_t
                    943: urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr)
                    944: {
                    945:        uint32_t reg[R92C_MAX_CHAINS], val;
                    946:
                    947:        reg[0] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(0));
                    948:        if (chain != 0) {
                    949:                reg[chain] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
                    950:        }
                    951:
                    952:        urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
                    953:            reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE);
                    954:        DELAY(1000);
                    955:
                    956:        urtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
                    957:            RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) |
                    958:            R92C_HSSI_PARAM2_READ_EDGE);
                    959:        DELAY(1000);
                    960:
                    961:        urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
                    962:            reg[0] | R92C_HSSI_PARAM2_READ_EDGE);
                    963:        DELAY(1000);
                    964:
                    965:        if (urtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI) {
                    966:                val = urtwn_bb_read(sc, R92C_HSPI_READBACK(chain));
                    967:        } else {
                    968:                val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain));
                    969:        }
                    970:        return (MS(val, R92C_LSSI_READBACK_DATA));
                    971: }
                    972:
                    973: static int
                    974: urtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
                    975: {
                    976:        int ntries;
                    977:
1.12      christos  978:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                    979:
1.1       nonaka    980:        urtwn_write_4(sc, R92C_LLT_INIT,
                    981:            SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
                    982:            SM(R92C_LLT_INIT_ADDR, addr) |
                    983:            SM(R92C_LLT_INIT_DATA, data));
                    984:        /* Wait for write operation to complete. */
                    985:        for (ntries = 0; ntries < 20; ntries++) {
                    986:                if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
                    987:                    R92C_LLT_INIT_OP_NO_ACTIVE) {
                    988:                        /* Done */
                    989:                        return (0);
                    990:                }
                    991:                DELAY(5);
                    992:        }
                    993:        return (ETIMEDOUT);
                    994: }
                    995:
                    996: static uint8_t
                    997: urtwn_efuse_read_1(struct urtwn_softc *sc, uint16_t addr)
                    998: {
                    999:        uint32_t reg;
                   1000:        int ntries;
                   1001:
1.12      christos 1002:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   1003:
1.1       nonaka   1004:        reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
                   1005:        reg = RW(reg, R92C_EFUSE_CTRL_ADDR, addr);
                   1006:        reg &= ~R92C_EFUSE_CTRL_VALID;
                   1007:        urtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
                   1008:
                   1009:        /* Wait for read operation to complete. */
                   1010:        for (ntries = 0; ntries < 100; ntries++) {
                   1011:                reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
                   1012:                if (reg & R92C_EFUSE_CTRL_VALID) {
                   1013:                        /* Done */
                   1014:                        return (MS(reg, R92C_EFUSE_CTRL_DATA));
                   1015:                }
                   1016:                DELAY(5);
                   1017:        }
                   1018:        aprint_error_dev(sc->sc_dev,
                   1019:            "could not read efuse byte at address 0x%04x\n", addr);
                   1020:        return (0xff);
                   1021: }
                   1022:
                   1023: static void
                   1024: urtwn_efuse_read(struct urtwn_softc *sc)
                   1025: {
                   1026:        uint8_t *rom = (uint8_t *)&sc->rom;
                   1027:        uint32_t reg;
                   1028:        uint16_t addr = 0;
                   1029:        uint8_t off, msk;
1.22      christos 1030:        size_t i;
1.1       nonaka   1031:
                   1032:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1033:
1.12      christos 1034:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   1035:
1.1       nonaka   1036:        reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
                   1037:        if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
                   1038:                urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
                   1039:                    reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
                   1040:        }
                   1041:        reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
                   1042:        if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
                   1043:                urtwn_write_2(sc, R92C_SYS_FUNC_EN,
                   1044:                    reg | R92C_SYS_FUNC_EN_ELDR);
                   1045:        }
                   1046:        reg = urtwn_read_2(sc, R92C_SYS_CLKR);
                   1047:        if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
                   1048:            (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
                   1049:                urtwn_write_2(sc, R92C_SYS_CLKR,
                   1050:                    reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
                   1051:        }
                   1052:        memset(&sc->rom, 0xff, sizeof(sc->rom));
                   1053:        while (addr < 512) {
                   1054:                reg = urtwn_efuse_read_1(sc, addr);
                   1055:                if (reg == 0xff)
                   1056:                        break;
                   1057:                addr++;
                   1058:                off = reg >> 4;
                   1059:                msk = reg & 0xf;
                   1060:                for (i = 0; i < 4; i++) {
                   1061:                        if (msk & (1U << i))
                   1062:                                continue;
                   1063:
                   1064:                        rom[off * 8 + i * 2 + 0] = urtwn_efuse_read_1(sc, addr);
                   1065:                        addr++;
                   1066:                        rom[off * 8 + i * 2 + 1] = urtwn_efuse_read_1(sc, addr);
                   1067:                        addr++;
                   1068:                }
                   1069:        }
                   1070: #ifdef URTWN_DEBUG
                   1071:        if (urtwn_debug & DBG_INIT) {
                   1072:                /* Dump ROM content. */
                   1073:                printf("%s: %s", device_xname(sc->sc_dev), __func__);
                   1074:                for (i = 0; i < (int)sizeof(sc->rom); i++)
                   1075:                        printf(":%02x", rom[i]);
                   1076:                printf("\n");
                   1077:        }
                   1078: #endif
                   1079: }
                   1080:
                   1081: static int
                   1082: urtwn_read_chipid(struct urtwn_softc *sc)
                   1083: {
                   1084:        uint32_t reg;
                   1085:
                   1086:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1087:
                   1088:        sc->chip = 0;
                   1089:        reg = urtwn_read_4(sc, R92C_SYS_CFG);
                   1090:        if (reg & R92C_SYS_CFG_TRP_VAUX_EN) {
                   1091:                /* test chip, not supported */
                   1092:                return (EIO);
                   1093:        }
                   1094:        if (reg & R92C_SYS_CFG_TYPE_92C) {
                   1095:                sc->chip |= URTWN_CHIP_92C;
                   1096:                /* Check if it is a castrated 8192C. */
                   1097:                if (MS(urtwn_read_4(sc, R92C_HPON_FSM),
                   1098:                    R92C_HPON_FSM_CHIP_BONDING_ID) ==
                   1099:                    R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R) {
                   1100:                        sc->chip |= URTWN_CHIP_92C_1T2R;
                   1101:                }
                   1102:        }
                   1103:        if (reg & R92C_SYS_CFG_VENDOR_UMC) {
                   1104:                sc->chip |= URTWN_CHIP_UMC;
                   1105:                if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0) {
                   1106:                        sc->chip |= URTWN_CHIP_UMC_A_CUT;
                   1107:                }
                   1108:        }
                   1109:        return (0);
                   1110: }
                   1111:
                   1112: #ifdef URTWN_DEBUG
                   1113: static void
                   1114: urtwn_dump_rom(struct urtwn_softc *sc, struct r92c_rom *rp)
                   1115: {
                   1116:
                   1117:        aprint_normal_dev(sc->sc_dev,
                   1118:            "id 0x%04x, dbg_sel 0x%x, vid 0x%x, pid 0x%x\n",
                   1119:            rp->id, rp->dbg_sel, rp->vid, rp->pid);
                   1120:
                   1121:        aprint_normal_dev(sc->sc_dev,
                   1122:            "usb_opt 0x%x, ep_setting 0x%x, usb_phy 0x%x\n",
                   1123:            rp->usb_opt, rp->ep_setting, rp->usb_phy);
                   1124:
                   1125:        aprint_normal_dev(sc->sc_dev,
                   1126:            "macaddr %02x:%02x:%02x:%02x:%02x:%02x\n",
                   1127:            rp->macaddr[0], rp->macaddr[1],
                   1128:            rp->macaddr[2], rp->macaddr[3],
                   1129:            rp->macaddr[4], rp->macaddr[5]);
                   1130:
                   1131:        aprint_normal_dev(sc->sc_dev,
                   1132:            "string %s, subcustomer_id 0x%x\n",
                   1133:            rp->string, rp->subcustomer_id);
                   1134:
                   1135:        aprint_normal_dev(sc->sc_dev,
                   1136:            "cck_tx_pwr c0: %d %d %d, c1: %d %d %d\n",
                   1137:            rp->cck_tx_pwr[0][0], rp->cck_tx_pwr[0][1], rp->cck_tx_pwr[0][2],
                   1138:            rp->cck_tx_pwr[1][0], rp->cck_tx_pwr[1][1], rp->cck_tx_pwr[1][2]);
                   1139:
                   1140:        aprint_normal_dev(sc->sc_dev,
                   1141:            "ht40_1s_tx_pwr c0 %d %d %d, c1 %d %d %d\n",
                   1142:            rp->ht40_1s_tx_pwr[0][0], rp->ht40_1s_tx_pwr[0][1],
                   1143:            rp->ht40_1s_tx_pwr[0][2],
                   1144:            rp->ht40_1s_tx_pwr[1][0], rp->ht40_1s_tx_pwr[1][1],
                   1145:            rp->ht40_1s_tx_pwr[1][2]);
                   1146:
                   1147:        aprint_normal_dev(sc->sc_dev,
                   1148:            "ht40_2s_tx_pwr_diff c0: %d %d %d, c1: %d %d %d\n",
                   1149:            rp->ht40_2s_tx_pwr_diff[0] & 0xf, rp->ht40_2s_tx_pwr_diff[1] & 0xf,
                   1150:            rp->ht40_2s_tx_pwr_diff[2] & 0xf,
                   1151:            rp->ht40_2s_tx_pwr_diff[0] >> 4, rp->ht40_2s_tx_pwr_diff[1] & 0xf,
                   1152:            rp->ht40_2s_tx_pwr_diff[2] >> 4);
                   1153:
                   1154:        aprint_normal_dev(sc->sc_dev,
                   1155:            "ht20_tx_pwr_diff c0: %d %d %d, c1: %d %d %d\n",
                   1156:            rp->ht20_tx_pwr_diff[0] & 0xf, rp->ht20_tx_pwr_diff[1] & 0xf,
                   1157:            rp->ht20_tx_pwr_diff[2] & 0xf,
                   1158:            rp->ht20_tx_pwr_diff[0] >> 4, rp->ht20_tx_pwr_diff[1] >> 4,
                   1159:            rp->ht20_tx_pwr_diff[2] >> 4);
                   1160:
                   1161:        aprint_normal_dev(sc->sc_dev,
                   1162:            "ofdm_tx_pwr_diff c0: %d %d %d, c1: %d %d %d\n",
                   1163:            rp->ofdm_tx_pwr_diff[0] & 0xf, rp->ofdm_tx_pwr_diff[1] & 0xf,
                   1164:            rp->ofdm_tx_pwr_diff[2] & 0xf,
                   1165:            rp->ofdm_tx_pwr_diff[0] >> 4, rp->ofdm_tx_pwr_diff[1] >> 4,
                   1166:            rp->ofdm_tx_pwr_diff[2] >> 4);
                   1167:
                   1168:        aprint_normal_dev(sc->sc_dev,
                   1169:            "ht40_max_pwr_offset c0: %d %d %d, c1: %d %d %d\n",
                   1170:            rp->ht40_max_pwr[0] & 0xf, rp->ht40_max_pwr[1] & 0xf,
                   1171:            rp->ht40_max_pwr[2] & 0xf,
                   1172:            rp->ht40_max_pwr[0] >> 4, rp->ht40_max_pwr[1] >> 4,
                   1173:            rp->ht40_max_pwr[2] >> 4);
                   1174:
                   1175:        aprint_normal_dev(sc->sc_dev,
                   1176:            "ht20_max_pwr_offset c0: %d %d %d, c1: %d %d %d\n",
                   1177:            rp->ht20_max_pwr[0] & 0xf, rp->ht20_max_pwr[1] & 0xf,
                   1178:            rp->ht20_max_pwr[2] & 0xf,
                   1179:            rp->ht20_max_pwr[0] >> 4, rp->ht20_max_pwr[1] >> 4,
                   1180:            rp->ht20_max_pwr[2] >> 4);
                   1181:
                   1182:        aprint_normal_dev(sc->sc_dev,
                   1183:            "xtal_calib %d, tssi %d %d, thermal %d\n",
                   1184:            rp->xtal_calib, rp->tssi[0], rp->tssi[1], rp->thermal_meter);
                   1185:
                   1186:        aprint_normal_dev(sc->sc_dev,
                   1187:            "rf_opt1 0x%x, rf_opt2 0x%x, rf_opt3 0x%x, rf_opt4 0x%x\n",
                   1188:            rp->rf_opt1, rp->rf_opt2, rp->rf_opt3, rp->rf_opt4);
                   1189:
                   1190:        aprint_normal_dev(sc->sc_dev,
                   1191:            "channnel_plan %d, version %d customer_id 0x%x\n",
                   1192:            rp->channel_plan, rp->version, rp->curstomer_id);
                   1193: }
                   1194: #endif
                   1195:
                   1196: static void
                   1197: urtwn_read_rom(struct urtwn_softc *sc)
                   1198: {
                   1199:        struct ieee80211com *ic = &sc->sc_ic;
                   1200:        struct r92c_rom *rom = &sc->rom;
                   1201:
                   1202:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1203:
1.12      christos 1204:        mutex_enter(&sc->sc_write_mtx);
                   1205:
1.1       nonaka   1206:        /* Read full ROM image. */
                   1207:        urtwn_efuse_read(sc);
                   1208: #ifdef URTWN_DEBUG
                   1209:        if (urtwn_debug & DBG_REG)
                   1210:                urtwn_dump_rom(sc, rom);
                   1211: #endif
                   1212:
                   1213:        /* XXX Weird but this is what the vendor driver does. */
                   1214:        sc->pa_setting = urtwn_efuse_read_1(sc, 0x1fa);
                   1215:        sc->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE);
                   1216:        sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
                   1217:
                   1218:        DPRINTFN(DBG_INIT,
                   1219:            ("%s: %s: PA setting=0x%x, board=0x%x, regulatory=%d\n",
                   1220:            device_xname(sc->sc_dev), __func__, sc->pa_setting,
                   1221:            sc->board_type, sc->regulatory));
                   1222:
                   1223:        IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr);
1.12      christos 1224:
                   1225:        mutex_exit(&sc->sc_write_mtx);
1.1       nonaka   1226: }
                   1227:
                   1228: static int
                   1229: urtwn_media_change(struct ifnet *ifp)
                   1230: {
                   1231: #ifdef URTWN_DEBUG
                   1232:        struct urtwn_softc *sc = ifp->if_softc;
                   1233: #endif
                   1234:        int error;
                   1235:
                   1236:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1237:
                   1238:        if ((error = ieee80211_media_change(ifp)) != ENETRESET)
                   1239:                return (error);
                   1240:
                   1241:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
                   1242:            (IFF_UP | IFF_RUNNING)) {
                   1243:                urtwn_init(ifp);
                   1244:        }
                   1245:        return (0);
                   1246: }
                   1247:
                   1248: /*
                   1249:  * Initialize rate adaptation in firmware.
                   1250:  */
                   1251: static int
                   1252: urtwn_ra_init(struct urtwn_softc *sc)
                   1253: {
                   1254:        static const uint8_t map[] = {
                   1255:                2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
                   1256:        };
                   1257:        struct ieee80211com *ic = &sc->sc_ic;
                   1258:        struct ieee80211_node *ni = ic->ic_bss;
                   1259:        struct ieee80211_rateset *rs = &ni->ni_rates;
                   1260:        struct r92c_fw_cmd_macid_cfg cmd;
                   1261:        uint32_t rates, basicrates;
                   1262:        uint32_t mask;
                   1263:        uint8_t mode;
1.22      christos 1264:        size_t maxrate, maxbasicrate, i, j;
                   1265:        int error;
1.1       nonaka   1266:
                   1267:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1268:
1.12      christos 1269:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   1270:
1.1       nonaka   1271:        /* Get normal and basic rates mask. */
                   1272:        rates = basicrates = 0;
                   1273:        maxrate = maxbasicrate = 0;
                   1274:        for (i = 0; i < rs->rs_nrates; i++) {
                   1275:                /* Convert 802.11 rate to HW rate index. */
1.22      christos 1276:                for (j = 0; j < __arraycount(map); j++) {
1.1       nonaka   1277:                        if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == map[j]) {
                   1278:                                break;
                   1279:                        }
                   1280:                }
                   1281:                if (j == __arraycount(map)) {
                   1282:                        /* Unknown rate, skip. */
                   1283:                        continue;
                   1284:                }
                   1285:
                   1286:                rates |= 1U << j;
                   1287:                if (j > maxrate) {
                   1288:                        maxrate = j;
                   1289:                }
                   1290:
                   1291:                if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) {
                   1292:                        basicrates |= 1U << j;
                   1293:                        if (j > maxbasicrate) {
                   1294:                                maxbasicrate = j;
                   1295:                        }
                   1296:                }
                   1297:        }
                   1298:        if (ic->ic_curmode == IEEE80211_MODE_11B) {
                   1299:                mode = R92C_RAID_11B;
                   1300:        } else {
                   1301:                mode = R92C_RAID_11BG;
                   1302:        }
                   1303:        DPRINTFN(DBG_INIT, ("%s: %s: mode=0x%x rates=0x%x, basicrates=0x%x, "
1.22      christos 1304:            "maxrate=%zx, maxbasicrate=%zx\n",
1.1       nonaka   1305:            device_xname(sc->sc_dev), __func__, mode, rates, basicrates,
                   1306:            maxrate, maxbasicrate));
                   1307:        if (basicrates == 0) {
                   1308:                basicrates |= 1;        /* add 1Mbps */
                   1309:        }
                   1310:
                   1311:        /* Set rates mask for group addressed frames. */
                   1312:        cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID;
                   1313:        mask = (mode << 28) | basicrates;
                   1314:        cmd.mask[0] = (uint8_t)mask;
                   1315:        cmd.mask[1] = (uint8_t)(mask >> 8);
                   1316:        cmd.mask[2] = (uint8_t)(mask >> 16);
                   1317:        cmd.mask[3] = (uint8_t)(mask >> 24);
                   1318:        error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
                   1319:        if (error != 0) {
                   1320:                aprint_error_dev(sc->sc_dev,
                   1321:                    "could not add broadcast station\n");
                   1322:                return (error);
                   1323:        }
                   1324:        /* Set initial MRR rate. */
1.22      christos 1325:        DPRINTFN(DBG_INIT, ("%s: %s: maxbasicrate=%zd\n",
1.1       nonaka   1326:            device_xname(sc->sc_dev), __func__, maxbasicrate));
                   1327:        urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BC), maxbasicrate);
                   1328:
                   1329:        /* Set rates mask for unicast frames. */
                   1330:        cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID;
                   1331:        mask = (mode << 28) | rates;
                   1332:        cmd.mask[0] = (uint8_t)mask;
                   1333:        cmd.mask[1] = (uint8_t)(mask >> 8);
                   1334:        cmd.mask[2] = (uint8_t)(mask >> 16);
                   1335:        cmd.mask[3] = (uint8_t)(mask >> 24);
                   1336:        error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
                   1337:        if (error != 0) {
                   1338:                aprint_error_dev(sc->sc_dev, "could not add BSS station\n");
                   1339:                return (error);
                   1340:        }
                   1341:        /* Set initial MRR rate. */
1.22      christos 1342:        DPRINTFN(DBG_INIT, ("%s: %s: maxrate=%zd\n", device_xname(sc->sc_dev),
1.1       nonaka   1343:            __func__, maxrate));
                   1344:        urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BSS), maxrate);
                   1345:
                   1346:        /* Indicate highest supported rate. */
                   1347:        ni->ni_txrate = rs->rs_nrates - 1;
                   1348:
                   1349:        return (0);
                   1350: }
                   1351:
                   1352: static int
                   1353: urtwn_get_nettype(struct urtwn_softc *sc)
                   1354: {
                   1355:        struct ieee80211com *ic = &sc->sc_ic;
                   1356:        int type;
                   1357:
                   1358:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1359:
                   1360:        switch (ic->ic_opmode) {
                   1361:        case IEEE80211_M_STA:
                   1362:                type = R92C_CR_NETTYPE_INFRA;
                   1363:                break;
                   1364:
                   1365:        case IEEE80211_M_IBSS:
                   1366:                type = R92C_CR_NETTYPE_ADHOC;
                   1367:                break;
                   1368:
                   1369:        default:
                   1370:                type = R92C_CR_NETTYPE_NOLINK;
                   1371:                break;
                   1372:        }
                   1373:
                   1374:        return (type);
                   1375: }
                   1376:
                   1377: static void
                   1378: urtwn_set_nettype0_msr(struct urtwn_softc *sc, uint8_t type)
                   1379: {
                   1380:        uint8_t reg;
                   1381:
                   1382:        DPRINTFN(DBG_FN, ("%s: %s: type=%d\n", device_xname(sc->sc_dev),
                   1383:            __func__, type));
                   1384:
1.12      christos 1385:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   1386:
1.1       nonaka   1387:        reg = urtwn_read_1(sc, R92C_CR + 2) & 0x0c;
                   1388:        urtwn_write_1(sc, R92C_CR + 2, reg | type);
                   1389: }
                   1390:
                   1391: static void
                   1392: urtwn_tsf_sync_enable(struct urtwn_softc *sc)
                   1393: {
                   1394:        struct ieee80211_node *ni = sc->sc_ic.ic_bss;
                   1395:        uint64_t tsf;
                   1396:
                   1397:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1398:
1.12      christos 1399:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   1400:
1.1       nonaka   1401:        /* Enable TSF synchronization. */
                   1402:        urtwn_write_1(sc, R92C_BCN_CTRL,
                   1403:            urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0);
                   1404:
                   1405:        /* Correct TSF */
                   1406:        urtwn_write_1(sc, R92C_BCN_CTRL,
                   1407:            urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN);
                   1408:
                   1409:        /* Set initial TSF. */
                   1410:        tsf = ni->ni_tstamp.tsf;
                   1411:        tsf = le64toh(tsf);
                   1412:        tsf = tsf - (tsf % (ni->ni_intval * IEEE80211_DUR_TU));
                   1413:        tsf -= IEEE80211_DUR_TU;
                   1414:        urtwn_write_4(sc, R92C_TSFTR + 0, (uint32_t)tsf);
                   1415:        urtwn_write_4(sc, R92C_TSFTR + 4, (uint32_t)(tsf >> 32));
                   1416:
                   1417:        urtwn_write_1(sc, R92C_BCN_CTRL,
                   1418:            urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN);
                   1419: }
                   1420:
                   1421: static void
                   1422: urtwn_set_led(struct urtwn_softc *sc, int led, int on)
                   1423: {
                   1424:        uint8_t reg;
                   1425:
                   1426:        DPRINTFN(DBG_FN, ("%s: %s: led=%d, on=%d\n", device_xname(sc->sc_dev),
                   1427:            __func__, led, on));
                   1428:
1.12      christos 1429:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   1430:
1.1       nonaka   1431:        if (led == URTWN_LED_LINK) {
                   1432:                reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
                   1433:                if (!on) {
                   1434:                        reg |= R92C_LEDCFG0_DIS;
                   1435:                }
                   1436:                urtwn_write_1(sc, R92C_LEDCFG0, reg);
                   1437:                sc->ledlink = on;       /* Save LED state. */
                   1438:        }
                   1439: }
                   1440:
                   1441: static void
                   1442: urtwn_calib_to(void *arg)
                   1443: {
                   1444:        struct urtwn_softc *sc = arg;
                   1445:
                   1446:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1447:
                   1448:        if (sc->sc_dying)
                   1449:                return;
                   1450:
                   1451:        /* Do it in a process context. */
                   1452:        urtwn_do_async(sc, urtwn_calib_to_cb, NULL, 0);
                   1453: }
                   1454:
                   1455: /* ARGSUSED */
                   1456: static void
                   1457: urtwn_calib_to_cb(struct urtwn_softc *sc, void *arg)
                   1458: {
                   1459:        struct r92c_fw_cmd_rssi cmd;
                   1460:
                   1461:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1462:
                   1463:        if (sc->sc_ic.ic_state != IEEE80211_S_RUN)
                   1464:                goto restart_timer;
                   1465:
1.12      christos 1466:        mutex_enter(&sc->sc_write_mtx);
1.1       nonaka   1467:        if (sc->avg_pwdb != -1) {
                   1468:                /* Indicate Rx signal strength to FW for rate adaptation. */
                   1469:                memset(&cmd, 0, sizeof(cmd));
                   1470:                cmd.macid = 0;  /* BSS. */
                   1471:                cmd.pwdb = sc->avg_pwdb;
                   1472:                DPRINTFN(DBG_RF, ("%s: %s: sending RSSI command avg=%d\n",
                   1473:                    device_xname(sc->sc_dev), __func__, sc->avg_pwdb));
                   1474:                urtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, sizeof(cmd));
                   1475:        }
                   1476:
                   1477:        /* Do temperature compensation. */
                   1478:        urtwn_temp_calib(sc);
1.12      christos 1479:        mutex_exit(&sc->sc_write_mtx);
1.1       nonaka   1480:
                   1481:  restart_timer:
                   1482:        if (!sc->sc_dying) {
                   1483:                /* Restart calibration timer. */
                   1484:                callout_schedule(&sc->sc_calib_to, hz);
                   1485:        }
                   1486: }
                   1487:
                   1488: static void
                   1489: urtwn_next_scan(void *arg)
                   1490: {
                   1491:        struct urtwn_softc *sc = arg;
1.16      jmcneill 1492:        int s;
1.1       nonaka   1493:
                   1494:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1495:
                   1496:        if (sc->sc_dying)
                   1497:                return;
                   1498:
1.16      jmcneill 1499:        s = splnet();
1.1       nonaka   1500:        if (sc->sc_ic.ic_state == IEEE80211_S_SCAN)
                   1501:                ieee80211_next_scan(&sc->sc_ic);
1.16      jmcneill 1502:        splx(s);
1.1       nonaka   1503: }
                   1504:
1.26    ! christos 1505: static void
        !          1506: urtwn_newassoc(struct ieee80211_node *ni, int isnew)
        !          1507: {
        !          1508:        DPRINTFN(DBG_FN, ("%s: new node %s\n", __func__,
        !          1509:            ether_sprintf(ni->ni_macaddr)));
        !          1510:        /* start with lowest Tx rate */
        !          1511:        ni->ni_txrate = 0;
        !          1512: }
        !          1513:
1.1       nonaka   1514: static int
                   1515: urtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
                   1516: {
                   1517:        struct urtwn_softc *sc = ic->ic_ifp->if_softc;
                   1518:        struct urtwn_cmd_newstate cmd;
                   1519:
                   1520:        DPRINTFN(DBG_FN, ("%s: %s: nstate=%s(%d), arg=%d\n",
                   1521:            device_xname(sc->sc_dev), __func__,
                   1522:            ieee80211_state_name[nstate], nstate, arg));
                   1523:
                   1524:        callout_stop(&sc->sc_scan_to);
                   1525:        callout_stop(&sc->sc_calib_to);
                   1526:
                   1527:        /* Do it in a process context. */
                   1528:        cmd.state = nstate;
                   1529:        cmd.arg = arg;
                   1530:        urtwn_do_async(sc, urtwn_newstate_cb, &cmd, sizeof(cmd));
                   1531:        return (0);
                   1532: }
                   1533:
                   1534: static void
                   1535: urtwn_newstate_cb(struct urtwn_softc *sc, void *arg)
                   1536: {
                   1537:        struct urtwn_cmd_newstate *cmd = arg;
                   1538:        struct ieee80211com *ic = &sc->sc_ic;
                   1539:        struct ieee80211_node *ni;
                   1540:        enum ieee80211_state ostate = ic->ic_state;
                   1541:        enum ieee80211_state nstate = cmd->state;
                   1542:        uint32_t reg;
1.26    ! christos 1543:        uint8_t sifs_time, msr;
1.1       nonaka   1544:        int s;
                   1545:
                   1546:        DPRINTFN(DBG_FN|DBG_STM, ("%s: %s: %s(%d)->%s(%d)\n",
                   1547:            device_xname(sc->sc_dev), __func__,
                   1548:            ieee80211_state_name[ostate], ostate,
                   1549:            ieee80211_state_name[nstate], nstate));
                   1550:
                   1551:        s = splnet();
1.12      christos 1552:        mutex_enter(&sc->sc_write_mtx);
                   1553:
                   1554:        callout_stop(&sc->sc_scan_to);
                   1555:        callout_stop(&sc->sc_calib_to);
1.1       nonaka   1556:
                   1557:        switch (ostate) {
                   1558:        case IEEE80211_S_INIT:
                   1559:                break;
                   1560:
                   1561:        case IEEE80211_S_SCAN:
                   1562:                if (nstate != IEEE80211_S_SCAN) {
                   1563:                        /*
                   1564:                         * End of scanning
                   1565:                         */
                   1566:                        /* flush 4-AC Queue after site_survey */
                   1567:                        urtwn_write_1(sc, R92C_TXPAUSE, 0x0);
                   1568:
                   1569:                        /* Allow Rx from our BSSID only. */
                   1570:                        urtwn_write_4(sc, R92C_RCR,
                   1571:                            urtwn_read_4(sc, R92C_RCR) |
                   1572:                              R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
                   1573:                }
                   1574:                break;
1.7       christos 1575:
1.1       nonaka   1576:        case IEEE80211_S_AUTH:
                   1577:        case IEEE80211_S_ASSOC:
                   1578:                break;
                   1579:
                   1580:        case IEEE80211_S_RUN:
                   1581:                /* Turn link LED off. */
                   1582:                urtwn_set_led(sc, URTWN_LED_LINK, 0);
                   1583:
                   1584:                /* Set media status to 'No Link'. */
                   1585:                urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
                   1586:
                   1587:                /* Stop Rx of data frames. */
                   1588:                urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
                   1589:
                   1590:                /* Reset TSF. */
                   1591:                urtwn_write_1(sc, R92C_DUAL_TSF_RST, 0x03);
                   1592:
                   1593:                /* Disable TSF synchronization. */
                   1594:                urtwn_write_1(sc, R92C_BCN_CTRL,
                   1595:                    urtwn_read_1(sc, R92C_BCN_CTRL) |
                   1596:                      R92C_BCN_CTRL_DIS_TSF_UDT0);
                   1597:
                   1598:                /* Back to 20MHz mode */
1.14      jmcneill 1599:                urtwn_set_chan(sc, ic->ic_curchan,
1.1       nonaka   1600:                    IEEE80211_HTINFO_2NDCHAN_NONE);
                   1601:
                   1602:                if (ic->ic_opmode == IEEE80211_M_IBSS ||
                   1603:                    ic->ic_opmode == IEEE80211_M_HOSTAP) {
                   1604:                        /* Stop BCN */
                   1605:                        urtwn_write_1(sc, R92C_BCN_CTRL,
                   1606:                            urtwn_read_1(sc, R92C_BCN_CTRL) &
                   1607:                            ~(R92C_BCN_CTRL_EN_BCN | R92C_BCN_CTRL_TXBCN_RPT));
                   1608:                }
                   1609:
                   1610:                /* Reset EDCA parameters. */
                   1611:                urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217);
                   1612:                urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317);
                   1613:                urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320);
                   1614:                urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444);
                   1615:
                   1616:                /* flush all cam entries */
                   1617:                urtwn_cam_init(sc);
                   1618:                break;
                   1619:        }
                   1620:
                   1621:        switch (nstate) {
                   1622:        case IEEE80211_S_INIT:
                   1623:                /* Turn link LED off. */
                   1624:                urtwn_set_led(sc, URTWN_LED_LINK, 0);
                   1625:                break;
                   1626:
                   1627:        case IEEE80211_S_SCAN:
                   1628:                if (ostate != IEEE80211_S_SCAN) {
                   1629:                        /*
                   1630:                         * Begin of scanning
                   1631:                         */
                   1632:
                   1633:                        /* Set gain for scanning. */
                   1634:                        reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
                   1635:                        reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
                   1636:                        urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
                   1637:
                   1638:                        reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
                   1639:                        reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
                   1640:                        urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
                   1641:
                   1642:                        /* Set media status to 'No Link'. */
                   1643:                        urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
                   1644:
                   1645:                        /* Allow Rx from any BSSID. */
                   1646:                        urtwn_write_4(sc, R92C_RCR,
                   1647:                            urtwn_read_4(sc, R92C_RCR) &
                   1648:                            ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
                   1649:
                   1650:                        /* Stop Rx of data frames. */
                   1651:                        urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
                   1652:
                   1653:                        /* Disable update TSF */
                   1654:                        urtwn_write_1(sc, R92C_BCN_CTRL,
                   1655:                            urtwn_read_1(sc, R92C_BCN_CTRL) |
                   1656:                              R92C_BCN_CTRL_DIS_TSF_UDT0);
                   1657:                }
                   1658:
                   1659:                /* Make link LED blink during scan. */
                   1660:                urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink);
                   1661:
                   1662:                /* Pause AC Tx queues. */
                   1663:                urtwn_write_1(sc, R92C_TXPAUSE,
                   1664:                    urtwn_read_1(sc, R92C_TXPAUSE) | 0x0f);
                   1665:
                   1666:                urtwn_set_chan(sc, ic->ic_curchan,
                   1667:                    IEEE80211_HTINFO_2NDCHAN_NONE);
                   1668:
                   1669:                /* Start periodic scan. */
                   1670:                if (!sc->sc_dying)
                   1671:                        callout_schedule(&sc->sc_scan_to, hz / 5);
                   1672:                break;
                   1673:
                   1674:        case IEEE80211_S_AUTH:
                   1675:                /* Set initial gain under link. */
                   1676:                reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
1.12      christos 1677: #ifdef doaslinux
1.1       nonaka   1678:                reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
1.12      christos 1679: #else
                   1680:                reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
                   1681: #endif
1.1       nonaka   1682:                urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
                   1683:
                   1684:                reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
1.12      christos 1685: #ifdef doaslinux
1.1       nonaka   1686:                reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
1.12      christos 1687: #else
                   1688:                reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
                   1689: #endif
1.1       nonaka   1690:                urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
                   1691:
                   1692:                /* Set media status to 'No Link'. */
                   1693:                urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
                   1694:
                   1695:                /* Allow Rx from any BSSID. */
                   1696:                urtwn_write_4(sc, R92C_RCR,
                   1697:                    urtwn_read_4(sc, R92C_RCR) &
                   1698:                      ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
                   1699:
                   1700:                urtwn_set_chan(sc, ic->ic_curchan,
                   1701:                    IEEE80211_HTINFO_2NDCHAN_NONE);
                   1702:                break;
                   1703:
                   1704:        case IEEE80211_S_ASSOC:
                   1705:                break;
                   1706:
                   1707:        case IEEE80211_S_RUN:
                   1708:                ni = ic->ic_bss;
                   1709:
                   1710:                /* XXX: Set 20MHz mode */
                   1711:                urtwn_set_chan(sc, ic->ic_curchan,
                   1712:                    IEEE80211_HTINFO_2NDCHAN_NONE);
                   1713:
                   1714:                if (ic->ic_opmode == IEEE80211_M_MONITOR) {
                   1715:                        /* Back to 20MHz mode */
1.13      jmcneill 1716:                        urtwn_set_chan(sc, ic->ic_curchan,
1.1       nonaka   1717:                            IEEE80211_HTINFO_2NDCHAN_NONE);
                   1718:
1.19      christos 1719:                        /* Set media status to 'No Link'. */
                   1720:                        urtwn_set_nettype0_msr(sc, R92C_CR_NETTYPE_NOLINK);
                   1721:
1.1       nonaka   1722:                        /* Enable Rx of data frames. */
                   1723:                        urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
                   1724:
1.19      christos 1725:                        /* Allow Rx from any BSSID. */
                   1726:                        urtwn_write_4(sc, R92C_RCR,
                   1727:                            urtwn_read_4(sc, R92C_RCR) &
                   1728:                            ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
                   1729:
                   1730:                        /* Accept Rx data/control/management frames */
                   1731:                        urtwn_write_4(sc, R92C_RCR,
                   1732:                            urtwn_read_4(sc, R92C_RCR) |
                   1733:                            R92C_RCR_ADF | R92C_RCR_ACF | R92C_RCR_AMF);
                   1734:
1.1       nonaka   1735:                        /* Turn link LED on. */
                   1736:                        urtwn_set_led(sc, URTWN_LED_LINK, 1);
                   1737:                        break;
                   1738:                }
                   1739:
                   1740:                /* Set media status to 'Associated'. */
                   1741:                urtwn_set_nettype0_msr(sc, urtwn_get_nettype(sc));
                   1742:
                   1743:                /* Set BSSID. */
                   1744:                urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0]));
                   1745:                urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4]));
                   1746:
                   1747:                if (ic->ic_curmode == IEEE80211_MODE_11B) {
                   1748:                        urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
                   1749:                } else {
                   1750:                        /* 802.11b/g */
                   1751:                        urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
                   1752:                }
                   1753:
                   1754:                /* Enable Rx of data frames. */
                   1755:                urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
                   1756:
                   1757:                /* Set beacon interval. */
                   1758:                urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval);
                   1759:
1.26    ! christos 1760:                 msr = urtwn_read_1(sc, R92C_MSR);
        !          1761:                 msr &= 0xfc;
        !          1762:                switch (ic->ic_opmode) {
        !          1763:                case IEEE80211_M_STA:
1.1       nonaka   1764:                        /* Allow Rx from our BSSID only. */
                   1765:                        urtwn_write_4(sc, R92C_RCR,
                   1766:                            urtwn_read_4(sc, R92C_RCR) |
                   1767:                              R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
                   1768:
                   1769:                        /* Enable TSF synchronization. */
                   1770:                        urtwn_tsf_sync_enable(sc);
1.26    ! christos 1771:                        /*FALLTHROUGH*/
        !          1772:                default:
        !          1773:                         msr |= R92C_MSR_ADHOC;
        !          1774:                        break;
        !          1775:                case IEEE80211_M_HOSTAP:
        !          1776:                         urtwn_write_2(sc, R92C_BCNTCFG, 0x000f);
        !          1777:
        !          1778:                         /* Allow Rx from any BSSID. */
        !          1779:                         urtwn_write_4(sc, R92C_RCR,
        !          1780:                             urtwn_read_4(sc, R92C_RCR) &
        !          1781:                             ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
        !          1782:
        !          1783:                         /* Reset TSF timer to zero. */
        !          1784:                         reg = urtwn_read_4(sc, R92C_TCR);
        !          1785:                         reg &= ~0x01;
        !          1786:                         urtwn_write_4(sc, R92C_TCR, reg);
        !          1787:                         reg |= 0x01;
        !          1788:                         urtwn_write_4(sc, R92C_TCR, reg);
        !          1789:                         msr |= R92C_MSR_AP;
        !          1790:                        break;
        !          1791:                 }
        !          1792:                 urtwn_write_1(sc, R92C_MSR, msr);
1.1       nonaka   1793:
                   1794:                sifs_time = 10;
                   1795:                urtwn_write_1(sc, R92C_SIFS_CCK + 1, sifs_time);
                   1796:                urtwn_write_1(sc, R92C_SIFS_OFDM + 1, sifs_time);
                   1797:                urtwn_write_1(sc, R92C_SPEC_SIFS + 1, sifs_time);
                   1798:                urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, sifs_time);
                   1799:                urtwn_write_1(sc, R92C_R2T_SIFS + 1, sifs_time);
                   1800:                urtwn_write_1(sc, R92C_T2T_SIFS + 1, sifs_time);
                   1801:
                   1802:                /* Intialize rate adaptation. */
                   1803:                urtwn_ra_init(sc);
                   1804:
                   1805:                /* Turn link LED on. */
                   1806:                urtwn_set_led(sc, URTWN_LED_LINK, 1);
                   1807:
                   1808:                /* Reset average RSSI. */
                   1809:                sc->avg_pwdb = -1;
                   1810:
                   1811:                /* Reset temperature calibration state machine. */
                   1812:                sc->thcal_state = 0;
                   1813:                sc->thcal_lctemp = 0;
                   1814:
                   1815:                /* Start periodic calibration. */
                   1816:                if (!sc->sc_dying)
                   1817:                        callout_schedule(&sc->sc_calib_to, hz);
                   1818:                break;
                   1819:        }
                   1820:
                   1821:        (*sc->sc_newstate)(ic, nstate, cmd->arg);
                   1822:
1.12      christos 1823:        mutex_exit(&sc->sc_write_mtx);
1.1       nonaka   1824:        splx(s);
                   1825: }
                   1826:
                   1827: static int
                   1828: urtwn_wme_update(struct ieee80211com *ic)
                   1829: {
                   1830:        struct urtwn_softc *sc = ic->ic_ifp->if_softc;
                   1831:
                   1832:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   1833:
                   1834:        /* don't override default WME values if WME is not actually enabled */
                   1835:        if (!(ic->ic_flags & IEEE80211_F_WME))
                   1836:                return (0);
                   1837:
                   1838:        /* Do it in a process context. */
                   1839:        urtwn_do_async(sc, urtwn_wme_update_cb, NULL, 0);
                   1840:        return (0);
                   1841: }
                   1842:
                   1843: static void
                   1844: urtwn_wme_update_cb(struct urtwn_softc *sc, void *arg)
                   1845: {
                   1846:        static const uint16_t ac2reg[WME_NUM_AC] = {
                   1847:                R92C_EDCA_BE_PARAM,
                   1848:                R92C_EDCA_BK_PARAM,
                   1849:                R92C_EDCA_VI_PARAM,
                   1850:                R92C_EDCA_VO_PARAM
                   1851:        };
                   1852:        struct ieee80211com *ic = &sc->sc_ic;
                   1853:        const struct wmeParams *wmep;
                   1854:        int ac, aifs, slottime;
                   1855:        int s;
                   1856:
                   1857:        DPRINTFN(DBG_FN|DBG_STM, ("%s: %s\n", device_xname(sc->sc_dev),
                   1858:            __func__));
                   1859:
                   1860:        s = splnet();
1.12      christos 1861:        mutex_enter(&sc->sc_write_mtx);
1.1       nonaka   1862:        slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
                   1863:        for (ac = 0; ac < WME_NUM_AC; ac++) {
                   1864:                wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac];
                   1865:                /* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */
                   1866:                aifs = wmep->wmep_aifsn * slottime + 10;
                   1867:                urtwn_write_4(sc, ac2reg[ac],
                   1868:                    SM(R92C_EDCA_PARAM_TXOP, wmep->wmep_txopLimit) |
                   1869:                    SM(R92C_EDCA_PARAM_ECWMIN, wmep->wmep_logcwmin) |
                   1870:                    SM(R92C_EDCA_PARAM_ECWMAX, wmep->wmep_logcwmax) |
                   1871:                    SM(R92C_EDCA_PARAM_AIFS, aifs));
                   1872:        }
1.12      christos 1873:        mutex_exit(&sc->sc_write_mtx);
1.1       nonaka   1874:        splx(s);
                   1875: }
                   1876:
                   1877: static void
                   1878: urtwn_update_avgrssi(struct urtwn_softc *sc, int rate, int8_t rssi)
                   1879: {
                   1880:        int pwdb;
                   1881:
                   1882:        DPRINTFN(DBG_FN, ("%s: %s: rate=%d, rsst=%d\n",
                   1883:            device_xname(sc->sc_dev), __func__, rate, rssi));
                   1884:
                   1885:        /* Convert antenna signal to percentage. */
                   1886:        if (rssi <= -100 || rssi >= 20)
                   1887:                pwdb = 0;
                   1888:        else if (rssi >= 0)
                   1889:                pwdb = 100;
                   1890:        else
                   1891:                pwdb = 100 + rssi;
                   1892:        if (rate <= 3) {
                   1893:                /* CCK gain is smaller than OFDM/MCS gain. */
                   1894:                pwdb += 6;
                   1895:                if (pwdb > 100)
                   1896:                        pwdb = 100;
                   1897:                if (pwdb <= 14)
                   1898:                        pwdb -= 4;
                   1899:                else if (pwdb <= 26)
                   1900:                        pwdb -= 8;
                   1901:                else if (pwdb <= 34)
                   1902:                        pwdb -= 6;
                   1903:                else if (pwdb <= 42)
                   1904:                        pwdb -= 2;
                   1905:        }
                   1906:        if (sc->avg_pwdb == -1) /* Init. */
                   1907:                sc->avg_pwdb = pwdb;
                   1908:        else if (sc->avg_pwdb < pwdb)
                   1909:                sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20) + 1;
                   1910:        else
                   1911:                sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20);
                   1912:
1.12      christos 1913:        DPRINTFN(DBG_RF, ("%s: %s: rate=%d rssi=%d PWDB=%d EMA=%d\n",
                   1914:                     device_xname(sc->sc_dev), __func__,
                   1915:                     rate, rssi, pwdb, sc->avg_pwdb));
1.1       nonaka   1916: }
                   1917:
                   1918: static int8_t
                   1919: urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
                   1920: {
                   1921:        static const int8_t cckoff[] = { 16, -12, -26, -46 };
                   1922:        struct r92c_rx_phystat *phy;
                   1923:        struct r92c_rx_cck *cck;
                   1924:        uint8_t rpt;
                   1925:        int8_t rssi;
                   1926:
                   1927:        DPRINTFN(DBG_FN, ("%s: %s: rate=%d\n", device_xname(sc->sc_dev),
                   1928:            __func__, rate));
                   1929:
                   1930:        if (rate <= 3) {
                   1931:                cck = (struct r92c_rx_cck *)physt;
                   1932:                if (ISSET(sc->sc_flags, URTWN_FLAG_CCK_HIPWR)) {
                   1933:                        rpt = (cck->agc_rpt >> 5) & 0x3;
                   1934:                        rssi = (cck->agc_rpt & 0x1f) << 1;
                   1935:                } else {
                   1936:                        rpt = (cck->agc_rpt >> 6) & 0x3;
                   1937:                        rssi = cck->agc_rpt & 0x3e;
                   1938:                }
                   1939:                rssi = cckoff[rpt] - rssi;
                   1940:        } else {        /* OFDM/HT. */
                   1941:                phy = (struct r92c_rx_phystat *)physt;
                   1942:                rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110;
                   1943:        }
                   1944:        return (rssi);
                   1945: }
                   1946:
                   1947: static void
                   1948: urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen)
                   1949: {
                   1950:        struct ieee80211com *ic = &sc->sc_ic;
                   1951:        struct ifnet *ifp = ic->ic_ifp;
                   1952:        struct ieee80211_frame *wh;
                   1953:        struct ieee80211_node *ni;
                   1954:        struct r92c_rx_stat *stat;
                   1955:        uint32_t rxdw0, rxdw3;
                   1956:        struct mbuf *m;
                   1957:        uint8_t rate;
                   1958:        int8_t rssi = 0;
                   1959:        int s, infosz;
                   1960:
                   1961:        DPRINTFN(DBG_FN, ("%s: %s: buf=%p, pktlen=%d\n",
                   1962:            device_xname(sc->sc_dev), __func__, buf, pktlen));
                   1963:
                   1964:        stat = (struct r92c_rx_stat *)buf;
                   1965:        rxdw0 = le32toh(stat->rxdw0);
                   1966:        rxdw3 = le32toh(stat->rxdw3);
                   1967:
                   1968:        if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) {
                   1969:                /*
                   1970:                 * This should not happen since we setup our Rx filter
                   1971:                 * to not receive these frames.
                   1972:                 */
                   1973:                DPRINTFN(DBG_RX, ("%s: %s: CRC error\n",
                   1974:                    device_xname(sc->sc_dev), __func__));
                   1975:                ifp->if_ierrors++;
                   1976:                return;
                   1977:        }
1.19      christos 1978:        /*
                   1979:         * XXX: This will drop most control packets.  Do we really
                   1980:         * want this in IEEE80211_M_MONITOR mode?
                   1981:         */
1.22      christos 1982: //     if (__predict_false(pktlen < (int)sizeof(*wh))) {
                   1983:        if (__predict_false(pktlen < (int)sizeof(struct ieee80211_frame_ack))) {
1.1       nonaka   1984:                DPRINTFN(DBG_RX, ("%s: %s: packet too short %d\n",
                   1985:                    device_xname(sc->sc_dev), __func__, pktlen));
                   1986:                ic->ic_stats.is_rx_tooshort++;
                   1987:                ifp->if_ierrors++;
                   1988:                return;
                   1989:        }
                   1990:        if (__predict_false(pktlen > MCLBYTES)) {
                   1991:                DPRINTFN(DBG_RX, ("%s: %s: packet too big %d\n",
                   1992:                    device_xname(sc->sc_dev), __func__, pktlen));
                   1993:                ifp->if_ierrors++;
                   1994:                return;
                   1995:        }
                   1996:
                   1997:        rate = MS(rxdw3, R92C_RXDW3_RATE);
                   1998:        infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
                   1999:
                   2000:        /* Get RSSI from PHY status descriptor if present. */
                   2001:        if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
                   2002:                rssi = urtwn_get_rssi(sc, rate, &stat[1]);
                   2003:                /* Update our average RSSI. */
                   2004:                urtwn_update_avgrssi(sc, rate, rssi);
                   2005:        }
                   2006:
                   2007:        DPRINTFN(DBG_RX, ("%s: %s: Rx frame len=%d rate=%d infosz=%d rssi=%d\n",
                   2008:            device_xname(sc->sc_dev), __func__, pktlen, rate, infosz, rssi));
                   2009:
                   2010:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   2011:        if (__predict_false(m == NULL)) {
                   2012:                aprint_error_dev(sc->sc_dev, "couldn't allocate rx mbuf\n");
                   2013:                ic->ic_stats.is_rx_nobuf++;
                   2014:                ifp->if_ierrors++;
                   2015:                return;
                   2016:        }
                   2017:        if (pktlen > (int)MHLEN) {
                   2018:                MCLGET(m, M_DONTWAIT);
                   2019:                if (__predict_false(!(m->m_flags & M_EXT))) {
                   2020:                        aprint_error_dev(sc->sc_dev,
                   2021:                            "couldn't allocate rx mbuf cluster\n");
                   2022:                        m_freem(m);
                   2023:                        ic->ic_stats.is_rx_nobuf++;
                   2024:                        ifp->if_ierrors++;
                   2025:                        return;
                   2026:                }
                   2027:        }
                   2028:
                   2029:        /* Finalize mbuf. */
                   2030:        m->m_pkthdr.rcvif = ifp;
                   2031:        wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
                   2032:        memcpy(mtod(m, uint8_t *), wh, pktlen);
                   2033:        m->m_pkthdr.len = m->m_len = pktlen;
                   2034:
                   2035:        s = splnet();
                   2036:        if (__predict_false(sc->sc_drvbpf != NULL)) {
                   2037:                struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
                   2038:
1.19      christos 2039:                tap->wr_flags = 0;
1.1       nonaka   2040:                if (!(rxdw3 & R92C_RXDW3_HT)) {
                   2041:                        switch (rate) {
                   2042:                        /* CCK. */
                   2043:                        case  0: tap->wr_rate =   2; break;
                   2044:                        case  1: tap->wr_rate =   4; break;
                   2045:                        case  2: tap->wr_rate =  11; break;
                   2046:                        case  3: tap->wr_rate =  22; break;
                   2047:                        /* OFDM. */
                   2048:                        case  4: tap->wr_rate =  12; break;
                   2049:                        case  5: tap->wr_rate =  18; break;
                   2050:                        case  6: tap->wr_rate =  24; break;
                   2051:                        case  7: tap->wr_rate =  36; break;
                   2052:                        case  8: tap->wr_rate =  48; break;
                   2053:                        case  9: tap->wr_rate =  72; break;
                   2054:                        case 10: tap->wr_rate =  96; break;
                   2055:                        case 11: tap->wr_rate = 108; break;
                   2056:                        }
                   2057:                } else if (rate >= 12) {        /* MCS0~15. */
                   2058:                        /* Bit 7 set means HT MCS instead of rate. */
                   2059:                        tap->wr_rate = 0x80 | (rate - 12);
                   2060:                }
                   2061:                tap->wr_dbm_antsignal = rssi;
1.13      jmcneill 2062:                tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
                   2063:                tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
1.1       nonaka   2064:
                   2065:                bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
                   2066:        }
                   2067:
                   2068:        ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
                   2069:
                   2070:        /* push the frame up to the 802.11 stack */
                   2071:        ieee80211_input(ic, m, ni, rssi, 0);
                   2072:
                   2073:        /* Node is no longer needed. */
                   2074:        ieee80211_free_node(ni);
                   2075:
                   2076:        splx(s);
                   2077: }
                   2078:
                   2079: static void
                   2080: urtwn_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   2081: {
                   2082:        struct urtwn_rx_data *data = priv;
                   2083:        struct urtwn_softc *sc = data->sc;
                   2084:        struct r92c_rx_stat *stat;
                   2085:        uint32_t rxdw0;
                   2086:        uint8_t *buf;
                   2087:        int len, totlen, pktlen, infosz, npkts;
                   2088:
                   2089:        DPRINTFN(DBG_FN|DBG_RX, ("%s: %s: status=%d\n",
                   2090:            device_xname(sc->sc_dev), __func__, status));
                   2091:
                   2092:        if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
                   2093:                if (status == USBD_STALLED)
                   2094:                        usbd_clear_endpoint_stall_async(sc->rx_pipe);
                   2095:                else if (status != USBD_CANCELLED)
                   2096:                        goto resubmit;
                   2097:                return;
                   2098:        }
                   2099:        usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
                   2100:
                   2101:        if (__predict_false(len < (int)sizeof(*stat))) {
                   2102:                DPRINTFN(DBG_RX, ("%s: %s: xfer too short %d\n",
                   2103:                    device_xname(sc->sc_dev), __func__, len));
                   2104:                goto resubmit;
                   2105:        }
                   2106:        buf = data->buf;
                   2107:
                   2108:        /* Get the number of encapsulated frames. */
                   2109:        stat = (struct r92c_rx_stat *)buf;
                   2110:        npkts = MS(le32toh(stat->rxdw2), R92C_RXDW2_PKTCNT);
                   2111:        DPRINTFN(DBG_RX, ("%s: %s: Rx %d frames in one chunk\n",
                   2112:            device_xname(sc->sc_dev), __func__, npkts));
                   2113:
                   2114:        /* Process all of them. */
                   2115:        while (npkts-- > 0) {
                   2116:                if (__predict_false(len < (int)sizeof(*stat))) {
                   2117:                        DPRINTFN(DBG_RX,
                   2118:                            ("%s: %s: len(%d) is short than header\n",
                   2119:                            device_xname(sc->sc_dev), __func__, len));
                   2120:                        break;
                   2121:                }
                   2122:                stat = (struct r92c_rx_stat *)buf;
                   2123:                rxdw0 = le32toh(stat->rxdw0);
                   2124:
                   2125:                pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
                   2126:                if (__predict_false(pktlen == 0)) {
                   2127:                        DPRINTFN(DBG_RX, ("%s: %s: pktlen is 0 byte\n",
                   2128:                            device_xname(sc->sc_dev), __func__));
1.19      christos 2129:                        break;
1.1       nonaka   2130:                }
                   2131:
                   2132:                infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
                   2133:
                   2134:                /* Make sure everything fits in xfer. */
                   2135:                totlen = sizeof(*stat) + infosz + pktlen;
                   2136:                if (__predict_false(totlen > len)) {
                   2137:                        DPRINTFN(DBG_RX, ("%s: %s: pktlen %d(%d+%d+%d) > %d\n",
                   2138:                            device_xname(sc->sc_dev), __func__, totlen,
                   2139:                            (int)sizeof(*stat), infosz, pktlen, len));
                   2140:                        break;
                   2141:                }
                   2142:
                   2143:                /* Process 802.11 frame. */
                   2144:                urtwn_rx_frame(sc, buf, pktlen);
                   2145:
                   2146:                /* Next chunk is 128-byte aligned. */
                   2147:                totlen = roundup2(totlen, 128);
                   2148:                buf += totlen;
                   2149:                len -= totlen;
                   2150:        }
                   2151:
                   2152:  resubmit:
                   2153:        /* Setup a new transfer. */
                   2154:        usbd_setup_xfer(xfer, sc->rx_pipe, data, data->buf, URTWN_RXBUFSZ,
                   2155:            USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, urtwn_rxeof);
                   2156:        (void)usbd_transfer(xfer);
                   2157: }
                   2158:
                   2159: static void
                   2160: urtwn_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
                   2161: {
                   2162:        struct urtwn_tx_data *data = priv;
                   2163:        struct urtwn_softc *sc = data->sc;
                   2164:        struct ifnet *ifp = &sc->sc_if;
1.20      christos 2165:        usbd_pipe_handle pipe = data->pipe;
1.1       nonaka   2166:        int s;
                   2167:
                   2168:        DPRINTFN(DBG_FN|DBG_TX, ("%s: %s: status=%d\n",
                   2169:            device_xname(sc->sc_dev), __func__, status));
                   2170:
                   2171:        mutex_enter(&sc->sc_tx_mtx);
                   2172:        /* Put this Tx buffer back to our free list. */
                   2173:        TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
                   2174:        mutex_exit(&sc->sc_tx_mtx);
                   2175:
1.16      jmcneill 2176:        s = splnet();
                   2177:        sc->tx_timer = 0;
                   2178:        ifp->if_flags &= ~IFF_OACTIVE;
                   2179:
1.1       nonaka   2180:        if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
                   2181:                if (status != USBD_NOT_STARTED && status != USBD_CANCELLED) {
                   2182:                        if (status == USBD_STALLED)
1.20      christos 2183:                                usbd_clear_endpoint_stall_async(pipe);
1.1       nonaka   2184:                        ifp->if_oerrors++;
                   2185:                }
1.16      jmcneill 2186:                splx(s);
1.1       nonaka   2187:                return;
                   2188:        }
                   2189:
1.21      christos 2190:        ifp->if_opackets++;
1.16      jmcneill 2191:        urtwn_start(ifp);
1.1       nonaka   2192:
                   2193:        splx(s);
                   2194: }
                   2195:
                   2196: static int
1.12      christos 2197: urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
                   2198:     struct urtwn_tx_data *data)
1.1       nonaka   2199: {
                   2200:        struct ieee80211com *ic = &sc->sc_ic;
                   2201:        struct ieee80211_frame *wh;
                   2202:        struct ieee80211_key *k = NULL;
                   2203:        struct r92c_tx_desc *txd;
                   2204:        usbd_pipe_handle pipe;
1.22      christos 2205:        size_t i, padsize, xferlen;
1.1       nonaka   2206:        uint16_t seq, sum;
                   2207:        uint8_t raid, type, tid, qid;
1.22      christos 2208:        int s, hasqos, error;
1.1       nonaka   2209:
                   2210:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2211:
                   2212:        wh = mtod(m, struct ieee80211_frame *);
                   2213:        type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
                   2214:
                   2215:        if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
                   2216:                k = ieee80211_crypto_encap(ic, ni, m);
1.12      christos 2217:                if (k == NULL)
                   2218:                        return ENOBUFS;
                   2219:
1.1       nonaka   2220:                /* packet header may have moved, reset our local pointer */
                   2221:                wh = mtod(m, struct ieee80211_frame *);
                   2222:        }
                   2223:
                   2224:        if (__predict_false(sc->sc_drvbpf != NULL)) {
                   2225:                struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap;
                   2226:
                   2227:                tap->wt_flags = 0;
1.14      jmcneill 2228:                tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
                   2229:                tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1.1       nonaka   2230:                if (wh->i_fc[1] & IEEE80211_FC1_WEP)
                   2231:                        tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
                   2232:
1.19      christos 2233:                /* XXX: set tap->wt_rate? */
                   2234:
1.1       nonaka   2235:                bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
                   2236:        }
                   2237:
1.23      christos 2238:        if ((hasqos = ieee80211_has_qos(wh))) {
1.1       nonaka   2239:                /* data frames in 11n mode */
                   2240:                struct ieee80211_qosframe *qwh = (void *)wh;
                   2241:                tid = qwh->i_qos[0] & IEEE80211_QOS_TID;
                   2242:                qid = TID_TO_WME_AC(tid);
                   2243:        } else if (type != IEEE80211_FC0_TYPE_DATA) {
                   2244:                /* Use AC_VO for management frames. */
                   2245:                qid = WME_AC_VO;
                   2246:                tid = 0;        /* compiler happy */
                   2247:        } else {
                   2248:                /* non-qos data frames */
                   2249:                tid = R92C_TXDW1_QSEL_BE;
                   2250:                qid = WME_AC_BE;
                   2251:        }
                   2252:
                   2253:        /* Get the USB pipe to use for this AC. */
                   2254:        pipe = sc->tx_pipe[sc->ac2idx[qid]];
                   2255:
                   2256:        if (((sizeof(*txd) + m->m_pkthdr.len) % 64) == 0) /* XXX: 64 */
                   2257:                padsize = 8;
                   2258:        else
                   2259:                padsize = 0;
                   2260:
                   2261:        /* Fill Tx descriptor. */
                   2262:        txd = (struct r92c_tx_desc *)data->buf;
                   2263:        memset(txd, 0, sizeof(*txd) + padsize);
                   2264:
                   2265:        txd->txdw0 |= htole32(
                   2266:            SM(R92C_TXDW0_PKTLEN, m->m_pkthdr.len) |
                   2267:            SM(R92C_TXDW0_OFFSET, sizeof(*txd)) |
                   2268:            R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
                   2269:
                   2270:        if (IEEE80211_IS_MULTICAST(wh->i_addr1))
                   2271:                txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
                   2272:
                   2273:        /* fix pad field */
                   2274:        if (padsize > 0) {
1.22      christos 2275:                DPRINTFN(DBG_TX, ("%s: %s: padding: size=%zd\n",
1.1       nonaka   2276:                    device_xname(sc->sc_dev), __func__, padsize));
                   2277:                txd->txdw1 |= htole32(SM(R92C_TXDW1_PKTOFF, (padsize / 8)));
                   2278:        }
                   2279:
                   2280:        if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
                   2281:            type == IEEE80211_FC0_TYPE_DATA) {
                   2282:                if (ic->ic_curmode == IEEE80211_MODE_11B)
                   2283:                        raid = R92C_RAID_11B;
                   2284:                else
                   2285:                        raid = R92C_RAID_11BG;
                   2286:                DPRINTFN(DBG_TX,
                   2287:                    ("%s: %s: data packet: tid=%d, raid=%d\n",
                   2288:                    device_xname(sc->sc_dev), __func__, tid, raid));
                   2289:
                   2290:                txd->txdw1 |= htole32(
                   2291:                    SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
                   2292:                    SM(R92C_TXDW1_QSEL, tid) |
                   2293:                    SM(R92C_TXDW1_RAID, raid) |
                   2294:                    R92C_TXDW1_AGGBK);
                   2295:
                   2296:                if (hasqos) {
                   2297:                        txd->txdw4 |= htole32(R92C_TXDW4_QOS);
                   2298:                }
                   2299:
                   2300:                if (ic->ic_flags & IEEE80211_F_USEPROT) {
                   2301:                        /* for 11g */
                   2302:                        if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
                   2303:                                txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF |
                   2304:                                    R92C_TXDW4_HWRTSEN);
                   2305:                        } else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) {
                   2306:                                txd->txdw4 |= htole32(R92C_TXDW4_RTSEN |
                   2307:                                    R92C_TXDW4_HWRTSEN);
                   2308:                        }
                   2309:                }
                   2310:                /* Send RTS at OFDM24. */
                   2311:                txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
                   2312:                txd->txdw5 |= htole32(0x0001ff00);
                   2313:                /* Send data at OFDM54. */
                   2314:                txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
                   2315:        } else if (type == IEEE80211_FC0_TYPE_MGT) {
                   2316:                DPRINTFN(DBG_TX, ("%s: %s: mgmt packet\n",
                   2317:                    device_xname(sc->sc_dev), __func__));
                   2318:                txd->txdw1 |= htole32(
                   2319:                    SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
                   2320:                    SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT) |
                   2321:                    SM(R92C_TXDW1_RAID, R92C_RAID_11B));
                   2322:
                   2323:                /* Force CCK1. */
                   2324:                txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
                   2325:                /* Use 1Mbps */
                   2326:                txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0));
                   2327:        } else {
                   2328:                /* broadcast or multicast packets */
                   2329:                DPRINTFN(DBG_TX, ("%s: %s: bc or mc packet\n",
                   2330:                    device_xname(sc->sc_dev), __func__));
                   2331:                txd->txdw1 |= htole32(
                   2332:                    SM(R92C_TXDW1_MACID, URTWN_MACID_BC) |
                   2333:                    SM(R92C_TXDW1_RAID, R92C_RAID_11B));
                   2334:
                   2335:                /* Force CCK1. */
                   2336:                txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
                   2337:                /* Use 1Mbps */
                   2338:                txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0));
                   2339:        }
                   2340:
                   2341:        /* Set sequence number */
                   2342:        seq = LE_READ_2(&wh->i_seq[0]) >> IEEE80211_SEQ_SEQ_SHIFT;
                   2343:        txd->txdseq |= htole16(seq);
                   2344:
                   2345:        if (!hasqos) {
                   2346:                /* Use HW sequence numbering for non-QoS frames. */
                   2347:                txd->txdw4  |= htole32(R92C_TXDW4_HWSEQ);
                   2348:                txd->txdseq |= htole16(0x8000);         /* WTF? */
                   2349:        }
                   2350:
                   2351:        /* Compute Tx descriptor checksum. */
                   2352:        sum = 0;
1.22      christos 2353:        for (i = 0; i < sizeof(*txd) / 2; i++)
1.1       nonaka   2354:                sum ^= ((uint16_t *)txd)[i];
                   2355:        txd->txdsum = sum;      /* NB: already little endian. */
                   2356:
                   2357:        xferlen = sizeof(*txd) + m->m_pkthdr.len + padsize;
                   2358:        m_copydata(m, 0, m->m_pkthdr.len, (char *)&txd[1] + padsize);
                   2359:
                   2360:        s = splnet();
                   2361:        data->pipe = pipe;
                   2362:        usbd_setup_xfer(data->xfer, pipe, data, data->buf, xferlen,
                   2363:            USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTWN_TX_TIMEOUT,
                   2364:            urtwn_txeof);
                   2365:        error = usbd_transfer(data->xfer);
                   2366:        if (__predict_false(error != USBD_NORMAL_COMPLETION &&
                   2367:            error != USBD_IN_PROGRESS)) {
                   2368:                splx(s);
                   2369:                DPRINTFN(DBG_TX, ("%s: %s: transfer failed %d\n",
                   2370:                    device_xname(sc->sc_dev), __func__, error));
1.12      christos 2371:                return error;
1.1       nonaka   2372:        }
                   2373:        splx(s);
1.12      christos 2374:        return 0;
1.1       nonaka   2375: }
                   2376:
                   2377: static void
                   2378: urtwn_start(struct ifnet *ifp)
                   2379: {
                   2380:        struct urtwn_softc *sc = ifp->if_softc;
                   2381:        struct ieee80211com *ic = &sc->sc_ic;
1.12      christos 2382:        struct urtwn_tx_data *data;
1.1       nonaka   2383:        struct ether_header *eh;
                   2384:        struct ieee80211_node *ni;
                   2385:        struct mbuf *m;
                   2386:
                   2387:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2388:
                   2389:        if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
                   2390:                return;
                   2391:
1.12      christos 2392:        data = NULL;
1.1       nonaka   2393:        for (;;) {
                   2394:                mutex_enter(&sc->sc_tx_mtx);
1.17      jmcneill 2395:                if (data == NULL && !TAILQ_EMPTY(&sc->tx_free_list)) {
1.12      christos 2396:                        data = TAILQ_FIRST(&sc->tx_free_list);
                   2397:                        TAILQ_REMOVE(&sc->tx_free_list, data, next);
1.1       nonaka   2398:                }
1.17      jmcneill 2399:                mutex_exit(&sc->sc_tx_mtx);
                   2400:
                   2401:                if (data == NULL) {
                   2402:                        ifp->if_flags |= IFF_OACTIVE;
                   2403:                        DPRINTFN(DBG_TX, ("%s: empty tx_free_list\n",
                   2404:                                     device_xname(sc->sc_dev)));
                   2405:                        return;
                   2406:                }
1.1       nonaka   2407:
                   2408:                /* Send pending management frames first. */
                   2409:                IF_DEQUEUE(&ic->ic_mgtq, m);
                   2410:                if (m != NULL) {
                   2411:                        ni = (void *)m->m_pkthdr.rcvif;
                   2412:                        m->m_pkthdr.rcvif = NULL;
                   2413:                        goto sendit;
                   2414:                }
                   2415:                if (ic->ic_state != IEEE80211_S_RUN)
                   2416:                        break;
                   2417:
                   2418:                /* Encapsulate and send data frames. */
                   2419:                IFQ_DEQUEUE(&ifp->if_snd, m);
                   2420:                if (m == NULL)
                   2421:                        break;
1.12      christos 2422:
1.1       nonaka   2423:                if (m->m_len < (int)sizeof(*eh) &&
                   2424:                    (m = m_pullup(m, sizeof(*eh))) == NULL) {
                   2425:                        ifp->if_oerrors++;
                   2426:                        continue;
                   2427:                }
                   2428:                eh = mtod(m, struct ether_header *);
                   2429:                ni = ieee80211_find_txnode(ic, eh->ether_dhost);
                   2430:                if (ni == NULL) {
                   2431:                        m_freem(m);
                   2432:                        ifp->if_oerrors++;
                   2433:                        continue;
                   2434:                }
                   2435:
                   2436:                bpf_mtap(ifp, m);
                   2437:
                   2438:                if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
                   2439:                        ieee80211_free_node(ni);
                   2440:                        ifp->if_oerrors++;
                   2441:                        continue;
                   2442:                }
                   2443:  sendit:
                   2444:                bpf_mtap3(ic->ic_rawbpf, m);
                   2445:
1.12      christos 2446:                if (urtwn_tx(sc, m, ni, data) != 0) {
                   2447:                        m_freem(m);
1.1       nonaka   2448:                        ieee80211_free_node(ni);
                   2449:                        ifp->if_oerrors++;
                   2450:                        continue;
                   2451:                }
1.12      christos 2452:                data = NULL;
                   2453:                m_freem(m);
                   2454:                ieee80211_free_node(ni);
1.1       nonaka   2455:                sc->tx_timer = 5;
                   2456:                ifp->if_timer = 1;
                   2457:        }
1.12      christos 2458:
                   2459:        /* Return the Tx buffer to the free list */
1.17      jmcneill 2460:        mutex_enter(&sc->sc_tx_mtx);
1.12      christos 2461:        TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
                   2462:        mutex_exit(&sc->sc_tx_mtx);
1.1       nonaka   2463: }
                   2464:
                   2465: static void
                   2466: urtwn_watchdog(struct ifnet *ifp)
                   2467: {
                   2468:        struct urtwn_softc *sc = ifp->if_softc;
                   2469:
                   2470:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2471:
                   2472:        ifp->if_timer = 0;
                   2473:
                   2474:        if (sc->tx_timer > 0) {
                   2475:                if (--sc->tx_timer == 0) {
                   2476:                        aprint_error_dev(sc->sc_dev, "device timeout\n");
                   2477:                        /* urtwn_init(ifp); XXX needs a process context! */
                   2478:                        ifp->if_oerrors++;
                   2479:                        return;
                   2480:                }
                   2481:                ifp->if_timer = 1;
                   2482:        }
                   2483:        ieee80211_watchdog(&sc->sc_ic);
                   2484: }
                   2485:
                   2486: static int
                   2487: urtwn_ioctl(struct ifnet *ifp, u_long cmd, void *data)
                   2488: {
                   2489:        struct urtwn_softc *sc = ifp->if_softc;
                   2490:        struct ieee80211com *ic = &sc->sc_ic;
                   2491:        int s, error = 0;
                   2492:
                   2493:        DPRINTFN(DBG_FN, ("%s: %s: cmd=0x%08lx, data=%p\n",
                   2494:            device_xname(sc->sc_dev), __func__, cmd, data));
                   2495:
                   2496:        s = splnet();
                   2497:
                   2498:        switch (cmd) {
                   2499:        case SIOCSIFFLAGS:
                   2500:                if ((error = ifioctl_common(ifp, cmd, data)) != 0)
                   2501:                        break;
1.12      christos 2502:                switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
                   2503:                case IFF_UP | IFF_RUNNING:
1.1       nonaka   2504:                        break;
                   2505:                case IFF_UP:
                   2506:                        urtwn_init(ifp);
                   2507:                        break;
                   2508:                case IFF_RUNNING:
                   2509:                        urtwn_stop(ifp, 1);
                   2510:                        break;
                   2511:                case 0:
                   2512:                        break;
                   2513:                }
                   2514:                break;
                   2515:
                   2516:        case SIOCADDMULTI:
                   2517:        case SIOCDELMULTI:
                   2518:                if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
                   2519:                        /* setup multicast filter, etc */
                   2520:                        error = 0;
                   2521:                }
                   2522:                break;
                   2523:
                   2524:        default:
                   2525:                error = ieee80211_ioctl(ic, cmd, data);
                   2526:                break;
                   2527:        }
                   2528:        if (error == ENETRESET) {
                   2529:                if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
1.16      jmcneill 2530:                    (IFF_UP | IFF_RUNNING) &&
                   2531:                    ic->ic_roaming != IEEE80211_ROAMING_MANUAL) {
1.1       nonaka   2532:                        urtwn_init(ifp);
                   2533:                }
                   2534:                error = 0;
                   2535:        }
                   2536:
                   2537:        splx(s);
                   2538:
                   2539:        return (error);
                   2540: }
                   2541:
                   2542: static int
                   2543: urtwn_power_on(struct urtwn_softc *sc)
                   2544: {
                   2545:        uint32_t reg;
                   2546:        int ntries;
                   2547:
                   2548:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2549:
1.12      christos 2550:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2551:
1.1       nonaka   2552:        /* Wait for autoload done bit. */
                   2553:        for (ntries = 0; ntries < 1000; ntries++) {
                   2554:                if (urtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
                   2555:                        break;
                   2556:                DELAY(5);
                   2557:        }
                   2558:        if (ntries == 1000) {
                   2559:                aprint_error_dev(sc->sc_dev,
                   2560:                    "timeout waiting for chip autoload\n");
                   2561:                return (ETIMEDOUT);
                   2562:        }
                   2563:
                   2564:        /* Unlock ISO/CLK/Power control register. */
                   2565:        urtwn_write_1(sc, R92C_RSV_CTRL, 0);
                   2566:        /* Move SPS into PWM mode. */
                   2567:        urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
                   2568:        DELAY(100);
                   2569:
                   2570:        reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL);
                   2571:        if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
                   2572:                urtwn_write_1(sc, R92C_LDOV12D_CTRL,
                   2573:                    reg | R92C_LDOV12D_CTRL_LDV12_EN);
                   2574:                DELAY(100);
                   2575:                urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
                   2576:                    urtwn_read_1(sc, R92C_SYS_ISO_CTRL) &
                   2577:                    ~R92C_SYS_ISO_CTRL_MD2PP);
                   2578:        }
                   2579:
                   2580:        /* Auto enable WLAN. */
                   2581:        urtwn_write_2(sc, R92C_APS_FSMCO,
                   2582:            urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
                   2583:        for (ntries = 0; ntries < 1000; ntries++) {
                   2584:                if (!(urtwn_read_2(sc, R92C_APS_FSMCO) &
                   2585:                    R92C_APS_FSMCO_APFM_ONMAC))
                   2586:                        break;
                   2587:                DELAY(5);
                   2588:        }
                   2589:        if (ntries == 1000) {
                   2590:                aprint_error_dev(sc->sc_dev,
                   2591:                    "timeout waiting for MAC auto ON\n");
                   2592:                return (ETIMEDOUT);
                   2593:        }
                   2594:
                   2595:        /* Enable radio, GPIO and LED functions. */
                   2596:        KASSERT((R92C_APS_FSMCO_AFSM_HSUS | R92C_APS_FSMCO_PDN_EN |
                   2597:            R92C_APS_FSMCO_PFM_ALDN) == 0x0812);
                   2598:        urtwn_write_2(sc, R92C_APS_FSMCO,
                   2599:            R92C_APS_FSMCO_AFSM_HSUS |
                   2600:            R92C_APS_FSMCO_PDN_EN |
                   2601:            R92C_APS_FSMCO_PFM_ALDN);
                   2602:
                   2603:        /* Release RF digital isolation. */
                   2604:        urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
                   2605:            urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR);
                   2606:
                   2607:        /* Initialize MAC. */
                   2608:        urtwn_write_1(sc, R92C_APSD_CTRL,
                   2609:            urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF);
                   2610:        for (ntries = 0; ntries < 200; ntries++) {
                   2611:                if (!(urtwn_read_1(sc, R92C_APSD_CTRL) &
                   2612:                    R92C_APSD_CTRL_OFF_STATUS))
                   2613:                        break;
                   2614:                DELAY(5);
                   2615:        }
                   2616:        if (ntries == 200) {
                   2617:                aprint_error_dev(sc->sc_dev,
                   2618:                    "timeout waiting for MAC initialization\n");
                   2619:                return (ETIMEDOUT);
                   2620:        }
                   2621:
                   2622:        /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
                   2623:        reg = urtwn_read_2(sc, R92C_CR);
                   2624:        reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
                   2625:            R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
                   2626:            R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
                   2627:            R92C_CR_ENSEC;
                   2628:        urtwn_write_2(sc, R92C_CR, reg);
                   2629:
                   2630:        urtwn_write_1(sc, 0xfe10, 0x19);
                   2631:        return (0);
                   2632: }
                   2633:
                   2634: static int
                   2635: urtwn_llt_init(struct urtwn_softc *sc)
                   2636: {
1.22      christos 2637:        size_t i;
                   2638:        int error;
1.1       nonaka   2639:
                   2640:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2641:
1.12      christos 2642:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2643:
1.1       nonaka   2644:        /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
                   2645:        for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
                   2646:                if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
                   2647:                        return (error);
                   2648:        }
                   2649:        /* NB: 0xff indicates end-of-list. */
                   2650:        if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
                   2651:                return (error);
                   2652:        /*
                   2653:         * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
                   2654:         * as ring buffer.
                   2655:         */
                   2656:        for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
                   2657:                if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
                   2658:                        return (error);
                   2659:        }
                   2660:        /* Make the last page point to the beginning of the ring buffer. */
                   2661:        error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
                   2662:        return (error);
                   2663: }
                   2664:
                   2665: static void
                   2666: urtwn_fw_reset(struct urtwn_softc *sc)
                   2667: {
                   2668:        uint16_t reg;
                   2669:        int ntries;
                   2670:
                   2671:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2672:
1.12      christos 2673:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2674:
1.1       nonaka   2675:        /* Tell 8051 to reset itself. */
                   2676:        urtwn_write_1(sc, R92C_HMETFR + 3, 0x20);
                   2677:
                   2678:        /* Wait until 8051 resets by itself. */
                   2679:        for (ntries = 0; ntries < 100; ntries++) {
                   2680:                reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
                   2681:                if (!(reg & R92C_SYS_FUNC_EN_CPUEN))
                   2682:                        return;
                   2683:                DELAY(50);
                   2684:        }
                   2685:        /* Force 8051 reset. */
                   2686:        urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
                   2687: }
                   2688:
                   2689: static int
                   2690: urtwn_fw_loadpage(struct urtwn_softc *sc, int page, uint8_t *buf, int len)
                   2691: {
                   2692:        uint32_t reg;
                   2693:        int off, mlen, error = 0;
                   2694:
                   2695:        DPRINTFN(DBG_FN, ("%s: %s: page=%d, buf=%p, len=%d\n",
                   2696:            device_xname(sc->sc_dev), __func__, page, buf, len));
                   2697:
                   2698:        reg = urtwn_read_4(sc, R92C_MCUFWDL);
                   2699:        reg = RW(reg, R92C_MCUFWDL_PAGE, page);
                   2700:        urtwn_write_4(sc, R92C_MCUFWDL, reg);
                   2701:
                   2702:        off = R92C_FW_START_ADDR;
                   2703:        while (len > 0) {
                   2704:                if (len > 196)
                   2705:                        mlen = 196;
                   2706:                else if (len > 4)
                   2707:                        mlen = 4;
                   2708:                else
                   2709:                        mlen = 1;
                   2710:                error = urtwn_write_region(sc, off, buf, mlen);
                   2711:                if (error != 0)
                   2712:                        break;
                   2713:                off += mlen;
                   2714:                buf += mlen;
                   2715:                len -= mlen;
                   2716:        }
                   2717:        return (error);
                   2718: }
                   2719:
                   2720: static int
                   2721: urtwn_load_firmware(struct urtwn_softc *sc)
                   2722: {
                   2723:        firmware_handle_t fwh;
                   2724:        const struct r92c_fw_hdr *hdr;
                   2725:        const char *name;
                   2726:        u_char *fw, *ptr;
                   2727:        size_t len;
                   2728:        uint32_t reg;
                   2729:        int mlen, ntries, page, error;
                   2730:
                   2731:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2732:
1.12      christos 2733:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2734:
1.1       nonaka   2735:        /* Read firmware image from the filesystem. */
                   2736:        if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
                   2737:            URTWN_CHIP_UMC_A_CUT)
1.5       riz      2738:                name = "rtl8192cfwU.bin";
1.1       nonaka   2739:        else
1.5       riz      2740:                name = "rtl8192cfw.bin";
                   2741:        if ((error = firmware_open("if_urtwn", name, &fwh)) != 0) {
1.1       nonaka   2742:                aprint_error_dev(sc->sc_dev,
                   2743:                    "failed loadfirmware of file %s (error %d)\n", name, error);
                   2744:                return (error);
                   2745:        }
                   2746:        len = firmware_get_size(fwh);
                   2747:        fw = firmware_malloc(len);
                   2748:        if (fw == NULL) {
                   2749:                aprint_error_dev(sc->sc_dev,
                   2750:                    "failed to allocate firmware memory\n");
                   2751:                firmware_close(fwh);
                   2752:                return (ENOMEM);
                   2753:        }
                   2754:        error = firmware_read(fwh, 0, fw, len);
                   2755:        firmware_close(fwh);
                   2756:        if (error != 0) {
                   2757:                aprint_error_dev(sc->sc_dev,
                   2758:                    "failed to read firmware (error %d)\n", error);
                   2759:                firmware_free(fw, 0);
                   2760:                return (error);
                   2761:        }
                   2762:
                   2763:        ptr = fw;
                   2764:        hdr = (const struct r92c_fw_hdr *)ptr;
                   2765:        /* Check if there is a valid FW header and skip it. */
                   2766:        if ((le16toh(hdr->signature) >> 4) == 0x88c ||
                   2767:            (le16toh(hdr->signature) >> 4) == 0x92c) {
                   2768:                DPRINTFN(DBG_INIT, ("%s: %s: FW V%d.%d %02d-%02d %02d:%02d\n",
                   2769:                    device_xname(sc->sc_dev), __func__,
                   2770:                    le16toh(hdr->version), le16toh(hdr->subversion),
                   2771:                    hdr->month, hdr->date, hdr->hour, hdr->minute));
                   2772:                ptr += sizeof(*hdr);
                   2773:                len -= sizeof(*hdr);
                   2774:        }
                   2775:
                   2776:        if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) {
                   2777:                urtwn_fw_reset(sc);
                   2778:                urtwn_write_1(sc, R92C_MCUFWDL, 0);
                   2779:        }
                   2780:
                   2781:        /* download enabled */
                   2782:        urtwn_write_2(sc, R92C_SYS_FUNC_EN,
                   2783:            urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
                   2784:            R92C_SYS_FUNC_EN_CPUEN);
                   2785:        urtwn_write_1(sc, R92C_MCUFWDL,
                   2786:            urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
                   2787:        urtwn_write_1(sc, R92C_MCUFWDL + 2,
                   2788:            urtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08);
                   2789:
                   2790:        /* download firmware */
                   2791:        for (page = 0; len > 0; page++) {
                   2792:                mlen = MIN(len, R92C_FW_PAGE_SIZE);
                   2793:                error = urtwn_fw_loadpage(sc, page, ptr, mlen);
                   2794:                if (error != 0) {
                   2795:                        aprint_error_dev(sc->sc_dev,
                   2796:                            "could not load firmware page %d\n", page);
                   2797:                        goto fail;
                   2798:                }
                   2799:                ptr += mlen;
                   2800:                len -= mlen;
                   2801:        }
                   2802:
                   2803:        /* download disable */
                   2804:        urtwn_write_1(sc, R92C_MCUFWDL,
                   2805:            urtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN);
                   2806:        urtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
                   2807:
                   2808:        /* Wait for checksum report. */
                   2809:        for (ntries = 0; ntries < 1000; ntries++) {
                   2810:                if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT)
                   2811:                        break;
                   2812:                DELAY(5);
                   2813:        }
                   2814:        if (ntries == 1000) {
                   2815:                aprint_error_dev(sc->sc_dev,
                   2816:                    "timeout waiting for checksum report\n");
                   2817:                error = ETIMEDOUT;
                   2818:                goto fail;
                   2819:        }
                   2820:
                   2821:        /* Wait for firmware readiness. */
                   2822:        reg = urtwn_read_4(sc, R92C_MCUFWDL);
                   2823:        reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY;
                   2824:        urtwn_write_4(sc, R92C_MCUFWDL, reg);
                   2825:        for (ntries = 0; ntries < 1000; ntries++) {
                   2826:                if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
                   2827:                        break;
                   2828:                DELAY(5);
                   2829:        }
                   2830:        if (ntries == 1000) {
                   2831:                aprint_error_dev(sc->sc_dev,
                   2832:                    "timeout waiting for firmware readiness\n");
                   2833:                error = ETIMEDOUT;
                   2834:                goto fail;
                   2835:        }
                   2836:  fail:
                   2837:        firmware_free(fw, 0);
                   2838:        return (error);
                   2839: }
                   2840:
                   2841: static int
                   2842: urtwn_dma_init(struct urtwn_softc *sc)
                   2843: {
                   2844:        int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
                   2845:        uint32_t reg;
                   2846:        int error;
                   2847:
                   2848:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2849:
1.12      christos 2850:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2851:
1.1       nonaka   2852:        /* Initialize LLT table. */
                   2853:        error = urtwn_llt_init(sc);
                   2854:        if (error != 0)
                   2855:                return (error);
                   2856:
                   2857:        /* Get Tx queues to USB endpoints mapping. */
                   2858:        hashq = hasnq = haslq = 0;
                   2859:        reg = urtwn_read_2(sc, R92C_USB_EP + 1);
                   2860:        DPRINTFN(DBG_INIT, ("%s: %s: USB endpoints mapping 0x%x\n",
                   2861:            device_xname(sc->sc_dev), __func__, reg));
                   2862:        if (MS(reg, R92C_USB_EP_HQ) != 0)
                   2863:                hashq = 1;
                   2864:        if (MS(reg, R92C_USB_EP_NQ) != 0)
                   2865:                hasnq = 1;
                   2866:        if (MS(reg, R92C_USB_EP_LQ) != 0)
                   2867:                haslq = 1;
                   2868:        nqueues = hashq + hasnq + haslq;
                   2869:        if (nqueues == 0)
                   2870:                return (EIO);
                   2871:        /* Get the number of pages for each queue. */
                   2872:        nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues;
                   2873:        /* The remaining pages are assigned to the high priority queue. */
                   2874:        nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
                   2875:
                   2876:        /* Set number of pages for normal priority queue. */
                   2877:        urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
                   2878:        urtwn_write_4(sc, R92C_RQPN,
                   2879:            /* Set number of pages for public queue. */
                   2880:            SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
                   2881:            /* Set number of pages for high priority queue. */
                   2882:            SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) |
                   2883:            /* Set number of pages for low priority queue. */
                   2884:            SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
                   2885:            /* Load values. */
                   2886:            R92C_RQPN_LD);
                   2887:
                   2888:        urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
                   2889:        urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
                   2890:        urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
                   2891:        urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
                   2892:        urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
                   2893:
                   2894:        /* Set queue to USB pipe mapping. */
                   2895:        reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
                   2896:        reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
                   2897:        if (nqueues == 1) {
                   2898:                if (hashq) {
                   2899:                        reg |= R92C_TRXDMA_CTRL_QMAP_HQ;
                   2900:                } else if (hasnq) {
                   2901:                        reg |= R92C_TRXDMA_CTRL_QMAP_NQ;
                   2902:                } else {
                   2903:                        reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
                   2904:                }
                   2905:        } else if (nqueues == 2) {
                   2906:                /* All 2-endpoints configs have a high priority queue. */
                   2907:                if (!hashq) {
                   2908:                        return (EIO);
                   2909:                }
                   2910:                if (hasnq) {
                   2911:                        reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
                   2912:                } else {
                   2913:                        reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ;
                   2914:                }
                   2915:        } else {
                   2916:                reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
                   2917:        }
                   2918:        urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
                   2919:
                   2920:        /* Set Tx/Rx transfer page boundary. */
                   2921:        urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
                   2922:
                   2923:        /* Set Tx/Rx transfer page size. */
                   2924:        urtwn_write_1(sc, R92C_PBP,
                   2925:            SM(R92C_PBP_PSRX, R92C_PBP_128) | SM(R92C_PBP_PSTX, R92C_PBP_128));
                   2926:        return (0);
                   2927: }
                   2928:
                   2929: static void
                   2930: urtwn_mac_init(struct urtwn_softc *sc)
                   2931: {
1.22      christos 2932:        size_t i;
1.1       nonaka   2933:
                   2934:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2935:
1.12      christos 2936:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2937:
1.1       nonaka   2938:        /* Write MAC initialization values. */
1.22      christos 2939:        for (i = 0; i < __arraycount(rtl8192cu_mac); i++)
1.1       nonaka   2940:                urtwn_write_1(sc, rtl8192cu_mac[i].reg, rtl8192cu_mac[i].val);
                   2941: }
                   2942:
                   2943: static void
                   2944: urtwn_bb_init(struct urtwn_softc *sc)
                   2945: {
                   2946:        const struct urtwn_bb_prog *prog;
                   2947:        uint32_t reg;
1.22      christos 2948:        size_t i;
1.1       nonaka   2949:
                   2950:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   2951:
1.12      christos 2952:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   2953:
1.1       nonaka   2954:        /* Enable BB and RF. */
                   2955:        urtwn_write_2(sc, R92C_SYS_FUNC_EN,
                   2956:            urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
                   2957:            R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
                   2958:            R92C_SYS_FUNC_EN_DIO_RF);
                   2959:
                   2960:        urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x83);
                   2961:        urtwn_write_1(sc, R92C_AFE_PLL_CTRL + 1, 0xdb);
                   2962:
                   2963:        urtwn_write_1(sc, R92C_RF_CTRL,
                   2964:            R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
                   2965:        urtwn_write_1(sc, R92C_SYS_FUNC_EN,
                   2966:            R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
                   2967:            R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
                   2968:
                   2969:        urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
                   2970:        urtwn_write_1(sc, 0x15, 0xe9);
                   2971:        urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
                   2972:
                   2973:        /* Select BB programming based on board type. */
                   2974:        if (!(sc->chip & URTWN_CHIP_92C)) {
                   2975:                if (sc->board_type == R92C_BOARD_TYPE_MINICARD) {
                   2976:                        prog = &rtl8188ce_bb_prog;
                   2977:                } else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) {
                   2978:                        prog = &rtl8188ru_bb_prog;
                   2979:                } else {
                   2980:                        prog = &rtl8188cu_bb_prog;
                   2981:                }
                   2982:        } else {
                   2983:                if (sc->board_type == R92C_BOARD_TYPE_MINICARD) {
                   2984:                        prog = &rtl8192ce_bb_prog;
                   2985:                } else {
                   2986:                        prog = &rtl8192cu_bb_prog;
                   2987:                }
                   2988:        }
                   2989:        /* Write BB initialization values. */
                   2990:        for (i = 0; i < prog->count; i++) {
                   2991:                /* additional delay depend on registers */
                   2992:                switch (prog->regs[i]) {
                   2993:                case 0xfe:
                   2994:                        usbd_delay_ms(sc->sc_udev, 50);
                   2995:                        break;
                   2996:                case 0xfd:
                   2997:                        usbd_delay_ms(sc->sc_udev, 5);
                   2998:                        break;
                   2999:                case 0xfc:
                   3000:                        usbd_delay_ms(sc->sc_udev, 1);
                   3001:                        break;
                   3002:                case 0xfb:
                   3003:                        DELAY(50);
                   3004:                        break;
                   3005:                case 0xfa:
                   3006:                        DELAY(5);
                   3007:                        break;
                   3008:                case 0xf9:
                   3009:                        DELAY(1);
                   3010:                        break;
                   3011:                }
                   3012:                urtwn_bb_write(sc, prog->regs[i], prog->vals[i]);
                   3013:                DELAY(1);
                   3014:        }
                   3015:
                   3016:        if (sc->chip & URTWN_CHIP_92C_1T2R) {
                   3017:                /* 8192C 1T only configuration. */
                   3018:                reg = urtwn_bb_read(sc, R92C_FPGA0_TXINFO);
                   3019:                reg = (reg & ~0x00000003) | 0x2;
                   3020:                urtwn_bb_write(sc, R92C_FPGA0_TXINFO, reg);
                   3021:
                   3022:                reg = urtwn_bb_read(sc, R92C_FPGA1_TXINFO);
                   3023:                reg = (reg & ~0x00300033) | 0x00200022;
                   3024:                urtwn_bb_write(sc, R92C_FPGA1_TXINFO, reg);
                   3025:
                   3026:                reg = urtwn_bb_read(sc, R92C_CCK0_AFESETTING);
                   3027:                reg = (reg & ~0xff000000) | (0x45 << 24);
                   3028:                urtwn_bb_write(sc, R92C_CCK0_AFESETTING, reg);
                   3029:
                   3030:                reg = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA);
                   3031:                reg = (reg & ~0x000000ff) | 0x23;
                   3032:                urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg);
                   3033:
                   3034:                reg = urtwn_bb_read(sc, R92C_OFDM0_AGCPARAM1);
                   3035:                reg = (reg & ~0x00000030) | (1 << 4);
                   3036:                urtwn_bb_write(sc, R92C_OFDM0_AGCPARAM1, reg);
                   3037:
                   3038:                reg = urtwn_bb_read(sc, 0xe74);
                   3039:                reg = (reg & ~0x0c000000) | (2 << 26);
                   3040:                urtwn_bb_write(sc, 0xe74, reg);
                   3041:                reg = urtwn_bb_read(sc, 0xe78);
                   3042:                reg = (reg & ~0x0c000000) | (2 << 26);
                   3043:                urtwn_bb_write(sc, 0xe78, reg);
                   3044:                reg = urtwn_bb_read(sc, 0xe7c);
                   3045:                reg = (reg & ~0x0c000000) | (2 << 26);
                   3046:                urtwn_bb_write(sc, 0xe7c, reg);
                   3047:                reg = urtwn_bb_read(sc, 0xe80);
                   3048:                reg = (reg & ~0x0c000000) | (2 << 26);
                   3049:                urtwn_bb_write(sc, 0xe80, reg);
                   3050:                reg = urtwn_bb_read(sc, 0xe88);
                   3051:                reg = (reg & ~0x0c000000) | (2 << 26);
                   3052:                urtwn_bb_write(sc, 0xe88, reg);
                   3053:        }
                   3054:
                   3055:        /* Write AGC values. */
                   3056:        for (i = 0; i < prog->agccount; i++) {
                   3057:                urtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE, prog->agcvals[i]);
                   3058:                DELAY(1);
                   3059:        }
                   3060:
                   3061:        if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
                   3062:            R92C_HSSI_PARAM2_CCK_HIPWR) {
                   3063:                SET(sc->sc_flags, URTWN_FLAG_CCK_HIPWR);
                   3064:        }
                   3065: }
                   3066:
                   3067: static void
                   3068: urtwn_rf_init(struct urtwn_softc *sc)
                   3069: {
                   3070:        const struct urtwn_rf_prog *prog;
                   3071:        uint32_t reg, mask, saved;
1.22      christos 3072:        size_t i, j, idx;
1.1       nonaka   3073:
                   3074:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3075:
                   3076:        /* Select RF programming based on board type. */
                   3077:        if (!(sc->chip & URTWN_CHIP_92C)) {
                   3078:                if (sc->board_type == R92C_BOARD_TYPE_MINICARD) {
                   3079:                        prog = rtl8188ce_rf_prog;
                   3080:                } else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) {
                   3081:                        prog = rtl8188ru_rf_prog;
                   3082:                } else {
                   3083:                        prog = rtl8188cu_rf_prog;
                   3084:                }
                   3085:        } else {
                   3086:                prog = rtl8192ce_rf_prog;
                   3087:        }
                   3088:
                   3089:        for (i = 0; i < sc->nrxchains; i++) {
                   3090:                /* Save RF_ENV control type. */
                   3091:                idx = i / 2;
                   3092:                mask = 0xffffU << ((i % 2) * 16);
                   3093:                saved = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx)) & mask;
                   3094:
                   3095:                /* Set RF_ENV enable. */
                   3096:                reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
                   3097:                reg |= 0x100000;
                   3098:                urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
                   3099:                DELAY(1);
                   3100:
                   3101:                /* Set RF_ENV output high. */
                   3102:                reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
                   3103:                reg |= 0x10;
                   3104:                urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
                   3105:                DELAY(1);
                   3106:
                   3107:                /* Set address and data lengths of RF registers. */
                   3108:                reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
                   3109:                reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH;
                   3110:                urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
                   3111:                DELAY(1);
                   3112:                reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
                   3113:                reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH;
                   3114:                urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
                   3115:                DELAY(1);
                   3116:
                   3117:                /* Write RF initialization values for this chain. */
                   3118:                for (j = 0; j < prog[i].count; j++) {
                   3119:                        if (prog[i].regs[j] >= 0xf9 &&
                   3120:                            prog[i].regs[j] <= 0xfe) {
                   3121:                                /*
                   3122:                                 * These are fake RF registers offsets that
                   3123:                                 * indicate a delay is required.
                   3124:                                 */
                   3125:                                usbd_delay_ms(sc->sc_udev, 50);
                   3126:                                continue;
                   3127:                        }
                   3128:                        urtwn_rf_write(sc, i, prog[i].regs[j], prog[i].vals[j]);
                   3129:                        DELAY(1);
                   3130:                }
                   3131:
                   3132:                /* Restore RF_ENV control type. */
                   3133:                reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx)) & ~mask;
                   3134:                urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(idx), reg | saved);
                   3135:        }
                   3136:
                   3137:        if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
                   3138:            URTWN_CHIP_UMC_A_CUT) {
                   3139:                urtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
                   3140:                urtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
                   3141:        }
                   3142:
                   3143:        /* Cache RF register CHNLBW. */
                   3144:        for (i = 0; i < 2; i++) {
                   3145:                sc->rf_chnlbw[i] = urtwn_rf_read(sc, i, R92C_RF_CHNLBW);
                   3146:        }
                   3147: }
                   3148:
                   3149: static void
                   3150: urtwn_cam_init(struct urtwn_softc *sc)
                   3151: {
                   3152:        uint32_t content, command;
                   3153:        uint8_t idx;
1.22      christos 3154:        size_t i;
1.1       nonaka   3155:
                   3156:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3157:
1.12      christos 3158:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3159:
1.1       nonaka   3160:        for (idx = 0; idx < R92C_CAM_ENTRY_COUNT; idx++) {
                   3161:                content = (idx & 3)
                   3162:                    | (R92C_CAM_ALGO_AES << R92C_CAM_ALGO_S)
                   3163:                    | R92C_CAM_VALID;
                   3164:
                   3165:                command = R92C_CAMCMD_POLLING
                   3166:                    | R92C_CAMCMD_WRITE
                   3167:                    | R92C_CAM_CTL0(idx);
                   3168:
                   3169:                urtwn_write_4(sc, R92C_CAMWRITE, content);
                   3170:                urtwn_write_4(sc, R92C_CAMCMD, command);
                   3171:        }
                   3172:
                   3173:        for (idx = 0; idx < R92C_CAM_ENTRY_COUNT; idx++) {
                   3174:                for (i = 0; i < /* CAM_CONTENT_COUNT */ 8; i++) {
                   3175:                        if (i == 0) {
                   3176:                                content = (idx & 3)
                   3177:                                    | (R92C_CAM_ALGO_AES << R92C_CAM_ALGO_S)
                   3178:                                    | R92C_CAM_VALID;
                   3179:                        } else {
                   3180:                                content = 0;
                   3181:                        }
                   3182:
                   3183:                        command = R92C_CAMCMD_POLLING
                   3184:                            | R92C_CAMCMD_WRITE
                   3185:                            | R92C_CAM_CTL0(idx)
1.22      christos 3186:                            | i;
1.1       nonaka   3187:
                   3188:                        urtwn_write_4(sc, R92C_CAMWRITE, content);
                   3189:                        urtwn_write_4(sc, R92C_CAMCMD, command);
                   3190:                }
                   3191:        }
                   3192:
                   3193:        /* Invalidate all CAM entries. */
                   3194:        urtwn_write_4(sc, R92C_CAMCMD, R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR);
                   3195: }
                   3196:
                   3197: static void
                   3198: urtwn_pa_bias_init(struct urtwn_softc *sc)
                   3199: {
                   3200:        uint8_t reg;
1.22      christos 3201:        size_t i;
1.1       nonaka   3202:
                   3203:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3204:
1.12      christos 3205:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3206:
1.1       nonaka   3207:        for (i = 0; i < sc->nrxchains; i++) {
                   3208:                if (sc->pa_setting & (1U << i))
                   3209:                        continue;
                   3210:
                   3211:                urtwn_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
                   3212:                urtwn_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
                   3213:                urtwn_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
                   3214:                urtwn_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
                   3215:        }
                   3216:        if (!(sc->pa_setting & 0x10)) {
                   3217:                reg = urtwn_read_1(sc, 0x16);
                   3218:                reg = (reg & ~0xf0) | 0x90;
                   3219:                urtwn_write_1(sc, 0x16, reg);
                   3220:        }
                   3221: }
                   3222:
                   3223: static void
                   3224: urtwn_rxfilter_init(struct urtwn_softc *sc)
                   3225: {
                   3226:
                   3227:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3228:
1.12      christos 3229:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3230:
1.1       nonaka   3231:        /* Initialize Rx filter. */
                   3232:        /* TODO: use better filter for monitor mode. */
                   3233:        urtwn_write_4(sc, R92C_RCR,
                   3234:            R92C_RCR_AAP | R92C_RCR_APM | R92C_RCR_AM | R92C_RCR_AB |
                   3235:            R92C_RCR_APP_ICV | R92C_RCR_AMF | R92C_RCR_HTC_LOC_CTRL |
                   3236:            R92C_RCR_APP_MIC | R92C_RCR_APP_PHYSTS);
                   3237:        /* Accept all multicast frames. */
                   3238:        urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff);
                   3239:        urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff);
                   3240:        /* Accept all management frames. */
                   3241:        urtwn_write_2(sc, R92C_RXFLTMAP0, 0xffff);
                   3242:        /* Reject all control frames. */
                   3243:        urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000);
                   3244:        /* Accept all data frames. */
                   3245:        urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
                   3246: }
                   3247:
                   3248: static void
                   3249: urtwn_edca_init(struct urtwn_softc *sc)
                   3250: {
                   3251:
                   3252:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3253:
1.12      christos 3254:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3255:
1.1       nonaka   3256:        /* set spec SIFS (used in NAV) */
                   3257:        urtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
                   3258:        urtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
                   3259:
                   3260:        /* set SIFS CCK/OFDM */
                   3261:        urtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
                   3262:        urtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
                   3263:
                   3264:        /* TXOP */
                   3265:        urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
                   3266:        urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
                   3267:        urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
                   3268:        urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
                   3269: }
                   3270:
                   3271: static void
                   3272: urtwn_write_txpower(struct urtwn_softc *sc, int chain,
                   3273:     uint16_t power[URTWN_RIDX_COUNT])
                   3274: {
                   3275:        uint32_t reg;
                   3276:
                   3277:        DPRINTFN(DBG_FN, ("%s: %s: chain=%d\n", device_xname(sc->sc_dev),
                   3278:            __func__, chain));
                   3279:
                   3280:        /* Write per-CCK rate Tx power. */
                   3281:        if (chain == 0) {
                   3282:                reg = urtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
                   3283:                reg = RW(reg, R92C_TXAGC_A_CCK1,  power[0]);
                   3284:                urtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
                   3285:
                   3286:                reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
                   3287:                reg = RW(reg, R92C_TXAGC_A_CCK2,  power[1]);
                   3288:                reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]);
                   3289:                reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]);
                   3290:                urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
                   3291:        } else {
                   3292:                reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
                   3293:                reg = RW(reg, R92C_TXAGC_B_CCK1,  power[0]);
                   3294:                reg = RW(reg, R92C_TXAGC_B_CCK2,  power[1]);
                   3295:                reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]);
                   3296:                urtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
                   3297:
                   3298:                reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
                   3299:                reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]);
                   3300:                urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
                   3301:        }
                   3302:        /* Write per-OFDM rate Tx power. */
                   3303:        urtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
                   3304:            SM(R92C_TXAGC_RATE06, power[ 4]) |
                   3305:            SM(R92C_TXAGC_RATE09, power[ 5]) |
                   3306:            SM(R92C_TXAGC_RATE12, power[ 6]) |
                   3307:            SM(R92C_TXAGC_RATE18, power[ 7]));
                   3308:        urtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
                   3309:            SM(R92C_TXAGC_RATE24, power[ 8]) |
                   3310:            SM(R92C_TXAGC_RATE36, power[ 9]) |
                   3311:            SM(R92C_TXAGC_RATE48, power[10]) |
                   3312:            SM(R92C_TXAGC_RATE54, power[11]));
                   3313:        /* Write per-MCS Tx power. */
                   3314:        urtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
                   3315:            SM(R92C_TXAGC_MCS00,  power[12]) |
                   3316:            SM(R92C_TXAGC_MCS01,  power[13]) |
                   3317:            SM(R92C_TXAGC_MCS02,  power[14]) |
                   3318:            SM(R92C_TXAGC_MCS03,  power[15]));
                   3319:        urtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
                   3320:            SM(R92C_TXAGC_MCS04,  power[16]) |
                   3321:            SM(R92C_TXAGC_MCS05,  power[17]) |
                   3322:            SM(R92C_TXAGC_MCS06,  power[18]) |
                   3323:            SM(R92C_TXAGC_MCS07,  power[19]));
                   3324:        urtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
                   3325:            SM(R92C_TXAGC_MCS08,  power[20]) |
                   3326:            SM(R92C_TXAGC_MCS09,  power[21]) |
                   3327:            SM(R92C_TXAGC_MCS10,  power[22]) |
                   3328:            SM(R92C_TXAGC_MCS11,  power[23]));
                   3329:        urtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
                   3330:            SM(R92C_TXAGC_MCS12,  power[24]) |
                   3331:            SM(R92C_TXAGC_MCS13,  power[25]) |
                   3332:            SM(R92C_TXAGC_MCS14,  power[26]) |
                   3333:            SM(R92C_TXAGC_MCS15,  power[27]));
                   3334: }
                   3335:
                   3336: static void
1.22      christos 3337: urtwn_get_txpower(struct urtwn_softc *sc, size_t chain, u_int chan, u_int ht40m,
1.1       nonaka   3338:     uint16_t power[URTWN_RIDX_COUNT])
                   3339: {
                   3340:        struct r92c_rom *rom = &sc->rom;
                   3341:        uint16_t cckpow, ofdmpow, htpow, diff, maxpow;
                   3342:        const struct urtwn_txpwr *base;
                   3343:        int ridx, group;
                   3344:
1.22      christos 3345:        DPRINTFN(DBG_FN, ("%s: %s: chain=%zd, chan=%d\n",
1.1       nonaka   3346:            device_xname(sc->sc_dev), __func__, chain, chan));
                   3347:
                   3348:        /* Determine channel group. */
                   3349:        if (chan <= 3) {
                   3350:                group = 0;
                   3351:        } else if (chan <= 9) {
                   3352:                group = 1;
                   3353:        } else {
                   3354:                group = 2;
                   3355:        }
                   3356:
                   3357:        /* Get original Tx power based on board type and RF chain. */
                   3358:        if (!(sc->chip & URTWN_CHIP_92C)) {
                   3359:                if (sc->board_type == R92C_BOARD_TYPE_HIGHPA) {
                   3360:                        base = &rtl8188ru_txagc[chain];
                   3361:                } else {
                   3362:                        base = &rtl8192cu_txagc[chain];
                   3363:                }
                   3364:        } else {
                   3365:                base = &rtl8192cu_txagc[chain];
                   3366:        }
                   3367:
                   3368:        memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0]));
                   3369:        if (sc->regulatory == 0) {
                   3370:                for (ridx = 0; ridx <= 3; ridx++) {
                   3371:                        power[ridx] = base->pwr[0][ridx];
                   3372:                }
                   3373:        }
                   3374:        for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) {
                   3375:                if (sc->regulatory == 3) {
                   3376:                        power[ridx] = base->pwr[0][ridx];
                   3377:                        /* Apply vendor limits. */
                   3378:                        if (ht40m != IEEE80211_HTINFO_2NDCHAN_NONE) {
                   3379:                                maxpow = rom->ht40_max_pwr[group];
                   3380:                        } else {
                   3381:                                maxpow = rom->ht20_max_pwr[group];
                   3382:                        }
                   3383:                        maxpow = (maxpow >> (chain * 4)) & 0xf;
                   3384:                        if (power[ridx] > maxpow) {
                   3385:                                power[ridx] = maxpow;
                   3386:                        }
                   3387:                } else if (sc->regulatory == 1) {
                   3388:                        if (ht40m == IEEE80211_HTINFO_2NDCHAN_NONE) {
                   3389:                                power[ridx] = base->pwr[group][ridx];
                   3390:                        }
                   3391:                } else if (sc->regulatory != 2) {
                   3392:                        power[ridx] = base->pwr[0][ridx];
                   3393:                }
                   3394:        }
                   3395:
                   3396:        /* Compute per-CCK rate Tx power. */
                   3397:        cckpow = rom->cck_tx_pwr[chain][group];
                   3398:        for (ridx = 0; ridx <= 3; ridx++) {
                   3399:                power[ridx] += cckpow;
                   3400:                if (power[ridx] > R92C_MAX_TX_PWR) {
                   3401:                        power[ridx] = R92C_MAX_TX_PWR;
                   3402:                }
                   3403:        }
                   3404:
                   3405:        htpow = rom->ht40_1s_tx_pwr[chain][group];
                   3406:        if (sc->ntxchains > 1) {
                   3407:                /* Apply reduction for 2 spatial streams. */
                   3408:                diff = rom->ht40_2s_tx_pwr_diff[group];
                   3409:                diff = (diff >> (chain * 4)) & 0xf;
                   3410:                htpow = (htpow > diff) ? htpow - diff : 0;
                   3411:        }
                   3412:
                   3413:        /* Compute per-OFDM rate Tx power. */
                   3414:        diff = rom->ofdm_tx_pwr_diff[group];
                   3415:        diff = (diff >> (chain * 4)) & 0xf;
                   3416:        ofdmpow = htpow + diff; /* HT->OFDM correction. */
                   3417:        for (ridx = 4; ridx <= 11; ridx++) {
                   3418:                power[ridx] += ofdmpow;
                   3419:                if (power[ridx] > R92C_MAX_TX_PWR) {
                   3420:                        power[ridx] = R92C_MAX_TX_PWR;
                   3421:                }
                   3422:        }
                   3423:
                   3424:        /* Compute per-MCS Tx power. */
                   3425:        if (ht40m == IEEE80211_HTINFO_2NDCHAN_NONE) {
                   3426:                diff = rom->ht20_tx_pwr_diff[group];
                   3427:                diff = (diff >> (chain * 4)) & 0xf;
                   3428:                htpow += diff;  /* HT40->HT20 correction. */
                   3429:        }
                   3430:        for (ridx = 12; ridx < URTWN_RIDX_COUNT; ridx++) {
                   3431:                power[ridx] += htpow;
                   3432:                if (power[ridx] > R92C_MAX_TX_PWR) {
                   3433:                        power[ridx] = R92C_MAX_TX_PWR;
                   3434:                }
                   3435:        }
                   3436: #ifdef URTWN_DEBUG
                   3437:        if (urtwn_debug & DBG_RF) {
                   3438:                /* Dump per-rate Tx power values. */
1.22      christos 3439:                printf("%s: %s: Tx power for chain %zd:\n",
1.1       nonaka   3440:                    device_xname(sc->sc_dev), __func__, chain);
                   3441:                for (ridx = 0; ridx < URTWN_RIDX_COUNT; ridx++) {
                   3442:                        printf("%s: %s: Rate %d = %u\n",
                   3443:                            device_xname(sc->sc_dev), __func__, ridx,
                   3444:                            power[ridx]);
                   3445:                }
                   3446:        }
                   3447: #endif
                   3448: }
                   3449:
                   3450: static void
                   3451: urtwn_set_txpower(struct urtwn_softc *sc, u_int chan, u_int ht40m)
                   3452: {
                   3453:        uint16_t power[URTWN_RIDX_COUNT];
1.22      christos 3454:        size_t i;
1.1       nonaka   3455:
                   3456:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3457:
                   3458:        for (i = 0; i < sc->ntxchains; i++) {
                   3459:                /* Compute per-rate Tx power values. */
                   3460:                urtwn_get_txpower(sc, i, chan, ht40m, power);
                   3461:                /* Write per-rate Tx power values to hardware. */
                   3462:                urtwn_write_txpower(sc, i, power);
                   3463:        }
                   3464: }
                   3465:
                   3466: static void
                   3467: urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c, u_int ht40m)
                   3468: {
                   3469:        struct ieee80211com *ic = &sc->sc_ic;
                   3470:        u_int chan;
1.22      christos 3471:        size_t i;
1.1       nonaka   3472:
                   3473:        chan = ieee80211_chan2ieee(ic, c);      /* XXX center freq! */
                   3474:
                   3475:        DPRINTFN(DBG_FN, ("%s: %s: chan=%d\n", device_xname(sc->sc_dev),
                   3476:            __func__, chan));
                   3477:
1.12      christos 3478:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3479:
1.1       nonaka   3480:        if (ht40m == IEEE80211_HTINFO_2NDCHAN_ABOVE) {
                   3481:                chan += 2;
                   3482:        } else if (ht40m == IEEE80211_HTINFO_2NDCHAN_BELOW){
                   3483:                chan -= 2;
                   3484:        }
                   3485:
                   3486:        /* Set Tx power for this new channel. */
                   3487:        urtwn_set_txpower(sc, chan, ht40m);
                   3488:
                   3489:        for (i = 0; i < sc->nrxchains; i++) {
                   3490:                urtwn_rf_write(sc, i, R92C_RF_CHNLBW,
                   3491:                    RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan));
                   3492:        }
                   3493:
                   3494:        if (ht40m) {
                   3495:                /* Is secondary channel below or above primary? */
                   3496:                int prichlo = (ht40m == IEEE80211_HTINFO_2NDCHAN_ABOVE);
                   3497:                uint32_t reg;
                   3498:
                   3499:                urtwn_write_1(sc, R92C_BWOPMODE,
                   3500:                    urtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ);
                   3501:
                   3502:                reg = urtwn_read_1(sc, R92C_RRSR + 2);
                   3503:                reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5;
                   3504:                urtwn_write_1(sc, R92C_RRSR + 2, (uint8_t)reg);
                   3505:
                   3506:                urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
                   3507:                    urtwn_bb_read(sc, R92C_FPGA0_RFMOD) | R92C_RFMOD_40MHZ);
                   3508:                urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
                   3509:                    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) | R92C_RFMOD_40MHZ);
                   3510:
                   3511:                /* Set CCK side band. */
                   3512:                reg = urtwn_bb_read(sc, R92C_CCK0_SYSTEM);
                   3513:                reg = (reg & ~0x00000010) | (prichlo ? 0 : 1) << 4;
                   3514:                urtwn_bb_write(sc, R92C_CCK0_SYSTEM, reg);
                   3515:
                   3516:                reg = urtwn_bb_read(sc, R92C_OFDM1_LSTF);
                   3517:                reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10;
                   3518:                urtwn_bb_write(sc, R92C_OFDM1_LSTF, reg);
                   3519:
                   3520:                urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
                   3521:                    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) &
                   3522:                    ~R92C_FPGA0_ANAPARAM2_CBW20);
                   3523:
                   3524:                reg = urtwn_bb_read(sc, 0x818);
                   3525:                reg = (reg & ~0x0c000000) | (prichlo ? 2 : 1) << 26;
                   3526:                urtwn_bb_write(sc, 0x818, reg);
                   3527:
                   3528:                /* Select 40MHz bandwidth. */
                   3529:                urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
                   3530:                    (sc->rf_chnlbw[0] & ~0xfff) | chan);
                   3531:        } else {
                   3532:                urtwn_write_1(sc, R92C_BWOPMODE,
                   3533:                    urtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ);
                   3534:
                   3535:                urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
                   3536:                    urtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ);
                   3537:                urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
                   3538:                    urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ);
                   3539:
                   3540:                urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
                   3541:                    urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
                   3542:                    R92C_FPGA0_ANAPARAM2_CBW20);
                   3543:
                   3544:                /* Select 20MHz bandwidth. */
                   3545:                urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
                   3546:                    (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan);
                   3547:        }
                   3548: }
                   3549:
                   3550: static void
                   3551: urtwn_iq_calib(struct urtwn_softc *sc, bool inited)
                   3552: {
                   3553:
                   3554:        DPRINTFN(DBG_FN, ("%s: %s: inited=%d\n", device_xname(sc->sc_dev),
                   3555:            __func__, inited));
                   3556:
                   3557:        /* TODO */
                   3558: }
                   3559:
                   3560: static void
                   3561: urtwn_lc_calib(struct urtwn_softc *sc)
                   3562: {
                   3563:        uint32_t rf_ac[2];
                   3564:        uint8_t txmode;
1.22      christos 3565:        size_t i;
1.1       nonaka   3566:
                   3567:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3568:
1.12      christos 3569:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3570:
1.1       nonaka   3571:        txmode = urtwn_read_1(sc, R92C_OFDM1_LSTF + 3);
                   3572:        if ((txmode & 0x70) != 0) {
                   3573:                /* Disable all continuous Tx. */
                   3574:                urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70);
                   3575:
                   3576:                /* Set RF mode to standby mode. */
                   3577:                for (i = 0; i < sc->nrxchains; i++) {
                   3578:                        rf_ac[i] = urtwn_rf_read(sc, i, R92C_RF_AC);
                   3579:                        urtwn_rf_write(sc, i, R92C_RF_AC,
                   3580:                            RW(rf_ac[i], R92C_RF_AC_MODE,
                   3581:                                R92C_RF_AC_MODE_STANDBY));
                   3582:                }
                   3583:        } else {
                   3584:                /* Block all Tx queues. */
                   3585:                urtwn_write_1(sc, R92C_TXPAUSE, 0xff);
                   3586:        }
                   3587:        /* Start calibration. */
                   3588:        urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
                   3589:            urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART);
                   3590:
                   3591:        /* Give calibration the time to complete. */
                   3592:        usbd_delay_ms(sc->sc_udev, 100);
                   3593:
                   3594:        /* Restore configuration. */
                   3595:        if ((txmode & 0x70) != 0) {
                   3596:                /* Restore Tx mode. */
                   3597:                urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode);
                   3598:                /* Restore RF mode. */
                   3599:                for (i = 0; i < sc->nrxchains; i++) {
                   3600:                        urtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]);
                   3601:                }
                   3602:        } else {
                   3603:                /* Unblock all Tx queues. */
                   3604:                urtwn_write_1(sc, R92C_TXPAUSE, 0x00);
                   3605:        }
                   3606: }
                   3607:
                   3608: static void
                   3609: urtwn_temp_calib(struct urtwn_softc *sc)
                   3610: {
                   3611:        int temp;
                   3612:
                   3613:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3614:
1.12      christos 3615:        KASSERT(mutex_owned(&sc->sc_write_mtx));
                   3616:
1.1       nonaka   3617:        if (sc->thcal_state == 0) {
                   3618:                /* Start measuring temperature. */
                   3619:                DPRINTFN(DBG_RF, ("%s: %s: start measuring temperature\n",
                   3620:                    device_xname(sc->sc_dev), __func__));
                   3621:                urtwn_rf_write(sc, 0, R92C_RF_T_METER, 0x60);
                   3622:                sc->thcal_state = 1;
                   3623:                return;
                   3624:        }
                   3625:        sc->thcal_state = 0;
                   3626:
                   3627:        /* Read measured temperature. */
                   3628:        temp = urtwn_rf_read(sc, 0, R92C_RF_T_METER) & 0x1f;
                   3629:        DPRINTFN(DBG_RF, ("%s: %s: temperature=%d\n", device_xname(sc->sc_dev),
                   3630:            __func__, temp));
                   3631:        if (temp == 0)  /* Read failed, skip. */
                   3632:                return;
                   3633:
                   3634:        /*
                   3635:         * Redo LC calibration if temperature changed significantly since
                   3636:         * last calibration.
                   3637:         */
                   3638:        if (sc->thcal_lctemp == 0) {
                   3639:                /* First LC calibration is performed in urtwn_init(). */
                   3640:                sc->thcal_lctemp = temp;
                   3641:        } else if (abs(temp - sc->thcal_lctemp) > 1) {
                   3642:                DPRINTFN(DBG_RF,
                   3643:                    ("%s: %s: LC calib triggered by temp: %d -> %d\n",
                   3644:                    device_xname(sc->sc_dev), __func__, sc->thcal_lctemp,
                   3645:                    temp));
                   3646:                urtwn_lc_calib(sc);
                   3647:                /* Record temperature of last LC calibration. */
                   3648:                sc->thcal_lctemp = temp;
                   3649:        }
                   3650: }
                   3651:
                   3652: static int
                   3653: urtwn_init(struct ifnet *ifp)
                   3654: {
                   3655:        struct urtwn_softc *sc = ifp->if_softc;
                   3656:        struct ieee80211com *ic = &sc->sc_ic;
                   3657:        struct urtwn_rx_data *data;
                   3658:        uint32_t reg;
1.22      christos 3659:        size_t i;
                   3660:        int error;
1.1       nonaka   3661:
                   3662:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3663:
                   3664:        urtwn_stop(ifp, 0);
                   3665:
1.12      christos 3666:        mutex_enter(&sc->sc_write_mtx);
                   3667:
1.1       nonaka   3668:        mutex_enter(&sc->sc_task_mtx);
                   3669:        /* Init host async commands ring. */
                   3670:        sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;
                   3671:        mutex_exit(&sc->sc_task_mtx);
                   3672:
                   3673:        mutex_enter(&sc->sc_fwcmd_mtx);
                   3674:        /* Init firmware commands ring. */
                   3675:        sc->fwcur = 0;
                   3676:        mutex_exit(&sc->sc_fwcmd_mtx);
                   3677:
1.12      christos 3678:        /* Allocate Tx/Rx buffers. */
                   3679:        error = urtwn_alloc_rx_list(sc);
                   3680:        if (error != 0) {
                   3681:                aprint_error_dev(sc->sc_dev,
                   3682:                    "could not allocate Rx buffers\n");
                   3683:                goto fail;
                   3684:        }
                   3685:        error = urtwn_alloc_tx_list(sc);
                   3686:        if (error != 0) {
                   3687:                aprint_error_dev(sc->sc_dev,
                   3688:                    "could not allocate Tx buffers\n");
                   3689:                goto fail;
1.1       nonaka   3690:        }
                   3691:
                   3692:        /* Power on adapter. */
                   3693:        error = urtwn_power_on(sc);
                   3694:        if (error != 0)
                   3695:                goto fail;
                   3696:
                   3697:        /* Initialize DMA. */
                   3698:        error = urtwn_dma_init(sc);
                   3699:        if (error != 0)
                   3700:                goto fail;
                   3701:
                   3702:        /* Set info size in Rx descriptors (in 64-bit words). */
                   3703:        urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);
                   3704:
                   3705:        /* Init interrupts. */
                   3706:        urtwn_write_4(sc, R92C_HISR, 0xffffffff);
                   3707:        urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
                   3708:
                   3709:        /* Set MAC address. */
                   3710:        IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
                   3711:        urtwn_write_region(sc, R92C_MACID, ic->ic_myaddr, IEEE80211_ADDR_LEN);
                   3712:
                   3713:        /* Set initial network type. */
                   3714:        reg = urtwn_read_4(sc, R92C_CR);
                   3715:        switch (ic->ic_opmode) {
                   3716:        case IEEE80211_M_STA:
                   3717:        default:
                   3718:                reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
                   3719:                break;
1.7       christos 3720:
1.1       nonaka   3721:        case IEEE80211_M_IBSS:
                   3722:                reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_ADHOC);
                   3723:                break;
                   3724:        }
                   3725:        urtwn_write_4(sc, R92C_CR, reg);
                   3726:
                   3727:        /* Set response rate */
                   3728:        reg = urtwn_read_4(sc, R92C_RRSR);
                   3729:        reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M);
                   3730:        urtwn_write_4(sc, R92C_RRSR, reg);
                   3731:
                   3732:        /* SIFS (used in NAV) */
                   3733:        urtwn_write_2(sc, R92C_SPEC_SIFS,
                   3734:            SM(R92C_SPEC_SIFS_CCK, 0x10) | SM(R92C_SPEC_SIFS_OFDM, 0x10));
                   3735:
                   3736:        /* Set short/long retry limits. */
                   3737:        urtwn_write_2(sc, R92C_RL,
                   3738:            SM(R92C_RL_SRL, 0x30) | SM(R92C_RL_LRL, 0x30));
                   3739:
                   3740:        /* Initialize EDCA parameters. */
                   3741:        urtwn_edca_init(sc);
                   3742:
                   3743:        /* Setup rate fallback. */
                   3744:        urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
                   3745:        urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
                   3746:        urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
                   3747:        urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
                   3748:
                   3749:        urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
                   3750:            urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
                   3751:            R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
                   3752:        /* Set ACK timeout. */
                   3753:        urtwn_write_1(sc, R92C_ACKTO, 0x40);
                   3754:
                   3755:        /* Setup USB aggregation. */
                   3756:        /* Tx */
                   3757:        reg = urtwn_read_4(sc, R92C_TDECTRL);
                   3758:        reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, 6);
                   3759:        urtwn_write_4(sc, R92C_TDECTRL, reg);
                   3760:        /* Rx */
                   3761:        urtwn_write_1(sc, R92C_TRXDMA_CTRL,
                   3762:            urtwn_read_1(sc, R92C_TRXDMA_CTRL) |
                   3763:              R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
                   3764:        urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
                   3765:            urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) &
                   3766:              ~R92C_USB_SPECIAL_OPTION_AGG_EN);
                   3767:        urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
                   3768:        urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
                   3769:
                   3770:        /* Initialize beacon parameters. */
                   3771:        urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
1.26    ! christos 3772:        urtwn_write_1(sc, R92C_DRVERLYINT, R92C_DRIVER_EARLY_INT_TIME);
        !          3773:        urtwn_write_1(sc, R92C_BCNDMATIM, R92C_DMA_ATIME_INT_TIME);
1.1       nonaka   3774:        urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);
                   3775:
                   3776:        /* Setup AMPDU aggregation. */
                   3777:        urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
                   3778:        urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
                   3779:        urtwn_write_2(sc, 0x4ca, 0x0708);
                   3780:
                   3781:        urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
                   3782:        urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0);
                   3783:
                   3784:        /* Load 8051 microcode. */
                   3785:        error = urtwn_load_firmware(sc);
                   3786:        if (error != 0)
                   3787:                goto fail;
                   3788:        SET(sc->sc_flags, URTWN_FLAG_FWREADY);
                   3789:
                   3790:        /* Initialize MAC/BB/RF blocks. */
1.19      christos 3791:        /*
                   3792:         * XXX: urtwn_mac_init() sets R92C_RCR[0:15] = R92C_RCR_APM |
                   3793:         * R92C_RCR_AM | R92C_RCR_AB | R92C_RCR_AICV | R92C_RCR_AMF.
                   3794:         * XXX: This setting should be removed from rtl8192cu_mac[].
                   3795:         */
                   3796:        urtwn_mac_init(sc);             // sets R92C_RCR[0:15]
                   3797:        urtwn_rxfilter_init(sc);        // reset R92C_RCR
1.1       nonaka   3798:        urtwn_bb_init(sc);
                   3799:        urtwn_rf_init(sc);
                   3800:
                   3801:        /* Turn CCK and OFDM blocks on. */
                   3802:        reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
                   3803:        reg |= R92C_RFMOD_CCK_EN;
                   3804:        urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
                   3805:        reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
                   3806:        reg |= R92C_RFMOD_OFDM_EN;
                   3807:        urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
                   3808:
                   3809:        /* Clear per-station keys table. */
                   3810:        urtwn_cam_init(sc);
                   3811:
                   3812:        /* Enable hardware sequence numbering. */
                   3813:        urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff);
                   3814:
                   3815:        /* Perform LO and IQ calibrations. */
                   3816:        urtwn_iq_calib(sc, sc->iqk_inited);
                   3817:        sc->iqk_inited = true;
                   3818:
                   3819:        /* Perform LC calibration. */
                   3820:        urtwn_lc_calib(sc);
                   3821:
                   3822:        /* Fix USB interference issue. */
                   3823:        urtwn_write_1(sc, 0xfe40, 0xe0);
                   3824:        urtwn_write_1(sc, 0xfe41, 0x8d);
                   3825:        urtwn_write_1(sc, 0xfe42, 0x80);
                   3826:        urtwn_write_4(sc, 0x20c, 0xfd0320);
                   3827:
                   3828:        urtwn_pa_bias_init(sc);
                   3829:
                   3830:        if (!(sc->chip & (URTWN_CHIP_92C | URTWN_CHIP_92C_1T2R))) {
                   3831:                /* 1T1R */
                   3832:                urtwn_bb_write(sc, R92C_FPGA0_RFPARAM(0),
                   3833:                    urtwn_bb_read(sc, R92C_FPGA0_RFPARAM(0)) | __BIT(13));
                   3834:        }
                   3835:
                   3836:        /* Initialize GPIO setting. */
                   3837:        urtwn_write_1(sc, R92C_GPIO_MUXCFG,
                   3838:            urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT);
                   3839:
                   3840:        /* Fix for lower temperature. */
                   3841:        urtwn_write_1(sc, 0x15, 0xe9);
                   3842:
                   3843:        /* Set default channel. */
1.13      jmcneill 3844:        urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE);
1.1       nonaka   3845:
                   3846:        /* Queue Rx xfers. */
                   3847:        for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
                   3848:                data = &sc->rx_data[i];
                   3849:                usbd_setup_xfer(data->xfer, sc->rx_pipe, data, data->buf,
                   3850:                    URTWN_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
                   3851:                    USBD_NO_TIMEOUT, urtwn_rxeof);
                   3852:                error = usbd_transfer(data->xfer);
                   3853:                if (__predict_false(error != USBD_NORMAL_COMPLETION &&
                   3854:                    error != USBD_IN_PROGRESS))
                   3855:                        goto fail;
                   3856:        }
                   3857:
                   3858:        /* We're ready to go. */
                   3859:        ifp->if_flags &= ~IFF_OACTIVE;
                   3860:        ifp->if_flags |= IFF_RUNNING;
                   3861:
1.16      jmcneill 3862:        mutex_exit(&sc->sc_write_mtx);
                   3863:
1.1       nonaka   3864:        if (ic->ic_opmode == IEEE80211_M_MONITOR)
                   3865:                ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
1.16      jmcneill 3866:        else if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
1.1       nonaka   3867:                ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
1.16      jmcneill 3868:        urtwn_wait_async(sc);
1.12      christos 3869:
1.1       nonaka   3870:        return (0);
                   3871:
                   3872:  fail:
1.12      christos 3873:        mutex_exit(&sc->sc_write_mtx);
                   3874:
1.1       nonaka   3875:        urtwn_stop(ifp, 1);
                   3876:        return (error);
                   3877: }
                   3878:
                   3879: static void
                   3880: urtwn_stop(struct ifnet *ifp, int disable)
                   3881: {
                   3882:        struct urtwn_softc *sc = ifp->if_softc;
                   3883:        struct ieee80211com *ic = &sc->sc_ic;
1.22      christos 3884:        size_t i;
                   3885:        int s;
1.1       nonaka   3886:
                   3887:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3888:
                   3889:        s = splusb();
                   3890:        ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
                   3891:        urtwn_wait_async(sc);
                   3892:        splx(s);
                   3893:
1.16      jmcneill 3894:        sc->tx_timer = 0;
                   3895:        ifp->if_timer = 0;
                   3896:        ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
                   3897:
1.1       nonaka   3898:        callout_stop(&sc->sc_scan_to);
                   3899:        callout_stop(&sc->sc_calib_to);
                   3900:
                   3901:        /* Abort Tx. */
                   3902:        for (i = 0; i < R92C_MAX_EPOUT; i++) {
                   3903:                if (sc->tx_pipe[i] != NULL)
                   3904:                        usbd_abort_pipe(sc->tx_pipe[i]);
                   3905:        }
                   3906:
                   3907:        /* Stop Rx pipe. */
                   3908:        usbd_abort_pipe(sc->rx_pipe);
                   3909:
1.12      christos 3910:        /* Free Tx/Rx buffers. */
                   3911:        urtwn_free_tx_list(sc);
                   3912:        urtwn_free_rx_list(sc);
                   3913:
1.1       nonaka   3914:        if (disable)
                   3915:                urtwn_chip_stop(sc);
                   3916: }
                   3917:
1.16      jmcneill 3918: static int
                   3919: urtwn_reset(struct ifnet *ifp)
                   3920: {
                   3921:        struct urtwn_softc *sc = ifp->if_softc;
                   3922:        struct ieee80211com *ic = &sc->sc_ic;
                   3923:
                   3924:        if (ic->ic_opmode != IEEE80211_M_MONITOR)
                   3925:                return ENETRESET;
                   3926:
                   3927:        urtwn_set_chan(sc, ic->ic_curchan, IEEE80211_HTINFO_2NDCHAN_NONE);
                   3928:
                   3929:        return 0;
                   3930: }
                   3931:
1.1       nonaka   3932: static void
                   3933: urtwn_chip_stop(struct urtwn_softc *sc)
                   3934: {
                   3935:        uint32_t reg;
                   3936:        bool disabled = true;
                   3937:
                   3938:        DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__));
                   3939:
1.12      christos 3940:        mutex_enter(&sc->sc_write_mtx);
                   3941:
1.1       nonaka   3942:        /*
                   3943:         * RF Off Sequence
                   3944:         */
                   3945:        /* Pause MAC TX queue */
                   3946:        urtwn_write_1(sc, R92C_TXPAUSE, 0xFF);
                   3947:
                   3948:        /* Disable RF */
                   3949:        urtwn_rf_write(sc, 0, 0, 0);
                   3950:
                   3951:        urtwn_write_1(sc, R92C_APSD_CTRL, R92C_APSD_CTRL_OFF);
                   3952:
                   3953:        /* Reset BB state machine */
                   3954:        urtwn_write_1(sc, R92C_SYS_FUNC_EN,
                   3955:            R92C_SYS_FUNC_EN_USBD |
                   3956:            R92C_SYS_FUNC_EN_USBA |
                   3957:            R92C_SYS_FUNC_EN_BB_GLB_RST);
                   3958:        urtwn_write_1(sc, R92C_SYS_FUNC_EN,
                   3959:            R92C_SYS_FUNC_EN_USBD | R92C_SYS_FUNC_EN_USBA);
                   3960:
                   3961:        /*
                   3962:         * Reset digital sequence
                   3963:         */
                   3964:        if (urtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) {
                   3965:                /* Reset MCU ready status */
                   3966:                urtwn_write_1(sc, R92C_MCUFWDL, 0);
                   3967:                /* If firmware in ram code, do reset */
                   3968:                if (ISSET(sc->sc_flags, URTWN_FLAG_FWREADY)) {
                   3969:                        urtwn_fw_reset(sc);
                   3970:                        CLR(sc->sc_flags, URTWN_FLAG_FWREADY);
                   3971:                }
                   3972:        }
                   3973:
                   3974:        /* Reset MAC and Enable 8051 */
                   3975:        urtwn_write_1(sc, R92C_SYS_FUNC_EN + 1, 0x54);
                   3976:
                   3977:        /* Reset MCU ready status */
                   3978:        urtwn_write_1(sc, R92C_MCUFWDL, 0);
                   3979:
                   3980:        if (disabled) {
                   3981:                /* Disable MAC clock */
                   3982:                urtwn_write_2(sc, R92C_SYS_CLKR, 0x70A3);
                   3983:                /* Disable AFE PLL */
                   3984:                urtwn_write_1(sc, R92C_AFE_PLL_CTRL, 0x80);
                   3985:                /* Gated AFE DIG_CLOCK */
                   3986:                urtwn_write_2(sc, R92C_AFE_XTAL_CTRL, 0x880F);
                   3987:                /* Isolated digital to PON */
                   3988:                urtwn_write_1(sc, R92C_SYS_ISO_CTRL, 0xF9);
                   3989:        }
                   3990:
                   3991:        /*
                   3992:         * Pull GPIO PIN to balance level and LED control
                   3993:         */
                   3994:        /* 1. Disable GPIO[7:0] */
                   3995:        urtwn_write_2(sc, R92C_GPIO_PIN_CTRL + 2, 0x0000);
                   3996:
                   3997:        reg = urtwn_read_4(sc, R92C_GPIO_PIN_CTRL) & ~0x0000ff00;
                   3998:        reg |= ((reg << 8) & 0x0000ff00) | 0x00ff0000;
                   3999:        urtwn_write_4(sc, R92C_GPIO_PIN_CTRL, reg);
                   4000:
                   4001:         /* Disable GPIO[10:8] */
                   4002:         urtwn_write_1(sc, R92C_GPIO_MUXCFG + 3, 0x00);
                   4003:
                   4004:        reg = urtwn_read_2(sc, R92C_GPIO_MUXCFG + 2) & ~0x00f0;
                   4005:         reg |= (((reg & 0x000f) << 4) | 0x0780);
                   4006:         urtwn_write_2(sc, R92C_GPIO_PIN_CTRL+2, reg);
                   4007:
                   4008:        /* Disable LED0 & 1 */
                   4009:         urtwn_write_2(sc, R92C_LEDCFG0, 0x8080);
                   4010:
                   4011:        /*
                   4012:         * Reset digital sequence
                   4013:         */
                   4014:         if (disabled) {
                   4015:                /* Disable ELDR clock */
                   4016:                urtwn_write_2(sc, R92C_SYS_CLKR, 0x70A3);
                   4017:                /* Isolated ELDR to PON */
                   4018:                urtwn_write_1(sc, R92C_SYS_ISO_CTRL + 1, 0x82);
                   4019:        }
                   4020:
                   4021:        /*
                   4022:         * Disable analog sequence
                   4023:         */
                   4024:         if (disabled) {
                   4025:                /* Disable A15 power */
                   4026:                 urtwn_write_1(sc, R92C_LDOA15_CTRL, 0x04);
                   4027:                /* Disable digital core power */
                   4028:                 urtwn_write_1(sc, R92C_LDOV12D_CTRL,
                   4029:                     urtwn_read_1(sc, R92C_LDOV12D_CTRL) &
                   4030:                      ~R92C_LDOV12D_CTRL_LDV12_EN);
                   4031:         }
                   4032:
                   4033:        /* Enter PFM mode */
                   4034:        urtwn_write_1(sc, R92C_SPS0_CTRL, 0x23);
                   4035:
                   4036:        /* Set USB suspend */
                   4037:        urtwn_write_2(sc, R92C_APS_FSMCO,
                   4038:            R92C_APS_FSMCO_APDM_HOST |
                   4039:            R92C_APS_FSMCO_AFSM_HSUS |
                   4040:            R92C_APS_FSMCO_PFM_ALDN);
                   4041:
                   4042:        urtwn_write_1(sc, R92C_RSV_CTRL, 0x0E);
1.12      christos 4043:
                   4044:        mutex_exit(&sc->sc_write_mtx);
1.1       nonaka   4045: }
                   4046:
1.4       nonaka   4047: MODULE(MODULE_CLASS_DRIVER, if_urtwn, "bpf");
1.1       nonaka   4048:
                   4049: #ifdef _MODULE
                   4050: #include "ioconf.c"
                   4051: #endif
                   4052:
                   4053: static int
                   4054: if_urtwn_modcmd(modcmd_t cmd, void *aux)
                   4055: {
                   4056:        int error = 0;
                   4057:
                   4058:        switch (cmd) {
                   4059:        case MODULE_CMD_INIT:
                   4060: #ifdef _MODULE
                   4061:                error = config_init_component(cfdriver_ioconf_urtwn,
                   4062:                    cfattach_ioconf_urtwn, cfdata_ioconf_urtwn);
                   4063: #endif
                   4064:                return (error);
                   4065:        case MODULE_CMD_FINI:
                   4066: #ifdef _MODULE
                   4067:                error = config_fini_component(cfdriver_ioconf_urtwn,
                   4068:                    cfattach_ioconf_urtwn, cfdata_ioconf_urtwn);
                   4069: #endif
                   4070:                return (error);
                   4071:        default:
                   4072:                return (ENOTTY);
                   4073:        }
                   4074: }

CVSweb <webmaster@jp.NetBSD.org>