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