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