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