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