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