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