Home | History | Annotate | Line # | Download | only in usb
if_otus.c revision 1.39
      1 /*	$NetBSD: if_otus.c,v 1.39 2019/09/14 12:37:34 maxv 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.39 2019/09/14 12:37:34 maxv 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 	mutex_init(&sc->sc_cmd_mtx,   MUTEX_DEFAULT, IPL_NONE);
    634 	mutex_init(&sc->sc_task_mtx,  MUTEX_DEFAULT, IPL_NET);
    635 	mutex_init(&sc->sc_tx_mtx,    MUTEX_DEFAULT, IPL_NONE);
    636 	mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
    637 
    638 	usb_init_task(&sc->sc_task, otus_task, sc, 0);
    639 
    640 	callout_init(&sc->sc_scan_to, 0);
    641 	callout_setfunc(&sc->sc_scan_to, otus_next_scan, sc);
    642 	callout_init(&sc->sc_calib_to, 0);
    643 	callout_setfunc(&sc->sc_calib_to, otus_calib_to, sc);
    644 
    645 	sc->sc_amrr.amrr_min_success_threshold =  1;
    646 	sc->sc_amrr.amrr_max_success_threshold = 10;
    647 
    648 	if (usbd_set_config_no(sc->sc_udev, 1, 0) != 0) {
    649 		aprint_error_dev(sc->sc_dev,
    650 		    "could not set configuration no\n");
    651 		return;
    652 	}
    653 
    654 	/* Get the first interface handle. */
    655 	error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
    656 	if (error != 0) {
    657 		aprint_error_dev(sc->sc_dev,
    658 		    "could not get interface handle\n");
    659 		return;
    660 	}
    661 
    662 	if ((error = otus_open_pipes(sc)) != 0) {
    663 		aprint_error_dev(sc->sc_dev, "could not open pipes\n");
    664 		return;
    665 	}
    666 
    667 	/*
    668 	 * We need the firmware loaded from file system to complete the attach.
    669 	 */
    670 	config_mountroot(self, otus_attachhook);
    671 
    672 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
    673 }
    674 
    675 Static void
    676 otus_wait_async(struct otus_softc *sc)
    677 {
    678 
    679 	DPRINTFN(DBG_FN, sc, "\n");
    680 
    681 	while (sc->sc_cmdq.queued > 0)
    682 		tsleep(&sc->sc_cmdq, 0, "sc_cmdq", 0);
    683 }
    684 
    685 Static int
    686 otus_detach(device_t self, int flags)
    687 {
    688 	struct otus_softc *sc;
    689 	struct ifnet *ifp;
    690 	int s;
    691 
    692 	sc = device_private(self);
    693 
    694 	DPRINTFN(DBG_FN, sc, "\n");
    695 
    696 	s = splusb();
    697 
    698 	sc->sc_dying = 1;
    699 
    700 	ifp = sc->sc_ic.ic_ifp;
    701 	if (ifp != NULL)	/* Failed to attach properly */
    702 		otus_stop(ifp);
    703 
    704 	usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
    705 	callout_destroy(&sc->sc_scan_to);
    706 	callout_destroy(&sc->sc_calib_to);
    707 
    708 	if (ifp && ifp->if_flags != 0) { /* if_attach() has been called. */
    709 		ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
    710 		bpf_detach(ifp);
    711 		ieee80211_ifdetach(&sc->sc_ic);
    712 		if_detach(ifp);
    713 	}
    714 	otus_close_pipes(sc);
    715 	splx(s);
    716 
    717 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
    718 
    719 	mutex_destroy(&sc->sc_write_mtx);
    720 	mutex_destroy(&sc->sc_tx_mtx);
    721 	mutex_destroy(&sc->sc_task_mtx);
    722 	mutex_destroy(&sc->sc_cmd_mtx);
    723 	return 0;
    724 }
    725 
    726 Static int
    727 otus_activate(device_t self, devact_t act)
    728 {
    729 	struct otus_softc *sc;
    730 
    731 	sc = device_private(self);
    732 
    733 	DPRINTFN(DBG_FN, sc, "%d\n", act);
    734 
    735 	switch (act) {
    736 	case DVACT_DEACTIVATE:
    737 		sc->sc_dying = 1;
    738 		if_deactivate(sc->sc_ic.ic_ifp);
    739 		return 0;
    740 	default:
    741 		return EOPNOTSUPP;
    742 	}
    743 }
    744 
    745 Static void
    746 otus_attachhook(device_t arg)
    747 {
    748 	struct otus_softc *sc;
    749 	struct ieee80211com *ic;
    750 	struct ifnet *ifp;
    751 	usb_device_request_t req;
    752 	uint32_t in, out;
    753 	int error;
    754 
    755 	sc = device_private(arg);
    756 
    757 	DPRINTFN(DBG_FN, sc, "\n");
    758 
    759 	ic = &sc->sc_ic;
    760 	ifp = &sc->sc_if;
    761 
    762 	error = otus_load_firmware(sc, "otus-init", AR_FW_INIT_ADDR);
    763 	if (error != 0) {
    764 		aprint_error_dev(sc->sc_dev, "could not load init firmware\n");
    765 		return;
    766 	}
    767 	usbd_delay_ms(sc->sc_udev, 1000);
    768 
    769 	error = otus_load_firmware(sc, "otus-main", AR_FW_MAIN_ADDR);
    770 	if (error != 0) {
    771 		aprint_error_dev(sc->sc_dev, "could not load main firmware\n");
    772 		return;
    773 	}
    774 
    775 	/* Tell device that firmware transfer is complete. */
    776 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    777 	req.bRequest = AR_FW_DOWNLOAD_COMPLETE;
    778 	USETW(req.wValue, 0);
    779 	USETW(req.wIndex, 0);
    780 	USETW(req.wLength, 0);
    781 	if (usbd_do_request(sc->sc_udev, &req, NULL) != 0) {
    782 		aprint_error_dev(sc->sc_dev,
    783 		    "firmware initialization failed\n");
    784 		return;
    785 	}
    786 
    787 	/* Send an ECHO command to check that everything is settled. */
    788 	in = 0xbadc0ffe;
    789 	if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof(in), &out) != 0) {
    790 		aprint_error_dev(sc->sc_dev, "echo command failed\n");
    791 		return;
    792 	}
    793 	if (in != out) {
    794 		aprint_error_dev(sc->sc_dev,
    795 		    "echo reply mismatch: 0x%08x!=0x%08x\n", in, out);
    796 		return;
    797 	}
    798 
    799 	/* Read entire EEPROM. */
    800 	if (otus_read_eeprom(sc) != 0) {
    801 		aprint_error_dev(sc->sc_dev, "could not read EEPROM\n");
    802 		return;
    803 	}
    804 
    805 	sc->sc_txmask = sc->sc_eeprom.baseEepHeader.txMask;
    806 	sc->sc_rxmask = sc->sc_eeprom.baseEepHeader.rxMask;
    807 	sc->sc_capflags = sc->sc_eeprom.baseEepHeader.opCapFlags;
    808 	IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_eeprom.baseEepHeader.macAddr);
    809 	sc->sc_led_newstate = otus_led_newstate_type3;	/* XXX */
    810 
    811 	aprint_normal_dev(sc->sc_dev,
    812 	    "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n",
    813 	    (sc->sc_capflags & AR5416_OPFLAGS_11A) ?
    814 		0x9104 : ((sc->sc_txmask == 0x5) ? 0x9102 : 0x9101),
    815 	    (sc->sc_txmask == 0x5) ? 2 : 1, (sc->sc_rxmask == 0x5) ? 2 : 1,
    816 	    ether_sprintf(ic->ic_myaddr));
    817 
    818 	/*
    819 	 * Setup the 802.11 device.
    820 	 */
    821 	ic->ic_ifp = ifp;
    822 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
    823 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
    824 	ic->ic_state = IEEE80211_S_INIT;
    825 
    826 	/* Set device capabilities. */
    827 	ic->ic_caps =
    828 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
    829 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
    830 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
    831 	    IEEE80211_C_WPA;		/* 802.11i */
    832 
    833 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
    834 		/* Set supported .11b and .11g rates. */
    835 		ic->ic_sup_rates[IEEE80211_MODE_11B] =
    836 		    ieee80211_std_rateset_11b;
    837 		ic->ic_sup_rates[IEEE80211_MODE_11G] =
    838 		    ieee80211_std_rateset_11g;
    839 	}
    840 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
    841 		/* Set supported .11a rates. */
    842 		ic->ic_sup_rates[IEEE80211_MODE_11A] =
    843 		    ieee80211_std_rateset_11a;
    844 	}
    845 
    846 	/* Build the list of supported channels. */
    847 	otus_get_chanlist(sc);
    848 
    849 	ifp->if_softc = sc;
    850 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    851 	ifp->if_init  = otus_init;
    852 	ifp->if_ioctl = otus_ioctl;
    853 	ifp->if_start = otus_start;
    854 	ifp->if_watchdog = otus_watchdog;
    855 	IFQ_SET_READY(&ifp->if_snd);
    856 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    857 
    858 	if_attach(ifp);
    859 
    860 	ieee80211_ifattach(ic);
    861 
    862 	ic->ic_node_alloc = otus_node_alloc;
    863 	ic->ic_newassoc	  = otus_newassoc;
    864 	ic->ic_updateslot = otus_updateslot;
    865 #ifdef HAVE_EDCA
    866 	ic->ic_updateedca = otus_updateedca;
    867 #endif /* HAVE_EDCA */
    868 #ifdef notyet
    869 	ic->ic_set_key = otus_set_key;
    870 	ic->ic_delete_key = otus_delete_key;
    871 #endif /* notyet */
    872 
    873 	/* Override state transition machine. */
    874 	sc->sc_newstate = ic->ic_newstate;
    875 	ic->ic_newstate = otus_newstate;
    876 	ieee80211_media_init(ic, otus_media_change, ieee80211_media_status);
    877 
    878 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
    879 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
    880 	    &sc->sc_drvbpf);
    881 
    882 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
    883 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
    884 	sc->sc_rxtap.wr_ihdr.it_present = htole32(OTUS_RX_RADIOTAP_PRESENT);
    885 
    886 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
    887 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
    888 	sc->sc_txtap.wt_ihdr.it_present = htole32(OTUS_TX_RADIOTAP_PRESENT);
    889 
    890 	ieee80211_announce(ic);
    891 }
    892 
    893 Static void
    894 otus_get_chanlist(struct otus_softc *sc)
    895 {
    896 	struct ieee80211com *ic;
    897 	uint8_t chan;
    898 	int i;
    899 
    900 #ifdef OTUS_DEBUG
    901 	/* XXX regulatory domain. */
    902 	uint16_t domain = le16toh(sc->sc_eeprom.baseEepHeader.regDmn[0]);
    903 
    904 	DPRINTFN(DBG_FN | DBG_INIT, sc, "regdomain=0x%04x\n", domain);
    905 #endif
    906 
    907 	ic = &sc->sc_ic;
    908 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
    909 		for (i = 0; i < 14; i++) {
    910 			chan = ar_chans[i];
    911 			ic->ic_channels[chan].ic_freq =
    912 			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
    913 			ic->ic_channels[chan].ic_flags =
    914 			    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
    915 			    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
    916 		}
    917 	}
    918 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
    919 		for (i = 14; i < __arraycount(ar_chans); i++) {
    920 			chan = ar_chans[i];
    921 			ic->ic_channels[chan].ic_freq =
    922 			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
    923 			ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
    924 		}
    925 	}
    926 }
    927 
    928 Static int
    929 otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr)
    930 {
    931 	usb_device_request_t req;
    932 	firmware_handle_t fh;
    933 	uint8_t *ptr;
    934 	uint8_t *fw;
    935 	size_t size;
    936 	int mlen, error;
    937 
    938 	DPRINTFN(DBG_FN, sc, "\n");
    939 
    940 	if ((error = firmware_open("if_otus", name, &fh)) != 0)
    941 		return error;
    942 
    943 	size = firmware_get_size(fh);
    944 	if ((fw = firmware_malloc(size)) == NULL) {
    945 		firmware_close(fh);
    946 		return ENOMEM;
    947 	}
    948 	if ((error = firmware_read(fh, 0, fw, size)) != 0)
    949 		firmware_free(fw, size);
    950 	firmware_close(fh);
    951 	if (error)
    952 		return error;
    953 
    954 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
    955 	req.bRequest = AR_FW_DOWNLOAD;
    956 	USETW(req.wIndex, 0);
    957 
    958 	ptr = fw;
    959 	addr >>= 8;
    960 	while (size > 0) {
    961 		mlen = MIN(size, 4096);
    962 
    963 		USETW(req.wValue, addr);
    964 		USETW(req.wLength, mlen);
    965 		if (usbd_do_request(sc->sc_udev, &req, ptr) != 0) {
    966 			error = EIO;
    967 			break;
    968 		}
    969 		addr += mlen >> 8;
    970 		ptr  += mlen;
    971 		size -= mlen;
    972 	}
    973 	free(fw, M_DEVBUF);
    974 	return error;
    975 }
    976 
    977 Static int
    978 otus_open_pipes(struct otus_softc *sc)
    979 {
    980 	usb_endpoint_descriptor_t *ed;
    981 	int i, error;
    982 
    983 	DPRINTFN(DBG_FN, sc, "\n");
    984 
    985 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_RX_NO, 0,
    986 	    &sc->sc_data_rx_pipe);
    987 	if (error != 0) {
    988 		aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe\n");
    989 		goto fail;
    990 	}
    991 
    992 	ed = usbd_get_endpoint_descriptor(sc->sc_iface, AR_EPT_INTR_RX_NO);
    993 	if (ed == NULL) {
    994 		aprint_error_dev(sc->sc_dev,
    995 		    "could not retrieve Rx intr pipe descriptor\n");
    996 		goto fail;
    997 	}
    998 	sc->sc_ibuf_size = UGETW(ed->wMaxPacketSize);
    999 	if (sc->sc_ibuf_size == 0) {
   1000 		aprint_error_dev(sc->sc_dev,
   1001 		    "invalid Rx intr pipe descriptor\n");
   1002 		goto fail;
   1003 	}
   1004 	sc->sc_ibuf = kmem_alloc(sc->sc_ibuf_size, KM_SLEEP);
   1005 	error = usbd_open_pipe_intr(sc->sc_iface, AR_EPT_INTR_RX_NO,
   1006 	    USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf,
   1007 	    sc->sc_ibuf_size, otus_intr, USBD_DEFAULT_INTERVAL);
   1008 	if (error != 0) {
   1009 		aprint_error_dev(sc->sc_dev, "could not open Rx intr pipe\n");
   1010 		goto fail;
   1011 	}
   1012 
   1013 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_TX_NO, 0,
   1014 	    &sc->sc_data_tx_pipe);
   1015 	if (error != 0) {
   1016 		aprint_error_dev(sc->sc_dev, "could not open Tx bulk pipe\n");
   1017 		goto fail;
   1018 	}
   1019 
   1020 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_INTR_TX_NO, 0,
   1021 	    &sc->sc_cmd_tx_pipe);
   1022 	if (error != 0) {
   1023 		aprint_error_dev(sc->sc_dev, "could not open Tx intr pipe\n");
   1024 		goto fail;
   1025 	}
   1026 
   1027 	if (otus_alloc_tx_cmd(sc) != 0) {
   1028 		aprint_error_dev(sc->sc_dev,
   1029 		    "could not allocate command xfer\n");
   1030 		goto fail;
   1031 	}
   1032 
   1033 	if (otus_alloc_tx_data_list(sc)) {
   1034 		aprint_error_dev(sc->sc_dev, "could not allocate Tx xfers\n");
   1035 		goto fail;
   1036 	}
   1037 
   1038 	if (otus_alloc_rx_data_list(sc)) {
   1039 		aprint_error_dev(sc->sc_dev, "could not allocate Rx xfers\n");
   1040 		goto fail;
   1041 	}
   1042 
   1043 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) {
   1044 		struct otus_rx_data *data = &sc->sc_rx_data[i];
   1045 
   1046 		usbd_setup_xfer(data->xfer, data, data->buf, OTUS_RXBUFSZ,
   1047 		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof);
   1048 		error = usbd_transfer(data->xfer);
   1049 		if (error != USBD_IN_PROGRESS && error != 0) {
   1050 			aprint_error_dev(sc->sc_dev,
   1051 			    "could not queue Rx xfer\n");
   1052 			goto fail;
   1053 		}
   1054 	}
   1055 	return 0;
   1056 
   1057  fail:	otus_close_pipes(sc);
   1058 	return error;
   1059 }
   1060 
   1061 Static void
   1062 otus_close_pipes(struct otus_softc *sc)
   1063 {
   1064 
   1065 	DPRINTFN(DBG_FN, sc, "\n");
   1066 
   1067 	otus_free_tx_cmd(sc);
   1068 	otus_free_tx_data_list(sc);
   1069 	otus_free_rx_data_list(sc);
   1070 
   1071 	if (sc->sc_data_rx_pipe != NULL)
   1072 		usbd_close_pipe(sc->sc_data_rx_pipe);
   1073 	if (sc->sc_cmd_rx_pipe != NULL) {
   1074 		usbd_abort_pipe(sc->sc_cmd_rx_pipe);
   1075 		usbd_close_pipe(sc->sc_cmd_rx_pipe);
   1076 	}
   1077 	if (sc->sc_ibuf != NULL)
   1078 		kmem_free(sc->sc_ibuf, sc->sc_ibuf_size);
   1079 	if (sc->sc_data_tx_pipe != NULL)
   1080 		usbd_close_pipe(sc->sc_data_tx_pipe);
   1081 	if (sc->sc_cmd_tx_pipe != NULL)
   1082 		usbd_close_pipe(sc->sc_cmd_tx_pipe);
   1083 }
   1084 
   1085 Static int
   1086 otus_alloc_tx_cmd(struct otus_softc *sc)
   1087 {
   1088 	struct otus_tx_cmd *cmd;
   1089 
   1090 	DPRINTFN(DBG_FN, sc, "\n");
   1091 
   1092 	cmd = &sc->sc_tx_cmd;
   1093 
   1094 	int error = usbd_create_xfer(sc->sc_cmd_tx_pipe, OTUS_MAX_TXCMDSZ,
   1095 	    USBD_FORCE_SHORT_XFER, 0, &cmd->xfer);
   1096 	if (error)
   1097 		return error;
   1098 
   1099 	cmd->buf = usbd_get_buffer(cmd->xfer);
   1100 
   1101 	return 0;
   1102 }
   1103 
   1104 Static void
   1105 otus_free_tx_cmd(struct otus_softc *sc)
   1106 {
   1107 
   1108 	DPRINTFN(DBG_FN, sc, "\n");
   1109 
   1110 	if (sc->sc_cmd_tx_pipe == NULL)
   1111 		return;
   1112 
   1113 	/* Make sure no transfers are pending. */
   1114 	usbd_abort_pipe(sc->sc_cmd_tx_pipe);
   1115 
   1116 	mutex_enter(&sc->sc_cmd_mtx);
   1117 	if (sc->sc_tx_cmd.xfer != NULL)
   1118 		usbd_destroy_xfer(sc->sc_tx_cmd.xfer);
   1119 	sc->sc_tx_cmd.xfer = NULL;
   1120 	sc->sc_tx_cmd.buf  = NULL;
   1121 	mutex_exit(&sc->sc_cmd_mtx);
   1122 }
   1123 
   1124 Static int
   1125 otus_alloc_tx_data_list(struct otus_softc *sc)
   1126 {
   1127 	struct otus_tx_data *data;
   1128 	int i, error;
   1129 
   1130 	DPRINTFN(DBG_FN, sc, "\n");
   1131 
   1132 	mutex_enter(&sc->sc_tx_mtx);
   1133 	error = 0;
   1134 	TAILQ_INIT(&sc->sc_tx_free_list);
   1135 	for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) {
   1136 		data = &sc->sc_tx_data[i];
   1137 
   1138 		data->sc = sc;	/* Backpointer for callbacks. */
   1139 
   1140 		error = usbd_create_xfer(sc->sc_data_tx_pipe, OTUS_TXBUFSZ,
   1141 		    USBD_FORCE_SHORT_XFER, 0, &data->xfer);
   1142 		if (error) {
   1143 			aprint_error_dev(sc->sc_dev,
   1144 			    "could not allocate xfer\n");
   1145 			break;
   1146 		}
   1147 		data->buf = usbd_get_buffer(data->xfer);
   1148 		/* Append this Tx buffer to our free list. */
   1149 		TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
   1150 	}
   1151 	if (error != 0)
   1152 		otus_free_tx_data_list(sc);
   1153 	mutex_exit(&sc->sc_tx_mtx);
   1154 	return error;
   1155 }
   1156 
   1157 Static void
   1158 otus_free_tx_data_list(struct otus_softc *sc)
   1159 {
   1160 	int i;
   1161 
   1162 	DPRINTFN(DBG_FN, sc, "\n");
   1163 
   1164 	if (sc->sc_data_tx_pipe == NULL)
   1165 		return;
   1166 
   1167 	/* Make sure no transfers are pending. */
   1168 	usbd_abort_pipe(sc->sc_data_tx_pipe);
   1169 
   1170 	for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) {
   1171 		if (sc->sc_tx_data[i].xfer != NULL)
   1172 			usbd_destroy_xfer(sc->sc_tx_data[i].xfer);
   1173 	}
   1174 }
   1175 
   1176 Static int
   1177 otus_alloc_rx_data_list(struct otus_softc *sc)
   1178 {
   1179 	struct otus_rx_data *data;
   1180 	int i, error;
   1181 
   1182 	DPRINTFN(DBG_FN, sc, "\n");
   1183 
   1184 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) {
   1185 		data = &sc->sc_rx_data[i];
   1186 
   1187 		data->sc = sc;	/* Backpointer for callbacks. */
   1188 
   1189 		error = usbd_create_xfer(sc->sc_data_rx_pipe, OTUS_RXBUFSZ,
   1190 		   0, 0, &data->xfer);
   1191 
   1192 		if (error) {
   1193 			aprint_error_dev(sc->sc_dev,
   1194 			    "could not allocate xfer\n");
   1195 			goto fail;
   1196 		}
   1197 		data->buf = usbd_get_buffer(data->xfer);
   1198 	}
   1199 	return 0;
   1200 
   1201 fail:	otus_free_rx_data_list(sc);
   1202 	return error;
   1203 }
   1204 
   1205 Static void
   1206 otus_free_rx_data_list(struct otus_softc *sc)
   1207 {
   1208 	int i;
   1209 
   1210 	DPRINTFN(DBG_FN, sc, "\n");
   1211 
   1212 	if (sc->sc_data_rx_pipe == NULL)
   1213 		return;
   1214 
   1215 	/* Make sure no transfers are pending. */
   1216 	usbd_abort_pipe(sc->sc_data_rx_pipe);
   1217 
   1218 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++)
   1219 		if (sc->sc_rx_data[i].xfer != NULL)
   1220 			usbd_destroy_xfer(sc->sc_rx_data[i].xfer);
   1221 }
   1222 
   1223 Static void
   1224 otus_next_scan(void *arg)
   1225 {
   1226 	struct otus_softc *sc;
   1227 
   1228 	sc = arg;
   1229 
   1230 	DPRINTFN(DBG_FN, sc, "\n");
   1231 
   1232 	if (sc->sc_dying)
   1233 		return;
   1234 
   1235 	if (sc->sc_ic.ic_state == IEEE80211_S_SCAN)
   1236 		ieee80211_next_scan(&sc->sc_ic);
   1237 }
   1238 
   1239 Static void
   1240 otus_task(void *arg)
   1241 {
   1242 	struct otus_softc *sc;
   1243 	struct otus_host_cmd_ring *ring;
   1244 	struct otus_host_cmd *cmd;
   1245 	int s;
   1246 
   1247 	sc = arg;
   1248 
   1249 	DPRINTFN(DBG_FN, sc, "\n");
   1250 
   1251 	/* Process host commands. */
   1252 	s = splusb();
   1253 	mutex_spin_enter(&sc->sc_task_mtx);
   1254 	ring = &sc->sc_cmdq;
   1255 	while (ring->next != ring->cur) {
   1256 		cmd = &ring->cmd[ring->next];
   1257 		mutex_spin_exit(&sc->sc_task_mtx);
   1258 		splx(s);
   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 		s = splusb();
   1266 		mutex_spin_enter(&sc->sc_task_mtx);
   1267 		ring->queued--;
   1268 		ring->next = (ring->next + 1) % OTUS_HOST_CMD_RING_COUNT;
   1269 	}
   1270 	mutex_spin_exit(&sc->sc_task_mtx);
   1271 	wakeup(ring);
   1272 	splx(s);
   1273 }
   1274 
   1275 Static void
   1276 otus_do_async(struct otus_softc *sc, void (*cb)(struct otus_softc *, void *),
   1277     void *arg, int len)
   1278 {
   1279 	struct otus_host_cmd_ring *ring;
   1280 	struct otus_host_cmd *cmd;
   1281 	int s;
   1282 
   1283 	DPRINTFN(DBG_FN, sc, "cb=%p\n", cb);
   1284 
   1285 
   1286 	s = splusb();
   1287 	mutex_spin_enter(&sc->sc_task_mtx);
   1288 	ring = &sc->sc_cmdq;
   1289 	cmd = &ring->cmd[ring->cur];
   1290 	cmd->cb = cb;
   1291 	KASSERT(len <= sizeof(cmd->data));
   1292 	memcpy(cmd->data, arg, len);
   1293 	ring->cur = (ring->cur + 1) % OTUS_HOST_CMD_RING_COUNT;
   1294 
   1295 	/* If there is no pending command already, schedule a task. */
   1296 	if (++ring->queued == 1) {
   1297 		mutex_spin_exit(&sc->sc_task_mtx);
   1298 		usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
   1299 	}
   1300 	else
   1301 		mutex_spin_exit(&sc->sc_task_mtx);
   1302 	wakeup(ring);
   1303 	splx(s);
   1304 }
   1305 
   1306 Static int
   1307 otus_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   1308 {
   1309 	struct otus_softc *sc;
   1310 	struct otus_cmd_newstate cmd;
   1311 
   1312 	sc = ic->ic_ifp->if_softc;
   1313 
   1314 	DPRINTFN(DBG_FN | DBG_STM, sc, "nstate=%s(%d), arg=%d\n",
   1315 	    ieee80211_state_name[nstate], nstate, arg);
   1316 
   1317 	/* Do it in a process context. */
   1318 	cmd.state = nstate;
   1319 	cmd.arg = arg;
   1320 	otus_do_async(sc, otus_newstate_cb, &cmd, sizeof(cmd));
   1321 	return 0;
   1322 }
   1323 
   1324 Static void
   1325 otus_newstate_cb(struct otus_softc *sc, void *arg)
   1326 {
   1327 	struct otus_cmd_newstate *cmd;
   1328 	struct ieee80211com *ic;
   1329 	struct ieee80211_node *ni;
   1330 	enum ieee80211_state nstate;
   1331 	int s;
   1332 
   1333 	cmd = arg;
   1334 	ic = &sc->sc_ic;
   1335 	ni = ic->ic_bss;
   1336 	nstate = cmd->state;
   1337 
   1338 #ifdef OTUS_DEBUG
   1339 	enum ieee80211_state ostate = ostate = ic->ic_state;
   1340 	DPRINTFN(DBG_FN | DBG_STM, sc, "%s(%d)->%s(%d)\n",
   1341 	    ieee80211_state_name[ostate], ostate,
   1342 	    ieee80211_state_name[nstate], nstate);
   1343 #endif
   1344 
   1345 	s = splnet();
   1346 
   1347 	callout_halt(&sc->sc_scan_to, NULL);
   1348 	callout_halt(&sc->sc_calib_to, NULL);
   1349 
   1350 	mutex_enter(&sc->sc_write_mtx);
   1351 
   1352 	switch (nstate) {
   1353 	case IEEE80211_S_INIT:
   1354 		break;
   1355 
   1356 	case IEEE80211_S_SCAN:
   1357 		otus_set_chan(sc, ic->ic_curchan, 0);
   1358 		if (!sc->sc_dying)
   1359 			callout_schedule(&sc->sc_scan_to, hz / 5);
   1360 		break;
   1361 
   1362 	case IEEE80211_S_AUTH:
   1363 	case IEEE80211_S_ASSOC:
   1364 		otus_set_chan(sc, ic->ic_curchan, 0);
   1365 		break;
   1366 
   1367 	case IEEE80211_S_RUN:
   1368 		otus_set_chan(sc, ic->ic_curchan, 1);
   1369 
   1370 		switch (ic->ic_opmode) {
   1371 		case IEEE80211_M_STA:
   1372 			otus_updateslot_cb_locked(sc);
   1373 			otus_set_bssid(sc, ni->ni_bssid);
   1374 
   1375 			/* Fake a join to init the Tx rate. */
   1376 			otus_newassoc(ni, 1);
   1377 
   1378 			/* Start calibration timer. */
   1379 			if (!sc->sc_dying)
   1380 				callout_schedule(&sc->sc_calib_to, hz);
   1381 			break;
   1382 
   1383 		case IEEE80211_M_IBSS:
   1384 		case IEEE80211_M_AHDEMO:
   1385 		case IEEE80211_M_HOSTAP:
   1386 		case IEEE80211_M_MONITOR:
   1387 			break;
   1388 		}
   1389 		break;
   1390 	}
   1391 	(void)sc->sc_newstate(ic, nstate, cmd->arg);
   1392 	sc->sc_led_newstate(sc);
   1393 	mutex_exit(&sc->sc_write_mtx);
   1394 
   1395 	splx(s);
   1396 }
   1397 
   1398 Static int
   1399 otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen,
   1400     void *odata)
   1401 {
   1402 	struct otus_tx_cmd *cmd;
   1403 	struct ar_cmd_hdr *hdr;
   1404 	int s, xferlen, error;
   1405 
   1406 	DPRINTFN(DBG_FN, sc, "\n");
   1407 
   1408 	cmd = &sc->sc_tx_cmd;
   1409 
   1410 	mutex_enter(&sc->sc_cmd_mtx);
   1411 
   1412 	/* Always bulk-out a multiple of 4 bytes. */
   1413 	xferlen = roundup2(sizeof(*hdr) + ilen, 4);
   1414 
   1415 	hdr = (void *)cmd->buf;
   1416 	if (hdr == NULL) {	/* we may have been freed while detaching */
   1417 		mutex_exit(&sc->sc_cmd_mtx);
   1418 		DPRINTFN(DBG_CMD, sc, "tx_cmd freed with commands pending\n");
   1419 		return 0;
   1420 	}
   1421 	hdr->code  = code;
   1422 	hdr->len   = ilen;
   1423 	hdr->token = ++cmd->token;	/* Don't care about endianness. */
   1424 	KASSERT(sizeof(hdr) + ilen <= OTUS_MAX_TXCMDSZ);
   1425 	memcpy(cmd->buf + sizeof(hdr[0]), idata, ilen);
   1426 
   1427 	DPRINTFN(DBG_CMD, sc, "sending command code=0x%02x len=%d token=%d\n",
   1428 	    code, ilen, hdr->token);
   1429 
   1430 	s = splusb();
   1431 	cmd->odata = odata;
   1432 	cmd->done = 0;
   1433 	usbd_setup_xfer(cmd->xfer, cmd, cmd->buf, xferlen,
   1434 	    USBD_FORCE_SHORT_XFER, OTUS_CMD_TIMEOUT, NULL);
   1435 	error = usbd_sync_transfer(cmd->xfer);
   1436 	if (error != 0) {
   1437 		splx(s);
   1438 		mutex_exit(&sc->sc_cmd_mtx);
   1439 #if defined(DIAGNOSTIC) || defined(OTUS_DEBUG)	/* XXX: kill some noise */
   1440 		aprint_error_dev(sc->sc_dev,
   1441 		    "could not send command 0x%x (error=%s)\n",
   1442 		    code, usbd_errstr(error));
   1443 #endif
   1444 		return EIO;
   1445 	}
   1446 	if (!cmd->done)
   1447 		error = tsleep(cmd, PCATCH, "otuscmd", hz);
   1448 	cmd->odata = NULL;	/* In case answer is received too late. */
   1449 	splx(s);
   1450 	mutex_exit(&sc->sc_cmd_mtx);
   1451 	if (error != 0) {
   1452 		aprint_error_dev(sc->sc_dev,
   1453 		    "timeout waiting for command 0x%02x reply\n", code);
   1454 	}
   1455 	return error;
   1456 }
   1457 
   1458 Static void
   1459 otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val)
   1460 {
   1461 
   1462 	DPRINTFN(DBG_FN | DBG_REG, sc, "reg=0x%x, val=0x%x\n", reg, val);
   1463 
   1464 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   1465 	KASSERT(sc->sc_write_idx < __arraycount(sc->sc_write_buf));
   1466 
   1467 	sc->sc_write_buf[sc->sc_write_idx].reg = htole32(reg);
   1468 	sc->sc_write_buf[sc->sc_write_idx].val = htole32(val);
   1469 
   1470 	if (++sc->sc_write_idx >= __arraycount(sc->sc_write_buf))
   1471 		(void)otus_write_barrier(sc);
   1472 }
   1473 
   1474 Static int
   1475 otus_write_barrier(struct otus_softc *sc)
   1476 {
   1477 	int error;
   1478 
   1479 	DPRINTFN(DBG_FN, sc, "\n");
   1480 
   1481 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   1482 	KASSERT(sc->sc_write_idx <= __arraycount(sc->sc_write_buf));
   1483 
   1484 	if (sc->sc_write_idx == 0)
   1485 		return 0;	/* Nothing to flush. */
   1486 
   1487 	error = otus_cmd(sc, AR_CMD_WREG, sc->sc_write_buf,
   1488 	    sizeof(sc->sc_write_buf[0]) * sc->sc_write_idx, NULL);
   1489 
   1490 	sc->sc_write_idx = 0;
   1491 	if (error)
   1492 		DPRINTFN(DBG_REG, sc, "error=%d\n", error);
   1493 	return error;
   1494 }
   1495 
   1496 Static struct ieee80211_node *
   1497 otus_node_alloc(struct ieee80211_node_table *ntp)
   1498 {
   1499 	struct otus_node *on;
   1500 
   1501 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
   1502 
   1503 	on = malloc(sizeof(*on), M_DEVBUF, M_NOWAIT | M_ZERO);
   1504 	return &on->ni;
   1505 }
   1506 
   1507 Static int
   1508 otus_media_change(struct ifnet *ifp)
   1509 {
   1510 	struct otus_softc *sc;
   1511 	struct ieee80211com *ic;
   1512 	uint8_t rate, ridx;
   1513 	int error;
   1514 
   1515 	sc = ifp->if_softc;
   1516 
   1517 	DPRINTFN(DBG_FN, sc, "\n");
   1518 
   1519 	error = ieee80211_media_change(ifp);
   1520 	if (error != ENETRESET)
   1521 		return error;
   1522 
   1523 	ic = &sc->sc_ic;
   1524 	if (ic->ic_fixed_rate != -1) {
   1525 		rate = ic->ic_sup_rates[ic->ic_curmode].
   1526 		    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
   1527 		for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
   1528 			if (otus_rates[ridx].rate == rate)
   1529 				break;
   1530 		sc->sc_fixed_ridx = ridx;
   1531 	}
   1532 
   1533 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
   1534 		error = otus_init(ifp);
   1535 
   1536 	return error;
   1537 }
   1538 
   1539 Static int
   1540 otus_read_eeprom(struct otus_softc *sc)
   1541 {
   1542 	uint32_t regs[8], reg;
   1543 	uint8_t *eep;
   1544 	int i, j, error;
   1545 
   1546 	DPRINTFN(DBG_FN, sc, "\n");
   1547 
   1548 	KASSERT(sizeof(sc->sc_eeprom) % 32 == 0);
   1549 
   1550 	/* Read EEPROM by blocks of 32 bytes. */
   1551 	eep = (uint8_t *)&sc->sc_eeprom;
   1552 	reg = AR_EEPROM_OFFSET;
   1553 	for (i = 0; i < sizeof(sc->sc_eeprom) / 32; i++) {
   1554 		for (j = 0; j < 8; j++, reg += 4)
   1555 			regs[j] = htole32(reg);
   1556 		error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof(regs), eep);
   1557 		if (error != 0)
   1558 			break;
   1559 		eep += 32;
   1560 	}
   1561 	return error;
   1562 }
   1563 
   1564 Static void
   1565 otus_newassoc(struct ieee80211_node *ni, int isnew)
   1566 {
   1567 	struct ieee80211_rateset *rs;
   1568 	struct otus_softc *sc;
   1569 	struct otus_node *on;
   1570 	uint8_t rate;
   1571 	int ridx, i;
   1572 
   1573 	sc = ni->ni_ic->ic_ifp->if_softc;
   1574 
   1575 	DPRINTFN(DBG_FN, sc, "isnew=%d addr=%s\n",
   1576 	    isnew, ether_sprintf(ni->ni_macaddr));
   1577 
   1578 	on = (void *)ni;
   1579 	ieee80211_amrr_node_init(&sc->sc_amrr, &on->amn);
   1580 	/* Start at lowest available bit-rate, AMRR will raise. */
   1581 	ni->ni_txrate = 0;
   1582 	rs = &ni->ni_rates;
   1583 	for (i = 0; i < rs->rs_nrates; i++) {
   1584 		rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
   1585 		/* Convert 802.11 rate to hardware rate index. */
   1586 		for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
   1587 			if (otus_rates[ridx].rate == rate)
   1588 				break;
   1589 		on->ridx[i] = ridx;
   1590 		DPRINTFN(DBG_INIT, sc, "rate=0x%02x ridx=%d\n",
   1591 		    rs->rs_rates[i], on->ridx[i]);
   1592 	}
   1593 }
   1594 
   1595 /* ARGSUSED */
   1596 Static void
   1597 otus_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
   1598 {
   1599 #if 0
   1600 	struct otus_softc *sc;
   1601 	int len;
   1602 
   1603 	sc = priv;
   1604 
   1605 	DPRINTFN(DBG_FN, sc, "\n");
   1606 
   1607 	/*
   1608 	 * The Rx intr pipe is unused with current firmware.  Notifications
   1609 	 * and replies to commands are sent through the Rx bulk pipe instead
   1610 	 * (with a magic PLCP header.)
   1611 	 */
   1612 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
   1613 		DPRINTFN(DBG_INTR, sc, "status=%d\n", status);
   1614 		if (status == USBD_STALLED)
   1615 			usbd_clear_endpoint_stall_async(sc->sc_cmd_rx_pipe);
   1616 		return;
   1617 	}
   1618 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
   1619 
   1620 	otus_cmd_rxeof(sc, sc->sc_ibuf, len);
   1621 #endif
   1622 }
   1623 
   1624 Static void
   1625 otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
   1626 {
   1627 	struct ieee80211com *ic;
   1628 	struct otus_tx_cmd *cmd;
   1629 	struct ar_cmd_hdr *hdr;
   1630 	int s;
   1631 
   1632 	DPRINTFN(DBG_FN, sc, "\n");
   1633 
   1634 	ic = &sc->sc_ic;
   1635 
   1636 	if (__predict_false(len < sizeof(*hdr))) {
   1637 		DPRINTFN(DBG_RX, sc, "cmd too small %d\n", len);
   1638 		return;
   1639 	}
   1640 	hdr = (void *)buf;
   1641 	if (__predict_false(sizeof(*hdr) + hdr->len > len ||
   1642 	    sizeof(*hdr) + hdr->len > 64)) {
   1643 		DPRINTFN(DBG_RX, sc, "cmd too large %d\n", hdr->len);
   1644 		return;
   1645 	}
   1646 
   1647 	if ((hdr->code & 0xc0) != 0xc0) {
   1648 		DPRINTFN(DBG_RX, sc, "received reply code=0x%02x len=%d token=%d\n",
   1649 		    hdr->code, hdr->len, hdr->token);
   1650 		cmd = &sc->sc_tx_cmd;
   1651 		if (__predict_false(hdr->token != cmd->token))
   1652 			return;
   1653 		/* Copy answer into caller's supplied buffer. */
   1654 		if (cmd->odata != NULL)
   1655 			memcpy(cmd->odata, &hdr[1], hdr->len);
   1656 		cmd->done = 1;
   1657 		wakeup(cmd);
   1658 		return;
   1659 	}
   1660 
   1661 	/* Received unsolicited notification. */
   1662 	DPRINTFN(DBG_RX, sc, "received notification code=0x%02x len=%d\n",
   1663 	    hdr->code, hdr->len);
   1664 	switch (hdr->code & 0x3f) {
   1665 	case AR_EVT_BEACON:
   1666 		break;
   1667 	case AR_EVT_TX_COMP:
   1668 	{
   1669 		struct ar_evt_tx_comp *tx;
   1670 		struct ieee80211_node *ni;
   1671 		struct otus_node *on;
   1672 
   1673 		tx = (void *)&hdr[1];
   1674 
   1675 		DPRINTFN(DBG_RX, sc, "tx completed %s status=%d phy=0x%x\n",
   1676 		    ether_sprintf(tx->macaddr), le16toh(tx->status),
   1677 		    le32toh(tx->phy));
   1678 		s = splnet();
   1679 #ifdef notyet
   1680 #ifndef IEEE80211_STA_ONLY
   1681 		if (ic->ic_opmode != IEEE80211_M_STA) {
   1682 			ni = ieee80211_find_node(ic, tx->macaddr);
   1683 			if (__predict_false(ni == NULL)) {
   1684 				splx(s);
   1685 				break;
   1686 			}
   1687 		} else
   1688 #endif
   1689 #endif
   1690 			ni = ic->ic_bss;
   1691 		/* Update rate control statistics. */
   1692 		on = (void *)ni;
   1693 		/* NB: we do not set the TX_MAC_RATE_PROBING flag. */
   1694 		if (__predict_true(tx->status != 0))
   1695 			on->amn.amn_retrycnt++;
   1696 		splx(s);
   1697 		break;
   1698 	}
   1699 	case AR_EVT_TBTT:
   1700 		break;
   1701 	}
   1702 }
   1703 
   1704 Static void
   1705 otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
   1706 {
   1707 	struct ieee80211com *ic;
   1708 	struct ifnet *ifp;
   1709 	struct ieee80211_node *ni;
   1710 	struct ar_rx_tail *tail;
   1711 	struct ieee80211_frame *wh;
   1712 	struct mbuf *m;
   1713 	uint8_t *plcp;
   1714 	int s, mlen, align;
   1715 
   1716 	DPRINTFN(DBG_FN, sc, "\n");
   1717 
   1718 	ic = &sc->sc_ic;
   1719 	ifp = ic->ic_ifp;
   1720 
   1721 	if (__predict_false(len < AR_PLCP_HDR_LEN)) {
   1722 		DPRINTFN(DBG_RX, sc, "sub-xfer too short %d\n", len);
   1723 		return;
   1724 	}
   1725 	plcp = buf;
   1726 
   1727 	/* All bits in the PLCP header are set to 1 for non-MPDU. */
   1728 	if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) {
   1729 		otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN,
   1730 		    len - AR_PLCP_HDR_LEN);
   1731 		return;
   1732 	}
   1733 
   1734 	/* Received MPDU. */
   1735 	if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof(*tail))) {
   1736 		DPRINTFN(DBG_RX, sc, "MPDU too short %d\n", len);
   1737 		ifp->if_ierrors++;
   1738 		return;
   1739 	}
   1740 	tail = (void *)(plcp + len - sizeof(*tail));
   1741 	wh = (void *)(plcp + AR_PLCP_HDR_LEN);
   1742 
   1743 	/* Discard error frames. */
   1744 	if (__predict_false((tail->error & sc->sc_rx_error_msk) != 0)) {
   1745 		DPRINTFN(DBG_RX, sc, "error frame 0x%02x\n", tail->error);
   1746 		if (tail->error & AR_RX_ERROR_FCS) {
   1747 			DPRINTFN(DBG_RX, sc, "bad FCS\n");
   1748 		} else if (tail->error & AR_RX_ERROR_MMIC) {
   1749 			/* Report Michael MIC failures to net80211. */
   1750 			ieee80211_notify_michael_failure(ic, wh, 0 /* XXX: keyix */);
   1751 		}
   1752 		ifp->if_ierrors++;
   1753 		return;
   1754 	}
   1755 	/* Compute MPDU's length. */
   1756 	mlen = len - AR_PLCP_HDR_LEN - sizeof(*tail);
   1757 	mlen -= IEEE80211_CRC_LEN;	/* strip 802.11 FCS */
   1758 	/* Make sure there's room for an 802.11 header. */
   1759 	/*
   1760 	 * XXX: This will drop most control packets.  Do we really
   1761 	 * want this in IEEE80211_M_MONITOR mode?
   1762 	 */
   1763 	if (__predict_false(mlen < sizeof(*wh))) {
   1764 		ifp->if_ierrors++;
   1765 		return;
   1766 	}
   1767 
   1768 	/* Provide a 32-bit aligned protocol header to the stack. */
   1769 	align = (ieee80211_has_qos(wh) ^ ieee80211_has_addr4(wh)) ? 2 : 0;
   1770 
   1771 	MGETHDR(m, M_DONTWAIT, MT_DATA);
   1772 	if (__predict_false(m == NULL)) {
   1773 		ifp->if_ierrors++;
   1774 		return;
   1775 	}
   1776 	if (align + mlen > MHLEN) {
   1777 		MCLGET(m, M_DONTWAIT);
   1778 		if (__predict_false(!(m->m_flags & M_EXT))) {
   1779 			ifp->if_ierrors++;
   1780 			m_freem(m);
   1781 			return;
   1782 		}
   1783 	}
   1784 	/* Finalize mbuf. */
   1785 	m_set_rcvif(m, ifp);
   1786 	m->m_data += align;
   1787 	memcpy(mtod(m, void *), wh, mlen);
   1788 	m->m_pkthdr.len = m->m_len = mlen;
   1789 
   1790 	s = splnet();
   1791 	if (__predict_false(sc->sc_drvbpf != NULL)) {
   1792 		struct otus_rx_radiotap_header *tap;
   1793 
   1794 		tap = &sc->sc_rxtap;
   1795 		tap->wr_flags = 0;
   1796 		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
   1797 		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
   1798 		tap->wr_antsignal = tail->rssi;
   1799 		tap->wr_rate = 2;	/* In case it can't be found below. */
   1800 		switch (tail->status & AR_RX_STATUS_MT_MASK) {
   1801 		case AR_RX_STATUS_MT_CCK:
   1802 			switch (plcp[0]) {
   1803 			case  10: tap->wr_rate =   2; break;
   1804 			case  20: tap->wr_rate =   4; break;
   1805 			case  55: tap->wr_rate =  11; break;
   1806 			case 110: tap->wr_rate =  22; break;
   1807 			}
   1808 			if (tail->status & AR_RX_STATUS_SHPREAMBLE)
   1809 				tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
   1810 			break;
   1811 		case AR_RX_STATUS_MT_OFDM:
   1812 			switch (plcp[0] & 0xf) {
   1813 			case 0xb: tap->wr_rate =  12; break;
   1814 			case 0xf: tap->wr_rate =  18; break;
   1815 			case 0xa: tap->wr_rate =  24; break;
   1816 			case 0xe: tap->wr_rate =  36; break;
   1817 			case 0x9: tap->wr_rate =  48; break;
   1818 			case 0xd: tap->wr_rate =  72; break;
   1819 			case 0x8: tap->wr_rate =  96; break;
   1820 			case 0xc: tap->wr_rate = 108; break;
   1821 			}
   1822 			break;
   1823 		}
   1824 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN);
   1825 	}
   1826 
   1827 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   1828 
   1829 	/* push the frame up to the 802.11 stack */
   1830 	ieee80211_input(ic, m, ni, tail->rssi, 0);
   1831 
   1832 	/* Node is no longer needed. */
   1833 	ieee80211_free_node(ni);
   1834 	splx(s);
   1835 }
   1836 
   1837 Static void
   1838 otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
   1839 {
   1840 	struct otus_rx_data *data;
   1841 	struct otus_softc *sc;
   1842 	uint8_t *buf;
   1843 	struct ar_rx_head *head;
   1844 	uint16_t hlen;
   1845 	int len;
   1846 
   1847 	data = priv;
   1848 	sc = data->sc;
   1849 
   1850 	DPRINTFN(DBG_FN, sc, "\n");
   1851 
   1852 	buf = data->buf;
   1853 
   1854 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
   1855 		DPRINTFN(DBG_RX, sc, "RX status=%d\n", status);
   1856 		if (status == USBD_STALLED)
   1857 			usbd_clear_endpoint_stall_async(sc->sc_data_rx_pipe);
   1858 		else if (status != USBD_CANCELLED) {
   1859 			DPRINTFN(DBG_RX, sc,
   1860 			    "otus_rxeof: goto resubmit: status=%d\n", status);
   1861 			goto resubmit;
   1862 		}
   1863 		return;
   1864 	}
   1865 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
   1866 
   1867 	while (len >= sizeof(*head)) {
   1868 		head = (void *)buf;
   1869 		if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) {
   1870 			DPRINTFN(DBG_RX, sc, "tag not valid 0x%x\n",
   1871 			    le16toh(head->tag));
   1872 			break;
   1873 		}
   1874 		hlen = le16toh(head->len);
   1875 		if (__predict_false(sizeof(*head) + hlen > len)) {
   1876 			DPRINTFN(DBG_RX, sc, "xfer too short %d/%d\n",
   1877 			    len, hlen);
   1878 			break;
   1879 		}
   1880 		/* Process sub-xfer. */
   1881 		otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen);
   1882 
   1883 		/* Next sub-xfer is aligned on a 32-bit boundary. */
   1884 		hlen = roundup2(sizeof(*head) + hlen, 4);
   1885 		buf += hlen;
   1886 		len -= hlen;
   1887 	}
   1888 
   1889  resubmit:
   1890 	usbd_setup_xfer(xfer, data, data->buf, OTUS_RXBUFSZ,
   1891 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof);
   1892 	(void)usbd_transfer(data->xfer);
   1893 }
   1894 
   1895 Static void
   1896 otus_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
   1897 {
   1898 	struct otus_tx_data *data;
   1899 	struct otus_softc *sc;
   1900 	struct ieee80211com *ic;
   1901 	struct ifnet *ifp;
   1902 	int s;
   1903 
   1904 	data = priv;
   1905 	sc = data->sc;
   1906 
   1907 	DPRINTFN(DBG_FN, sc, "\n");
   1908 
   1909 	/* Put this Tx buffer back to the free list. */
   1910 	mutex_enter(&sc->sc_tx_mtx);
   1911 	TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
   1912 	mutex_exit(&sc->sc_tx_mtx);
   1913 
   1914 	ic = &sc->sc_ic;
   1915 	ifp = ic->ic_ifp;
   1916 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
   1917 		DPRINTFN(DBG_TX, sc, "TX status=%d\n", status);
   1918 		if (status == USBD_STALLED)
   1919 			usbd_clear_endpoint_stall_async(sc->sc_data_tx_pipe);
   1920 		ifp->if_oerrors++;
   1921 		return;
   1922 	}
   1923 	ifp->if_opackets++;
   1924 
   1925 	s = splnet();
   1926 	sc->sc_tx_timer = 0;
   1927 	ifp->if_flags &= ~IFF_OACTIVE;	/* XXX: do after freeing Tx buffer? */
   1928 	otus_start(ifp);
   1929 	splx(s);
   1930 }
   1931 
   1932 Static int
   1933 otus_tx(struct otus_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
   1934     struct otus_tx_data *data)
   1935 {
   1936 	struct ieee80211com *ic;
   1937 	struct otus_node *on;
   1938 	struct ieee80211_frame *wh;
   1939 	struct ieee80211_key *k;
   1940 	struct ar_tx_head *head;
   1941 	uint32_t phyctl;
   1942 	uint16_t macctl, qos;
   1943 	uint8_t qid;
   1944 	int error, ridx, hasqos, xferlen;
   1945 
   1946 	DPRINTFN(DBG_FN, sc, "\n");
   1947 
   1948 	ic = &sc->sc_ic;
   1949 	on = (void *)ni;
   1950 
   1951 	wh = mtod(m, struct ieee80211_frame *);
   1952 	if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
   1953 		/* XXX: derived from upgt_tx_task() and ural_tx_data() */
   1954 		k = ieee80211_crypto_encap(ic, ni, m);
   1955 		if (k == NULL)
   1956 			return ENOBUFS;
   1957 
   1958 		/* Packet header may have moved, reset our local pointer. */
   1959 		wh = mtod(m, struct ieee80211_frame *);
   1960 	}
   1961 
   1962 #ifdef HAVE_EDCA
   1963 	if ((hasqos = ieee80211_has_qos(wh))) {
   1964 		qos = ieee80211_get_qos(wh);
   1965 		qid = ieee80211_up_to_ac(ic, qos & IEEE80211_QOS_TID);
   1966 	} else {
   1967 		qos = 0;
   1968 		qid = WME_AC_BE;
   1969 	}
   1970 #else
   1971 	hasqos = 0;
   1972 	qos = 0;
   1973 	qid = WME_AC_BE;
   1974 #endif
   1975 
   1976 	/* Pickup a rate index. */
   1977 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   1978 	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA)
   1979 		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
   1980 		    OTUS_RIDX_OFDM6 : OTUS_RIDX_CCK1;
   1981 	else if (ic->ic_fixed_rate != -1)
   1982 		ridx = sc->sc_fixed_ridx;
   1983 	else
   1984 		ridx = on->ridx[ni->ni_txrate];
   1985 
   1986 	phyctl = 0;
   1987 	macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid);
   1988 
   1989 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
   1990 	    (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY_MASK) ==
   1991 	     IEEE80211_QOS_ACKPOLICY_NOACK)))
   1992 		macctl |= AR_TX_MAC_NOACK;
   1993 
   1994 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
   1995 		if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= ic->ic_rtsthreshold)
   1996 			macctl |= AR_TX_MAC_RTS;
   1997 		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
   1998 		    ridx >= OTUS_RIDX_OFDM6) {
   1999 			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
   2000 				macctl |= AR_TX_MAC_CTS;
   2001 			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
   2002 				macctl |= AR_TX_MAC_RTS;
   2003 		}
   2004 	}
   2005 
   2006 	phyctl |= AR_TX_PHY_MCS(otus_rates[ridx].mcs);
   2007 	if (ridx >= OTUS_RIDX_OFDM6) {
   2008 		phyctl |= AR_TX_PHY_MT_OFDM;
   2009 		if (ridx <= OTUS_RIDX_OFDM24)
   2010 			phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask);
   2011 		else
   2012 			phyctl |= AR_TX_PHY_ANTMSK(1);
   2013 	} else {	/* CCK */
   2014 		phyctl |= AR_TX_PHY_MT_CCK;
   2015 		phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask);
   2016 	}
   2017 
   2018 	/* Update rate control stats for frames that are ACK'ed. */
   2019 	if (!(macctl & AR_TX_MAC_NOACK))
   2020 		on->amn.amn_txcnt++;
   2021 
   2022 	/* Fill Tx descriptor. */
   2023 	head = (void *)data->buf;
   2024 	head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN);
   2025 	head->macctl = htole16(macctl);
   2026 	head->phyctl = htole32(phyctl);
   2027 
   2028 	if (__predict_false(sc->sc_drvbpf != NULL)) {
   2029 		struct otus_tx_radiotap_header *tap = &sc->sc_txtap;
   2030 
   2031 		tap->wt_flags = 0;
   2032 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
   2033 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
   2034 		tap->wt_rate = otus_rates[ridx].rate;
   2035 		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
   2036 		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
   2037 
   2038 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT);
   2039 	}
   2040 
   2041 	xferlen = sizeof(*head) + m->m_pkthdr.len;
   2042 	m_copydata(m, 0, m->m_pkthdr.len, (void *)&head[1]);
   2043 
   2044 	DPRINTFN(DBG_TX, sc, "queued len=%d mac=0x%04x phy=0x%08x rate=%d\n",
   2045 	    head->len, head->macctl, head->phyctl, otus_rates[ridx].rate);
   2046 
   2047 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
   2048 	    USBD_FORCE_SHORT_XFER, OTUS_TX_TIMEOUT, otus_txeof);
   2049 	error = usbd_transfer(data->xfer);
   2050 	if (__predict_false(
   2051 		    error != USBD_NORMAL_COMPLETION &&
   2052 		    error != USBD_IN_PROGRESS)) {
   2053 		DPRINTFN(DBG_TX, sc, "transfer failed %d\n", error);
   2054 		return error;
   2055 	}
   2056 	return 0;
   2057 }
   2058 
   2059 Static void
   2060 otus_start(struct ifnet *ifp)
   2061 {
   2062 	struct otus_softc *sc;
   2063 	struct ieee80211com *ic;
   2064 	struct otus_tx_data *data;
   2065 	struct ether_header *eh;
   2066 	struct ieee80211_node *ni;
   2067 	struct mbuf *m;
   2068 
   2069 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   2070 		return;
   2071 
   2072 	sc = ifp->if_softc;
   2073 	ic = &sc->sc_ic;
   2074 
   2075 	DPRINTFN(DBG_FN, sc, "\n");
   2076 
   2077 	data = NULL;
   2078 	for (;;) {
   2079 		/*
   2080 		 * Grab a Tx buffer if we don't already have one.  If
   2081 		 * one isn't available, bail out.
   2082 		 * NB: We must obtain this Tx buffer _before_
   2083 		 * dequeueing anything as one may not be available
   2084 		 * later.  Both must be done inside a single lock.
   2085 		 */
   2086 		mutex_enter(&sc->sc_tx_mtx);
   2087 		if (data == NULL && !TAILQ_EMPTY(&sc->sc_tx_free_list)) {
   2088 			data = TAILQ_FIRST(&sc->sc_tx_free_list);
   2089 			TAILQ_REMOVE(&sc->sc_tx_free_list, data, next);
   2090 		}
   2091 		mutex_exit(&sc->sc_tx_mtx);
   2092 
   2093 		if (data == NULL) {
   2094 			ifp->if_flags |= IFF_OACTIVE;
   2095 			DPRINTFN(DBG_TX, sc, "empty sc_tx_free_list\n");
   2096 			return;
   2097 		}
   2098 
   2099 		/* Send pending management frames first. */
   2100 		IF_DEQUEUE(&ic->ic_mgtq, m);
   2101 		if (m != NULL) {
   2102 			ni = M_GETCTX(m, struct ieee80211_node *);
   2103 			M_CLEARCTX(m);
   2104 			goto sendit;
   2105 		}
   2106 
   2107 		if (ic->ic_state != IEEE80211_S_RUN)
   2108 			break;
   2109 
   2110 		/* Encapsulate and send data frames. */
   2111 		IFQ_DEQUEUE(&ifp->if_snd, m);
   2112 		if (m == NULL)
   2113 			break;
   2114 
   2115 		if (m->m_len < (int)sizeof(*eh) &&
   2116 		    (m = m_pullup(m, sizeof(*eh))) == NULL) {
   2117 			ifp->if_oerrors++;
   2118 			continue;
   2119 		}
   2120 
   2121 		eh = mtod(m, struct ether_header *);
   2122 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   2123 		if (ni == NULL) {
   2124 			m_freem(m);
   2125 			ifp->if_oerrors++;
   2126 			continue;
   2127 		}
   2128 
   2129 		bpf_mtap(ifp, m, BPF_D_OUT);
   2130 
   2131 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
   2132 			/* original m was freed by ieee80211_encap() */
   2133 			ieee80211_free_node(ni);
   2134 			ifp->if_oerrors++;
   2135 			continue;
   2136 		}
   2137  sendit:
   2138 		bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
   2139 
   2140 		if (otus_tx(sc, m, ni, data) != 0) {
   2141 			m_freem(m);
   2142 			ieee80211_free_node(ni);
   2143 			ifp->if_oerrors++;
   2144 			continue;
   2145 		}
   2146 
   2147 		data = NULL;	/* we're finished with this data buffer */
   2148 		m_freem(m);
   2149 		ieee80211_free_node(ni);
   2150 		sc->sc_tx_timer = 5;
   2151 		ifp->if_timer = 1;
   2152 	}
   2153 
   2154 	/*
   2155 	 * If here, we have a Tx buffer, but ran out of mbufs to
   2156 	 * transmit.  Put the Tx buffer back to the free list.
   2157 	 */
   2158 	mutex_enter(&sc->sc_tx_mtx);
   2159 	TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
   2160 	mutex_exit(&sc->sc_tx_mtx);
   2161 }
   2162 
   2163 Static void
   2164 otus_watchdog(struct ifnet *ifp)
   2165 {
   2166 	struct otus_softc *sc;
   2167 
   2168 	sc = ifp->if_softc;
   2169 
   2170 	DPRINTFN(DBG_FN, sc, "\n");
   2171 
   2172 	ifp->if_timer = 0;
   2173 
   2174 	if (sc->sc_tx_timer > 0) {
   2175 		if (--sc->sc_tx_timer == 0) {
   2176 			aprint_error_dev(sc->sc_dev, "device timeout\n");
   2177 			/* otus_init(ifp); XXX needs a process context! */
   2178 			ifp->if_oerrors++;
   2179 			return;
   2180 		}
   2181 		ifp->if_timer = 1;
   2182 	}
   2183 	ieee80211_watchdog(&sc->sc_ic);
   2184 }
   2185 
   2186 Static int
   2187 otus_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   2188 {
   2189 	struct otus_softc *sc;
   2190 	struct ieee80211com *ic;
   2191 	int s, error = 0;
   2192 
   2193 	sc = ifp->if_softc;
   2194 
   2195 	DPRINTFN(DBG_FN, sc, "0x%lx\n", cmd);
   2196 
   2197 	ic = &sc->sc_ic;
   2198 
   2199 	s = splnet();
   2200 
   2201 	switch (cmd) {
   2202 	case SIOCSIFADDR:
   2203 		ifp->if_flags |= IFF_UP;
   2204 #ifdef INET
   2205 		struct ifaddr *ifa = data;
   2206 		if (ifa->ifa_addr->sa_family == AF_INET)
   2207 			arp_ifinit(&ic->ic_ac, ifa);
   2208 #endif
   2209 		/* FALLTHROUGH */
   2210 	case SIOCSIFFLAGS:
   2211 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   2212 			break;
   2213 
   2214 		switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
   2215 		case IFF_UP | IFF_RUNNING:
   2216 			if (((ifp->if_flags ^ sc->sc_if_flags) &
   2217 				(IFF_ALLMULTI | IFF_PROMISC)) != 0)
   2218 				otus_set_multi(sc);
   2219 			break;
   2220 		case IFF_UP:
   2221 			otus_init(ifp);
   2222 			break;
   2223 
   2224 		case IFF_RUNNING:
   2225 			otus_stop(ifp);
   2226 			break;
   2227 		case 0:
   2228 		default:
   2229 			break;
   2230 		}
   2231 		sc->sc_if_flags = ifp->if_flags;
   2232 		break;
   2233 
   2234 	case SIOCADDMULTI:
   2235 	case SIOCDELMULTI:
   2236 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
   2237 			/* setup multicast filter, etc */
   2238 			/* XXX: ??? */
   2239 			error = 0;
   2240 		}
   2241 		break;
   2242 
   2243 	case SIOCS80211CHANNEL:
   2244 		/*
   2245 		 * This allows for fast channel switching in monitor mode
   2246 		 * (used by kismet). In IBSS mode, we must explicitly reset
   2247 		 * the interface to generate a new beacon frame.
   2248 		 */
   2249 		error = ieee80211_ioctl(ic, cmd, data);
   2250 
   2251 		DPRINTFN(DBG_CHAN, sc,
   2252 		    "ic_curchan=%d ic_ibss_chan=%d ic_des_chan=%d ni_chan=%d error=%d\n",
   2253 		    ieee80211_chan2ieee(ic, ic->ic_curchan),
   2254 		    ieee80211_chan2ieee(ic, ic->ic_ibss_chan),
   2255 		    ieee80211_chan2ieee(ic, ic->ic_des_chan),
   2256 		    ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
   2257 		    error);
   2258 
   2259 		if (error == ENETRESET &&
   2260 		    ic->ic_opmode == IEEE80211_M_MONITOR) {
   2261 			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   2262 			    (IFF_UP | IFF_RUNNING)) {
   2263 				mutex_enter(&sc->sc_write_mtx);
   2264 				otus_set_chan(sc, ic->ic_curchan, 0);
   2265 				mutex_exit(&sc->sc_write_mtx);
   2266 			}
   2267 			error = 0;
   2268 		}
   2269 		break;
   2270 
   2271 	default:
   2272 		error = ieee80211_ioctl(ic, cmd, data);
   2273 	}
   2274 	if (error == ENETRESET) {
   2275 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   2276 		    (IFF_UP | IFF_RUNNING))
   2277 			otus_init(ifp);
   2278 		error = 0;
   2279 	}
   2280 	splx(s);
   2281 	return error;
   2282 }
   2283 
   2284 Static int
   2285 otus_set_multi(struct otus_softc *sc)
   2286 {
   2287 	struct ethercom *ec = &sc->sc_ec;
   2288 	struct ifnet *ifp;
   2289 	struct ether_multi *enm;
   2290 	struct ether_multistep step;
   2291 	uint32_t lo, hi;
   2292 	uint8_t bit;
   2293 	int error;
   2294 
   2295 	DPRINTFN(DBG_FN, sc, "\n");
   2296 
   2297 	ifp = sc->sc_ic.ic_ifp;
   2298 	if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
   2299 		lo = hi = 0xffffffff;
   2300 		goto done;
   2301 	}
   2302 	lo = hi = 0;
   2303 	ETHER_LOCK(ec);
   2304 	ETHER_FIRST_MULTI(step, ec, enm);
   2305 	while (enm != NULL) {
   2306 		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
   2307 			ifp->if_flags |= IFF_ALLMULTI;
   2308 			lo = hi = 0xffffffff;
   2309 			goto done;
   2310 		}
   2311 		bit = enm->enm_addrlo[5] >> 2;
   2312 		if (bit < 32)
   2313 			lo |= 1 << bit;
   2314 		else
   2315 			hi |= 1 << (bit - 32);
   2316 		ETHER_NEXT_MULTI(step, enm);
   2317 	}
   2318  done:
   2319 	ETHER_UNLOCK(ec);
   2320 	mutex_enter(&sc->sc_write_mtx);
   2321 	hi |= 1 << 31;	/* Make sure the broadcast bit is set. */
   2322 	otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo);
   2323 	otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi);
   2324 	error = otus_write_barrier(sc);
   2325 	mutex_exit(&sc->sc_write_mtx);
   2326 	return error;
   2327 }
   2328 
   2329 #ifdef HAVE_EDCA
   2330 Static void
   2331 otus_updateedca(struct ieee80211com *ic)
   2332 {
   2333 
   2334 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
   2335 
   2336 	/* Do it in a process context. */
   2337 	otus_do_async(ic->ic_ifp->if_softc, otus_updateedca_cb, NULL, 0);
   2338 }
   2339 
   2340 Static void
   2341 otus_updateedca_cb(struct otus_softc *sc, void *arg __used)
   2342 {
   2343 
   2344 	DPRINTFN(DBG_FN, sc, "\n");
   2345 
   2346 	mutex_enter(&sc->sc_write_mtx);
   2347 	otus_updateedca_cb_locked(sc);
   2348 	mutex_exit(&sc->sc_write_mtx);
   2349 }
   2350 #endif
   2351 
   2352 Static void
   2353 otus_updateedca_cb_locked(struct otus_softc *sc)
   2354 {
   2355 #ifdef HAVE_EDCA
   2356 	struct ieee80211com *ic;
   2357 #endif
   2358 	const struct ieee80211_edca_ac_params *edca;
   2359 	int s;
   2360 
   2361 	DPRINTFN(DBG_FN, sc, "\n");
   2362 
   2363 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   2364 
   2365 	s = splnet();
   2366 
   2367 #ifdef HAVE_EDCA
   2368 	ic = &sc->sc_ic;
   2369 	edca = (ic->ic_flags & IEEE80211_F_QOS) ?
   2370 	    ic->ic_edca_ac : otus_edca_def;
   2371 #else
   2372 	edca = otus_edca_def;
   2373 #endif /* HAVE_EDCA */
   2374 
   2375 #define EXP2(val)	((1 << (val)) - 1)
   2376 #define AIFS(val)	((val) * 9 + 10)
   2377 
   2378 	/* Set CWmin/CWmax values. */
   2379 	otus_write(sc, AR_MAC_REG_AC0_CW,
   2380 	    EXP2(edca[WME_AC_BE].ac_ecwmax) << 16 |
   2381 	    EXP2(edca[WME_AC_BE].ac_ecwmin));
   2382 	otus_write(sc, AR_MAC_REG_AC1_CW,
   2383 	    EXP2(edca[WME_AC_BK].ac_ecwmax) << 16 |
   2384 	    EXP2(edca[WME_AC_BK].ac_ecwmin));
   2385 	otus_write(sc, AR_MAC_REG_AC2_CW,
   2386 	    EXP2(edca[WME_AC_VI].ac_ecwmax) << 16 |
   2387 	    EXP2(edca[WME_AC_VI].ac_ecwmin));
   2388 	otus_write(sc, AR_MAC_REG_AC3_CW,
   2389 	    EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 |
   2390 	    EXP2(edca[WME_AC_VO].ac_ecwmin));
   2391 	otus_write(sc, AR_MAC_REG_AC4_CW,		/* Special TXQ. */
   2392 	    EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 |
   2393 	    EXP2(edca[WME_AC_VO].ac_ecwmin));
   2394 
   2395 	/* Set AIFSN values. */
   2396 	otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS,
   2397 	    AIFS(edca[WME_AC_VI].ac_aifsn) << 24 |
   2398 	    AIFS(edca[WME_AC_BK].ac_aifsn) << 12 |
   2399 	    AIFS(edca[WME_AC_BE].ac_aifsn));
   2400 	otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS,
   2401 	    AIFS(edca[WME_AC_VO].ac_aifsn) << 16 |	/* Special TXQ. */
   2402 	    AIFS(edca[WME_AC_VO].ac_aifsn) <<  4 |
   2403 	    AIFS(edca[WME_AC_VI].ac_aifsn) >>  8);
   2404 
   2405 	/* Set TXOP limit. */
   2406 	otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP,
   2407 	    edca[WME_AC_BK].ac_txoplimit << 16 |
   2408 	    edca[WME_AC_BE].ac_txoplimit);
   2409 	otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP,
   2410 	    edca[WME_AC_VO].ac_txoplimit << 16 |
   2411 	    edca[WME_AC_VI].ac_txoplimit);
   2412 #undef AIFS
   2413 #undef EXP2
   2414 
   2415 	splx(s);
   2416 
   2417 	(void)otus_write_barrier(sc);
   2418 }
   2419 
   2420 Static void
   2421 otus_updateslot(struct ifnet *ifp)
   2422 {
   2423 	struct otus_softc *sc;
   2424 
   2425 	sc = ifp->if_softc;
   2426 
   2427 	DPRINTFN(DBG_FN, sc, "\n");
   2428 
   2429 	/* Do it in a process context. */
   2430 	otus_do_async(sc, otus_updateslot_cb, NULL, 0);
   2431 }
   2432 
   2433 /* ARGSUSED */
   2434 Static void
   2435 otus_updateslot_cb(struct otus_softc *sc, void *arg)
   2436 {
   2437 
   2438 	DPRINTFN(DBG_FN, sc, "\n");
   2439 
   2440 	mutex_enter(&sc->sc_write_mtx);
   2441 	otus_updateslot_cb_locked(sc);
   2442 	mutex_exit(&sc->sc_write_mtx);
   2443 }
   2444 
   2445 Static void
   2446 otus_updateslot_cb_locked(struct otus_softc *sc)
   2447 {
   2448 	uint32_t slottime;
   2449 
   2450 	DPRINTFN(DBG_FN, sc, "\n");
   2451 
   2452 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   2453 
   2454 	slottime = (sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
   2455 	otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10);
   2456 	(void)otus_write_barrier(sc);
   2457 }
   2458 
   2459 Static int
   2460 otus_init_mac(struct otus_softc *sc)
   2461 {
   2462 	int error;
   2463 
   2464 	DPRINTFN(DBG_FN | DBG_INIT, sc, "\n");
   2465 
   2466 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   2467 
   2468 	otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40);
   2469 	otus_write(sc, AR_MAC_REG_RETRY_MAX, 0);
   2470 	otus_write(sc, AR_MAC_REG_SNIFFER, AR_MAC_REG_SNIFFER_DEFAULTS);
   2471 	otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80);
   2472 	otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70);
   2473 	otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000);
   2474 	otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10);
   2475 
   2476 	/* CF-END mode */
   2477 	otus_write(sc, 0x1c3b2c, 0x19000000);
   2478 
   2479 	/* NAV protects ACK only (in TXOP). */
   2480 	otus_write(sc, 0x1c3b38, 0x201);
   2481 
   2482 	/* Set beacon PHY CTRL's TPC to 0x7, TA1=1 */
   2483 	/* OTUS set AM to 0x1 */
   2484 	otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170);
   2485 
   2486 	otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105);
   2487 
   2488 	/* AGG test code*/
   2489 	/* Aggregation MAX number and timeout */
   2490 	otus_write(sc, AR_MAC_REG_AMPDU_FACTOR, 0x10000a);
   2491 
   2492 	/* Filter any control frames, BAR is bit 24. */
   2493 	otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, AR_MAC_REG_FTF_DEFAULTS);
   2494 
   2495 	/* Enable deaggregator, response in sniffer mode */
   2496 	otus_write(sc, 0x1c3c40, 0x1 | 1 << 30);	/* XXX: was 0x1 */
   2497 
   2498 	/* rate sets */
   2499 	otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f);
   2500 	otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f);
   2501 	otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
   2502 
   2503 	/* MIMO response control */
   2504 	otus_write(sc, 0x1c3694, 0x4003c1e);	/* bit 26~28  otus-AM */
   2505 
   2506 	/* Switch MAC to OTUS interface. */
   2507 	otus_write(sc, 0x1c3600, 0x3);
   2508 
   2509 	otus_write(sc, AR_MAC_REG_AMPDU_RX_THRESH, 0xffff);
   2510 
   2511 	/* set PHY register read timeout (??) */
   2512 	otus_write(sc, AR_MAC_REG_MISC_680, 0xf00008);
   2513 
   2514 	/* Disable Rx TimeOut, workaround for BB. */
   2515 	otus_write(sc, AR_MAC_REG_RX_TIMEOUT, 0x0);
   2516 
   2517 	/* Set clock frequency to 88/80MHz. */
   2518 	otus_write(sc, AR_PWR_REG_CLOCK_SEL,
   2519 	    AR_PWR_CLK_AHB_80_88MHZ | AR_PWR_CLK_DAC_160_INV_DLY);
   2520 
   2521 	/* Set WLAN DMA interrupt mode: generate intr per packet. */
   2522 	otus_write(sc, AR_MAC_REG_TXRX_MPI, 0x110011);
   2523 
   2524 	otus_write(sc, AR_MAC_REG_FCS_SELECT, AR_MAC_FCS_FIFO_PROT);
   2525 
   2526 	/* Disables the CF_END frame, undocumented register */
   2527 	otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48);
   2528 
   2529 	/* Disable HW decryption for now. */
   2530 	otus_write(sc, AR_MAC_REG_ENCRYPTION,
   2531 	    AR_MAC_REG_ENCRYPTION_DEFAULTS | AR_MAC_REG_ENCRYPTION_RX_SOFTWARE);
   2532 
   2533 	/*
   2534 	 * XXX: should these be elsewhere?
   2535 	 */
   2536 	/* Enable LED0 and LED1. */
   2537 	otus_write(sc, AR_GPIO_REG_PORT_TYPE, 3);
   2538 	otus_write(sc, AR_GPIO_REG_DATA,
   2539 	    AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON);
   2540 
   2541 	/* Set USB Rx stream mode maximum frame number to 2. */
   2542 	otus_write(sc, AR_USB_REG_MAX_AGG_UPLOAD, (1 << 2));
   2543 
   2544 	/* Set USB Rx stream mode timeout to 10us. */
   2545 	otus_write(sc, AR_USB_REG_UPLOAD_TIME_CTL, 0x80);
   2546 
   2547 	if ((error = otus_write_barrier(sc)) != 0)
   2548 		return error;
   2549 
   2550 	/* Set default EDCA parameters. */
   2551 	otus_updateedca_cb_locked(sc);
   2552 	return 0;
   2553 }
   2554 
   2555 /*
   2556  * Return default value for PHY register based on current operating mode.
   2557  */
   2558 Static uint32_t
   2559 otus_phy_get_def(struct otus_softc *sc, uint32_t reg)
   2560 {
   2561 	int i;
   2562 
   2563 	DPRINTFN(DBG_FN, sc, "\n");
   2564 
   2565 	for (i = 0; i < __arraycount(ar5416_phy_regs); i++)
   2566 		if (AR_PHY(ar5416_phy_regs[i]) == reg)
   2567 			return sc->sc_phy_vals[i];
   2568 	return 0;	/* Register not found. */
   2569 }
   2570 
   2571 /*
   2572  * Update PHY's programming based on vendor-specific data stored in EEPROM.
   2573  * This is for FEM-type devices only.
   2574  */
   2575 Static int
   2576 otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c)
   2577 {
   2578 	const struct ModalEepHeader *eep;
   2579 	uint32_t tmp, offset;
   2580 
   2581 	DPRINTFN(DBG_FN, sc, "\n");
   2582 
   2583 	if (IEEE80211_IS_CHAN_5GHZ(c))
   2584 		eep = &sc->sc_eeprom.modalHeader[0];
   2585 	else
   2586 		eep = &sc->sc_eeprom.modalHeader[1];
   2587 
   2588 	/* Offset of chain 2. */
   2589 	offset = 2 * 0x1000;
   2590 
   2591 	tmp = le32toh(eep->antCtrlCommon);
   2592 	otus_write(sc, AR_PHY_SWITCH_COM, tmp);
   2593 
   2594 	tmp = le32toh(eep->antCtrlChain[0]);
   2595 	otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp);
   2596 
   2597 	tmp = le32toh(eep->antCtrlChain[1]);
   2598 	otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp);
   2599 
   2600 	if (1 /* sc->sc_sco == AR_SCO_SCN */) {
   2601 		tmp = otus_phy_get_def(sc, AR_PHY_SETTLING);
   2602 		tmp &= ~(0x7f << 7);
   2603 		tmp |= (eep->switchSettling & 0x7f) << 7;
   2604 		otus_write(sc, AR_PHY_SETTLING, tmp);
   2605 	}
   2606 
   2607 	tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ);
   2608 	tmp &= ~0xffff;
   2609 	tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize;
   2610 	otus_write(sc, AR_PHY_DESIRED_SZ, tmp);
   2611 
   2612 	tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 |
   2613 	      eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn;
   2614 	otus_write(sc, AR_PHY_RF_CTL4, tmp);
   2615 
   2616 	tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3);
   2617 	tmp &= ~(0xff << 16);
   2618 	tmp |= eep->txEndToRxOn << 16;
   2619 	otus_write(sc, AR_PHY_RF_CTL3, tmp);
   2620 
   2621 	tmp = otus_phy_get_def(sc, AR_PHY_CCA);
   2622 	tmp &= ~(0x7f << 12);
   2623 	tmp |= (eep->thresh62 & 0x7f) << 12;
   2624 	otus_write(sc, AR_PHY_CCA, tmp);
   2625 
   2626 	tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN);
   2627 	tmp &= ~(0x3f << 12);
   2628 	tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12;
   2629 	otus_write(sc, AR_PHY_RXGAIN, tmp);
   2630 
   2631 	tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset);
   2632 	tmp &= ~(0x3f << 12);
   2633 	tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12;
   2634 	otus_write(sc, AR_PHY_RXGAIN + offset, tmp);
   2635 
   2636 	tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ);
   2637 	tmp &= ~(0x3f << 18);
   2638 	tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18;
   2639 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
   2640 		tmp &= ~(0xf << 10);
   2641 		tmp |= (eep->bswMargin[0] & 0xf) << 10;
   2642 	}
   2643 	otus_write(sc, AR_PHY_GAIN_2GHZ, tmp);
   2644 
   2645 	tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset);
   2646 	tmp &= ~(0x3f << 18);
   2647 	tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18;
   2648 	otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp);
   2649 
   2650 	tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4);
   2651 	tmp &= ~(0x3f << 5 | 0x1f);
   2652 	tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f);
   2653 	otus_write(sc, AR_PHY_TIMING_CTRL4, tmp);
   2654 
   2655 	tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset);
   2656 	tmp &= ~(0x3f << 5 | 0x1f);
   2657 	tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f);
   2658 	otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp);
   2659 
   2660 	tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1);
   2661 	tmp &= ~(0xf << 16);
   2662 	tmp |= (eep->xpd & 0xf) << 16;
   2663 	otus_write(sc, AR_PHY_TPCRG1, tmp);
   2664 
   2665 	return otus_write_barrier(sc);
   2666 }
   2667 
   2668 Static int
   2669 otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c)
   2670 {
   2671 	const uint32_t *vals;
   2672 	int error, i;
   2673 
   2674 	DPRINTFN(DBG_FN, sc, "\n");
   2675 
   2676 	/* Select PHY programming based on band and bandwidth. */
   2677 	if (IEEE80211_IS_CHAN_2GHZ(c))
   2678 		vals = ar5416_phy_vals_2ghz_20mhz;
   2679 	else
   2680 		vals = ar5416_phy_vals_5ghz_20mhz;
   2681 	for (i = 0; i < __arraycount(ar5416_phy_regs); i++)
   2682 		otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]);
   2683 	sc->sc_phy_vals = vals;
   2684 
   2685 	if (sc->sc_eeprom.baseEepHeader.deviceType == 0x80)	/* FEM */
   2686 		if ((error = otus_set_board_values(sc, c)) != 0)
   2687 			return error;
   2688 
   2689 	/* Initial Tx power settings. */
   2690 	otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f);
   2691 	otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f);
   2692 	otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f);
   2693 	otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f);
   2694 	otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f);
   2695 	otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f);
   2696 	otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f);
   2697 	otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f);
   2698 	otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f);
   2699 	otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f);
   2700 
   2701 	if (IEEE80211_IS_CHAN_2GHZ(c))
   2702 		otus_write(sc, 0x1d4014, 0x5163);
   2703 	else
   2704 		otus_write(sc, 0x1d4014, 0x5143);
   2705 
   2706 	return otus_write_barrier(sc);
   2707 }
   2708 
   2709 static __inline uint8_t
   2710 otus_reverse_bits(uint8_t v)
   2711 {
   2712 
   2713 	v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
   2714 	v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
   2715 	v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
   2716 	return v;
   2717 }
   2718 
   2719 Static int
   2720 otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c)
   2721 {
   2722 	uint8_t chansel, d0, d1;
   2723 	uint16_t data;
   2724 	int error;
   2725 
   2726 	DPRINTFN(DBG_FN, sc, "\n");
   2727 
   2728 	d0 = 0;
   2729 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
   2730 		chansel = (c->ic_freq - 4800) / 5;
   2731 		if (chansel & 1)
   2732 			d0 |= AR_BANK4_AMODE_REFSEL(2);
   2733 		else
   2734 			d0 |= AR_BANK4_AMODE_REFSEL(1);
   2735 	} else {
   2736 		d0 |= AR_BANK4_AMODE_REFSEL(2);
   2737 		if (c->ic_freq == 2484) {	/* CH 14 */
   2738 			d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ;
   2739 			chansel = 10 + (c->ic_freq - 2274) / 5;
   2740 		} else
   2741 			chansel = 16 + (c->ic_freq - 2272) / 5;
   2742 		chansel <<= 2;
   2743 	}
   2744 	d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP;
   2745 	d1 = otus_reverse_bits(chansel);
   2746 
   2747 	/* Write bits 0-4 of d0 and d1. */
   2748 	data = (d1 & 0x1f) << 5 | (d0 & 0x1f);
   2749 	otus_write(sc, AR_PHY(44), data);
   2750 	/* Write bits 5-7 of d0 and d1. */
   2751 	data = (d1 >> 5) << 5 | (d0 >> 5);
   2752 	otus_write(sc, AR_PHY(58), data);
   2753 
   2754 	if ((error = otus_write_barrier(sc)) == 0)
   2755 		usbd_delay_ms(sc->sc_udev, 10);
   2756 
   2757 	return error;
   2758 }
   2759 
   2760 Static void
   2761 otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa)
   2762 {
   2763 #define COEFF_SCALE_SHIFT	24
   2764 	uint32_t exp, man;
   2765 
   2766 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
   2767 
   2768 	/* exponent = 14 - floor(log2(coeff)) */
   2769 	for (exp = 31; exp > 0; exp--)
   2770 		if (coeff & (1 << exp))
   2771 			break;
   2772 	KASSERT(exp != 0);
   2773 	exp = 14 - (exp - COEFF_SCALE_SHIFT);
   2774 
   2775 	/* mantissa = floor(coeff * 2^exponent + 0.5) */
   2776 	man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1));
   2777 
   2778 	*mantissa = man >> (COEFF_SCALE_SHIFT - exp);
   2779 	*exponent = exp - 16;
   2780 #undef COEFF_SCALE_SHIFT
   2781 }
   2782 
   2783 Static int
   2784 otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc)
   2785 {
   2786 	struct ar_cmd_frequency cmd;
   2787 	struct ar_rsp_frequency rsp;
   2788 	const uint32_t *vals;
   2789 	uint32_t coeff, exp, man, tmp;
   2790 	uint8_t code;
   2791 	int error, i;
   2792 
   2793 	DPRINTFN(DBG_FN, sc, "\n");
   2794 
   2795 
   2796 #ifdef OTUS_DEBUG
   2797 	struct ieee80211com *ic = &sc->sc_ic;
   2798 	int chan = ieee80211_chan2ieee(ic, c);
   2799 
   2800 	DPRINTFN(DBG_CHAN, sc, "setting channel %d (%dMHz)\n",
   2801 	    chan, c->ic_freq);
   2802 #endif
   2803 
   2804 	tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104;
   2805 	otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp);
   2806 	if ((error = otus_write_barrier(sc)) != 0)
   2807 		return error;
   2808 
   2809 	/* Disable BB Heavy Clip. */
   2810 	otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200);
   2811 	if ((error = otus_write_barrier(sc)) != 0)
   2812 		return error;
   2813 
   2814 	/* XXX Is that FREQ_START ? */
   2815 	error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL);
   2816 	if (error != 0)
   2817 		return error;
   2818 
   2819 	/* Reprogram PHY and RF on channel band or bandwidth changes. */
   2820 	if (sc->sc_bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) {
   2821 		DPRINTFN(DBG_CHAN, sc, "band switch\n");
   2822 
   2823 		/* Cold/Warm reset BB/ADDA. */
   2824 		otus_write(sc, 0x1d4004, sc->sc_bb_reset ? 0x800 : 0x400);
   2825 		if ((error = otus_write_barrier(sc)) != 0)
   2826 			return error;
   2827 
   2828 		otus_write(sc, 0x1d4004, 0);
   2829 		if ((error = otus_write_barrier(sc)) != 0)
   2830 			return error;
   2831 		sc->sc_bb_reset = 0;
   2832 
   2833 		if ((error = otus_program_phy(sc, c)) != 0) {
   2834 			aprint_error_dev(sc->sc_dev,
   2835 			    "could not program PHY\n");
   2836 			return error;
   2837 		}
   2838 
   2839 		/* Select RF programming based on band. */
   2840 		if (IEEE80211_IS_CHAN_5GHZ(c))
   2841 			vals = ar5416_banks_vals_5ghz;
   2842 		else
   2843 			vals = ar5416_banks_vals_2ghz;
   2844 		for (i = 0; i < __arraycount(ar5416_banks_regs); i++)
   2845 			otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]);
   2846 		if ((error = otus_write_barrier(sc)) != 0) {
   2847 			aprint_error_dev(sc->sc_dev, "could not program RF\n");
   2848 			return error;
   2849 		}
   2850 		code = AR_CMD_RF_INIT;
   2851 	} else {
   2852 		code = AR_CMD_FREQUENCY;
   2853 	}
   2854 
   2855 	if ((error = otus_set_rf_bank4(sc, c)) != 0)
   2856 		return error;
   2857 
   2858 	tmp = (sc->sc_txmask == 0x5) ? 0x340 : 0x240;
   2859 	otus_write(sc, AR_PHY_TURBO, tmp);
   2860 	if ((error = otus_write_barrier(sc)) != 0)
   2861 		return error;
   2862 
   2863 	/* Send firmware command to set channel. */
   2864 	cmd.freq = htole32((uint32_t)c->ic_freq * 1000);
   2865 	cmd.dynht2040 = htole32(0);
   2866 	cmd.htena = htole32(1);
   2867 
   2868 	/* Set Delta Slope (exponent and mantissa). */
   2869 	coeff = (100 << 24) / c->ic_freq;
   2870 	otus_get_delta_slope(coeff, &exp, &man);
   2871 	cmd.dsc_exp = htole32(exp);
   2872 	cmd.dsc_man = htole32(man);
   2873 	DPRINTFN(DBG_CHAN, sc, "ds coeff=%u exp=%u man=%u\n",
   2874 	    coeff, exp, man);
   2875 
   2876 	/* For Short GI, coeff is 9/10 that of normal coeff. */
   2877 	coeff = (9 * coeff) / 10;
   2878 	otus_get_delta_slope(coeff, &exp, &man);
   2879 	cmd.dsc_shgi_exp = htole32(exp);
   2880 	cmd.dsc_shgi_man = htole32(man);
   2881 	DPRINTFN(DBG_CHAN, sc, "ds shgi coeff=%u exp=%u man=%u\n",
   2882 	    coeff, exp, man);
   2883 
   2884 	/* Set wait time for AGC and noise calibration (100 or 200ms). */
   2885 	cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000);
   2886 	DPRINTFN(DBG_CHAN, sc, "%s\n",
   2887 	    code == AR_CMD_RF_INIT ? "RF_INIT" : "FREQUENCY");
   2888 	error = otus_cmd(sc, code, &cmd, sizeof(cmd), &rsp);
   2889 	if (error != 0)
   2890 		return error;
   2891 
   2892 	if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) {
   2893 		DPRINTFN(DBG_CHAN, sc, "status=0x%x\n", le32toh(rsp.status));
   2894 		/* Force cold reset on next channel. */
   2895 		sc->sc_bb_reset = 1;
   2896 	}
   2897 
   2898 #ifdef OTUS_DEBUG
   2899 	if (otus_debug & DBG_CHAN) {
   2900 		DPRINTFN(DBG_CHAN, sc, "calibration status=0x%x\n",
   2901 		    le32toh(rsp.status));
   2902 		for (i = 0; i < 2; i++) {	/* 2 Rx chains */
   2903 			/* Sign-extend 9-bit NF values. */
   2904 			DPRINTFN(DBG_CHAN, sc, "noisefloor chain %d=%d\n",
   2905 			    i, (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23);
   2906 			DPRINTFN(DBG_CHAN, sc, "noisefloor ext chain %d=%d\n",
   2907 			    i, ((int32_t)le32toh(rsp.nf_ext[i])) >> 23);
   2908 		}
   2909 	}
   2910 #endif
   2911 	sc->sc_curchan = c;
   2912 	return 0;
   2913 }
   2914 
   2915 #ifdef notyet
   2916 Static int
   2917 otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
   2918     struct ieee80211_key *k)
   2919 {
   2920 	struct otus_softc *sc;
   2921 	struct otus_cmd_key cmd;
   2922 
   2923 	sc = ic->ic_ifp->if_softc;
   2924 
   2925 	DPRINTFN(DBG_FN, sc, "\n");
   2926 
   2927 	/* Defer setting of WEP keys until interface is brought up. */
   2928 	if ((ic->ic_ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
   2929 	    (IFF_UP | IFF_RUNNING))
   2930 		return 0;
   2931 
   2932 	/* Do it in a process context. */
   2933 	cmd.key = *k;
   2934 	cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
   2935 	otus_do_async(sc, otus_set_key_cb, &cmd, sizeof(cmd));
   2936 	return 0;
   2937 }
   2938 
   2939 Static void
   2940 otus_set_key_cb(struct otus_softc *sc, void *arg)
   2941 {
   2942 	struct otus_cmd_key *cmd;
   2943 	struct ieee80211_key *k;
   2944 	struct ar_cmd_ekey key;
   2945 	uint16_t cipher;
   2946 	int error;
   2947 
   2948 	DPRINTFN(DBG_FN, sc, "\n");
   2949 
   2950 	cmd = arg;
   2951 	k = &cmd->key;
   2952 
   2953 	memset(&key, 0, sizeof(key));
   2954 	if (k->k_flags & IEEE80211_KEY_GROUP) {
   2955 		key.uid = htole16(k->k_id);
   2956 		IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr);
   2957 		key.macaddr[0] |= 0x80;
   2958 	} else {
   2959 		key.uid = htole16(OTUS_UID(cmd->associd));
   2960 		IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr);
   2961 	}
   2962 	key.kix = htole16(0);
   2963 	/* Map net80211 cipher to hardware. */
   2964 	switch (k->k_cipher) {
   2965 	case IEEE80211_CIPHER_WEP40:
   2966 		cipher = AR_CIPHER_WEP64;
   2967 		break;
   2968 	case IEEE80211_CIPHER_WEP104:
   2969 		cipher = AR_CIPHER_WEP128;
   2970 		break;
   2971 	case IEEE80211_CIPHER_TKIP:
   2972 		cipher = AR_CIPHER_TKIP;
   2973 		break;
   2974 	case IEEE80211_CIPHER_CCMP:
   2975 		cipher = AR_CIPHER_AES;
   2976 		break;
   2977 	default:
   2978 		return;
   2979 	}
   2980 	key.cipher = htole16(cipher);
   2981 	memcpy(key.key, k->k_key, MIN(k->k_len, 16));
   2982 	error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL);
   2983 	if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP)
   2984 		return;
   2985 
   2986 	/* TKIP: set Tx/Rx MIC Key. */
   2987 	key.kix = htole16(1);
   2988 	memcpy(key.key, k->k_key + 16, 16);
   2989 	(void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL);
   2990 }
   2991 
   2992 Static void
   2993 otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
   2994     struct ieee80211_key *k)
   2995 {
   2996 	struct otus_softc *sc;
   2997 	struct otus_cmd_key cmd;
   2998 
   2999 	sc = ic->ic_ifp->if_softc;
   3000 
   3001 	DPRINTFN(DBG_FN, sc, "\n");
   3002 
   3003 	if (!(ic->ic_ifp->if_flags & IFF_RUNNING) ||
   3004 	    ic->ic_state != IEEE80211_S_RUN)
   3005 		return;	/* Nothing to do. */
   3006 
   3007 	/* Do it in a process context. */
   3008 	cmd.key = *k;
   3009 	cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
   3010 	otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof(cmd));
   3011 }
   3012 
   3013 Static void
   3014 otus_delete_key_cb(struct otus_softc *sc, void *arg)
   3015 {
   3016 	struct otus_cmd_key *cmd;
   3017 	struct ieee80211_key *k;
   3018 	uint32_t uid;
   3019 
   3020 	DPRINTFN(DBG_FN, sc, "\n");
   3021 
   3022 	cmd = arg;
   3023 	k = &cmd->key;
   3024 	if (k->k_flags & IEEE80211_KEY_GROUP)
   3025 		uid = htole32(k->k_id);
   3026 	else
   3027 		uid = htole32(OTUS_UID(cmd->associd));
   3028 	(void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof(uid), NULL);
   3029 }
   3030 #endif /* notyet */
   3031 
   3032 Static void
   3033 otus_calib_to(void *arg)
   3034 {
   3035 	struct otus_softc *sc;
   3036 	struct ieee80211com *ic;
   3037 	struct ieee80211_node *ni;
   3038 	struct otus_node *on;
   3039 	int s;
   3040 
   3041 	sc = arg;
   3042 
   3043 	DPRINTFN(DBG_FN, sc, "\n");
   3044 
   3045 	if (sc->sc_dying)
   3046 		return;
   3047 
   3048 	s = splnet();
   3049 	ic = &sc->sc_ic;
   3050 	ni = ic->ic_bss;
   3051 	on = (void *)ni;
   3052 	ieee80211_amrr_choose(&sc->sc_amrr, ni, &on->amn);
   3053 	splx(s);
   3054 
   3055 	if (!sc->sc_dying)
   3056 		callout_schedule(&sc->sc_calib_to, hz);
   3057 }
   3058 
   3059 Static int
   3060 otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid)
   3061 {
   3062 
   3063 	DPRINTFN(DBG_FN, sc, "\n");
   3064 
   3065 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   3066 
   3067 	otus_write(sc, AR_MAC_REG_BSSID_L,
   3068 	    bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
   3069 	otus_write(sc, AR_MAC_REG_BSSID_H,
   3070 	    bssid[4] | bssid[5] << 8);
   3071 	return otus_write_barrier(sc);
   3072 }
   3073 
   3074 Static int
   3075 otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr)
   3076 {
   3077 
   3078 	DPRINTFN(DBG_FN, sc, "\n");
   3079 
   3080 	KASSERT(mutex_owned(&sc->sc_write_mtx));
   3081 
   3082 	otus_write(sc, AR_MAC_REG_MAC_ADDR_L,
   3083 	    addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
   3084 	otus_write(sc, AR_MAC_REG_MAC_ADDR_H,
   3085 	    addr[4] | addr[5] << 8);
   3086 	return otus_write_barrier(sc);
   3087 }
   3088 
   3089 #ifdef notyet
   3090 /* Default single-LED. */
   3091 Static void
   3092 otus_led_newstate_type1(struct otus_softc *sc)
   3093 {
   3094 
   3095 	DPRINTFN(DBG_FN, sc, "\n");
   3096 
   3097 	/* TBD */
   3098 }
   3099 
   3100 /* NETGEAR, dual-LED. */
   3101 Static void
   3102 otus_led_newstate_type2(struct otus_softc *sc)
   3103 {
   3104 
   3105 	DPRINTFN(DBG_FN, sc, "\n");
   3106 
   3107 	/* TBD */
   3108 }
   3109 #endif /* notyet */
   3110 
   3111 /*
   3112  * NETGEAR, single-LED/3 colors (blue, red, purple.)
   3113  */
   3114 Static void
   3115 otus_led_newstate_type3(struct otus_softc *sc)
   3116 {
   3117 	struct ieee80211com *ic;
   3118 	uint32_t led_state;
   3119 
   3120 	DPRINTFN(DBG_FN, sc, "\n");
   3121 
   3122 	ic = &sc->sc_ic;
   3123 	led_state = sc->sc_led_state;
   3124 	switch (ic->ic_state) {
   3125 	case IEEE80211_S_INIT:
   3126 		led_state = 0;
   3127 		break;
   3128 	case IEEE80211_S_SCAN:
   3129 		led_state ^= AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON;
   3130 		led_state &= ~(IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ?
   3131 		    AR_GPIO_REG_DATA_LED1_ON : AR_GPIO_REG_DATA_LED0_ON);
   3132 		break;
   3133 	case IEEE80211_S_AUTH:
   3134 	case IEEE80211_S_ASSOC:
   3135 		/* XXX: Turn both LEDs on for AUTH and ASSOC? */
   3136 		led_state = AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON;
   3137 		break;
   3138 	case IEEE80211_S_RUN:
   3139 		led_state = IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ?
   3140 		    AR_GPIO_REG_DATA_LED0_ON : AR_GPIO_REG_DATA_LED1_ON;
   3141 		break;
   3142 	}
   3143 	if (led_state != sc->sc_led_state) {
   3144 		otus_write(sc, AR_GPIO_REG_DATA, led_state);
   3145 		if (otus_write_barrier(sc) == 0)
   3146 			sc->sc_led_state = led_state;
   3147 	}
   3148 }
   3149 
   3150 Static int
   3151 otus_init(struct ifnet *ifp)
   3152 {
   3153 	struct otus_softc *sc;
   3154 	struct ieee80211com *ic;
   3155 	uint32_t filter, pm_mode, sniffer;
   3156 	int error;
   3157 
   3158 	sc = ifp->if_softc;
   3159 
   3160 	DPRINTFN(DBG_FN | DBG_INIT, sc, "\n");
   3161 
   3162 	ic = &sc->sc_ic;
   3163 
   3164 	mutex_enter(&sc->sc_write_mtx);
   3165 
   3166 	/* Init host command ring. */
   3167 	mutex_spin_enter(&sc->sc_task_mtx);
   3168 	sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0;
   3169 	mutex_spin_exit(&sc->sc_task_mtx);
   3170 
   3171 	if ((error = otus_init_mac(sc)) != 0) {
   3172 		mutex_exit(&sc->sc_write_mtx);
   3173 		aprint_error_dev(sc->sc_dev, "could not initialize MAC\n");
   3174 		return error;
   3175 	}
   3176 
   3177 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
   3178 	(void)otus_set_macaddr(sc, ic->ic_myaddr);
   3179 
   3180 	pm_mode = AR_MAC_REG_POWERMGT_DEFAULTS;
   3181 	sniffer = AR_MAC_REG_SNIFFER_DEFAULTS;
   3182 	filter = AR_MAC_REG_FTF_DEFAULTS;
   3183 	sc->sc_rx_error_msk = ~0;
   3184 
   3185 	switch (ic->ic_opmode) {
   3186 #ifdef notyet
   3187 #ifndef IEEE80211_STA_ONLY
   3188 	case IEEE80211_M_HOSTAP:
   3189 		pm_mode |= AR_MAC_REG_POWERMGT_AP;
   3190 		break;
   3191 	case IEEE80211_M_IBSS:
   3192 		pm_mode |= AR_MAC_REG_POWERMGT_IBSS;	/* XXX: was 0x0 */
   3193 		break;
   3194 #endif
   3195 #endif
   3196 	case IEEE80211_M_STA:
   3197 		pm_mode |= AR_MAC_REG_POWERMGT_STA;
   3198 		break;
   3199 	case IEEE80211_M_MONITOR:
   3200 		sc->sc_rx_error_msk = ~AR_RX_ERROR_BAD_RA;
   3201 		filter = AR_MAC_REG_FTF_MONITOR;
   3202 		sniffer |= AR_MAC_REG_SNIFFER_ENABLE_PROMISC;
   3203 		break;
   3204 	default:
   3205 		aprint_error_dev(sc->sc_dev, "bad opmode: %d", ic->ic_opmode);
   3206 		return EOPNOTSUPP;	/* XXX: ??? */
   3207 	}
   3208 	otus_write(sc, AR_MAC_REG_POWERMANAGEMENT, pm_mode);
   3209 	otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, filter);
   3210 	otus_write(sc, AR_MAC_REG_SNIFFER, sniffer);
   3211 	(void)otus_write_barrier(sc);
   3212 
   3213 	sc->sc_bb_reset = 1;	/* Force cold reset. */
   3214 	if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) {
   3215 		mutex_exit(&sc->sc_write_mtx);
   3216 		aprint_error_dev(sc->sc_dev, "could not set channel\n");
   3217 		return error;
   3218 	}
   3219 
   3220 	/* Start Rx. */
   3221 	otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_ENABLE);
   3222 	(void)otus_write_barrier(sc);
   3223 	mutex_exit(&sc->sc_write_mtx);
   3224 
   3225 	ifp->if_flags &= ~IFF_OACTIVE;
   3226 	ifp->if_flags |= IFF_RUNNING;
   3227 
   3228 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   3229 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   3230 	else
   3231 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   3232 
   3233 	return 0;
   3234 }
   3235 
   3236 Static void
   3237 otus_stop(struct ifnet *ifp)
   3238 {
   3239 	struct otus_softc *sc;
   3240 	struct ieee80211com *ic;
   3241 	int s;
   3242 
   3243 	sc = ifp->if_softc;
   3244 
   3245 	DPRINTFN(DBG_FN, sc, "\n");
   3246 
   3247 	ic = &sc->sc_ic;
   3248 
   3249 	sc->sc_tx_timer = 0;
   3250 	ifp->if_timer = 0;
   3251 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   3252 
   3253 	callout_halt(&sc->sc_scan_to, NULL);
   3254 	callout_halt(&sc->sc_calib_to, NULL);
   3255 
   3256 	s = splusb();
   3257 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   3258 	otus_wait_async(sc);
   3259 	splx(s);
   3260 
   3261 	/* Stop Rx. */
   3262 	mutex_enter(&sc->sc_write_mtx);
   3263 	otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_OFF);
   3264 	(void)otus_write_barrier(sc);
   3265 	mutex_exit(&sc->sc_write_mtx);
   3266 }
   3267