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