[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.1.4.4

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

CVSweb <webmaster@jp.NetBSD.org>