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