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