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