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