Home | History | Annotate | Line # | Download | only in usb
if_otus.c revision 1.25.6.9
      1 /*	$NetBSD: if_otus.c,v 1.25.6.9 2016/12/05 10:55:18 skrll Exp $	*/
      2 /*	$OpenBSD: if_otus.c,v 1.18 2010/08/27 17:08:00 jsg Exp $	*/
      3 
      4 /*-
      5  * Copyright (c) 2009 Damien Bergamini <damien.bergamini (at) 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 
     20 /*-
     21  * Driver for Atheros AR9001U chipset.
     22  * http://www.atheros.com/pt/bulletins/AR9001USBBulletin.pdf
     23  */
     24 
     25 #include <sys/cdefs.h>
     26 __KERNEL_RCSID(0, "$NetBSD: if_otus.c,v 1.25.6.9 2016/12/05 10:55:18 skrll Exp $");
     27 
     28 #ifdef _KERNEL_OPT
     29 #include "opt_usb.h"
     30 #endif
     31 
     32 #include <sys/param.h>
     33 #include <sys/sockio.h>
     34 #include <sys/mbuf.h>
     35 #include <sys/kernel.h>
     36 #include <sys/kmem.h>
     37 #include <sys/kthread.h>
     38 #include <sys/systm.h>
     39 #include <sys/callout.h>
     40 #include <sys/device.h>
     41 #include <sys/proc.h>
     42 #include <sys/bus.h>
     43 #include <sys/endian.h>
     44 #include <sys/intr.h>
     45 
     46 #include <net/bpf.h>
     47 #include <net/if.h>
     48 #include <net/if_arp.h>
     49 #include <net/if_dl.h>
     50 #include <net/if_ether.h>
     51 #include <net/if_media.h>
     52 #include <net/if_types.h>
     53 
     54 #include <netinet/in.h>
     55 #include <netinet/in_systm.h>
     56 #include <netinet/in_var.h>
     57 #include <netinet/ip.h>
     58 
     59 #include <net80211/ieee80211_var.h>
     60 #include <net80211/ieee80211_amrr.h>
     61 #include <net80211/ieee80211_radiotap.h>
     62 
     63 #include <dev/firmload.h>
     64 
     65 #include <dev/usb/usb.h>
     66 #include <dev/usb/usbdi.h>
     67 #include <dev/usb/usbdi_util.h>
     68 #include <dev/usb/usbdivar.h>
     69 #include <dev/usb/usbdevs.h>
     70 
     71 #include <dev/usb/if_otusreg.h>
     72 #include <dev/usb/if_otusvar.h>
     73 
     74 #ifdef OTUS_DEBUG
     75 
     76 #define	DBG_INIT	__BIT(0)
     77 #define	DBG_FN		__BIT(1)
     78 #define	DBG_TX		__BIT(2)
     79 #define	DBG_RX		__BIT(3)
     80 #define	DBG_STM		__BIT(4)
     81 #define	DBG_CHAN	__BIT(5)
     82 #define	DBG_REG		__BIT(6)
     83 #define	DBG_CMD		__BIT(7)
     84 #define	DBG_ALL		0xffffffffU
     85 #define DBG_NO_SC	(struct otus_softc *)NULL
     86 
     87 unsigned int otus_debug = 0;
     88 #define DPRINTFN(n, s, ...) do { \
     89 	if (otus_debug & (n)) { \
     90 		if ((s) != NULL) \
     91 			printf("%s: ", device_xname((s)->sc_dev)); \
     92 		else \
     93 			printf("otus0: "); \
     94 		printf("%s: ", __func__); \
     95 		printf(__VA_ARGS__); \
     96 	} \
     97 } while (0)
     98 
     99 #else	/* ! OTUS_DEBUG */
    100 
    101 #define DPRINTFN(n, ...) \
    102 	do { } while (0)
    103 
    104 #endif	/* OTUS_DEBUG */
    105 
    106 Static int	otus_match(device_t, cfdata_t, void *);
    107 Static void	otus_attach(device_t, device_t, void *);
    108 Static int	otus_detach(device_t, int);
    109 Static int	otus_activate(device_t, devact_t);
    110 Static void	otus_attachhook(device_t);
    111 Static void	otus_get_chanlist(struct otus_softc *);
    112 Static int	otus_load_firmware(struct otus_softc *, const char *,
    113 		    uint32_t);
    114 Static int	otus_open_pipes(struct otus_softc *);
    115 Static void	otus_close_pipes(struct otus_softc *);
    116 Static int	otus_alloc_tx_cmd(struct otus_softc *);
    117 Static void	otus_free_tx_cmd(struct otus_softc *);
    118 Static int	otus_alloc_tx_data_list(struct otus_softc *);
    119 Static void	otus_free_tx_data_list(struct otus_softc *);
    120 Static int	otus_alloc_rx_data_list(struct otus_softc *);
    121 Static void	otus_free_rx_data_list(struct otus_softc *);
    122 Static void	otus_next_scan(void *);
    123 Static void	otus_task(void *);
    124 Static void	otus_do_async(struct otus_softc *,
    125 		    void (*)(struct otus_softc *, void *), void *, int);
    126 Static int	otus_newstate(struct ieee80211com *, enum ieee80211_state,
    127 		    int);
    128 Static void	otus_newstate_cb(struct otus_softc *, void *);
    129 Static int	otus_cmd(struct otus_softc *, uint8_t, const void *, int,
    130 		    void *);
    131 Static void	otus_write(struct otus_softc *, uint32_t, uint32_t);
    132 Static int	otus_write_barrier(struct otus_softc *);
    133 Static struct	ieee80211_node *otus_node_alloc(struct ieee80211_node_table *);
    134 Static int	otus_media_change(struct ifnet *);
    135 Static int	otus_read_eeprom(struct otus_softc *);
    136 Static void	otus_newassoc(struct ieee80211_node *, int);
    137 Static void	otus_intr(struct usbd_xfer *, void *, usbd_status);
    138 Static void	otus_cmd_rxeof(struct otus_softc *, uint8_t *, int);
    139 Static void	otus_sub_rxeof(struct otus_softc *, uint8_t *, int);
    140 Static void	otus_rxeof(struct usbd_xfer *, void *, usbd_status);
    141 Static void	otus_txeof(struct usbd_xfer *, void *, usbd_status);
    142 Static int	otus_tx(struct otus_softc *, struct mbuf *,
    143 		    struct ieee80211_node *, struct otus_tx_data *);
    144 Static void	otus_start(struct ifnet *);
    145 Static void	otus_watchdog(struct ifnet *);
    146 Static int	otus_ioctl(struct ifnet *, u_long, void *);
    147 Static int	otus_set_multi(struct otus_softc *);
    148 #ifdef HAVE_EDCA
    149 Static void	otus_updateedca(struct ieee80211com *);
    150 Static void	otus_updateedca_cb(struct otus_softc *, void *);
    151 #endif
    152 Static void	otus_updateedca_cb_locked(struct otus_softc *);
    153 Static void	otus_updateslot(struct ifnet *);
    154 Static void	otus_updateslot_cb(struct otus_softc *, void *);
    155 Static void	otus_updateslot_cb_locked(struct otus_softc *);
    156 Static int	otus_init_mac(struct otus_softc *);
    157 Static uint32_t	otus_phy_get_def(struct otus_softc *, uint32_t);
    158 Static int	otus_set_board_values(struct otus_softc *,
    159 		    struct ieee80211_channel *);
    160 Static int	otus_program_phy(struct otus_softc *,
    161 		    struct ieee80211_channel *);
    162 Static int	otus_set_rf_bank4(struct otus_softc *,
    163 		    struct ieee80211_channel *);
    164 Static void	otus_get_delta_slope(uint32_t, uint32_t *, uint32_t *);
    165 Static int	otus_set_chan(struct otus_softc *, struct ieee80211_channel *,
    166 		    int);
    167 #ifdef notyet
    168 Static int	otus_set_key(struct ieee80211com *, struct ieee80211_node *,
    169 		    struct ieee80211_key *);
    170 Static void	otus_set_key_cb(struct otus_softc *, void *);
    171 Static void	otus_delete_key(struct ieee80211com *, struct ieee80211_node *,
    172 		    struct ieee80211_key *);
    173 Static void	otus_delete_key_cb(struct otus_softc *, void *);
    174 #endif /* notyet */
    175 Static void	otus_calib_to(void *);
    176 Static int	otus_set_bssid(struct otus_softc *, const uint8_t *);
    177 Static int	otus_set_macaddr(struct otus_softc *, const uint8_t *);
    178 #ifdef notyet
    179 Static void	otus_led_newstate_type1(struct otus_softc *);
    180 Static void	otus_led_newstate_type2(struct otus_softc *);
    181 #endif /* notyet */
    182 Static void	otus_led_newstate_type3(struct otus_softc *);
    183 Static int	otus_init(struct ifnet *);
    184 Static void	otus_stop(struct ifnet *);
    185 Static void	otus_wait_async(struct otus_softc *);
    186 
    187 /* List of supported channels. */
    188 static const uint8_t ar_chans[] = {
    189 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
    190 	36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124,
    191 	128, 132, 136, 140, 149, 153, 157, 161, 165, 34, 38, 42, 46
    192 };
    193 
    194 /*
    195  * This data is automatically generated from the "otus.ini" file.
    196  * It is stored in a different way though, to reduce kernel's .rodata
    197  * section overhead (5.1KB instead of 8.5KB).
    198  */
    199 
    200 /* NB: apply AR_PHY(). */
    201 static const uint16_t ar5416_phy_regs[] = {
    202 	0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008,
    203 	0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f, 0x010, 0x011,
    204 	0x012, 0x013, 0x014, 0x015, 0x016, 0x017, 0x018, 0x01a, 0x01b,
    205 	0x040, 0x041, 0x042, 0x043, 0x045, 0x046, 0x047, 0x048, 0x049,
    206 	0x04a, 0x04b, 0x04d, 0x04e, 0x04f, 0x051, 0x052, 0x053, 0x055,
    207 	0x056, 0x058, 0x059, 0x05c, 0x05d, 0x05e, 0x05f, 0x060, 0x061,
    208 	0x062, 0x063, 0x064, 0x065, 0x066, 0x067, 0x068, 0x069, 0x06a,
    209 	0x06b, 0x06c, 0x06d, 0x070, 0x071, 0x072, 0x073, 0x074, 0x075,
    210 	0x076, 0x077, 0x078, 0x079, 0x07a, 0x07b, 0x07c, 0x07f, 0x080,
    211 	0x081, 0x082, 0x083, 0x084, 0x085, 0x086, 0x087, 0x088, 0x089,
    212 	0x08a, 0x08b, 0x08c, 0x08d, 0x08e, 0x08f, 0x090, 0x091, 0x092,
    213 	0x093, 0x094, 0x095, 0x096, 0x097, 0x098, 0x099, 0x09a, 0x09b,
    214 	0x09c, 0x09d, 0x09e, 0x09f, 0x0a0, 0x0a1, 0x0a2, 0x0a3, 0x0a4,
    215 	0x0a5, 0x0a6, 0x0a7, 0x0a8, 0x0a9, 0x0aa, 0x0ab, 0x0ac, 0x0ad,
    216 	0x0ae, 0x0af, 0x0b0, 0x0b1, 0x0b2, 0x0b3, 0x0b4, 0x0b5, 0x0b6,
    217 	0x0b7, 0x0b8, 0x0b9, 0x0ba, 0x0bb, 0x0bc, 0x0bd, 0x0be, 0x0bf,
    218 	0x0c0, 0x0c1, 0x0c2, 0x0c3, 0x0c4, 0x0c5, 0x0c6, 0x0c7, 0x0c8,
    219 	0x0c9, 0x0ca, 0x0cb, 0x0cc, 0x0cd, 0x0ce, 0x0cf, 0x0d0, 0x0d1,
    220 	0x0d2, 0x0d3, 0x0d4, 0x0d5, 0x0d6, 0x0d7, 0x0d8, 0x0d9, 0x0da,
    221 	0x0db, 0x0dc, 0x0dd, 0x0de, 0x0df, 0x0e0, 0x0e1, 0x0e2, 0x0e3,
    222 	0x0e4, 0x0e5, 0x0e6, 0x0e7, 0x0e8, 0x0e9, 0x0ea, 0x0eb, 0x0ec,
    223 	0x0ed, 0x0ee, 0x0ef, 0x0f0, 0x0f1, 0x0f2, 0x0f3, 0x0f4, 0x0f5,
    224 	0x0f6, 0x0f7, 0x0f8, 0x0f9, 0x0fa, 0x0fb, 0x0fc, 0x0fd, 0x0fe,
    225 	0x0ff, 0x100, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108, 0x109,
    226 	0x10a, 0x10b, 0x10c, 0x10d, 0x10e, 0x10f, 0x13c, 0x13d, 0x13e,
    227 	0x13f, 0x280, 0x281, 0x282, 0x283, 0x284, 0x285, 0x286, 0x287,
    228 	0x288, 0x289, 0x28a, 0x28b, 0x28c, 0x28d, 0x28e, 0x28f, 0x290,
    229 	0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0x297, 0x298, 0x299,
    230 	0x29a, 0x29b, 0x29d, 0x29e, 0x29f, 0x2c0, 0x2c1, 0x2c2, 0x2c3,
    231 	0x2c4, 0x2c5, 0x2c6, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cc,
    232 	0x2cd, 0x2ce, 0x2cf, 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5,
    233 	0x2d6, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7, 0x2e8, 0x2e9,
    234 	0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f2,
    235 	0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7, 0x2f8, 0x412, 0x448, 0x458,
    236 	0x683, 0x69b, 0x812, 0x848, 0x858, 0xa83, 0xa9b, 0xc19, 0xc57,
    237 	0xc5a, 0xc6f, 0xe9c, 0xed7, 0xed8, 0xed9, 0xeda, 0xedb, 0xedc,
    238 	0xedd, 0xede, 0xedf, 0xee0, 0xee1
    239 };
    240 
    241 static const uint32_t ar5416_phy_vals_5ghz_20mhz[] = {
    242 	0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000,
    243 	0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e,
    244 	0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007,
    245 	0x00200400, 0x206a002e, 0x1372161e, 0x001a6a65, 0x1284233c,
    246 	0x6c48b4e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd10,
    247 	0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000,
    248 	0x00000000, 0x000007d0, 0x00000118, 0x10000fff, 0x0510081c,
    249 	0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f,
    250 	0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188,
    251 	0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000,
    252 	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    253 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    254 	0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000,
    255 	0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8,
    256 	0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
    257 	0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042,
    258 	0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1,
    259 	0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8,
    260 	0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009,
    261 	0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0,
    262 	0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011,
    263 	0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038,
    264 	0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059,
    265 	0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9,
    266 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    267 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    268 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    269 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    270 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000,
    271 	0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
    272 	0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c,
    273 	0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013,
    274 	0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a,
    275 	0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021,
    276 	0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028,
    277 	0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d,
    278 	0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034,
    279 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    280 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    281 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    282 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    283 	0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000,
    284 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    285 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    286 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    287 	0x00000000, 0x00000008, 0x00000440, 0xd6be4788, 0x012e8160,
    288 	0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6,
    289 	0x00000400, 0x000009b5, 0x00000000, 0x00000108, 0x3f3f3f3f,
    290 	0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc,
    291 	0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01,
    292 	0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a9caa,
    293 	0x1ce739ce, 0x051701ce, 0x18010000, 0x30032602, 0x48073e06,
    294 	0x560b4c0a, 0x641a600f, 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf,
    295 	0xb51fa69f, 0xcb3fbd07, 0x0000d7bf, 0x00000000, 0x00000000,
    296 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    297 	0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f,
    298 	0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce,
    299 	0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    300 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    301 	0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f,
    302 	0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a65, 0x0510001c,
    303 	0x00009b40, 0x012e8160, 0x09249126, 0x00180a65, 0x0510001c,
    304 	0x00009b40, 0x012e8160, 0x09249126, 0x0001c600, 0x004b6a8e,
    305 	0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207,
    306 	0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803,
    307 	0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
    308 };
    309 
    310 #ifdef notyet
    311 static const uint32_t ar5416_phy_vals_5ghz_40mhz[] = {
    312 	0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000,
    313 	0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e,
    314 	0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007,
    315 	0x00200400, 0x206a002e, 0x13721c1e, 0x001a6a65, 0x1284233c,
    316 	0x6c48b4e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd10,
    317 	0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000,
    318 	0x00000000, 0x000007d0, 0x00000230, 0x10000fff, 0x0510081c,
    319 	0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f,
    320 	0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188,
    321 	0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000,
    322 	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    323 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    324 	0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000,
    325 	0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8,
    326 	0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
    327 	0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042,
    328 	0x00000000, 0x00000040, 0x00000080, 0x000001a1, 0x000001e1,
    329 	0x00000021, 0x00000061, 0x00000168, 0x000001a8, 0x000001e8,
    330 	0x00000028, 0x00000068, 0x00000189, 0x000001c9, 0x00000009,
    331 	0x00000049, 0x00000089, 0x00000170, 0x000001b0, 0x000001f0,
    332 	0x00000030, 0x00000070, 0x00000191, 0x000001d1, 0x00000011,
    333 	0x00000051, 0x00000091, 0x000001b8, 0x000001f8, 0x00000038,
    334 	0x00000078, 0x00000199, 0x000001d9, 0x00000019, 0x00000059,
    335 	0x00000099, 0x000000d9, 0x000000f9, 0x000000f9, 0x000000f9,
    336 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    337 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    338 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    339 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    340 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000,
    341 	0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
    342 	0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c,
    343 	0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013,
    344 	0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a,
    345 	0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021,
    346 	0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028,
    347 	0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d,
    348 	0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034,
    349 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    350 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    351 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    352 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    353 	0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000,
    354 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    355 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    356 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    357 	0x00000000, 0x00000008, 0x00000440, 0xd6be4788, 0x012e8160,
    358 	0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6,
    359 	0x00000400, 0x000009b5, 0x00000000, 0x00000210, 0x3f3f3f3f,
    360 	0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc,
    361 	0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01,
    362 	0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a9caa,
    363 	0x1ce739ce, 0x051701ce, 0x18010000, 0x30032602, 0x48073e06,
    364 	0x560b4c0a, 0x641a600f, 0x7a4f6e1b, 0x8c5b7e5a, 0x9d0f96cf,
    365 	0xb51fa69f, 0xcb3fbcbf, 0x0000d7bf, 0x00000000, 0x00000000,
    366 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    367 	0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f,
    368 	0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce,
    369 	0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    370 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    371 	0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f,
    372 	0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a65, 0x0510001c,
    373 	0x00009b40, 0x012e8160, 0x09249126, 0x00180a65, 0x0510001c,
    374 	0x00009b40, 0x012e8160, 0x09249126, 0x0001c600, 0x004b6a8e,
    375 	0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207,
    376 	0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803,
    377 	0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
    378 };
    379 #endif
    380 
    381 #ifdef notyet
    382 static const uint32_t ar5416_phy_vals_2ghz_40mhz[] = {
    383 	0x00000007, 0x000003c4, 0x00000000, 0xad848e19, 0x7d14e000,
    384 	0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e,
    385 	0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007,
    386 	0x00200400, 0x206a002e, 0x13721c24, 0x00197a68, 0x1284233c,
    387 	0x6c48b0e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd20,
    388 	0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000,
    389 	0x00000000, 0x00000898, 0x00000268, 0x10000fff, 0x0510001c,
    390 	0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f,
    391 	0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188,
    392 	0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000,
    393 	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    394 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    395 	0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000,
    396 	0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8,
    397 	0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
    398 	0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042,
    399 	0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181,
    400 	0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8,
    401 	0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9,
    402 	0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0,
    403 	0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191,
    404 	0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8,
    405 	0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199,
    406 	0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9,
    407 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    408 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    409 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    410 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    411 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000,
    412 	0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
    413 	0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c,
    414 	0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013,
    415 	0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a,
    416 	0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021,
    417 	0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028,
    418 	0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d,
    419 	0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034,
    420 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    421 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    422 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    423 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    424 	0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000,
    425 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    426 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    427 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    428 	0x00000000, 0x0000000e, 0x00000440, 0xd03e4788, 0x012a8160,
    429 	0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6,
    430 	0x00000400, 0x000009b5, 0x00000000, 0x00000210, 0x3f3f3f3f,
    431 	0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc,
    432 	0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01,
    433 	0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a7caa,
    434 	0x1ce739ce, 0x051701ce, 0x18010000, 0x2e032402, 0x4a0a3c06,
    435 	0x621a540b, 0x764f6c1b, 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f,
    436 	0xbddfaf1f, 0xd1ffc93f, 0x00000000, 0x00000000, 0x00000000,
    437 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    438 	0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f,
    439 	0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce,
    440 	0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    441 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    442 	0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f,
    443 	0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a68, 0x0510001c,
    444 	0x00009b40, 0x012a8160, 0x09249126, 0x00180a68, 0x0510001c,
    445 	0x00009b40, 0x012a8160, 0x09249126, 0x0001c600, 0x004b6a8e,
    446 	0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207,
    447 	0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803,
    448 	0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
    449 };
    450 #endif
    451 
    452 static const uint32_t ar5416_phy_vals_2ghz_20mhz[] = {
    453 	0x00000007, 0x00000300, 0x00000000, 0xad848e19, 0x7d14e000,
    454 	0x9c0a9f6b, 0x00000090, 0x00000000, 0x02020200, 0x00000e0e,
    455 	0x0a020001, 0x0000a000, 0x00000000, 0x00000e0e, 0x00000007,
    456 	0x00200400, 0x206a002e, 0x137216a4, 0x00197a68, 0x1284233c,
    457 	0x6c48b0e4, 0x00000859, 0x7ec80d2e, 0x31395c5e, 0x0004dd20,
    458 	0x409a4190, 0x050cb081, 0x00000000, 0x00000000, 0x00000000,
    459 	0x00000000, 0x00000898, 0x00000134, 0x10000fff, 0x0510001c,
    460 	0xd0058a15, 0x00000001, 0x00000004, 0x3f3f3f3f, 0x3f3f3f3f,
    461 	0x0000007f, 0xdfb81020, 0x9280b212, 0x00020028, 0x5d50e188,
    462 	0x00081fff, 0x00009b40, 0x00001120, 0x190fb515, 0x00000000,
    463 	0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    464 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    465 	0x00000000, 0x00000007, 0x001fff00, 0x006f00c4, 0x03051000,
    466 	0x00000820, 0x038919be, 0x06336f77, 0x60f6532c, 0x08f186c8,
    467 	0x00046384, 0x00000000, 0x00000000, 0x00000000, 0x00000200,
    468 	0x64646464, 0x3c787878, 0x000000aa, 0x00000000, 0x00001042,
    469 	0x00000000, 0x00000040, 0x00000080, 0x00000141, 0x00000181,
    470 	0x000001c1, 0x00000001, 0x00000041, 0x000001a8, 0x000001e8,
    471 	0x00000028, 0x00000068, 0x000000a8, 0x00000169, 0x000001a9,
    472 	0x000001e9, 0x00000029, 0x00000069, 0x00000190, 0x000001d0,
    473 	0x00000010, 0x00000050, 0x00000090, 0x00000151, 0x00000191,
    474 	0x000001d1, 0x00000011, 0x00000051, 0x00000198, 0x000001d8,
    475 	0x00000018, 0x00000058, 0x00000098, 0x00000159, 0x00000199,
    476 	0x000001d9, 0x00000019, 0x00000059, 0x00000099, 0x000000d9,
    477 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    478 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    479 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    480 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9,
    481 	0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, 0x00000000,
    482 	0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000005,
    483 	0x00000008, 0x00000009, 0x0000000a, 0x0000000b, 0x0000000c,
    484 	0x0000000d, 0x00000010, 0x00000011, 0x00000012, 0x00000013,
    485 	0x00000014, 0x00000015, 0x00000018, 0x00000019, 0x0000001a,
    486 	0x0000001b, 0x0000001c, 0x0000001d, 0x00000020, 0x00000021,
    487 	0x00000022, 0x00000023, 0x00000024, 0x00000025, 0x00000028,
    488 	0x00000029, 0x0000002a, 0x0000002b, 0x0000002c, 0x0000002d,
    489 	0x00000030, 0x00000031, 0x00000032, 0x00000033, 0x00000034,
    490 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    491 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    492 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    493 	0x00000035, 0x00000035, 0x00000035, 0x00000035, 0x00000035,
    494 	0x00000035, 0x00000010, 0x0000001a, 0x00000000, 0x00000000,
    495 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    496 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    497 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    498 	0x00000000, 0x0000000e, 0x00000440, 0xd03e4788, 0x012a8160,
    499 	0x40806333, 0x00106c10, 0x009c4060, 0x1883800a, 0x018830c6,
    500 	0x00000400, 0x000009b5, 0x00000000, 0x00000108, 0x3f3f3f3f,
    501 	0x3f3f3f3f, 0x13c889af, 0x38490a20, 0x00007bb6, 0x0fff3ffc,
    502 	0x00000001, 0x0000a000, 0x00000000, 0x0cc75380, 0x0f0f0f01,
    503 	0xdfa91f01, 0x00418a11, 0x00000000, 0x09249126, 0x0a1a7caa,
    504 	0x1ce739ce, 0x051701ce, 0x18010000, 0x2e032402, 0x4a0a3c06,
    505 	0x621a540b, 0x764f6c1b, 0x845b7a5a, 0x950f8ccf, 0xa5cf9b4f,
    506 	0xbddfaf1f, 0xd1ffc93f, 0x00000000, 0x00000000, 0x00000000,
    507 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    508 	0x3fffffff, 0x3fffffff, 0x3fffffff, 0x0003ffff, 0x79a8aa1f,
    509 	0x08000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x1ce739ce, 0x000001ce,
    510 	0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    511 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    512 	0x00000000, 0x00000000, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f,
    513 	0x00000000, 0x1ce739ce, 0x000000c0, 0x00180a68, 0x0510001c,
    514 	0x00009b40, 0x012a8160, 0x09249126, 0x00180a68, 0x0510001c,
    515 	0x00009b40, 0x012a8160, 0x09249126, 0x0001c600, 0x004b6a8e,
    516 	0x000003ce, 0x00181400, 0x00820820, 0x066c420f, 0x0f282207,
    517 	0x17601685, 0x1f801104, 0x37a00c03, 0x3fc40883, 0x57c00803,
    518 	0x5fd80682, 0x7fe00482, 0x7f3c7bba, 0xf3307ff0
    519 };
    520 
    521 /* NB: apply AR_PHY(). */
    522 static const uint8_t ar5416_banks_regs[] = {
    523 	0x2c, 0x38, 0x2c, 0x3b, 0x2c, 0x38, 0x3c, 0x2c, 0x3a, 0x2c, 0x39,
    524 	0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
    525 	0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
    526 	0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
    527 	0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
    528 	0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x38, 0x2c, 0x2c,
    529 	0x2c, 0x3c
    530 };
    531 
    532 static const uint32_t ar5416_banks_vals_5ghz[] = {
    533 	0x1e5795e5, 0x02008020, 0x02108421, 0x00000008, 0x0e73ff17,
    534 	0x00000420, 0x01400018, 0x000001a1, 0x00000001, 0x00000013,
    535 	0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    536 	0x00000000, 0x00004000, 0x00006c00, 0x00002c00, 0x00004800,
    537 	0x00004000, 0x00006000, 0x00001000, 0x00004000, 0x00007c00,
    538 	0x00007c00, 0x00007c00, 0x00007c00, 0x00007c00, 0x00087c00,
    539 	0x00007c00, 0x00005400, 0x00000c00, 0x00001800, 0x00007c00,
    540 	0x00006c00, 0x00006c00, 0x00007c00, 0x00002c00, 0x00003c00,
    541 	0x00003800, 0x00001c00, 0x00000800, 0x00000408, 0x00004c15,
    542 	0x00004188, 0x0000201e, 0x00010408, 0x00000801, 0x00000c08,
    543 	0x0000181e, 0x00001016, 0x00002800, 0x00004010, 0x0000081c,
    544 	0x00000115, 0x00000015, 0x00000066, 0x0000001c, 0x00000000,
    545 	0x00000004, 0x00000015, 0x0000001f, 0x00000000, 0x000000a0,
    546 	0x00000000, 0x00000040, 0x0000001c
    547 };
    548 
    549 static const uint32_t ar5416_banks_vals_2ghz[] = {
    550 	0x1e5795e5, 0x02008020, 0x02108421, 0x00000008, 0x0e73ff17,
    551 	0x00000420, 0x01c00018, 0x000001a1, 0x00000001, 0x00000013,
    552 	0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
    553 	0x00000000, 0x00004000, 0x00006c00, 0x00002c00, 0x00004800,
    554 	0x00004000, 0x00006000, 0x00001000, 0x00004000, 0x00007c00,
    555 	0x00007c00, 0x00007c00, 0x00007c00, 0x00007c00, 0x00087c00,
    556 	0x00007c00, 0x00005400, 0x00000c00, 0x00001800, 0x00007c00,
    557 	0x00006c00, 0x00006c00, 0x00007c00, 0x00002c00, 0x00003c00,
    558 	0x00003800, 0x00001c00, 0x00000800, 0x00000408, 0x00004c15,
    559 	0x00004188, 0x0000201e, 0x00010408, 0x00000801, 0x00000c08,
    560 	0x0000181e, 0x00001016, 0x00002800, 0x00004010, 0x0000081c,
    561 	0x00000115, 0x00000015, 0x00000066, 0x0000001c, 0x00000000,
    562 	0x00000004, 0x00000015, 0x0000001f, 0x00000400, 0x000000a0,
    563 	0x00000000, 0x00000040, 0x0000001c
    564 };
    565 
    566 static const struct usb_devno otus_devs[] = {
    567 	{ USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_WN7512 },
    568 	{ USB_VENDOR_ATHEROS2,		USB_PRODUCT_ATHEROS2_3CRUSBN275 },
    569 	{ USB_VENDOR_ATHEROS2,		USB_PRODUCT_ATHEROS2_TG121N },
    570 	{ USB_VENDOR_ATHEROS2,		USB_PRODUCT_ATHEROS2_AR9170 },
    571 	{ USB_VENDOR_ATHEROS2,		USB_PRODUCT_ATHEROS2_WN612 },
    572 	{ USB_VENDOR_ATHEROS2,		USB_PRODUCT_ATHEROS2_WN821NV2 },
    573 	{ USB_VENDOR_AVM,		USB_PRODUCT_AVM_FRITZWLAN },
    574 	{ USB_VENDOR_CACE,		USB_PRODUCT_CACE_AIRPCAPNX },
    575 	{ USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA130D1 },
    576 	{ USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA160A1 },
    577 	{ USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA160A2 },
    578 	{ USB_VENDOR_IODATA,		USB_PRODUCT_IODATA_WNGDNUS2 },
    579 	{ USB_VENDOR_NEC,		USB_PRODUCT_NEC_WL300NUG },
    580 	{ USB_VENDOR_NETGEAR,		USB_PRODUCT_NETGEAR_WN111V2 },
    581 	{ USB_VENDOR_NETGEAR,		USB_PRODUCT_NETGEAR_WNA1000 },
    582 	{ USB_VENDOR_NETGEAR,		USB_PRODUCT_NETGEAR_WNDA3100 },
    583 	{ USB_VENDOR_PLANEX2,		USB_PRODUCT_PLANEX2_GW_US300 },
    584 	{ USB_VENDOR_WISTRONNEWEB,	USB_PRODUCT_WISTRONNEWEB_O8494 },
    585 	{ USB_VENDOR_WISTRONNEWEB,	USB_PRODUCT_WISTRONNEWEB_WNC0600 },
    586 	{ USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_UB81 },
    587 	{ USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_UB82 },
    588 	{ USB_VENDOR_ZYDAS,		USB_PRODUCT_ZYDAS_ZD1221 },
    589 	{ USB_VENDOR_ZYXEL,		USB_PRODUCT_ZYXEL_NWD271N }
    590 };
    591 
    592 CFATTACH_DECL_NEW(otus, sizeof(struct otus_softc), otus_match, otus_attach,
    593     otus_detach, otus_activate);
    594 
    595 Static int
    596 otus_match(device_t parent, cfdata_t match, void *aux)
    597 {
    598 	struct usb_attach_arg *uaa;
    599 
    600 	uaa = aux;
    601 
    602 	DPRINTFN(DBG_FN, DBG_NO_SC,
    603 	    "otus_match: vendor=0x%x product=0x%x revision=0x%x\n",
    604 		    uaa->uaa_vendor, uaa->uaa_product, uaa->uaa_release);
    605 
    606 	return usb_lookup(otus_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ?
    607 	    UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
    608 }
    609 
    610 Static void
    611 otus_attach(device_t parent, device_t self, void *aux)
    612 {
    613 	struct otus_softc *sc;
    614 	struct usb_attach_arg *uaa;
    615 	char *devinfop;
    616 	int error;
    617 
    618 	sc = device_private(self);
    619 
    620 	DPRINTFN(DBG_FN, sc, "\n");
    621 
    622 	sc->sc_dev = self;
    623 	uaa = aux;
    624 	sc->sc_udev = uaa->uaa_device;
    625 
    626 	aprint_naive("\n");
    627 	aprint_normal("\n");
    628 
    629 	devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
    630 	aprint_normal_dev(sc->sc_dev, "%s\n", devinfop);
    631 	usbd_devinfo_free(devinfop);
    632 
    633 	cv_init(&sc->sc_task_cv, "otustsk");
    634 	cv_init(&sc->sc_cmd_cv, "otuscmd");
    635 	mutex_init(&sc->sc_cmd_mtx,   MUTEX_DEFAULT, IPL_NONE);
    636 	mutex_init(&sc->sc_task_mtx,  MUTEX_DEFAULT, IPL_NET);
    637 	mutex_init(&sc->sc_tx_mtx,    MUTEX_DEFAULT, IPL_NONE);
    638 	mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
    639 
    640 	usb_init_task(&sc->sc_task, otus_task, sc, 0);
    641 
    642 	callout_init(&sc->sc_scan_to, 0);
    643 	callout_setfunc(&sc->sc_scan_to, otus_next_scan, sc);
    644 	callout_init(&sc->sc_calib_to, 0);
    645 	callout_setfunc(&sc->sc_calib_to, otus_calib_to, sc);
    646 
    647 	sc->sc_amrr.amrr_min_success_threshold =  1;
    648 	sc->sc_amrr.amrr_max_success_threshold = 10;
    649 
    650 	if (usbd_set_config_no(sc->sc_udev, 1, 0) != 0) {
    651 		aprint_error_dev(sc->sc_dev,
    652 		    "could not set configuration no\n");
    653 		return;
    654 	}
    655 
    656 	/* Get the first interface handle. */
    657 	error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
    658 	if (error != 0) {
    659 		aprint_error_dev(sc->sc_dev,
    660 		    "could not get interface handle\n");
    661 		return;
    662 	}
    663 
    664 	if ((error = otus_open_pipes(sc)) != 0) {
    665 		aprint_error_dev(sc->sc_dev, "could not open pipes\n");
    666 		return;
    667 	}
    668 
    669 	/*
    670 	 * We need the firmware loaded from file system to complete the attach.
    671 	 */
    672 	config_mountroot(self, otus_attachhook);
    673 
    674 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
    675 }
    676 
    677 Static void
    678 otus_wait_async(struct otus_softc *sc)
    679 {
    680 
    681 	DPRINTFN(DBG_FN, sc, "\n");
    682 
    683 	mutex_spin_enter(&sc->sc_task_mtx);
    684 	while (sc->sc_cmdq.queued > 0)
    685 		cv_wait(&sc->sc_task_cv, &sc->sc_task_mtx);
    686 	mutex_spin_exit(&sc->sc_task_mtx);
    687 }
    688 
    689 Static int
    690 otus_detach(device_t self, int flags)
    691 {
    692 	struct otus_softc *sc;
    693 	struct ifnet *ifp;
    694 	int s;
    695 
    696 	sc = device_private(self);
    697 
    698 	DPRINTFN(DBG_FN, sc, "\n");
    699 
    700 	s = splusb();
    701 
    702 	sc->sc_dying = 1;
    703 
    704 	ifp = sc->sc_ic.ic_ifp;
    705 	if (ifp != NULL)	/* Failed to attach properly */
    706 		otus_stop(ifp);
    707 
    708 	usb_rem_task(sc->sc_udev, &sc->sc_task);
    709 	callout_destroy(&sc->sc_scan_to);
    710 	callout_destroy(&sc->sc_calib_to);
    711 
    712 	if (ifp && ifp->if_flags != 0) { /* if_attach() has been called. */
    713 		ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
    714 		bpf_detach(ifp);
    715 		ieee80211_ifdetach(&sc->sc_ic);
    716 		if_detach(ifp);
    717 	}
    718 	otus_close_pipes(sc);
    719 	splx(s);
    720 
    721 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
    722 
    723 	mutex_destroy(&sc->sc_write_mtx);
    724 	mutex_destroy(&sc->sc_tx_mtx);
    725 	mutex_destroy(&sc->sc_task_mtx);
    726 	mutex_destroy(&sc->sc_cmd_mtx);
    727 	cv_destroy(&sc->sc_task_cv);
    728 	cv_destroy(&sc->sc_cmd_cv);
    729 
    730 	return 0;
    731 }
    732 
    733 Static int
    734 otus_activate(device_t self, devact_t act)
    735 {
    736 	struct otus_softc *sc;
    737 
    738 	sc = device_private(self);
    739 
    740 	DPRINTFN(DBG_FN, sc, "%d\n", act);
    741 
    742 	switch (act) {
    743 	case DVACT_DEACTIVATE:
    744 		sc->sc_dying = 1;
    745 		if_deactivate(sc->sc_ic.ic_ifp);
    746 		return 0;
    747 	default:
    748 		return EOPNOTSUPP;
    749 	}
    750 }
    751 
    752 Static void
    753 otus_attachhook(device_t arg)
    754 {
    755 	struct otus_softc *sc;
    756 	struct ieee80211com *ic;
    757 	struct ifnet *ifp;
    758 	usb_device_request_t req;
    759 	uint32_t in, out;
    760 	int error;
    761 
    762 	sc = device_private(arg);
    763 
    764 	DPRINTFN(DBG_FN, sc, "\n");
    765 
    766 	ic = &sc->sc_ic;
    767 	ifp = &sc->sc_if;
    768 
    769 	error = otus_load_firmware(sc, "otus-init", AR_FW_INIT_ADDR);
    770 	if (error != 0) {
    771 		aprint_error_dev(sc->sc_dev, "could not load init firmware\n");
    772 		return;
    773 	}
    774 	usbd_delay_ms(sc->sc_udev, 1000);
    775 
    776 	error = otus_load_firmware(sc, "otus-main", AR_FW_MAIN_ADDR);
    777 	if (error != 0) {
    778 		aprint_error_dev(sc->sc_dev, "could not load main firmware\n");
    779 		return;
    780 	}
    781 
    782 	/* Tell device that firmware transfer is complete. */
    783 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    784 	req.bRequest = AR_FW_DOWNLOAD_COMPLETE;
    785 	USETW(req.wValue, 0);
    786 	USETW(req.wIndex, 0);
    787 	USETW(req.wLength, 0);
    788 	if (usbd_do_request(sc->sc_udev, &req, NULL) != 0) {
    789 		aprint_error_dev(sc->sc_dev,
    790 		    "firmware initialization failed\n");
    791 		return;
    792 	}
    793 
    794 	/* Send an ECHO command to check that everything is settled. */
    795 	in = 0xbadc0ffe;
    796 	if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof(in), &out) != 0) {
    797 		aprint_error_dev(sc->sc_dev, "echo command failed\n");
    798 		return;
    799 	}
    800 	if (in != out) {
    801 		aprint_error_dev(sc->sc_dev,
    802 		    "echo reply mismatch: 0x%08x!=0x%08x\n", in, out);
    803 		return;
    804 	}
    805 
    806 	/* Read entire EEPROM. */
    807 	if (otus_read_eeprom(sc) != 0) {
    808 		aprint_error_dev(sc->sc_dev, "could not read EEPROM\n");
    809 		return;
    810 	}
    811 
    812 	sc->sc_txmask = sc->sc_eeprom.baseEepHeader.txMask;
    813 	sc->sc_rxmask = sc->sc_eeprom.baseEepHeader.rxMask;
    814 	sc->sc_capflags = sc->sc_eeprom.baseEepHeader.opCapFlags;
    815 	IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_eeprom.baseEepHeader.macAddr);
    816 	sc->sc_led_newstate = otus_led_newstate_type3;	/* XXX */
    817 
    818 	aprint_normal_dev(sc->sc_dev,
    819 	    "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n",
    820 	    (sc->sc_capflags & AR5416_OPFLAGS_11A) ?
    821 	        0x9104 : ((sc->sc_txmask == 0x5) ? 0x9102 : 0x9101),
    822 	    (sc->sc_txmask == 0x5) ? 2 : 1, (sc->sc_rxmask == 0x5) ? 2 : 1,
    823 	    ether_sprintf(ic->ic_myaddr));
    824 
    825 	/*
    826 	 * Setup the 802.11 device.
    827 	 */
    828 	ic->ic_ifp = ifp;
    829 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
    830 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
    831 	ic->ic_state = IEEE80211_S_INIT;
    832 
    833 	/* Set device capabilities. */
    834 	ic->ic_caps =
    835 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
    836 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
    837 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
    838 	    IEEE80211_C_WPA;		/* 802.11i */
    839 
    840 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
    841 		/* Set supported .11b and .11g rates. */
    842 		ic->ic_sup_rates[IEEE80211_MODE_11B] =
    843 		    ieee80211_std_rateset_11b;
    844 		ic->ic_sup_rates[IEEE80211_MODE_11G] =
    845 		    ieee80211_std_rateset_11g;
    846 	}
    847 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
    848 		/* Set supported .11a rates. */
    849 		ic->ic_sup_rates[IEEE80211_MODE_11A] =
    850 		    ieee80211_std_rateset_11a;
    851 	}
    852 
    853 	/* Build the list of supported channels. */
    854 	otus_get_chanlist(sc);
    855 
    856 	ifp->if_softc = sc;
    857 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    858 	ifp->if_init  = otus_init;
    859 	ifp->if_ioctl = otus_ioctl;
    860 	ifp->if_start = otus_start;
    861 	ifp->if_watchdog = otus_watchdog;
    862 	IFQ_SET_READY(&ifp->if_snd);
    863 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    864 
    865 	if_attach(ifp);
    866 
    867 	ieee80211_ifattach(ic);
    868 
    869 	ic->ic_node_alloc = otus_node_alloc;
    870 	ic->ic_newassoc   = otus_newassoc;
    871 	ic->ic_updateslot = otus_updateslot;
    872 #ifdef HAVE_EDCA
    873 	ic->ic_updateedca = otus_updateedca;
    874 #endif /* HAVE_EDCA */
    875 #ifdef notyet
    876 	ic->ic_set_key = otus_set_key;
    877 	ic->ic_delete_key = otus_delete_key;
    878 #endif /* notyet */
    879 
    880 	/* Override state transition machine. */
    881 	sc->sc_newstate = ic->ic_newstate;
    882 	ic->ic_newstate = otus_newstate;
    883 	ieee80211_media_init(ic, otus_media_change, ieee80211_media_status);
    884 
    885 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
    886 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
    887 	    &sc->sc_drvbpf);
    888 
    889 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
    890 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
    891 	sc->sc_rxtap.wr_ihdr.it_present = htole32(OTUS_RX_RADIOTAP_PRESENT);
    892 
    893 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
    894 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
    895 	sc->sc_txtap.wt_ihdr.it_present = htole32(OTUS_TX_RADIOTAP_PRESENT);
    896 
    897 	ieee80211_announce(ic);
    898 }
    899 
    900 Static void
    901 otus_get_chanlist(struct otus_softc *sc)
    902 {
    903 	struct ieee80211com *ic;
    904 	uint8_t chan;
    905 	int i;
    906 
    907 #ifdef OTUS_DEBUG
    908 	/* XXX regulatory domain. */
    909 	uint16_t domain = le16toh(sc->sc_eeprom.baseEepHeader.regDmn[0]);
    910 
    911 	DPRINTFN(DBG_FN|DBG_INIT, sc, "regdomain=0x%04x\n", domain);
    912 #endif
    913 
    914 	ic = &sc->sc_ic;
    915 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
    916 		for (i = 0; i < 14; i++) {
    917 			chan = ar_chans[i];
    918 			ic->ic_channels[chan].ic_freq =
    919 			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
    920 			ic->ic_channels[chan].ic_flags =
    921 			    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
    922 			    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
    923 		}
    924 	}
    925 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
    926 		for (i = 14; i < __arraycount(ar_chans); i++) {
    927 			chan = ar_chans[i];
    928 			ic->ic_channels[chan].ic_freq =
    929 			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
    930 			ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
    931 		}
    932 	}
    933 }
    934 
    935 Static int
    936 otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr)
    937 {
    938 	usb_device_request_t req;
    939 	firmware_handle_t fh;
    940 	uint8_t *ptr;
    941 	uint8_t *fw;
    942 	size_t size;
    943 	int mlen, error;
    944 
    945 	DPRINTFN(DBG_FN, sc, "\n");
    946 
    947 	if ((error = firmware_open("if_otus", name, &fh)) != 0)
    948 		return error;
    949 
    950 	size = firmware_get_size(fh);
    951 	if ((fw = firmware_malloc(size)) == NULL) {
    952 		firmware_close(fh);
    953 		return ENOMEM;
    954 	}
    955 	if ((error = firmware_read(fh, 0, fw, size)) != 0)
    956 		firmware_free(fw, size);
    957 	firmware_close(fh);
    958 	if (error)
    959 		return error;
    960 
    961 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    962 	req.bRequest = AR_FW_DOWNLOAD;
    963 	USETW(req.wIndex, 0);
    964 
    965 	ptr = fw;
    966 	addr >>= 8;
    967 	while (size > 0) {
    968 		mlen = MIN(size, 4096);
    969 
    970 		USETW(req.wValue, addr);
    971 		USETW(req.wLength, mlen);
    972 		if (usbd_do_request(sc->sc_udev, &req, ptr) != 0) {
    973 			error = EIO;
    974 			break;
    975 		}
    976 		addr += mlen >> 8;
    977 		ptr  += mlen;
    978 		size -= mlen;
    979 	}
    980 	free(fw, M_DEVBUF);
    981 	return error;
    982 }
    983 
    984 Static int
    985 otus_open_pipes(struct otus_softc *sc)
    986 {
    987 	usb_endpoint_descriptor_t *ed;
    988 	int i, error;
    989 
    990 	DPRINTFN(DBG_FN, sc, "\n");
    991 
    992 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_RX_NO, 0,
    993 	    &sc->sc_data_rx_pipe);
    994 	if (error != 0) {
    995 		aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe\n");
    996 		goto fail;
    997 	}
    998 
    999 	ed = usbd_get_endpoint_descriptor(sc->sc_iface, AR_EPT_INTR_RX_NO);
   1000 	if (ed == NULL) {
   1001 		aprint_error_dev(sc->sc_dev,
   1002 		    "could not retrieve Rx intr pipe descriptor\n");
   1003 		goto fail;
   1004 	}
   1005 	sc->sc_ibuf_size = UGETW(ed->wMaxPacketSize);
   1006 	if (sc->sc_ibuf_size == 0) {
   1007 		aprint_error_dev(sc->sc_dev,
   1008 		    "invalid Rx intr pipe descriptor\n");
   1009 		goto fail;
   1010 	}
   1011 	sc->sc_ibuf = kmem_alloc(sc->sc_ibuf_size, KM_SLEEP);
   1012 	if (sc->sc_ibuf == NULL) {
   1013 		aprint_error_dev(sc->sc_dev,
   1014 		    "could not allocate Rx intr buffer\n");
   1015 		goto fail;
   1016 	}
   1017 	error = usbd_open_pipe_intr(sc->sc_iface, AR_EPT_INTR_RX_NO,
   1018 	    USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf,
   1019 	    sc->sc_ibuf_size, otus_intr, USBD_DEFAULT_INTERVAL);
   1020 	if (error != 0) {
   1021 		aprint_error_dev(sc->sc_dev, "could not open Rx intr pipe\n");
   1022 		goto fail;
   1023 	}
   1024 
   1025 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_TX_NO, 0,
   1026 	    &sc->sc_data_tx_pipe);
   1027 	if (error != 0) {
   1028 		aprint_error_dev(sc->sc_dev, "could not open Tx bulk pipe\n");
   1029 		goto fail;
   1030 	}
   1031 
   1032 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_INTR_TX_NO, 0,
   1033 	    &sc->sc_cmd_tx_pipe);
   1034 	if (error != 0) {
   1035 		aprint_error_dev(sc->sc_dev, "could not open Tx intr pipe\n");
   1036 		goto fail;
   1037 	}
   1038 
   1039 	if (otus_alloc_tx_cmd(sc) != 0) {
   1040 		aprint_error_dev(sc->sc_dev,
   1041 		    "could not allocate command xfer\n");
   1042 		goto fail;
   1043 	}
   1044 
   1045 	if (otus_alloc_tx_data_list(sc)) {
   1046 		aprint_error_dev(sc->sc_dev, "could not allocate Tx xfers\n");
   1047 		goto fail;
   1048 	}
   1049 
   1050 	if (otus_alloc_rx_data_list(sc)) {
   1051 		aprint_error_dev(sc->sc_dev, "could not allocate Rx xfers\n");
   1052 		goto fail;
   1053 	}
   1054 
   1055 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) {
   1056 		struct otus_rx_data *data = &sc->sc_rx_data[i];
   1057 
   1058 		usbd_setup_xfer(data->xfer, data, data->buf, OTUS_RXBUFSZ,
   1059 		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof);
   1060 		error = usbd_transfer(data->xfer);
   1061 		if (error != USBD_IN_PROGRESS && error != 0) {
   1062 			aprint_error_dev(sc->sc_dev,
   1063 			    "could not queue Rx xfer\n");
   1064 			goto fail;
   1065 		}
   1066 	}
   1067 	return 0;
   1068 
   1069  fail:	otus_close_pipes(sc);
   1070 	return error;
   1071 }
   1072 
   1073 Static void
   1074 otus_close_pipes(struct otus_softc *sc)
   1075 {
   1076 
   1077 	DPRINTFN(DBG_FN, sc, "\n");
   1078 
   1079 	otus_free_tx_cmd(sc);
   1080 	otus_free_tx_data_list(sc);
   1081 	otus_free_rx_data_list(sc);
   1082 
   1083 	if (sc->sc_data_rx_pipe != NULL)
   1084 		usbd_close_pipe(sc->sc_data_rx_pipe);
   1085 	if (sc->sc_cmd_rx_pipe != NULL) {
   1086 		usbd_abort_pipe(sc->sc_cmd_rx_pipe);
   1087 		usbd_close_pipe(sc->sc_cmd_rx_pipe);
   1088 	}
   1089 	if (sc->sc_ibuf != NULL)
   1090 		kmem_free(sc->sc_ibuf, sc->sc_ibuf_size);
   1091 	if (sc->sc_data_tx_pipe != NULL)
   1092 		usbd_close_pipe(sc->sc_data_tx_pipe);
   1093 	if (sc->sc_cmd_tx_pipe != NULL)
   1094 		usbd_close_pipe(sc->sc_cmd_tx_pipe);
   1095 }
   1096 
   1097 Static int
   1098 otus_alloc_tx_cmd(struct otus_softc *sc)
   1099 {
   1100 	struct otus_tx_cmd *cmd;
   1101 
   1102 	DPRINTFN(DBG_FN, sc, "\n");
   1103 
   1104 	cmd = &sc->sc_tx_cmd;
   1105 
   1106 	int error = usbd_create_xfer(sc->sc_cmd_tx_pipe, OTUS_MAX_TXCMDSZ,
   1107 	    USBD_FORCE_SHORT_XFER, 0, &cmd->xfer);
   1108 	if (error)
   1109 		return error;
   1110 
   1111 	cmd->buf = usbd_get_buffer(cmd->xfer);
   1112 
   1113 	return 0;
   1114 }
   1115 
   1116 Static void
   1117 otus_free_tx_cmd(struct otus_softc *sc)
   1118 {
   1119 
   1120 	DPRINTFN(DBG_FN, sc, "\n");
   1121 
   1122 	/* Make sure no transfers are pending. */
   1123 	usbd_abort_pipe(sc->sc_cmd_tx_pipe);
   1124 
   1125 	mutex_enter(&sc->sc_cmd_mtx);
   1126 	if (sc->sc_tx_cmd.xfer != NULL)
   1127 		usbd_destroy_xfer(sc->sc_tx_cmd.xfer);
   1128 	sc->sc_tx_cmd.xfer = NULL;
   1129 	sc->sc_tx_cmd.buf  = NULL;
   1130 	mutex_exit(&sc->sc_cmd_mtx);
   1131 }
   1132 
   1133 Static int
   1134 otus_alloc_tx_data_list(struct otus_softc *sc)
   1135 {
   1136 	struct otus_tx_data *data;
   1137 	int i, error;
   1138 
   1139 	DPRINTFN(DBG_FN, sc, "\n");
   1140 
   1141 	mutex_enter(&sc->sc_tx_mtx);
   1142 	error = 0;
   1143 	TAILQ_INIT(&sc->sc_tx_free_list);
   1144 	for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) {
   1145 		data = &sc->sc_tx_data[i];
   1146 
   1147 		data->sc = sc;  /* Backpointer for callbacks. */
   1148 
   1149 		error = usbd_create_xfer(sc->sc_data_tx_pipe, OTUS_TXBUFSZ,
   1150 		    USBD_FORCE_SHORT_XFER, 0, &data->xfer);
   1151 		if (error) {
   1152 			aprint_error_dev(sc->sc_dev,
   1153 			    "could not allocate xfer\n");
   1154 			break;
   1155 		}
   1156 		data->buf = usbd_get_buffer(data->xfer);
   1157 		/* Append this Tx buffer to our free list. */
   1158 		TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
   1159 	}
   1160 	if (error != 0)
   1161 		otus_free_tx_data_list(sc);
   1162 	mutex_exit(&sc->sc_tx_mtx);
   1163 	return error;
   1164 }
   1165 
   1166 Static void
   1167 otus_free_tx_data_list(struct otus_softc *sc)
   1168 {
   1169 	int i;
   1170 
   1171 	DPRINTFN(DBG_FN, sc, "\n");
   1172 
   1173 	/* Make sure no transfers are pending. */
   1174 	usbd_abort_pipe(sc->sc_data_tx_pipe);
   1175 
   1176 	for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) {
   1177 		if (sc->sc_tx_data[i].xfer != NULL)
   1178 			usbd_destroy_xfer(sc->sc_tx_data[i].xfer);
   1179 	}
   1180 }
   1181 
   1182 Static int
   1183 otus_alloc_rx_data_list(struct otus_softc *sc)
   1184 {
   1185 	struct otus_rx_data *data;
   1186 	int i, error;
   1187 
   1188 	DPRINTFN(DBG_FN, sc, "\n");
   1189 
   1190 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) {
   1191 		data = &sc->sc_rx_data[i];
   1192 
   1193 		data->sc = sc;	/* Backpointer for callbacks. */
   1194 
   1195 		error = usbd_create_xfer(sc->sc_data_rx_pipe, OTUS_RXBUFSZ,
   1196 		    USBD_SHORT_XFER_OK, 0, &data->xfer);
   1197 
   1198 		if (error) {
   1199 			aprint_error_dev(sc->sc_dev,
   1200 			    "could not allocate xfer\n");
   1201 			goto fail;
   1202 		}
   1203 		data->buf = usbd_get_buffer(data->xfer);
   1204 	}
   1205 	return 0;
   1206 
   1207 fail:	otus_free_rx_data_list(sc);
   1208 	return error;
   1209 }
   1210 
   1211 Static void
   1212 otus_free_rx_data_list(struct otus_softc *sc)
   1213 {
   1214 	int i;
   1215 
   1216 	DPRINTFN(DBG_FN, sc, "\n");
   1217 
   1218 	/* Make sure no transfers are pending. */
   1219 	usbd_abort_pipe(sc->sc_data_rx_pipe);
   1220 
   1221 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++)
   1222 		if (sc->sc_rx_data[i].xfer != NULL)
   1223 			usbd_destroy_xfer(sc->sc_rx_data[i].xfer);
   1224 }
   1225 
   1226 Static void
   1227 otus_next_scan(void *arg)
   1228 {
   1229 	struct otus_softc *sc;
   1230 
   1231 	sc = arg;
   1232 
   1233 	DPRINTFN(DBG_FN, sc, "\n");
   1234 
   1235 	if (sc->sc_dying)
   1236 		return;
   1237 
   1238 	if (sc->sc_ic.ic_state == IEEE80211_S_SCAN)
   1239 		ieee80211_next_scan(&sc->sc_ic);
   1240 }
   1241 
   1242 Static void
   1243 otus_task(void *arg)
   1244 {
   1245 	struct otus_softc *sc;
   1246 	struct otus_host_cmd_ring *ring;
   1247 	struct otus_host_cmd *cmd;
   1248 
   1249 	sc = arg;
   1250 
   1251 	DPRINTFN(DBG_FN, sc, "\n");
   1252 
   1253 	/* Process host commands. */
   1254 	mutex_spin_enter(&sc->sc_task_mtx);
   1255 	ring = &sc->sc_cmdq;
   1256 	while (ring->next != ring->cur) {
   1257 		cmd = &ring->cmd[ring->next];
   1258 		mutex_spin_exit(&sc->sc_task_mtx);
   1259 
   1260 		/* Callback. */
   1261 		DPRINTFN(DBG_CMD, sc, "cb=%p queued=%d\n", cmd->cb,
   1262 		    ring->queued);
   1263 		cmd->cb(sc, cmd->data);
   1264 
   1265 		mutex_spin_enter(&sc->sc_task_mtx);
   1266 		ring->queued--;
   1267 		ring->next = (ring->next + 1) % OTUS_HOST_CMD_RING_COUNT;
   1268 	}
   1269 	cv_signal(&sc->sc_task_cv);
   1270 	mutex_spin_exit(&sc->sc_task_mtx);
   1271 }
   1272 
   1273 Static void
   1274 otus_do_async(struct otus_softc *sc, void (*cb)(struct otus_softc *, void *),
   1275     void *arg, int len)
   1276 {
   1277 	struct otus_host_cmd_ring *ring;
   1278 	struct otus_host_cmd *cmd;
   1279 	bool sched = false;
   1280 
   1281 	DPRINTFN(DBG_FN, sc, "cb=%p\n", cb);
   1282 
   1283 	mutex_spin_enter(&sc->sc_task_mtx);
   1284 	ring = &sc->sc_cmdq;
   1285 	cmd = &ring->cmd[ring->cur];
   1286 	cmd->cb = cb;
   1287 	KASSERT(len <= sizeof(cmd->data));
   1288 	memcpy(cmd->data, arg, len);
   1289 	ring->cur = (ring->cur + 1) % OTUS_HOST_CMD_RING_COUNT;
   1290 
   1291 	/* If there is no pending command already, schedule a task. */
   1292 	if (++ring->queued == 1) {
   1293 		sched = true;
   1294 	}
   1295 	cv_signal(&sc->sc_task_cv);
   1296 	mutex_spin_exit(&sc->sc_task_mtx);
   1297 	if (sched)
   1298 		usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
   1299 }
   1300 
   1301 Static int
   1302 otus_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   1303 {
   1304 	struct otus_softc *sc;
   1305 	struct otus_cmd_newstate cmd;
   1306 
   1307 	sc = ic->ic_ifp->if_softc;
   1308 
   1309 	DPRINTFN(DBG_FN|DBG_STM, sc, "nstate=%s(%d), arg=%d\n",
   1310 	    ieee80211_state_name[nstate], nstate, arg);
   1311 
   1312 	/* Do it in a process context. */
   1313 	cmd.state = nstate;
   1314 	cmd.arg = arg;
   1315 	otus_do_async(sc, otus_newstate_cb, &cmd, sizeof(cmd));
   1316 	return 0;
   1317 }
   1318 
   1319 Static void
   1320 otus_newstate_cb(struct otus_softc *sc, void *arg)
   1321 {
   1322 	struct otus_cmd_newstate *cmd;
   1323 	struct ieee80211com *ic;
   1324 	struct ieee80211_node *ni;
   1325 	enum ieee80211_state nstate;
   1326 	int s;
   1327 
   1328 	cmd = arg;
   1329 	ic = &sc->sc_ic;
   1330 	ni = ic->ic_bss;
   1331 	nstate = cmd->state;
   1332 
   1333 #ifdef OTUS_DEBUG
   1334 	enum ieee80211_state ostate = ostate = ic->ic_state;
   1335 	DPRINTFN(DBG_FN|DBG_STM, sc, "%s(%d)->%s(%d)\n",
   1336 	    ieee80211_state_name[ostate], ostate,
   1337 	    ieee80211_state_name[nstate], nstate);
   1338 #endif
   1339 
   1340 	s = splnet();
   1341 
   1342 	callout_halt(&sc->sc_scan_to, NULL);
   1343 	callout_halt(&sc->sc_calib_to, NULL);
   1344 
   1345 	mutex_enter(&sc->sc_write_mtx);
   1346 
   1347 	switch (nstate) {
   1348 	case IEEE80211_S_INIT:
   1349 		break;
   1350 
   1351 	case IEEE80211_S_SCAN:
   1352 		otus_set_chan(sc, ic->ic_curchan, 0);
   1353 		if (!sc->sc_dying)
   1354 			callout_schedule(&sc->sc_scan_to, hz / 5);
   1355 		break;
   1356 
   1357 	case IEEE80211_S_AUTH:
   1358 	case IEEE80211_S_ASSOC:
   1359 		otus_set_chan(sc, ic->ic_curchan, 0);
   1360 		break;
   1361 
   1362 	case IEEE80211_S_RUN:
   1363 		otus_set_chan(sc, ic->ic_curchan, 1);
   1364 
   1365 		switch (ic->ic_opmode) {
   1366 		case IEEE80211_M_STA:
   1367 			otus_updateslot_cb_locked(sc);
   1368 			otus_set_bssid(sc, ni->ni_bssid);
   1369 
   1370 			/* Fake a join to init the Tx rate. */
   1371 			otus_newassoc(ni, 1);
   1372 
   1373 			/* Start calibration timer. */
   1374 			if (!sc->sc_dying)
   1375 				callout_schedule(&sc->sc_calib_to, hz);
   1376 			break;
   1377 
   1378 		case IEEE80211_M_IBSS:
   1379 		case IEEE80211_M_AHDEMO:
   1380 		case IEEE80211_M_HOSTAP:
   1381 		case IEEE80211_M_MONITOR:
   1382 			break;
   1383 		}
   1384 		break;
   1385 	}
   1386 	(void)sc->sc_newstate(ic, nstate, cmd->arg);
   1387 	sc->sc_led_newstate(sc);
   1388 	mutex_exit(&sc->sc_write_mtx);
   1389 
   1390 	splx(s);
   1391 }
   1392 
   1393 Static int
   1394 otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen,
   1395     void *odata)
   1396 {
   1397 	struct otus_tx_cmd *cmd;
   1398 	struct ar_cmd_hdr *hdr;
   1399 	int xferlen, error;
   1400 
   1401 	DPRINTFN(DBG_FN, sc, "\n");
   1402 
   1403 	cmd = &sc->sc_tx_cmd;
   1404 
   1405 	mutex_enter(&sc->sc_cmd_mtx);
   1406 
   1407 	/* Always bulk-out a multiple of 4 bytes. */
   1408 	xferlen = roundup2(sizeof(*hdr) + ilen, 4);
   1409 
   1410 	hdr = (void *)cmd->buf;
   1411 	if (hdr == NULL) {	/* we may have been freed while detaching */
   1412 		mutex_exit(&sc->sc_cmd_mtx);
   1413 		DPRINTFN(DBG_CMD, sc, "tx_cmd freed with commands pending\n");
   1414 		return 0;
   1415 	}
   1416 	hdr->code  = code;
   1417 	hdr->len   = ilen;
   1418 	hdr->token = ++cmd->token;	/* Don't care about endianness. */
   1419 	KASSERT(sizeof(hdr) + ilen <= OTUS_MAX_TXCMDSZ);
   1420 	memcpy(cmd->buf + sizeof(hdr[0]), idata, ilen);
   1421 
   1422 	DPRINTFN(DBG_CMD, sc, "sending command code=0x%02x len=%d token=%d\n",
   1423 	    code, ilen, hdr->token);
   1424 
   1425 	cmd->odata = odata;
   1426 	cmd->done = 0;
   1427 	usbd_setup_xfer(cmd->xfer, cmd, cmd->buf, xferlen,
   1428 	    USBD_FORCE_SHORT_XFER, OTUS_CMD_TIMEOUT, NULL);
   1429 	error = usbd_sync_transfer(cmd->xfer);
   1430 	if (error != 0) {
   1431 		mutex_exit(&sc->sc_cmd_mtx);
   1432 #if defined(DIAGNOSTIC) || defined(OTUS_DEBUG)	/* XXX: kill some noise */
   1433 		aprint_error_dev(sc->sc_dev,
   1434 		    "could not send command 0x%x (error=%s)\n",
   1435 		    code, usbd_errstr(error));
   1436 #endif
   1437 		return EIO;
   1438 	}
   1439 	if (!cmd->done)
   1440 		error = cv_timedwait_sig(&sc->sc_cmd_cv, &sc->sc_cmd_mtx, hz);
   1441 	cmd->odata = NULL;	/* In case answer is received too late. */
   1442 	mutex_exit(&sc->sc_cmd_mtx);
   1443 	if (error != 0) {
   1444 		aprint_error_dev(sc->sc_dev,
   1445 		    "timeout waiting for command 0x%02x reply\n", code);
   1446 	}
   1447 	return error;
   1448 }
   1449 
   1450 Static void
   1451 otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val)
   1452 {
   1453 
   1454 	DPRINTFN(DBG_FN|DBG_REG, sc, "reg=0x%x, val=0x%x\n", reg, val);
   1455 
   1456 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   1457 	KASSERT(sc->sc_write_idx < __arraycount(sc->sc_write_buf));
   1458 
   1459 	sc->sc_write_buf[sc->sc_write_idx].reg = htole32(reg);
   1460 	sc->sc_write_buf[sc->sc_write_idx].val = htole32(val);
   1461 
   1462 	if (++sc->sc_write_idx >= __arraycount(sc->sc_write_buf))
   1463 		(void)otus_write_barrier(sc);
   1464 }
   1465 
   1466 Static int
   1467 otus_write_barrier(struct otus_softc *sc)
   1468 {
   1469 	int error;
   1470 
   1471 	DPRINTFN(DBG_FN, sc, "\n");
   1472 
   1473 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   1474 	KASSERT(sc->sc_write_idx <= __arraycount(sc->sc_write_buf));
   1475 
   1476 	if (sc->sc_write_idx == 0)
   1477 		return 0;	/* Nothing to flush. */
   1478 
   1479 	error = otus_cmd(sc, AR_CMD_WREG, sc->sc_write_buf,
   1480 	    sizeof(sc->sc_write_buf[0]) * sc->sc_write_idx, NULL);
   1481 
   1482 	sc->sc_write_idx = 0;
   1483 	if (error)
   1484 		DPRINTFN(DBG_REG, sc, "error=%d\n", error);
   1485 	return error;
   1486 }
   1487 
   1488 Static struct ieee80211_node *
   1489 otus_node_alloc(struct ieee80211_node_table *ntp)
   1490 {
   1491 	struct otus_node *on;
   1492 
   1493 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
   1494 
   1495 	on = malloc(sizeof(*on), M_DEVBUF, M_NOWAIT | M_ZERO);
   1496 	return &on->ni;
   1497 }
   1498 
   1499 Static int
   1500 otus_media_change(struct ifnet *ifp)
   1501 {
   1502 	struct otus_softc *sc;
   1503 	struct ieee80211com *ic;
   1504 	uint8_t rate, ridx;
   1505 	int error;
   1506 
   1507 	sc = ifp->if_softc;
   1508 
   1509 	DPRINTFN(DBG_FN, sc, "\n");
   1510 
   1511 	error = ieee80211_media_change(ifp);
   1512 	if (error != ENETRESET)
   1513 		return error;
   1514 
   1515 	ic = &sc->sc_ic;
   1516 	if (ic->ic_fixed_rate != -1) {
   1517 		rate = ic->ic_sup_rates[ic->ic_curmode].
   1518 		    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
   1519 		for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
   1520 			if (otus_rates[ridx].rate == rate)
   1521 				break;
   1522 		sc->sc_fixed_ridx = ridx;
   1523 	}
   1524 
   1525 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
   1526 		error = otus_init(ifp);
   1527 
   1528 	return error;
   1529 }
   1530 
   1531 Static int
   1532 otus_read_eeprom(struct otus_softc *sc)
   1533 {
   1534 	uint32_t regs[8], reg;
   1535 	uint8_t *eep;
   1536 	int i, j, error;
   1537 
   1538 	DPRINTFN(DBG_FN, sc, "\n");
   1539 
   1540 	KASSERT(sizeof(sc->sc_eeprom) % 32 == 0);
   1541 
   1542 	/* Read EEPROM by blocks of 32 bytes. */
   1543 	eep = (uint8_t *)&sc->sc_eeprom;
   1544 	reg = AR_EEPROM_OFFSET;
   1545 	for (i = 0; i < sizeof(sc->sc_eeprom) / 32; i++) {
   1546 		for (j = 0; j < 8; j++, reg += 4)
   1547 			regs[j] = htole32(reg);
   1548 		error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof(regs), eep);
   1549 		if (error != 0)
   1550 			break;
   1551 		eep += 32;
   1552 	}
   1553 	return error;
   1554 }
   1555 
   1556 Static void
   1557 otus_newassoc(struct ieee80211_node *ni, int isnew)
   1558 {
   1559 	struct ieee80211_rateset *rs;
   1560 	struct otus_softc *sc;
   1561 	struct otus_node *on;
   1562 	uint8_t rate;
   1563 	int ridx, i;
   1564 
   1565 	sc = ni->ni_ic->ic_ifp->if_softc;
   1566 
   1567 	DPRINTFN(DBG_FN, sc, "isnew=%d addr=%s\n",
   1568 	    isnew, ether_sprintf(ni->ni_macaddr));
   1569 
   1570 	on = (void *)ni;
   1571 	ieee80211_amrr_node_init(&sc->sc_amrr, &on->amn);
   1572 	/* Start at lowest available bit-rate, AMRR will raise. */
   1573 	ni->ni_txrate = 0;
   1574 	rs = &ni->ni_rates;
   1575 	for (i = 0; i < rs->rs_nrates; i++) {
   1576 		rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
   1577 		/* Convert 802.11 rate to hardware rate index. */
   1578 		for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
   1579 			if (otus_rates[ridx].rate == rate)
   1580 				break;
   1581 		on->ridx[i] = ridx;
   1582 		DPRINTFN(DBG_INIT, sc, "rate=0x%02x ridx=%d\n",
   1583 		    rs->rs_rates[i], on->ridx[i]);
   1584 	}
   1585 }
   1586 
   1587 /* ARGSUSED */
   1588 Static void
   1589 otus_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
   1590 {
   1591 #if 0
   1592 	struct otus_softc *sc;
   1593 	int len;
   1594 
   1595 	sc = priv;
   1596 
   1597 	DPRINTFN(DBG_FN, sc, "\n");
   1598 
   1599 	/*
   1600 	 * The Rx intr pipe is unused with current firmware.  Notifications
   1601 	 * and replies to commands are sent through the Rx bulk pipe instead
   1602 	 * (with a magic PLCP header.)
   1603 	 */
   1604 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
   1605 		DPRINTFN(DBG_INTR, sc, "status=%d\n", status);
   1606 		if (status == USBD_STALLED)
   1607 			usbd_clear_endpoint_stall_async(sc->sc_cmd_rx_pipe);
   1608 		return;
   1609 	}
   1610 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
   1611 
   1612 	otus_cmd_rxeof(sc, sc->sc_ibuf, len);
   1613 #endif
   1614 }
   1615 
   1616 Static void
   1617 otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
   1618 {
   1619 	struct ieee80211com *ic;
   1620 	struct otus_tx_cmd *cmd;
   1621 	struct ar_cmd_hdr *hdr;
   1622 	int s;
   1623 
   1624 	DPRINTFN(DBG_FN, sc, "\n");
   1625 
   1626 	ic = &sc->sc_ic;
   1627 
   1628 	if (__predict_false(len < sizeof(*hdr))) {
   1629 		DPRINTFN(DBG_RX, sc, "cmd too small %d\n", len);
   1630 		return;
   1631 	}
   1632 	hdr = (void *)buf;
   1633 	if (__predict_false(sizeof(*hdr) + hdr->len > len ||
   1634 	    sizeof(*hdr) + hdr->len > 64)) {
   1635 		DPRINTFN(DBG_RX, sc, "cmd too large %d\n", hdr->len);
   1636 		return;
   1637 	}
   1638 
   1639 	if ((hdr->code & 0xc0) != 0xc0) {
   1640 		DPRINTFN(DBG_RX, sc, "received reply code=0x%02x len=%d token=%d\n",
   1641 		    hdr->code, hdr->len, hdr->token);
   1642 		mutex_enter(&sc->sc_cmd_mtx);
   1643 		cmd = &sc->sc_tx_cmd;
   1644 		if (__predict_false(hdr->token != cmd->token)) {
   1645 			mutex_exit(&sc->sc_cmd_mtx);
   1646 			return;
   1647 		}
   1648 		/* Copy answer into caller's supplied buffer. */
   1649 		if (cmd->odata != NULL)
   1650 			memcpy(cmd->odata, &hdr[1], hdr->len);
   1651 		cmd->done = 1;
   1652 		cv_signal(&sc->sc_cmd_cv);
   1653 		mutex_exit(&sc->sc_cmd_mtx);
   1654 		return;
   1655 	}
   1656 
   1657 	/* Received unsolicited notification. */
   1658 	DPRINTFN(DBG_RX, sc, "received notification code=0x%02x len=%d\n",
   1659 	    hdr->code, hdr->len);
   1660 	switch (hdr->code & 0x3f) {
   1661 	case AR_EVT_BEACON:
   1662 		break;
   1663 	case AR_EVT_TX_COMP:
   1664 	{
   1665 		struct ar_evt_tx_comp *tx;
   1666 		struct ieee80211_node *ni;
   1667 		struct otus_node *on;
   1668 
   1669 		tx = (void *)&hdr[1];
   1670 
   1671 		DPRINTFN(DBG_RX, sc, "tx completed %s status=%d phy=0x%x\n",
   1672 		    ether_sprintf(tx->macaddr), le16toh(tx->status),
   1673 		    le32toh(tx->phy));
   1674 		s = splnet();
   1675 #ifdef notyet
   1676 #ifndef IEEE80211_STA_ONLY
   1677 		if (ic->ic_opmode != IEEE80211_M_STA) {
   1678 			ni = ieee80211_find_node(ic, tx->macaddr);
   1679 			if (__predict_false(ni == NULL)) {
   1680 				splx(s);
   1681 				break;
   1682 			}
   1683 		} else
   1684 #endif
   1685 #endif
   1686 			ni = ic->ic_bss;
   1687 		/* Update rate control statistics. */
   1688 		on = (void *)ni;
   1689 		/* NB: we do not set the TX_MAC_RATE_PROBING flag. */
   1690 		if (__predict_true(tx->status != 0))
   1691 			on->amn.amn_retrycnt++;
   1692 		splx(s);
   1693 		break;
   1694 	}
   1695 	case AR_EVT_TBTT:
   1696 		break;
   1697 	}
   1698 }
   1699 
   1700 Static void
   1701 otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
   1702 {
   1703 	struct ieee80211com *ic;
   1704 	struct ifnet *ifp;
   1705 	struct ieee80211_node *ni;
   1706 	struct ar_rx_tail *tail;
   1707 	struct ieee80211_frame *wh;
   1708 	struct mbuf *m;
   1709 	uint8_t *plcp;
   1710 	int s, mlen, align;
   1711 
   1712 	DPRINTFN(DBG_FN, sc, "\n");
   1713 
   1714 	ic = &sc->sc_ic;
   1715 	ifp = ic->ic_ifp;
   1716 
   1717 	if (__predict_false(len < AR_PLCP_HDR_LEN)) {
   1718 		DPRINTFN(DBG_RX, sc, "sub-xfer too short %d\n", len);
   1719 		return;
   1720 	}
   1721 	plcp = buf;
   1722 
   1723 	/* All bits in the PLCP header are set to 1 for non-MPDU. */
   1724 	if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) {
   1725 		otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN,
   1726 		    len - AR_PLCP_HDR_LEN);
   1727 		return;
   1728 	}
   1729 
   1730 	/* Received MPDU. */
   1731 	if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof(*tail))) {
   1732 		DPRINTFN(DBG_RX, sc, "MPDU too short %d\n", len);
   1733 		ifp->if_ierrors++;
   1734 		return;
   1735 	}
   1736 	tail = (void *)(plcp + len - sizeof(*tail));
   1737 	wh = (void *)(plcp + AR_PLCP_HDR_LEN);
   1738 
   1739 	/* Discard error frames. */
   1740 	if (__predict_false((tail->error & sc->sc_rx_error_msk) != 0)) {
   1741 		DPRINTFN(DBG_RX, sc, "error frame 0x%02x\n", tail->error);
   1742 		if (tail->error & AR_RX_ERROR_FCS) {
   1743 			DPRINTFN(DBG_RX, sc, "bad FCS\n");
   1744 		} else if (tail->error & AR_RX_ERROR_MMIC) {
   1745 			/* Report Michael MIC failures to net80211. */
   1746 			ieee80211_notify_michael_failure(ic, wh, 0 /* XXX: keyix */);
   1747 		}
   1748 		ifp->if_ierrors++;
   1749 		return;
   1750 	}
   1751 	/* Compute MPDU's length. */
   1752 	mlen = len - AR_PLCP_HDR_LEN - sizeof(*tail);
   1753 	mlen -= IEEE80211_CRC_LEN;	/* strip 802.11 FCS */
   1754 	/* Make sure there's room for an 802.11 header. */
   1755 	/*
   1756 	 * XXX: This will drop most control packets.  Do we really
   1757 	 * want this in IEEE80211_M_MONITOR mode?
   1758 	 */
   1759 	if (__predict_false(mlen < sizeof(*wh))) {
   1760 		ifp->if_ierrors++;
   1761 		return;
   1762 	}
   1763 
   1764 	/* Provide a 32-bit aligned protocol header to the stack. */
   1765 	align = (ieee80211_has_qos(wh) ^ ieee80211_has_addr4(wh)) ? 2 : 0;
   1766 
   1767 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1768 	if (__predict_false(m == NULL)) {
   1769 		ifp->if_ierrors++;
   1770 		return;
   1771 	}
   1772 	if (align + mlen > MHLEN) {
   1773 		MCLGET(m, M_DONTWAIT);
   1774 		if (__predict_false(!(m->m_flags & M_EXT))) {
   1775 			ifp->if_ierrors++;
   1776 			m_freem(m);
   1777 			return;
   1778 		}
   1779 	}
   1780 	/* Finalize mbuf. */
   1781 	m_set_rcvif(m, ifp);
   1782 	m->m_data += align;
   1783 	memcpy(mtod(m, void *), wh, mlen);
   1784 	m->m_pkthdr.len = m->m_len = mlen;
   1785 
   1786 	s = splnet();
   1787 	if (__predict_false(sc->sc_drvbpf != NULL)) {
   1788 		struct otus_rx_radiotap_header *tap;
   1789 
   1790 		tap = &sc->sc_rxtap;
   1791 		tap->wr_flags = 0;
   1792 		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
   1793 		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
   1794 		tap->wr_antsignal = tail->rssi;
   1795 		tap->wr_rate = 2;	/* In case it can't be found below. */
   1796 		switch (tail->status & AR_RX_STATUS_MT_MASK) {
   1797 		case AR_RX_STATUS_MT_CCK:
   1798 			switch (plcp[0]) {
   1799 			case  10: tap->wr_rate =   2; break;
   1800 			case  20: tap->wr_rate =   4; break;
   1801 			case  55: tap->wr_rate =  11; break;
   1802 			case 110: tap->wr_rate =  22; break;
   1803 			}
   1804 			if (tail->status & AR_RX_STATUS_SHPREAMBLE)
   1805 				tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
   1806 			break;
   1807 		case AR_RX_STATUS_MT_OFDM:
   1808 			switch (plcp[0] & 0xf) {
   1809 			case 0xb: tap->wr_rate =  12; break;
   1810 			case 0xf: tap->wr_rate =  18; break;
   1811 			case 0xa: tap->wr_rate =  24; break;
   1812 			case 0xe: tap->wr_rate =  36; break;
   1813 			case 0x9: tap->wr_rate =  48; break;
   1814 			case 0xd: tap->wr_rate =  72; break;
   1815 			case 0x8: tap->wr_rate =  96; break;
   1816 			case 0xc: tap->wr_rate = 108; break;
   1817 			}
   1818 			break;
   1819 		}
   1820 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
   1821 	}
   1822 
   1823 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   1824 
   1825 	/* push the frame up to the 802.11 stack */
   1826 	ieee80211_input(ic, m, ni, tail->rssi, 0);
   1827 
   1828 	/* Node is no longer needed. */
   1829 	ieee80211_free_node(ni);
   1830 	splx(s);
   1831 }
   1832 
   1833 Static void
   1834 otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
   1835 {
   1836 	struct otus_rx_data *data;
   1837 	struct otus_softc *sc;
   1838 	uint8_t *buf;
   1839 	struct ar_rx_head *head;
   1840 	uint16_t hlen;
   1841 	int len;
   1842 
   1843 	data = priv;
   1844 	sc = data->sc;
   1845 
   1846 	DPRINTFN(DBG_FN, sc, "\n");
   1847 
   1848 	buf = data->buf;
   1849 
   1850 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
   1851 		DPRINTFN(DBG_RX, sc, "RX status=%d\n", status);
   1852 		if (status == USBD_STALLED)
   1853 			usbd_clear_endpoint_stall_async(sc->sc_data_rx_pipe);
   1854 		else if (status != USBD_CANCELLED) {
   1855 			DPRINTFN(DBG_RX, sc,
   1856 			    "otus_rxeof: goto resubmit: status=%d\n", status);
   1857 			goto resubmit;
   1858 		}
   1859 		return;
   1860 	}
   1861 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
   1862 
   1863 	while (len >= sizeof(*head)) {
   1864 		head = (void *)buf;
   1865 		if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) {
   1866 			DPRINTFN(DBG_RX, sc, "tag not valid 0x%x\n",
   1867 			    le16toh(head->tag));
   1868 			break;
   1869 		}
   1870 		hlen = le16toh(head->len);
   1871 		if (__predict_false(sizeof(*head) + hlen > len)) {
   1872 			DPRINTFN(DBG_RX, sc, "xfer too short %d/%d\n",
   1873 			    len, hlen);
   1874 			break;
   1875 		}
   1876 		/* Process sub-xfer. */
   1877 		otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen);
   1878 
   1879 		/* Next sub-xfer is aligned on a 32-bit boundary. */
   1880 		hlen = roundup2(sizeof(*head) + hlen, 4);
   1881 		buf += hlen;
   1882 		len -= hlen;
   1883 	}
   1884 
   1885  resubmit:
   1886 	usbd_setup_xfer(xfer, data, data->buf, OTUS_RXBUFSZ,
   1887 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof);
   1888 	(void)usbd_transfer(data->xfer);
   1889 }
   1890 
   1891 Static void
   1892 otus_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
   1893 {
   1894 	struct otus_tx_data *data;
   1895 	struct otus_softc *sc;
   1896 	struct ieee80211com *ic;
   1897 	struct ifnet *ifp;
   1898 	int s;
   1899 
   1900 	data = priv;
   1901 	sc = data->sc;
   1902 
   1903 	DPRINTFN(DBG_FN, sc, "\n");
   1904 
   1905 	/* Put this Tx buffer back to the free list. */
   1906 	mutex_enter(&sc->sc_tx_mtx);
   1907 	TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
   1908 	mutex_exit(&sc->sc_tx_mtx);
   1909 
   1910 	ic = &sc->sc_ic;
   1911 	ifp = ic->ic_ifp;
   1912 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
   1913 		DPRINTFN(DBG_TX, sc, "TX status=%d\n", status);
   1914 		if (status == USBD_STALLED)
   1915 			usbd_clear_endpoint_stall_async(sc->sc_data_tx_pipe);
   1916 		ifp->if_oerrors++;
   1917 		return;
   1918 	}
   1919 	ifp->if_opackets++;
   1920 
   1921 	s = splnet();
   1922 	sc->sc_tx_timer = 0;
   1923 	ifp->if_flags &= ~IFF_OACTIVE;	/* XXX: do after freeing Tx buffer? */
   1924 	otus_start(ifp);
   1925 	splx(s);
   1926 }
   1927 
   1928 Static int
   1929 otus_tx(struct otus_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
   1930     struct otus_tx_data *data)
   1931 {
   1932 	struct ieee80211com *ic;
   1933 	struct otus_node *on;
   1934 	struct ieee80211_frame *wh;
   1935 	struct ieee80211_key *k;
   1936 	struct ar_tx_head *head;
   1937 	uint32_t phyctl;
   1938 	uint16_t macctl, qos;
   1939 	uint8_t qid;
   1940 	int error, ridx, hasqos, xferlen;
   1941 
   1942 	DPRINTFN(DBG_FN, sc, "\n");
   1943 
   1944 	ic = &sc->sc_ic;
   1945 	on = (void *)ni;
   1946 
   1947 	wh = mtod(m, struct ieee80211_frame *);
   1948 	if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
   1949 		/* XXX: derived from upgt_tx_task() and ural_tx_data() */
   1950 		k = ieee80211_crypto_encap(ic, ni, m);
   1951 		if (k == NULL)
   1952 			return ENOBUFS;
   1953 
   1954 		/* Packet header may have moved, reset our local pointer. */
   1955 		wh = mtod(m, struct ieee80211_frame *);
   1956 	}
   1957 
   1958 #ifdef HAVE_EDCA
   1959 	if ((hasqos = ieee80211_has_qos(wh))) {
   1960 		qos = ieee80211_get_qos(wh);
   1961 		qid = ieee80211_up_to_ac(ic, qos & IEEE80211_QOS_TID);
   1962 	} else {
   1963 		qos = 0;
   1964 		qid = WME_AC_BE;
   1965 	}
   1966 #else
   1967 	hasqos = 0;
   1968 	qos = 0;
   1969 	qid = WME_AC_BE;
   1970 #endif
   1971 
   1972 	/* Pickup a rate index. */
   1973 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   1974 	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA)
   1975 		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
   1976 		    OTUS_RIDX_OFDM6 : OTUS_RIDX_CCK1;
   1977 	else if (ic->ic_fixed_rate != -1)
   1978 		ridx = sc->sc_fixed_ridx;
   1979 	else
   1980 		ridx = on->ridx[ni->ni_txrate];
   1981 
   1982 	phyctl = 0;
   1983 	macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid);
   1984 
   1985 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   1986 	    (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY_MASK) ==
   1987 	     IEEE80211_QOS_ACKPOLICY_NOACK)))
   1988 		macctl |= AR_TX_MAC_NOACK;
   1989 
   1990 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   1991 		if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= ic->ic_rtsthreshold)
   1992 			macctl |= AR_TX_MAC_RTS;
   1993 		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
   1994 		    ridx >= OTUS_RIDX_OFDM6) {
   1995 			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
   1996 				macctl |= AR_TX_MAC_CTS;
   1997 			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
   1998 				macctl |= AR_TX_MAC_RTS;
   1999 		}
   2000 	}
   2001 
   2002 	phyctl |= AR_TX_PHY_MCS(otus_rates[ridx].mcs);
   2003 	if (ridx >= OTUS_RIDX_OFDM6) {
   2004 		phyctl |= AR_TX_PHY_MT_OFDM;
   2005 		if (ridx <= OTUS_RIDX_OFDM24)
   2006 			phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask);
   2007 		else
   2008 			phyctl |= AR_TX_PHY_ANTMSK(1);
   2009 	} else {	/* CCK */
   2010 		phyctl |= AR_TX_PHY_MT_CCK;
   2011 		phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask);
   2012 	}
   2013 
   2014 	/* Update rate control stats for frames that are ACK'ed. */
   2015 	if (!(macctl & AR_TX_MAC_NOACK))
   2016 		on->amn.amn_txcnt++;
   2017 
   2018 	/* Fill Tx descriptor. */
   2019 	head = (void *)data->buf;
   2020 	head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN);
   2021 	head->macctl = htole16(macctl);
   2022 	head->phyctl = htole32(phyctl);
   2023 
   2024 	if (__predict_false(sc->sc_drvbpf != NULL)) {
   2025 		struct otus_tx_radiotap_header *tap = &sc->sc_txtap;
   2026 
   2027 		tap->wt_flags = 0;
   2028 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
   2029 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
   2030 		tap->wt_rate = otus_rates[ridx].rate;
   2031 		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
   2032 		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
   2033 
   2034 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
   2035 	}
   2036 
   2037 	xferlen = sizeof(*head) + m->m_pkthdr.len;
   2038 	m_copydata(m, 0, m->m_pkthdr.len, (void *)&head[1]);
   2039 
   2040 	DPRINTFN(DBG_TX, sc, "queued len=%d mac=0x%04x phy=0x%08x rate=%d\n",
   2041 	    head->len, head->macctl, head->phyctl, otus_rates[ridx].rate);
   2042 
   2043 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
   2044 	    USBD_FORCE_SHORT_XFER, OTUS_TX_TIMEOUT, otus_txeof);
   2045 	error = usbd_transfer(data->xfer);
   2046 	if (__predict_false(
   2047 		    error != USBD_NORMAL_COMPLETION &&
   2048 		    error != USBD_IN_PROGRESS)) {
   2049 		DPRINTFN(DBG_TX, sc, "transfer failed %d\n", error);
   2050 		return error;
   2051 	}
   2052 	return 0;
   2053 }
   2054 
   2055 Static void
   2056 otus_start(struct ifnet *ifp)
   2057 {
   2058 	struct otus_softc *sc;
   2059 	struct ieee80211com *ic;
   2060 	struct otus_tx_data *data;
   2061 	struct ether_header *eh;
   2062 	struct ieee80211_node *ni;
   2063 	struct mbuf *m;
   2064 
   2065 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   2066 		return;
   2067 
   2068 	sc = ifp->if_softc;
   2069 	ic = &sc->sc_ic;
   2070 
   2071 	DPRINTFN(DBG_FN, sc, "\n");
   2072 
   2073 	data = NULL;
   2074 	for (;;) {
   2075 		/*
   2076 		 * Grab a Tx buffer if we don't already have one.  If
   2077 		 * one isn't available, bail out.
   2078 		 * NB: We must obtain this Tx buffer _before_
   2079 		 * dequeueing anything as one may not be available
   2080 		 * later.  Both must be done inside a single lock.
   2081 		 */
   2082 		mutex_enter(&sc->sc_tx_mtx);
   2083 		if (data == NULL && !TAILQ_EMPTY(&sc->sc_tx_free_list)) {
   2084 			data = TAILQ_FIRST(&sc->sc_tx_free_list);
   2085 			TAILQ_REMOVE(&sc->sc_tx_free_list, data, next);
   2086 		}
   2087 		mutex_exit(&sc->sc_tx_mtx);
   2088 
   2089 		if (data == NULL) {
   2090 			ifp->if_flags |= IFF_OACTIVE;
   2091 			DPRINTFN(DBG_TX, sc, "empty sc_tx_free_list\n");
   2092 			return;
   2093 		}
   2094 
   2095 		/* Send pending management frames first. */
   2096 		IF_DEQUEUE(&ic->ic_mgtq, m);
   2097 		if (m != NULL) {
   2098 			ni = M_GETCTX(m, struct ieee80211_node *);
   2099 			M_CLEARCTX(m);
   2100 			goto sendit;
   2101 		}
   2102 
   2103 		if (ic->ic_state != IEEE80211_S_RUN)
   2104 			break;
   2105 
   2106 		/* Encapsulate and send data frames. */
   2107 		IFQ_DEQUEUE(&ifp->if_snd, m);
   2108 		if (m == NULL)
   2109 			break;
   2110 
   2111 		if (m->m_len < (int)sizeof(*eh) &&
   2112 		    (m = m_pullup(m, sizeof(*eh))) == NULL) {
   2113 			ifp->if_oerrors++;
   2114 			continue;
   2115 		}
   2116 
   2117 		eh = mtod(m, struct ether_header *);
   2118 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   2119 		if (ni == NULL) {
   2120 			m_freem(m);
   2121 			ifp->if_oerrors++;
   2122 			continue;
   2123 		}
   2124 
   2125 		bpf_mtap(ifp, m);
   2126 
   2127 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
   2128 			/* original m was freed by ieee80211_encap() */
   2129 			ieee80211_free_node(ni);
   2130 			ifp->if_oerrors++;
   2131 			continue;
   2132 		}
   2133  sendit:
   2134 		bpf_mtap3(ic->ic_rawbpf, m);
   2135 
   2136 		if (otus_tx(sc, m, ni, data) != 0) {
   2137 			m_freem(m);
   2138 			ieee80211_free_node(ni);
   2139 			ifp->if_oerrors++;
   2140 			continue;
   2141 		}
   2142 
   2143 		data = NULL;	/* we're finished with this data buffer */
   2144 		m_freem(m);
   2145 		ieee80211_free_node(ni);
   2146 		sc->sc_tx_timer = 5;
   2147 		ifp->if_timer = 1;
   2148 	}
   2149 
   2150 	/*
   2151 	 * If here, we have a Tx buffer, but ran out of mbufs to
   2152 	 * transmit.  Put the Tx buffer back to the free list.
   2153 	 */
   2154 	mutex_enter(&sc->sc_tx_mtx);
   2155 	TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
   2156 	mutex_exit(&sc->sc_tx_mtx);
   2157 }
   2158 
   2159 Static void
   2160 otus_watchdog(struct ifnet *ifp)
   2161 {
   2162 	struct otus_softc *sc;
   2163 
   2164 	sc = ifp->if_softc;
   2165 
   2166 	DPRINTFN(DBG_FN, sc, "\n");
   2167 
   2168 	ifp->if_timer = 0;
   2169 
   2170 	if (sc->sc_tx_timer > 0) {
   2171 		if (--sc->sc_tx_timer == 0) {
   2172 			aprint_error_dev(sc->sc_dev, "device timeout\n");
   2173 			/* otus_init(ifp); XXX needs a process context! */
   2174 			ifp->if_oerrors++;
   2175 			return;
   2176 		}
   2177 		ifp->if_timer = 1;
   2178 	}
   2179 	ieee80211_watchdog(&sc->sc_ic);
   2180 }
   2181 
   2182 Static int
   2183 otus_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   2184 {
   2185 	struct otus_softc *sc;
   2186 	struct ieee80211com *ic;
   2187 	int s, error = 0;
   2188 
   2189 	sc = ifp->if_softc;
   2190 
   2191 	DPRINTFN(DBG_FN, sc, "0x%lx\n", cmd);
   2192 
   2193 	ic = &sc->sc_ic;
   2194 
   2195 	s = splnet();
   2196 
   2197 	switch (cmd) {
   2198 	case SIOCSIFADDR:
   2199 		ifp->if_flags |= IFF_UP;
   2200 #ifdef INET
   2201 		struct ifaddr *ifa = data;
   2202 		if (ifa->ifa_addr->sa_family == AF_INET)
   2203 			arp_ifinit(&ic->ic_ac, ifa);
   2204 #endif
   2205 		/* FALLTHROUGH */
   2206 	case SIOCSIFFLAGS:
   2207 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   2208 			break;
   2209 
   2210 		switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
   2211 		case IFF_UP | IFF_RUNNING:
   2212 			if (((ifp->if_flags ^ sc->sc_if_flags) &
   2213 				(IFF_ALLMULTI | IFF_PROMISC)) != 0)
   2214 				otus_set_multi(sc);
   2215 			break;
   2216 		case IFF_UP:
   2217 			otus_init(ifp);
   2218 			break;
   2219 
   2220 		case IFF_RUNNING:
   2221 			otus_stop(ifp);
   2222 			break;
   2223 		case 0:
   2224 		default:
   2225 			break;
   2226 		}
   2227 		sc->sc_if_flags = ifp->if_flags;
   2228 		break;
   2229 
   2230 	case SIOCADDMULTI:
   2231 	case SIOCDELMULTI:
   2232 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
   2233 			/* setup multicast filter, etc */
   2234 			/* XXX: ??? */
   2235 			error = 0;
   2236 		}
   2237 		break;
   2238 
   2239 	case SIOCS80211CHANNEL:
   2240 		/*
   2241 		 * This allows for fast channel switching in monitor mode
   2242 		 * (used by kismet). In IBSS mode, we must explicitly reset
   2243 		 * the interface to generate a new beacon frame.
   2244 		 */
   2245 		error = ieee80211_ioctl(ic, cmd, data);
   2246 
   2247 		DPRINTFN(DBG_CHAN, sc,
   2248 		    "ic_curchan=%d ic_ibss_chan=%d ic_des_chan=%d ni_chan=%d error=%d\n",
   2249 		    ieee80211_chan2ieee(ic, ic->ic_curchan),
   2250 		    ieee80211_chan2ieee(ic, ic->ic_ibss_chan),
   2251 		    ieee80211_chan2ieee(ic, ic->ic_des_chan),
   2252 		    ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
   2253 		    error);
   2254 
   2255 		if (error == ENETRESET &&
   2256 		    ic->ic_opmode == IEEE80211_M_MONITOR) {
   2257 			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   2258 			    (IFF_UP | IFF_RUNNING)) {
   2259 				mutex_enter(&sc->sc_write_mtx);
   2260 				otus_set_chan(sc, ic->ic_curchan, 0);
   2261 				mutex_exit(&sc->sc_write_mtx);
   2262 			}
   2263 			error = 0;
   2264 		}
   2265 		break;
   2266 
   2267 	default:
   2268 		error = ieee80211_ioctl(ic, cmd, data);
   2269 	}
   2270 	if (error == ENETRESET) {
   2271 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   2272 		    (IFF_UP | IFF_RUNNING))
   2273 			otus_init(ifp);
   2274 		error = 0;
   2275 	}
   2276 	splx(s);
   2277 	return error;
   2278 }
   2279 
   2280 Static int
   2281 otus_set_multi(struct otus_softc *sc)
   2282 {
   2283 	struct ifnet *ifp;
   2284 	struct ether_multi *enm;
   2285 	struct ether_multistep step;
   2286 	uint32_t lo, hi;
   2287 	uint8_t bit;
   2288 	int error;
   2289 
   2290 	DPRINTFN(DBG_FN, sc, "\n");
   2291 
   2292 	ifp = sc->sc_ic.ic_ifp;
   2293 	if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
   2294 		lo = hi = 0xffffffff;
   2295 		goto done;
   2296 	}
   2297 	lo = hi = 0;
   2298 	ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
   2299 	while (enm != NULL) {
   2300 		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
   2301 			ifp->if_flags |= IFF_ALLMULTI;
   2302 			lo = hi = 0xffffffff;
   2303 			goto done;
   2304 		}
   2305 		bit = enm->enm_addrlo[5] >> 2;
   2306 		if (bit < 32)
   2307 			lo |= 1 << bit;
   2308 		else
   2309 			hi |= 1 << (bit - 32);
   2310 		ETHER_NEXT_MULTI(step, enm);
   2311 	}
   2312  done:
   2313 	mutex_enter(&sc->sc_write_mtx);
   2314 	hi |= 1 << 31;	/* Make sure the broadcast bit is set. */
   2315 	otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo);
   2316 	otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi);
   2317 	error = otus_write_barrier(sc);
   2318 	mutex_exit(&sc->sc_write_mtx);
   2319 	return error;
   2320 }
   2321 
   2322 #ifdef HAVE_EDCA
   2323 Static void
   2324 otus_updateedca(struct ieee80211com *ic)
   2325 {
   2326 
   2327 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
   2328 
   2329 	/* Do it in a process context. */
   2330 	otus_do_async(ic->ic_ifp->if_softc, otus_updateedca_cb, NULL, 0);
   2331 }
   2332 
   2333 Static void
   2334 otus_updateedca_cb(struct otus_softc *sc, void *arg __used)
   2335 {
   2336 
   2337 	DPRINTFN(DBG_FN, sc, "\n");
   2338 
   2339 	mutex_enter(&sc->sc_write_mtx);
   2340 	otus_updateedca_cb_locked(sc);
   2341 	mutex_exit(&sc->sc_write_mtx);
   2342 }
   2343 #endif
   2344 
   2345 Static void
   2346 otus_updateedca_cb_locked(struct otus_softc *sc)
   2347 {
   2348 #ifdef HAVE_EDCA
   2349 	struct ieee80211com *ic;
   2350 #endif
   2351 	const struct ieee80211_edca_ac_params *edca;
   2352 	int s;
   2353 
   2354 	DPRINTFN(DBG_FN, sc, "\n");
   2355 
   2356 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   2357 
   2358 	s = splnet();
   2359 
   2360 #ifdef HAVE_EDCA
   2361 	ic = &sc->sc_ic;
   2362 	edca = (ic->ic_flags & IEEE80211_F_QOS) ?
   2363 	    ic->ic_edca_ac : otus_edca_def;
   2364 #else
   2365 	edca = otus_edca_def;
   2366 #endif /* HAVE_EDCA */
   2367 
   2368 #define EXP2(val)	((1 << (val)) - 1)
   2369 #define AIFS(val)	((val) * 9 + 10)
   2370 
   2371 	/* Set CWmin/CWmax values. */
   2372 	otus_write(sc, AR_MAC_REG_AC0_CW,
   2373 	    EXP2(edca[WME_AC_BE].ac_ecwmax) << 16 |
   2374 	    EXP2(edca[WME_AC_BE].ac_ecwmin));
   2375 	otus_write(sc, AR_MAC_REG_AC1_CW,
   2376 	    EXP2(edca[WME_AC_BK].ac_ecwmax) << 16 |
   2377 	    EXP2(edca[WME_AC_BK].ac_ecwmin));
   2378 	otus_write(sc, AR_MAC_REG_AC2_CW,
   2379 	    EXP2(edca[WME_AC_VI].ac_ecwmax) << 16 |
   2380 	    EXP2(edca[WME_AC_VI].ac_ecwmin));
   2381 	otus_write(sc, AR_MAC_REG_AC3_CW,
   2382 	    EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 |
   2383 	    EXP2(edca[WME_AC_VO].ac_ecwmin));
   2384 	otus_write(sc, AR_MAC_REG_AC4_CW,		/* Special TXQ. */
   2385 	    EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 |
   2386 	    EXP2(edca[WME_AC_VO].ac_ecwmin));
   2387 
   2388 	/* Set AIFSN values. */
   2389 	otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS,
   2390 	    AIFS(edca[WME_AC_VI].ac_aifsn) << 24 |
   2391 	    AIFS(edca[WME_AC_BK].ac_aifsn) << 12 |
   2392 	    AIFS(edca[WME_AC_BE].ac_aifsn));
   2393 	otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS,
   2394 	    AIFS(edca[WME_AC_VO].ac_aifsn) << 16 |	/* Special TXQ. */
   2395 	    AIFS(edca[WME_AC_VO].ac_aifsn) <<  4 |
   2396 	    AIFS(edca[WME_AC_VI].ac_aifsn) >>  8);
   2397 
   2398 	/* Set TXOP limit. */
   2399 	otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP,
   2400 	    edca[WME_AC_BK].ac_txoplimit << 16 |
   2401 	    edca[WME_AC_BE].ac_txoplimit);
   2402 	otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP,
   2403 	    edca[WME_AC_VO].ac_txoplimit << 16 |
   2404 	    edca[WME_AC_VI].ac_txoplimit);
   2405 #undef AIFS
   2406 #undef EXP2
   2407 
   2408 	splx(s);
   2409 
   2410 	(void)otus_write_barrier(sc);
   2411 }
   2412 
   2413 Static void
   2414 otus_updateslot(struct ifnet *ifp)
   2415 {
   2416 	struct otus_softc *sc;
   2417 
   2418 	sc = ifp->if_softc;
   2419 
   2420 	DPRINTFN(DBG_FN, sc, "\n");
   2421 
   2422 	/* Do it in a process context. */
   2423 	otus_do_async(sc, otus_updateslot_cb, NULL, 0);
   2424 }
   2425 
   2426 /* ARGSUSED */
   2427 Static void
   2428 otus_updateslot_cb(struct otus_softc *sc, void *arg)
   2429 {
   2430 
   2431 	DPRINTFN(DBG_FN, sc, "\n");
   2432 
   2433 	mutex_enter(&sc->sc_write_mtx);
   2434 	otus_updateslot_cb_locked(sc);
   2435 	mutex_exit(&sc->sc_write_mtx);
   2436 }
   2437 
   2438 Static void
   2439 otus_updateslot_cb_locked(struct otus_softc *sc)
   2440 {
   2441 	uint32_t slottime;
   2442 
   2443 	DPRINTFN(DBG_FN, sc, "\n");
   2444 
   2445 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   2446 
   2447 	slottime = (sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
   2448 	otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10);
   2449 	(void)otus_write_barrier(sc);
   2450 }
   2451 
   2452 Static int
   2453 otus_init_mac(struct otus_softc *sc)
   2454 {
   2455 	int error;
   2456 
   2457 	DPRINTFN(DBG_FN|DBG_INIT, sc, "\n");
   2458 
   2459 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   2460 
   2461 	otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40);
   2462 	otus_write(sc, AR_MAC_REG_RETRY_MAX, 0);
   2463 	otus_write(sc, AR_MAC_REG_SNIFFER, AR_MAC_REG_SNIFFER_DEFAULTS);
   2464 	otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80);
   2465 	otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70);
   2466 	otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000);
   2467 	otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10);
   2468 
   2469 	/* CF-END mode */
   2470 	otus_write(sc, 0x1c3b2c, 0x19000000);
   2471 
   2472 	/* NAV protects ACK only (in TXOP). */
   2473 	otus_write(sc, 0x1c3b38, 0x201);
   2474 
   2475 	/* Set beacon PHY CTRL's TPC to 0x7, TA1=1 */
   2476 	/* OTUS set AM to 0x1 */
   2477 	otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170);
   2478 
   2479 	otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105);
   2480 
   2481 	/* AGG test code*/
   2482 	/* Aggregation MAX number and timeout */
   2483 	otus_write(sc, AR_MAC_REG_AMPDU_FACTOR, 0x10000a);
   2484 
   2485 	/* Filter any control frames, BAR is bit 24. */
   2486 	otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, AR_MAC_REG_FTF_DEFAULTS);
   2487 
   2488 	/* Enable deaggregator, response in sniffer mode */
   2489 	otus_write(sc, 0x1c3c40, 0x1 | 1 << 30);	/* XXX: was 0x1 */
   2490 
   2491 	/* rate sets */
   2492 	otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f);
   2493 	otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f);
   2494 	otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
   2495 
   2496 	/* MIMO response control */
   2497 	otus_write(sc, 0x1c3694, 0x4003c1e);	/* bit 26~28  otus-AM */
   2498 
   2499 	/* Switch MAC to OTUS interface. */
   2500 	otus_write(sc, 0x1c3600, 0x3);
   2501 
   2502 	otus_write(sc, AR_MAC_REG_AMPDU_RX_THRESH, 0xffff);
   2503 
   2504 	/* set PHY register read timeout (??) */
   2505 	otus_write(sc, AR_MAC_REG_MISC_680, 0xf00008);
   2506 
   2507 	/* Disable Rx TimeOut, workaround for BB. */
   2508 	otus_write(sc, AR_MAC_REG_RX_TIMEOUT, 0x0);
   2509 
   2510 	/* Set clock frequency to 88/80MHz. */
   2511 	otus_write(sc, AR_PWR_REG_CLOCK_SEL,
   2512 	    AR_PWR_CLK_AHB_80_88MHZ | AR_PWR_CLK_DAC_160_INV_DLY);
   2513 
   2514 	/* Set WLAN DMA interrupt mode: generate intr per packet. */
   2515 	otus_write(sc, AR_MAC_REG_TXRX_MPI, 0x110011);
   2516 
   2517 	otus_write(sc, AR_MAC_REG_FCS_SELECT, AR_MAC_FCS_FIFO_PROT);
   2518 
   2519 	/* Disables the CF_END frame, undocumented register */
   2520 	otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48);
   2521 
   2522 	/* Disable HW decryption for now. */
   2523 	otus_write(sc, AR_MAC_REG_ENCRYPTION,
   2524 	    AR_MAC_REG_ENCRYPTION_DEFAULTS | AR_MAC_REG_ENCRYPTION_RX_SOFTWARE);
   2525 
   2526 	/*
   2527 	 * XXX: should these be elsewhere?
   2528 	 */
   2529 	/* Enable LED0 and LED1. */
   2530 	otus_write(sc, AR_GPIO_REG_PORT_TYPE, 3);
   2531 	otus_write(sc, AR_GPIO_REG_DATA,
   2532 	    AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON);
   2533 
   2534 	/* Set USB Rx stream mode maximum frame number to 2. */
   2535 	otus_write(sc, AR_USB_REG_MAX_AGG_UPLOAD, (1 << 2));
   2536 
   2537 	/* Set USB Rx stream mode timeout to 10us. */
   2538 	otus_write(sc, AR_USB_REG_UPLOAD_TIME_CTL, 0x80);
   2539 
   2540 	if ((error = otus_write_barrier(sc)) != 0)
   2541 		return error;
   2542 
   2543 	/* Set default EDCA parameters. */
   2544 	otus_updateedca_cb_locked(sc);
   2545 	return 0;
   2546 }
   2547 
   2548 /*
   2549  * Return default value for PHY register based on current operating mode.
   2550  */
   2551 Static uint32_t
   2552 otus_phy_get_def(struct otus_softc *sc, uint32_t reg)
   2553 {
   2554 	int i;
   2555 
   2556 	DPRINTFN(DBG_FN, sc, "\n");
   2557 
   2558 	for (i = 0; i < __arraycount(ar5416_phy_regs); i++)
   2559 		if (AR_PHY(ar5416_phy_regs[i]) == reg)
   2560 			return sc->sc_phy_vals[i];
   2561 	return 0;	/* Register not found. */
   2562 }
   2563 
   2564 /*
   2565  * Update PHY's programming based on vendor-specific data stored in EEPROM.
   2566  * This is for FEM-type devices only.
   2567  */
   2568 Static int
   2569 otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c)
   2570 {
   2571 	const struct ModalEepHeader *eep;
   2572 	uint32_t tmp, offset;
   2573 
   2574 	DPRINTFN(DBG_FN, sc, "\n");
   2575 
   2576 	if (IEEE80211_IS_CHAN_5GHZ(c))
   2577 		eep = &sc->sc_eeprom.modalHeader[0];
   2578 	else
   2579 		eep = &sc->sc_eeprom.modalHeader[1];
   2580 
   2581 	/* Offset of chain 2. */
   2582 	offset = 2 * 0x1000;
   2583 
   2584 	tmp = le32toh(eep->antCtrlCommon);
   2585 	otus_write(sc, AR_PHY_SWITCH_COM, tmp);
   2586 
   2587 	tmp = le32toh(eep->antCtrlChain[0]);
   2588 	otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp);
   2589 
   2590 	tmp = le32toh(eep->antCtrlChain[1]);
   2591 	otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp);
   2592 
   2593 	if (1 /* sc->sc_sco == AR_SCO_SCN */) {
   2594 		tmp = otus_phy_get_def(sc, AR_PHY_SETTLING);
   2595 		tmp &= ~(0x7f << 7);
   2596 		tmp |= (eep->switchSettling & 0x7f) << 7;
   2597 		otus_write(sc, AR_PHY_SETTLING, tmp);
   2598 	}
   2599 
   2600 	tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ);
   2601 	tmp &= ~0xffff;
   2602 	tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize;
   2603 	otus_write(sc, AR_PHY_DESIRED_SZ, tmp);
   2604 
   2605 	tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 |
   2606 	      eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn;
   2607 	otus_write(sc, AR_PHY_RF_CTL4, tmp);
   2608 
   2609 	tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3);
   2610 	tmp &= ~(0xff << 16);
   2611 	tmp |= eep->txEndToRxOn << 16;
   2612 	otus_write(sc, AR_PHY_RF_CTL3, tmp);
   2613 
   2614 	tmp = otus_phy_get_def(sc, AR_PHY_CCA);
   2615 	tmp &= ~(0x7f << 12);
   2616 	tmp |= (eep->thresh62 & 0x7f) << 12;
   2617 	otus_write(sc, AR_PHY_CCA, tmp);
   2618 
   2619 	tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN);
   2620 	tmp &= ~(0x3f << 12);
   2621 	tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12;
   2622 	otus_write(sc, AR_PHY_RXGAIN, tmp);
   2623 
   2624 	tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset);
   2625 	tmp &= ~(0x3f << 12);
   2626 	tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12;
   2627 	otus_write(sc, AR_PHY_RXGAIN + offset, tmp);
   2628 
   2629 	tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ);
   2630 	tmp &= ~(0x3f << 18);
   2631 	tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18;
   2632 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
   2633 		tmp &= ~(0xf << 10);
   2634 		tmp |= (eep->bswMargin[0] & 0xf) << 10;
   2635 	}
   2636 	otus_write(sc, AR_PHY_GAIN_2GHZ, tmp);
   2637 
   2638 	tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset);
   2639 	tmp &= ~(0x3f << 18);
   2640 	tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18;
   2641 	otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp);
   2642 
   2643 	tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4);
   2644 	tmp &= ~(0x3f << 5 | 0x1f);
   2645 	tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f);
   2646 	otus_write(sc, AR_PHY_TIMING_CTRL4, tmp);
   2647 
   2648 	tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset);
   2649 	tmp &= ~(0x3f << 5 | 0x1f);
   2650 	tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f);
   2651 	otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp);
   2652 
   2653 	tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1);
   2654 	tmp &= ~(0xf << 16);
   2655 	tmp |= (eep->xpd & 0xf) << 16;
   2656 	otus_write(sc, AR_PHY_TPCRG1, tmp);
   2657 
   2658 	return otus_write_barrier(sc);
   2659 }
   2660 
   2661 Static int
   2662 otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c)
   2663 {
   2664 	const uint32_t *vals;
   2665 	int error, i;
   2666 
   2667 	DPRINTFN(DBG_FN, sc, "\n");
   2668 
   2669 	/* Select PHY programming based on band and bandwidth. */
   2670 	if (IEEE80211_IS_CHAN_2GHZ(c))
   2671 		vals = ar5416_phy_vals_2ghz_20mhz;
   2672 	else
   2673 		vals = ar5416_phy_vals_5ghz_20mhz;
   2674 	for (i = 0; i < __arraycount(ar5416_phy_regs); i++)
   2675 		otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]);
   2676 	sc->sc_phy_vals = vals;
   2677 
   2678 	if (sc->sc_eeprom.baseEepHeader.deviceType == 0x80)	/* FEM */
   2679 		if ((error = otus_set_board_values(sc, c)) != 0)
   2680 			return error;
   2681 
   2682 	/* Initial Tx power settings. */
   2683 	otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f);
   2684 	otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f);
   2685 	otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f);
   2686 	otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f);
   2687 	otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f);
   2688 	otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f);
   2689 	otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f);
   2690 	otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f);
   2691 	otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f);
   2692 	otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f);
   2693 
   2694 	if (IEEE80211_IS_CHAN_2GHZ(c))
   2695 		otus_write(sc, 0x1d4014, 0x5163);
   2696 	else
   2697 		otus_write(sc, 0x1d4014, 0x5143);
   2698 
   2699 	return otus_write_barrier(sc);
   2700 }
   2701 
   2702 static __inline uint8_t
   2703 otus_reverse_bits(uint8_t v)
   2704 {
   2705 
   2706 	v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
   2707 	v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
   2708 	v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
   2709 	return v;
   2710 }
   2711 
   2712 Static int
   2713 otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c)
   2714 {
   2715 	uint8_t chansel, d0, d1;
   2716 	uint16_t data;
   2717 	int error;
   2718 
   2719 	DPRINTFN(DBG_FN, sc, "\n");
   2720 
   2721 	d0 = 0;
   2722 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
   2723 		chansel = (c->ic_freq - 4800) / 5;
   2724 		if (chansel & 1)
   2725 			d0 |= AR_BANK4_AMODE_REFSEL(2);
   2726 		else
   2727 			d0 |= AR_BANK4_AMODE_REFSEL(1);
   2728 	} else {
   2729 		d0 |= AR_BANK4_AMODE_REFSEL(2);
   2730 		if (c->ic_freq == 2484) {	/* CH 14 */
   2731 			d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ;
   2732 			chansel = 10 + (c->ic_freq - 2274) / 5;
   2733 		} else
   2734 			chansel = 16 + (c->ic_freq - 2272) / 5;
   2735 		chansel <<= 2;
   2736 	}
   2737 	d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP;
   2738 	d1 = otus_reverse_bits(chansel);
   2739 
   2740 	/* Write bits 0-4 of d0 and d1. */
   2741 	data = (d1 & 0x1f) << 5 | (d0 & 0x1f);
   2742 	otus_write(sc, AR_PHY(44), data);
   2743 	/* Write bits 5-7 of d0 and d1. */
   2744 	data = (d1 >> 5) << 5 | (d0 >> 5);
   2745 	otus_write(sc, AR_PHY(58), data);
   2746 
   2747 	if ((error = otus_write_barrier(sc)) == 0)
   2748 		usbd_delay_ms(sc->sc_udev, 10);
   2749 
   2750 	return error;
   2751 }
   2752 
   2753 Static void
   2754 otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa)
   2755 {
   2756 #define COEFF_SCALE_SHIFT	24
   2757 	uint32_t exp, man;
   2758 
   2759 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
   2760 
   2761 	/* exponent = 14 - floor(log2(coeff)) */
   2762 	for (exp = 31; exp > 0; exp--)
   2763 		if (coeff & (1 << exp))
   2764 			break;
   2765 	KASSERT(exp != 0);
   2766 	exp = 14 - (exp - COEFF_SCALE_SHIFT);
   2767 
   2768 	/* mantissa = floor(coeff * 2^exponent + 0.5) */
   2769 	man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1));
   2770 
   2771 	*mantissa = man >> (COEFF_SCALE_SHIFT - exp);
   2772 	*exponent = exp - 16;
   2773 #undef COEFF_SCALE_SHIFT
   2774 }
   2775 
   2776 Static int
   2777 otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc)
   2778 {
   2779 	struct ar_cmd_frequency cmd;
   2780 	struct ar_rsp_frequency rsp;
   2781 	const uint32_t *vals;
   2782 	uint32_t coeff, exp, man, tmp;
   2783 	uint8_t code;
   2784 	int error, i;
   2785 
   2786 	DPRINTFN(DBG_FN, sc, "\n");
   2787 
   2788 
   2789 #ifdef OTUS_DEBUG
   2790 	struct ieee80211com *ic = &sc->sc_ic;
   2791 	int chan = ieee80211_chan2ieee(ic, c);
   2792 
   2793 	DPRINTFN(DBG_CHAN, sc, "setting channel %d (%dMHz)\n",
   2794 	    chan, c->ic_freq);
   2795 #endif
   2796 
   2797 	tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104;
   2798 	otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp);
   2799 	if ((error = otus_write_barrier(sc)) != 0)
   2800 		return error;
   2801 
   2802 	/* Disable BB Heavy Clip. */
   2803 	otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200);
   2804 	if ((error = otus_write_barrier(sc)) != 0)
   2805 		return error;
   2806 
   2807 	/* XXX Is that FREQ_START ? */
   2808 	error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL);
   2809 	if (error != 0)
   2810 		return error;
   2811 
   2812 	/* Reprogram PHY and RF on channel band or bandwidth changes. */
   2813 	if (sc->sc_bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) {
   2814 		DPRINTFN(DBG_CHAN, sc, "band switch\n");
   2815 
   2816 		/* Cold/Warm reset BB/ADDA. */
   2817 		otus_write(sc, 0x1d4004, sc->sc_bb_reset ? 0x800 : 0x400);
   2818 		if ((error = otus_write_barrier(sc)) != 0)
   2819 			return error;
   2820 
   2821 		otus_write(sc, 0x1d4004, 0);
   2822 		if ((error = otus_write_barrier(sc)) != 0)
   2823 			return error;
   2824 		sc->sc_bb_reset = 0;
   2825 
   2826 		if ((error = otus_program_phy(sc, c)) != 0) {
   2827 			aprint_error_dev(sc->sc_dev,
   2828 			    "could not program PHY\n");
   2829 			return error;
   2830 		}
   2831 
   2832 		/* Select RF programming based on band. */
   2833 		if (IEEE80211_IS_CHAN_5GHZ(c))
   2834 			vals = ar5416_banks_vals_5ghz;
   2835 		else
   2836 			vals = ar5416_banks_vals_2ghz;
   2837 		for (i = 0; i < __arraycount(ar5416_banks_regs); i++)
   2838 			otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]);
   2839 		if ((error = otus_write_barrier(sc)) != 0) {
   2840 			aprint_error_dev(sc->sc_dev, "could not program RF\n");
   2841 			return error;
   2842 		}
   2843 		code = AR_CMD_RF_INIT;
   2844 	} else {
   2845 		code = AR_CMD_FREQUENCY;
   2846 	}
   2847 
   2848 	if ((error = otus_set_rf_bank4(sc, c)) != 0)
   2849 		return error;
   2850 
   2851 	tmp = (sc->sc_txmask == 0x5) ? 0x340 : 0x240;
   2852 	otus_write(sc, AR_PHY_TURBO, tmp);
   2853 	if ((error = otus_write_barrier(sc)) != 0)
   2854 		return error;
   2855 
   2856 	/* Send firmware command to set channel. */
   2857 	cmd.freq = htole32((uint32_t)c->ic_freq * 1000);
   2858 	cmd.dynht2040 = htole32(0);
   2859 	cmd.htena = htole32(1);
   2860 
   2861 	/* Set Delta Slope (exponent and mantissa). */
   2862 	coeff = (100 << 24) / c->ic_freq;
   2863 	otus_get_delta_slope(coeff, &exp, &man);
   2864 	cmd.dsc_exp = htole32(exp);
   2865 	cmd.dsc_man = htole32(man);
   2866 	DPRINTFN(DBG_CHAN, sc, "ds coeff=%u exp=%u man=%u\n",
   2867 	    coeff, exp, man);
   2868 
   2869 	/* For Short GI, coeff is 9/10 that of normal coeff. */
   2870 	coeff = (9 * coeff) / 10;
   2871 	otus_get_delta_slope(coeff, &exp, &man);
   2872 	cmd.dsc_shgi_exp = htole32(exp);
   2873 	cmd.dsc_shgi_man = htole32(man);
   2874 	DPRINTFN(DBG_CHAN, sc, "ds shgi coeff=%u exp=%u man=%u\n",
   2875 	    coeff, exp, man);
   2876 
   2877 	/* Set wait time for AGC and noise calibration (100 or 200ms). */
   2878 	cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000);
   2879 	DPRINTFN(DBG_CHAN, sc, "%s\n",
   2880 	    code == AR_CMD_RF_INIT ? "RF_INIT" : "FREQUENCY");
   2881 	error = otus_cmd(sc, code, &cmd, sizeof(cmd), &rsp);
   2882 	if (error != 0)
   2883 		return error;
   2884 
   2885 	if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) {
   2886 		DPRINTFN(DBG_CHAN, sc, "status=0x%x\n", le32toh(rsp.status));
   2887 		/* Force cold reset on next channel. */
   2888 		sc->sc_bb_reset = 1;
   2889 	}
   2890 
   2891 #ifdef OTUS_DEBUG
   2892 	if (otus_debug & DBG_CHAN) {
   2893 		DPRINTFN(DBG_CHAN, sc, "calibration status=0x%x\n",
   2894 		    le32toh(rsp.status));
   2895 		for (i = 0; i < 2; i++) {	/* 2 Rx chains */
   2896 			/* Sign-extend 9-bit NF values. */
   2897 			DPRINTFN(DBG_CHAN, sc, "noisefloor chain %d=%d\n",
   2898 			    i, (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23);
   2899 			DPRINTFN(DBG_CHAN, sc, "noisefloor ext chain %d=%d\n",
   2900 			    i, ((int32_t)le32toh(rsp.nf_ext[i])) >> 23);
   2901 		}
   2902 	}
   2903 #endif
   2904 	sc->sc_curchan = c;
   2905 	return 0;
   2906 }
   2907 
   2908 #ifdef notyet
   2909 Static int
   2910 otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
   2911     struct ieee80211_key *k)
   2912 {
   2913 	struct otus_softc *sc;
   2914 	struct otus_cmd_key cmd;
   2915 
   2916 	sc = ic->ic_ifp->if_softc;
   2917 
   2918 	DPRINTFN(DBG_FN, sc, "\n");
   2919 
   2920 	/* Defer setting of WEP keys until interface is brought up. */
   2921 	if ((ic->ic_ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
   2922 	    (IFF_UP | IFF_RUNNING))
   2923 		return 0;
   2924 
   2925 	/* Do it in a process context. */
   2926 	cmd.key = *k;
   2927 	cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
   2928 	otus_do_async(sc, otus_set_key_cb, &cmd, sizeof(cmd));
   2929 	return 0;
   2930 }
   2931 
   2932 Static void
   2933 otus_set_key_cb(struct otus_softc *sc, void *arg)
   2934 {
   2935 	struct otus_cmd_key *cmd;
   2936 	struct ieee80211_key *k;
   2937 	struct ar_cmd_ekey key;
   2938 	uint16_t cipher;
   2939 	int error;
   2940 
   2941 	DPRINTFN(DBG_FN, sc, "\n");
   2942 
   2943 	cmd = arg;
   2944 	k = &cmd->key;
   2945 
   2946 	memset(&key, 0, sizeof(key));
   2947 	if (k->k_flags & IEEE80211_KEY_GROUP) {
   2948 		key.uid = htole16(k->k_id);
   2949 		IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr);
   2950 		key.macaddr[0] |= 0x80;
   2951 	} else {
   2952 		key.uid = htole16(OTUS_UID(cmd->associd));
   2953 		IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr);
   2954 	}
   2955 	key.kix = htole16(0);
   2956 	/* Map net80211 cipher to hardware. */
   2957 	switch (k->k_cipher) {
   2958 	case IEEE80211_CIPHER_WEP40:
   2959 		cipher = AR_CIPHER_WEP64;
   2960 		break;
   2961 	case IEEE80211_CIPHER_WEP104:
   2962 		cipher = AR_CIPHER_WEP128;
   2963 		break;
   2964 	case IEEE80211_CIPHER_TKIP:
   2965 		cipher = AR_CIPHER_TKIP;
   2966 		break;
   2967 	case IEEE80211_CIPHER_CCMP:
   2968 		cipher = AR_CIPHER_AES;
   2969 		break;
   2970 	default:
   2971 		return;
   2972 	}
   2973 	key.cipher = htole16(cipher);
   2974 	memcpy(key.key, k->k_key, MIN(k->k_len, 16));
   2975 	error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL);
   2976 	if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP)
   2977 		return;
   2978 
   2979 	/* TKIP: set Tx/Rx MIC Key. */
   2980 	key.kix = htole16(1);
   2981 	memcpy(key.key, k->k_key + 16, 16);
   2982 	(void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL);
   2983 }
   2984 
   2985 Static void
   2986 otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
   2987     struct ieee80211_key *k)
   2988 {
   2989 	struct otus_softc *sc;
   2990 	struct otus_cmd_key cmd;
   2991 
   2992 	sc = ic->ic_ifp->if_softc;
   2993 
   2994 	DPRINTFN(DBG_FN, sc, "\n");
   2995 
   2996 	if (!(ic->ic_ifp->if_flags & IFF_RUNNING) ||
   2997 	    ic->ic_state != IEEE80211_S_RUN)
   2998 		return;	/* Nothing to do. */
   2999 
   3000 	/* Do it in a process context. */
   3001 	cmd.key = *k;
   3002 	cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
   3003 	otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof(cmd));
   3004 }
   3005 
   3006 Static void
   3007 otus_delete_key_cb(struct otus_softc *sc, void *arg)
   3008 {
   3009 	struct otus_cmd_key *cmd;
   3010 	struct ieee80211_key *k;
   3011 	uint32_t uid;
   3012 
   3013 	DPRINTFN(DBG_FN, sc, "\n");
   3014 
   3015 	cmd = arg;
   3016 	k = &cmd->key;
   3017 	if (k->k_flags & IEEE80211_KEY_GROUP)
   3018 		uid = htole32(k->k_id);
   3019 	else
   3020 		uid = htole32(OTUS_UID(cmd->associd));
   3021 	(void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof(uid), NULL);
   3022 }
   3023 #endif /* notyet */
   3024 
   3025 Static void
   3026 otus_calib_to(void *arg)
   3027 {
   3028 	struct otus_softc *sc;
   3029 	struct ieee80211com *ic;
   3030 	struct ieee80211_node *ni;
   3031 	struct otus_node *on;
   3032 	int s;
   3033 
   3034 	sc = arg;
   3035 
   3036 	DPRINTFN(DBG_FN, sc, "\n");
   3037 
   3038 	if (sc->sc_dying)
   3039 		return;
   3040 
   3041 	s = splnet();
   3042 	ic = &sc->sc_ic;
   3043 	ni = ic->ic_bss;
   3044 	on = (void *)ni;
   3045 	ieee80211_amrr_choose(&sc->sc_amrr, ni, &on->amn);
   3046 	splx(s);
   3047 
   3048 	if (!sc->sc_dying)
   3049 		callout_schedule(&sc->sc_calib_to, hz);
   3050 }
   3051 
   3052 Static int
   3053 otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid)
   3054 {
   3055 
   3056 	DPRINTFN(DBG_FN, sc, "\n");
   3057 
   3058 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   3059 
   3060 	otus_write(sc, AR_MAC_REG_BSSID_L,
   3061 	    bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
   3062 	otus_write(sc, AR_MAC_REG_BSSID_H,
   3063 	    bssid[4] | bssid[5] << 8);
   3064 	return otus_write_barrier(sc);
   3065 }
   3066 
   3067 Static int
   3068 otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr)
   3069 {
   3070 
   3071 	DPRINTFN(DBG_FN, sc, "\n");
   3072 
   3073 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   3074 
   3075 	otus_write(sc, AR_MAC_REG_MAC_ADDR_L,
   3076 	    addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
   3077 	otus_write(sc, AR_MAC_REG_MAC_ADDR_H,
   3078 	    addr[4] | addr[5] << 8);
   3079 	return otus_write_barrier(sc);
   3080 }
   3081 
   3082 #ifdef notyet
   3083 /* Default single-LED. */
   3084 Static void
   3085 otus_led_newstate_type1(struct otus_softc *sc)
   3086 {
   3087 
   3088 	DPRINTFN(DBG_FN, sc, "\n");
   3089 
   3090 	/* TBD */
   3091 }
   3092 
   3093 /* NETGEAR, dual-LED. */
   3094 Static void
   3095 otus_led_newstate_type2(struct otus_softc *sc)
   3096 {
   3097 
   3098 	DPRINTFN(DBG_FN, sc, "\n");
   3099 
   3100 	/* TBD */
   3101 }
   3102 #endif /* notyet */
   3103 
   3104 /*
   3105  * NETGEAR, single-LED/3 colors (blue, red, purple.)
   3106  */
   3107 Static void
   3108 otus_led_newstate_type3(struct otus_softc *sc)
   3109 {
   3110 	struct ieee80211com *ic;
   3111 	uint32_t led_state;
   3112 
   3113 	DPRINTFN(DBG_FN, sc, "\n");
   3114 
   3115 	ic = &sc->sc_ic;
   3116 	led_state = sc->sc_led_state;
   3117 	switch(ic->ic_state) {
   3118 	case IEEE80211_S_INIT:
   3119 		led_state = 0;
   3120 		break;
   3121 	case IEEE80211_S_SCAN:
   3122 		led_state ^= AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON;
   3123 		led_state &= ~(IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ?
   3124 		    AR_GPIO_REG_DATA_LED1_ON : AR_GPIO_REG_DATA_LED0_ON);
   3125 		break;
   3126 	case IEEE80211_S_AUTH:
   3127 	case IEEE80211_S_ASSOC:
   3128 		/* XXX: Turn both LEDs on for AUTH and ASSOC? */
   3129 		led_state = AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON;
   3130 		break;
   3131 	case IEEE80211_S_RUN:
   3132 		led_state = IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ?
   3133 		    AR_GPIO_REG_DATA_LED0_ON : AR_GPIO_REG_DATA_LED1_ON;
   3134 		break;
   3135 	}
   3136 	if (led_state != sc->sc_led_state) {
   3137 		otus_write(sc, AR_GPIO_REG_DATA, led_state);
   3138 		if (otus_write_barrier(sc) == 0)
   3139 			sc->sc_led_state = led_state;
   3140 	}
   3141 }
   3142 
   3143 Static int
   3144 otus_init(struct ifnet *ifp)
   3145 {
   3146 	struct otus_softc *sc;
   3147 	struct ieee80211com *ic;
   3148 	uint32_t filter, pm_mode, sniffer;
   3149 	int error;
   3150 
   3151 	sc = ifp->if_softc;
   3152 
   3153 	DPRINTFN(DBG_FN|DBG_INIT, sc, "\n");
   3154 
   3155 	ic = &sc->sc_ic;
   3156 
   3157 	mutex_enter(&sc->sc_write_mtx);
   3158 
   3159 	/* Init host command ring. */
   3160 	mutex_spin_enter(&sc->sc_task_mtx);
   3161 	sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0;
   3162 	mutex_spin_exit(&sc->sc_task_mtx);
   3163 
   3164 	if ((error = otus_init_mac(sc)) != 0) {
   3165 		mutex_exit(&sc->sc_write_mtx);
   3166 		aprint_error_dev(sc->sc_dev, "could not initialize MAC\n");
   3167 		return error;
   3168 	}
   3169 
   3170 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
   3171 	(void)otus_set_macaddr(sc, ic->ic_myaddr);
   3172 
   3173 	pm_mode = AR_MAC_REG_POWERMGT_DEFAULTS;
   3174 	sniffer = AR_MAC_REG_SNIFFER_DEFAULTS;
   3175 	filter = AR_MAC_REG_FTF_DEFAULTS;
   3176 	sc->sc_rx_error_msk = ~0;
   3177 
   3178 	switch (ic->ic_opmode) {
   3179 #ifdef notyet
   3180 #ifndef IEEE80211_STA_ONLY
   3181 	case IEEE80211_M_HOSTAP:
   3182 		pm_mode |= AR_MAC_REG_POWERMGT_AP;
   3183 		break;
   3184 	case IEEE80211_M_IBSS:
   3185 		pm_mode |= AR_MAC_REG_POWERMGT_IBSS;	/* XXX: was 0x0 */
   3186 		break;
   3187 #endif
   3188 #endif
   3189 	case IEEE80211_M_STA:
   3190 		pm_mode |= AR_MAC_REG_POWERMGT_STA;
   3191 		break;
   3192 	case IEEE80211_M_MONITOR:
   3193 		sc->sc_rx_error_msk = ~AR_RX_ERROR_BAD_RA;
   3194 		filter = AR_MAC_REG_FTF_MONITOR;
   3195 		sniffer |= AR_MAC_REG_SNIFFER_ENABLE_PROMISC;
   3196 		break;
   3197 	default:
   3198 		aprint_error_dev(sc->sc_dev, "bad opmode: %d", ic->ic_opmode);
   3199 		return EOPNOTSUPP;	/* XXX: ??? */
   3200 	}
   3201 	otus_write(sc, AR_MAC_REG_POWERMANAGEMENT, pm_mode);
   3202 	otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, filter);
   3203 	otus_write(sc, AR_MAC_REG_SNIFFER, sniffer);
   3204 	(void)otus_write_barrier(sc);
   3205 
   3206 	sc->sc_bb_reset = 1;	/* Force cold reset. */
   3207 	if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) {
   3208 		mutex_exit(&sc->sc_write_mtx);
   3209 		aprint_error_dev(sc->sc_dev, "could not set channel\n");
   3210 		return error;
   3211 	}
   3212 
   3213 	/* Start Rx. */
   3214 	otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_ENABLE);
   3215 	(void)otus_write_barrier(sc);
   3216 	mutex_exit(&sc->sc_write_mtx);
   3217 
   3218 	ifp->if_flags &= ~IFF_OACTIVE;
   3219 	ifp->if_flags |= IFF_RUNNING;
   3220 
   3221 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   3222 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   3223 	else
   3224 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   3225 
   3226 	return 0;
   3227 }
   3228 
   3229 Static void
   3230 otus_stop(struct ifnet *ifp)
   3231 {
   3232 	struct otus_softc *sc;
   3233 	struct ieee80211com *ic;
   3234 	int s;
   3235 
   3236 	sc = ifp->if_softc;
   3237 
   3238 	DPRINTFN(DBG_FN, sc, "\n");
   3239 
   3240 	ic = &sc->sc_ic;
   3241 
   3242 	sc->sc_tx_timer = 0;
   3243 	ifp->if_timer = 0;
   3244 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   3245 
   3246 	callout_halt(&sc->sc_scan_to, NULL);
   3247 	callout_halt(&sc->sc_calib_to, NULL);
   3248 
   3249 	s = splusb();
   3250 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   3251 	otus_wait_async(sc);
   3252 	splx(s);
   3253 
   3254 	/* Stop Rx. */
   3255 	mutex_enter(&sc->sc_write_mtx);
   3256 	otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_OFF);
   3257 	(void)otus_write_barrier(sc);
   3258 	mutex_exit(&sc->sc_write_mtx);
   3259 }
   3260