xref: /netbsd/sys/dev/usb/if_otus.c (revision 399f52d5)
1 /*	$NetBSD: if_otus.c,v 1.45 2020/06/11 09:51:37 martin 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.45 2020/06/11 09:51:37 martin 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
otus_match(device_t parent,cfdata_t match,void * aux)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=%#x product=%#x revision=%#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
otus_attach(device_t parent,device_t self,void * aux)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 	cv_init(&sc->sc_task_cv, "otustsk");
634 	cv_init(&sc->sc_cmd_cv, "otuscmd");
635 	mutex_init(&sc->sc_cmd_mtx,   MUTEX_DEFAULT, IPL_NONE);
636 	mutex_init(&sc->sc_task_mtx,  MUTEX_DEFAULT, IPL_NET);
637 	mutex_init(&sc->sc_tx_mtx,    MUTEX_DEFAULT, IPL_NONE);
638 	mutex_init(&sc->sc_write_mtx, MUTEX_DEFAULT, IPL_NONE);
639 
640 	usb_init_task(&sc->sc_task, otus_task, sc, 0);
641 
642 	callout_init(&sc->sc_scan_to, 0);
643 	callout_setfunc(&sc->sc_scan_to, otus_next_scan, sc);
644 	callout_init(&sc->sc_calib_to, 0);
645 	callout_setfunc(&sc->sc_calib_to, otus_calib_to, sc);
646 
647 	sc->sc_amrr.amrr_min_success_threshold =  1;
648 	sc->sc_amrr.amrr_max_success_threshold = 10;
649 
650 	if (usbd_set_config_no(sc->sc_udev, 1, 0) != 0) {
651 		aprint_error_dev(sc->sc_dev,
652 		    "could not set configuration no\n");
653 		return;
654 	}
655 
656 	/* Get the first interface handle. */
657 	error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
658 	if (error != 0) {
659 		aprint_error_dev(sc->sc_dev,
660 		    "could not get interface handle\n");
661 		return;
662 	}
663 
664 	if ((error = otus_open_pipes(sc)) != 0) {
665 		aprint_error_dev(sc->sc_dev, "could not open pipes\n");
666 		return;
667 	}
668 
669 	/*
670 	 * We need the firmware loaded from file system to complete the attach.
671 	 */
672 	config_mountroot(self, otus_attachhook);
673 
674 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
675 }
676 
677 Static void
otus_wait_async(struct otus_softc * sc)678 otus_wait_async(struct otus_softc *sc)
679 {
680 
681 	DPRINTFN(DBG_FN, sc, "\n");
682 
683 	mutex_spin_enter(&sc->sc_task_mtx);
684 	while (sc->sc_cmdq.queued > 0)
685 		cv_wait(&sc->sc_task_cv, &sc->sc_task_mtx);
686 	mutex_spin_exit(&sc->sc_task_mtx);
687 }
688 
689 Static int
otus_detach(device_t self,int flags)690 otus_detach(device_t self, int flags)
691 {
692 	struct otus_softc *sc;
693 	struct ifnet *ifp;
694 	int s;
695 
696 	sc = device_private(self);
697 
698 	DPRINTFN(DBG_FN, sc, "\n");
699 
700 	s = splusb();
701 
702 	sc->sc_dying = 1;
703 
704 	ifp = sc->sc_ic.ic_ifp;
705 	if (ifp != NULL)	/* Failed to attach properly */
706 		otus_stop(ifp);
707 
708 	usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
709 	callout_destroy(&sc->sc_scan_to);
710 	callout_destroy(&sc->sc_calib_to);
711 
712 	if (ifp && ifp->if_flags != 0) { /* if_attach() has been called. */
713 		ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
714 		bpf_detach(ifp);
715 		ieee80211_ifdetach(&sc->sc_ic);
716 		if_detach(ifp);
717 	}
718 	otus_close_pipes(sc);
719 	splx(s);
720 
721 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
722 
723 	mutex_destroy(&sc->sc_write_mtx);
724 	mutex_destroy(&sc->sc_tx_mtx);
725 	mutex_destroy(&sc->sc_task_mtx);
726 	mutex_destroy(&sc->sc_cmd_mtx);
727 	cv_destroy(&sc->sc_task_cv);
728 	cv_destroy(&sc->sc_cmd_cv);
729 
730 	return 0;
731 }
732 
733 Static int
otus_activate(device_t self,devact_t act)734 otus_activate(device_t self, devact_t act)
735 {
736 	struct otus_softc *sc;
737 
738 	sc = device_private(self);
739 
740 	DPRINTFN(DBG_FN, sc, "%d\n", act);
741 
742 	switch (act) {
743 	case DVACT_DEACTIVATE:
744 		sc->sc_dying = 1;
745 		if_deactivate(sc->sc_ic.ic_ifp);
746 		return 0;
747 	default:
748 		return EOPNOTSUPP;
749 	}
750 }
751 
752 Static void
otus_attachhook(device_t arg)753 otus_attachhook(device_t arg)
754 {
755 	struct otus_softc *sc;
756 	struct ieee80211com *ic;
757 	struct ifnet *ifp;
758 	usb_device_request_t req;
759 	uint32_t in, out;
760 	int error;
761 
762 	sc = device_private(arg);
763 
764 	DPRINTFN(DBG_FN, sc, "\n");
765 
766 	ic = &sc->sc_ic;
767 	ifp = &sc->sc_if;
768 
769 	error = otus_load_firmware(sc, "otus-init", AR_FW_INIT_ADDR);
770 	if (error != 0) {
771 		aprint_error_dev(sc->sc_dev, "could not load init firmware\n");
772 		return;
773 	}
774 	usbd_delay_ms(sc->sc_udev, 1000);
775 
776 	error = otus_load_firmware(sc, "otus-main", AR_FW_MAIN_ADDR);
777 	if (error != 0) {
778 		aprint_error_dev(sc->sc_dev, "could not load main firmware\n");
779 		return;
780 	}
781 
782 	/* Tell device that firmware transfer is complete. */
783 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
784 	req.bRequest = AR_FW_DOWNLOAD_COMPLETE;
785 	USETW(req.wValue, 0);
786 	USETW(req.wIndex, 0);
787 	USETW(req.wLength, 0);
788 	if (usbd_do_request(sc->sc_udev, &req, NULL) != 0) {
789 		aprint_error_dev(sc->sc_dev,
790 		    "firmware initialization failed\n");
791 		return;
792 	}
793 
794 	/* Send an ECHO command to check that everything is settled. */
795 	in = 0xbadc0ffe;
796 	if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof(in), &out) != 0) {
797 		aprint_error_dev(sc->sc_dev, "echo command failed\n");
798 		return;
799 	}
800 	if (in != out) {
801 		aprint_error_dev(sc->sc_dev,
802 		    "echo reply mismatch: 0x%08x!=0x%08x\n", in, out);
803 		return;
804 	}
805 
806 	/* Read entire EEPROM. */
807 	if (otus_read_eeprom(sc) != 0) {
808 		aprint_error_dev(sc->sc_dev, "could not read EEPROM\n");
809 		return;
810 	}
811 
812 	sc->sc_txmask = sc->sc_eeprom.baseEepHeader.txMask;
813 	sc->sc_rxmask = sc->sc_eeprom.baseEepHeader.rxMask;
814 	sc->sc_capflags = sc->sc_eeprom.baseEepHeader.opCapFlags;
815 	IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_eeprom.baseEepHeader.macAddr);
816 	sc->sc_led_newstate = otus_led_newstate_type3;	/* XXX */
817 
818 	aprint_normal_dev(sc->sc_dev,
819 	    "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n",
820 	    (sc->sc_capflags & AR5416_OPFLAGS_11A) ?
821 		0x9104 : ((sc->sc_txmask == 0x5) ? 0x9102 : 0x9101),
822 	    (sc->sc_txmask == 0x5) ? 2 : 1, (sc->sc_rxmask == 0x5) ? 2 : 1,
823 	    ether_sprintf(ic->ic_myaddr));
824 
825 	/*
826 	 * Setup the 802.11 device.
827 	 */
828 	ic->ic_ifp = ifp;
829 	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
830 	ic->ic_opmode = IEEE80211_M_STA;	/* default to BSS mode */
831 	ic->ic_state = IEEE80211_S_INIT;
832 
833 	/* Set device capabilities. */
834 	ic->ic_caps =
835 	    IEEE80211_C_MONITOR |	/* monitor mode supported */
836 	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
837 	    IEEE80211_C_SHSLOT |	/* short slot time supported */
838 	    IEEE80211_C_WPA;		/* 802.11i */
839 
840 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
841 		/* Set supported .11b and .11g rates. */
842 		ic->ic_sup_rates[IEEE80211_MODE_11B] =
843 		    ieee80211_std_rateset_11b;
844 		ic->ic_sup_rates[IEEE80211_MODE_11G] =
845 		    ieee80211_std_rateset_11g;
846 	}
847 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
848 		/* Set supported .11a rates. */
849 		ic->ic_sup_rates[IEEE80211_MODE_11A] =
850 		    ieee80211_std_rateset_11a;
851 	}
852 
853 	/* Build the list of supported channels. */
854 	otus_get_chanlist(sc);
855 
856 	ifp->if_softc = sc;
857 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
858 	ifp->if_init  = otus_init;
859 	ifp->if_ioctl = otus_ioctl;
860 	ifp->if_start = otus_start;
861 	ifp->if_watchdog = otus_watchdog;
862 	IFQ_SET_READY(&ifp->if_snd);
863 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
864 
865 	if_attach(ifp);
866 
867 	ieee80211_ifattach(ic);
868 
869 	ic->ic_node_alloc = otus_node_alloc;
870 	ic->ic_newassoc	  = otus_newassoc;
871 	ic->ic_updateslot = otus_updateslot;
872 #ifdef HAVE_EDCA
873 	ic->ic_updateedca = otus_updateedca;
874 #endif /* HAVE_EDCA */
875 #ifdef notyet
876 	ic->ic_set_key = otus_set_key;
877 	ic->ic_delete_key = otus_delete_key;
878 #endif /* notyet */
879 
880 	/* Override state transition machine. */
881 	sc->sc_newstate = ic->ic_newstate;
882 	ic->ic_newstate = otus_newstate;
883 
884 	/* XXX media locking needs revisiting */
885 	mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
886 	ieee80211_media_init_with_lock(ic,
887 	    otus_media_change, ieee80211_media_status, &sc->sc_media_mtx);
888 
889 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
890 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
891 	    &sc->sc_drvbpf);
892 
893 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
894 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
895 	sc->sc_rxtap.wr_ihdr.it_present = htole32(OTUS_RX_RADIOTAP_PRESENT);
896 
897 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
898 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
899 	sc->sc_txtap.wt_ihdr.it_present = htole32(OTUS_TX_RADIOTAP_PRESENT);
900 
901 	ieee80211_announce(ic);
902 }
903 
904 Static void
otus_get_chanlist(struct otus_softc * sc)905 otus_get_chanlist(struct otus_softc *sc)
906 {
907 	struct ieee80211com *ic;
908 	uint8_t chan;
909 	int i;
910 
911 #ifdef OTUS_DEBUG
912 	/* XXX regulatory domain. */
913 	uint16_t domain = le16toh(sc->sc_eeprom.baseEepHeader.regDmn[0]);
914 
915 	DPRINTFN(DBG_FN | DBG_INIT, sc, "regdomain=0x%04x\n", domain);
916 #endif
917 
918 	ic = &sc->sc_ic;
919 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) {
920 		for (i = 0; i < 14; i++) {
921 			chan = ar_chans[i];
922 			ic->ic_channels[chan].ic_freq =
923 			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ);
924 			ic->ic_channels[chan].ic_flags =
925 			    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
926 			    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
927 		}
928 	}
929 	if (sc->sc_eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) {
930 		for (i = 14; i < __arraycount(ar_chans); i++) {
931 			chan = ar_chans[i];
932 			ic->ic_channels[chan].ic_freq =
933 			    ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ);
934 			ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A;
935 		}
936 	}
937 }
938 
939 Static int
otus_load_firmware(struct otus_softc * sc,const char * name,uint32_t addr)940 otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr)
941 {
942 	usb_device_request_t req;
943 	firmware_handle_t fh;
944 	uint8_t *ptr;
945 	uint8_t *fw;
946 	size_t size;
947 	int mlen, error;
948 
949 	DPRINTFN(DBG_FN, sc, "\n");
950 
951 	if ((error = firmware_open("if_otus", name, &fh)) != 0)
952 		return error;
953 
954 	size = firmware_get_size(fh);
955 	if ((fw = firmware_malloc(size)) == NULL) {
956 		firmware_close(fh);
957 		return ENOMEM;
958 	}
959 	if ((error = firmware_read(fh, 0, fw, size)) != 0)
960 		firmware_free(fw, size);
961 	firmware_close(fh);
962 	if (error)
963 		return error;
964 
965 	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
966 	req.bRequest = AR_FW_DOWNLOAD;
967 	USETW(req.wIndex, 0);
968 
969 	ptr = fw;
970 	addr >>= 8;
971 	while (size > 0) {
972 		mlen = MIN(size, 4096);
973 
974 		USETW(req.wValue, addr);
975 		USETW(req.wLength, mlen);
976 		if (usbd_do_request(sc->sc_udev, &req, ptr) != 0) {
977 			error = EIO;
978 			break;
979 		}
980 		addr += mlen >> 8;
981 		ptr  += mlen;
982 		size -= mlen;
983 	}
984 	free(fw, M_DEVBUF);
985 	return error;
986 }
987 
988 Static int
otus_open_pipes(struct otus_softc * sc)989 otus_open_pipes(struct otus_softc *sc)
990 {
991 	usb_endpoint_descriptor_t *ed;
992 	int i, error;
993 
994 	DPRINTFN(DBG_FN, sc, "\n");
995 
996 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_RX_NO, 0,
997 	    &sc->sc_data_rx_pipe);
998 	if (error != 0) {
999 		aprint_error_dev(sc->sc_dev, "could not open Rx bulk pipe\n");
1000 		goto fail;
1001 	}
1002 
1003 	ed = usbd_get_endpoint_descriptor(sc->sc_iface, AR_EPT_INTR_RX_NO);
1004 	if (ed == NULL) {
1005 		aprint_error_dev(sc->sc_dev,
1006 		    "could not retrieve Rx intr pipe descriptor\n");
1007 		goto fail;
1008 	}
1009 	sc->sc_ibuf_size = UGETW(ed->wMaxPacketSize);
1010 	if (sc->sc_ibuf_size == 0) {
1011 		aprint_error_dev(sc->sc_dev,
1012 		    "invalid Rx intr pipe descriptor\n");
1013 		goto fail;
1014 	}
1015 	sc->sc_ibuf = kmem_alloc(sc->sc_ibuf_size, KM_SLEEP);
1016 	error = usbd_open_pipe_intr(sc->sc_iface, AR_EPT_INTR_RX_NO,
1017 	    USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf,
1018 	    sc->sc_ibuf_size, otus_intr, USBD_DEFAULT_INTERVAL);
1019 	if (error != 0) {
1020 		aprint_error_dev(sc->sc_dev, "could not open Rx intr pipe\n");
1021 		goto fail;
1022 	}
1023 
1024 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_BULK_TX_NO, 0,
1025 	    &sc->sc_data_tx_pipe);
1026 	if (error != 0) {
1027 		aprint_error_dev(sc->sc_dev, "could not open Tx bulk pipe\n");
1028 		goto fail;
1029 	}
1030 
1031 	error = usbd_open_pipe(sc->sc_iface, AR_EPT_INTR_TX_NO, 0,
1032 	    &sc->sc_cmd_tx_pipe);
1033 	if (error != 0) {
1034 		aprint_error_dev(sc->sc_dev, "could not open Tx intr pipe\n");
1035 		goto fail;
1036 	}
1037 
1038 	if (otus_alloc_tx_cmd(sc) != 0) {
1039 		aprint_error_dev(sc->sc_dev,
1040 		    "could not allocate command xfer\n");
1041 		goto fail;
1042 	}
1043 
1044 	if (otus_alloc_tx_data_list(sc)) {
1045 		aprint_error_dev(sc->sc_dev, "could not allocate Tx xfers\n");
1046 		goto fail;
1047 	}
1048 
1049 	if (otus_alloc_rx_data_list(sc)) {
1050 		aprint_error_dev(sc->sc_dev, "could not allocate Rx xfers\n");
1051 		goto fail;
1052 	}
1053 
1054 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) {
1055 		struct otus_rx_data *data = &sc->sc_rx_data[i];
1056 
1057 		usbd_setup_xfer(data->xfer, data, data->buf, OTUS_RXBUFSZ,
1058 		    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof);
1059 		error = usbd_transfer(data->xfer);
1060 		if (error != USBD_IN_PROGRESS && error != 0) {
1061 			aprint_error_dev(sc->sc_dev,
1062 			    "could not queue Rx xfer\n");
1063 			goto fail;
1064 		}
1065 	}
1066 	return 0;
1067 
1068  fail:	otus_close_pipes(sc);
1069 	return error;
1070 }
1071 
1072 Static void
otus_close_pipes(struct otus_softc * sc)1073 otus_close_pipes(struct otus_softc *sc)
1074 {
1075 
1076 	DPRINTFN(DBG_FN, sc, "\n");
1077 
1078 	otus_free_tx_cmd(sc);
1079 	otus_free_tx_data_list(sc);
1080 	otus_free_rx_data_list(sc);
1081 
1082 	if (sc->sc_data_rx_pipe != NULL)
1083 		usbd_close_pipe(sc->sc_data_rx_pipe);
1084 	if (sc->sc_cmd_rx_pipe != NULL) {
1085 		usbd_abort_pipe(sc->sc_cmd_rx_pipe);
1086 		usbd_close_pipe(sc->sc_cmd_rx_pipe);
1087 	}
1088 	if (sc->sc_ibuf != NULL)
1089 		kmem_free(sc->sc_ibuf, sc->sc_ibuf_size);
1090 	if (sc->sc_data_tx_pipe != NULL)
1091 		usbd_close_pipe(sc->sc_data_tx_pipe);
1092 	if (sc->sc_cmd_tx_pipe != NULL)
1093 		usbd_close_pipe(sc->sc_cmd_tx_pipe);
1094 }
1095 
1096 Static int
otus_alloc_tx_cmd(struct otus_softc * sc)1097 otus_alloc_tx_cmd(struct otus_softc *sc)
1098 {
1099 	struct otus_tx_cmd *cmd;
1100 
1101 	DPRINTFN(DBG_FN, sc, "\n");
1102 
1103 	cmd = &sc->sc_tx_cmd;
1104 
1105 	int error = usbd_create_xfer(sc->sc_cmd_tx_pipe, OTUS_MAX_TXCMDSZ,
1106 	    USBD_FORCE_SHORT_XFER, 0, &cmd->xfer);
1107 	if (error)
1108 		return error;
1109 
1110 	cmd->buf = usbd_get_buffer(cmd->xfer);
1111 
1112 	return 0;
1113 }
1114 
1115 Static void
otus_free_tx_cmd(struct otus_softc * sc)1116 otus_free_tx_cmd(struct otus_softc *sc)
1117 {
1118 
1119 	DPRINTFN(DBG_FN, sc, "\n");
1120 
1121 	if (sc->sc_cmd_tx_pipe == NULL)
1122 		return;
1123 
1124 	/* Make sure no transfers are pending. */
1125 	usbd_abort_pipe(sc->sc_cmd_tx_pipe);
1126 
1127 	mutex_enter(&sc->sc_cmd_mtx);
1128 	if (sc->sc_tx_cmd.xfer != NULL)
1129 		usbd_destroy_xfer(sc->sc_tx_cmd.xfer);
1130 	sc->sc_tx_cmd.xfer = NULL;
1131 	sc->sc_tx_cmd.buf  = NULL;
1132 	mutex_exit(&sc->sc_cmd_mtx);
1133 }
1134 
1135 Static int
otus_alloc_tx_data_list(struct otus_softc * sc)1136 otus_alloc_tx_data_list(struct otus_softc *sc)
1137 {
1138 	struct otus_tx_data *data;
1139 	int i, error;
1140 
1141 	DPRINTFN(DBG_FN, sc, "\n");
1142 
1143 	mutex_enter(&sc->sc_tx_mtx);
1144 	error = 0;
1145 	TAILQ_INIT(&sc->sc_tx_free_list);
1146 	for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) {
1147 		data = &sc->sc_tx_data[i];
1148 
1149 		data->sc = sc;	/* Backpointer for callbacks. */
1150 
1151 		error = usbd_create_xfer(sc->sc_data_tx_pipe, OTUS_TXBUFSZ,
1152 		    USBD_FORCE_SHORT_XFER, 0, &data->xfer);
1153 		if (error) {
1154 			aprint_error_dev(sc->sc_dev,
1155 			    "could not allocate xfer\n");
1156 			break;
1157 		}
1158 		data->buf = usbd_get_buffer(data->xfer);
1159 		/* Append this Tx buffer to our free list. */
1160 		TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
1161 	}
1162 	if (error != 0)
1163 		otus_free_tx_data_list(sc);
1164 	mutex_exit(&sc->sc_tx_mtx);
1165 	return error;
1166 }
1167 
1168 Static void
otus_free_tx_data_list(struct otus_softc * sc)1169 otus_free_tx_data_list(struct otus_softc *sc)
1170 {
1171 	int i;
1172 
1173 	DPRINTFN(DBG_FN, sc, "\n");
1174 
1175 	if (sc->sc_data_tx_pipe == NULL)
1176 		return;
1177 
1178 	/* Make sure no transfers are pending. */
1179 	usbd_abort_pipe(sc->sc_data_tx_pipe);
1180 
1181 	for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) {
1182 		if (sc->sc_tx_data[i].xfer != NULL)
1183 			usbd_destroy_xfer(sc->sc_tx_data[i].xfer);
1184 	}
1185 }
1186 
1187 Static int
otus_alloc_rx_data_list(struct otus_softc * sc)1188 otus_alloc_rx_data_list(struct otus_softc *sc)
1189 {
1190 	struct otus_rx_data *data;
1191 	int i, error;
1192 
1193 	DPRINTFN(DBG_FN, sc, "\n");
1194 
1195 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) {
1196 		data = &sc->sc_rx_data[i];
1197 
1198 		data->sc = sc;	/* Backpointer for callbacks. */
1199 
1200 		error = usbd_create_xfer(sc->sc_data_rx_pipe, OTUS_RXBUFSZ,
1201 		   0, 0, &data->xfer);
1202 
1203 		if (error) {
1204 			aprint_error_dev(sc->sc_dev,
1205 			    "could not allocate xfer\n");
1206 			goto fail;
1207 		}
1208 		data->buf = usbd_get_buffer(data->xfer);
1209 	}
1210 	return 0;
1211 
1212 fail:	otus_free_rx_data_list(sc);
1213 	return error;
1214 }
1215 
1216 Static void
otus_free_rx_data_list(struct otus_softc * sc)1217 otus_free_rx_data_list(struct otus_softc *sc)
1218 {
1219 	int i;
1220 
1221 	DPRINTFN(DBG_FN, sc, "\n");
1222 
1223 	if (sc->sc_data_rx_pipe == NULL)
1224 		return;
1225 
1226 	/* Make sure no transfers are pending. */
1227 	usbd_abort_pipe(sc->sc_data_rx_pipe);
1228 
1229 	for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++)
1230 		if (sc->sc_rx_data[i].xfer != NULL)
1231 			usbd_destroy_xfer(sc->sc_rx_data[i].xfer);
1232 }
1233 
1234 Static void
otus_next_scan(void * arg)1235 otus_next_scan(void *arg)
1236 {
1237 	struct otus_softc *sc;
1238 
1239 	sc = arg;
1240 
1241 	DPRINTFN(DBG_FN, sc, "\n");
1242 
1243 	if (sc->sc_dying)
1244 		return;
1245 
1246 	if (sc->sc_ic.ic_state == IEEE80211_S_SCAN)
1247 		ieee80211_next_scan(&sc->sc_ic);
1248 }
1249 
1250 Static void
otus_task(void * arg)1251 otus_task(void *arg)
1252 {
1253 	struct otus_softc *sc;
1254 	struct otus_host_cmd_ring *ring;
1255 	struct otus_host_cmd *cmd;
1256 
1257 	sc = arg;
1258 
1259 	DPRINTFN(DBG_FN, sc, "\n");
1260 
1261 	/* Process host commands. */
1262 	mutex_spin_enter(&sc->sc_task_mtx);
1263 	ring = &sc->sc_cmdq;
1264 	while (ring->next != ring->cur) {
1265 		cmd = &ring->cmd[ring->next];
1266 		mutex_spin_exit(&sc->sc_task_mtx);
1267 
1268 		/* Callback. */
1269 		DPRINTFN(DBG_CMD, sc, "cb=%p queued=%d\n", cmd->cb,
1270 		    ring->queued);
1271 		cmd->cb(sc, cmd->data);
1272 
1273 		mutex_spin_enter(&sc->sc_task_mtx);
1274 		ring->queued--;
1275 		ring->next = (ring->next + 1) % OTUS_HOST_CMD_RING_COUNT;
1276 	}
1277 	cv_signal(&sc->sc_task_cv);
1278 	mutex_spin_exit(&sc->sc_task_mtx);
1279 }
1280 
1281 Static void
otus_do_async(struct otus_softc * sc,void (* cb)(struct otus_softc *,void *),void * arg,int len)1282 otus_do_async(struct otus_softc *sc, void (*cb)(struct otus_softc *, void *),
1283     void *arg, int len)
1284 {
1285 	struct otus_host_cmd_ring *ring;
1286 	struct otus_host_cmd *cmd;
1287 	bool sched = false;
1288 
1289 	DPRINTFN(DBG_FN, sc, "cb=%p\n", cb);
1290 
1291 	mutex_spin_enter(&sc->sc_task_mtx);
1292 	ring = &sc->sc_cmdq;
1293 	cmd = &ring->cmd[ring->cur];
1294 	cmd->cb = cb;
1295 	KASSERT(len <= sizeof(cmd->data));
1296 	memcpy(cmd->data, arg, len);
1297 	ring->cur = (ring->cur + 1) % OTUS_HOST_CMD_RING_COUNT;
1298 
1299 	/* If there is no pending command already, schedule a task. */
1300 	if (++ring->queued == 1) {
1301 		sched = true;
1302 	}
1303 	cv_signal(&sc->sc_task_cv);
1304 	mutex_spin_exit(&sc->sc_task_mtx);
1305 	if (sched)
1306 		usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER);
1307 }
1308 
1309 Static int
otus_newstate(struct ieee80211com * ic,enum ieee80211_state nstate,int arg)1310 otus_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1311 {
1312 	struct otus_softc *sc;
1313 	struct otus_cmd_newstate cmd;
1314 
1315 	sc = ic->ic_ifp->if_softc;
1316 
1317 	DPRINTFN(DBG_FN | DBG_STM, sc, "nstate=%s(%d), arg=%d\n",
1318 	    ieee80211_state_name[nstate], nstate, arg);
1319 
1320 	/* Do it in a process context. */
1321 	cmd.state = nstate;
1322 	cmd.arg = arg;
1323 	otus_do_async(sc, otus_newstate_cb, &cmd, sizeof(cmd));
1324 	return 0;
1325 }
1326 
1327 Static void
otus_newstate_cb(struct otus_softc * sc,void * arg)1328 otus_newstate_cb(struct otus_softc *sc, void *arg)
1329 {
1330 	struct otus_cmd_newstate *cmd;
1331 	struct ieee80211com *ic;
1332 	struct ieee80211_node *ni;
1333 	enum ieee80211_state nstate;
1334 	int s;
1335 
1336 	cmd = arg;
1337 	ic = &sc->sc_ic;
1338 	ni = ic->ic_bss;
1339 	nstate = cmd->state;
1340 
1341 #ifdef OTUS_DEBUG
1342 	enum ieee80211_state ostate = ostate = ic->ic_state;
1343 	DPRINTFN(DBG_FN | DBG_STM, sc, "%s(%d)->%s(%d)\n",
1344 	    ieee80211_state_name[ostate], ostate,
1345 	    ieee80211_state_name[nstate], nstate);
1346 #endif
1347 
1348 	s = splnet();
1349 
1350 	callout_halt(&sc->sc_scan_to, NULL);
1351 	callout_halt(&sc->sc_calib_to, NULL);
1352 
1353 	mutex_enter(&sc->sc_write_mtx);
1354 
1355 	switch (nstate) {
1356 	case IEEE80211_S_INIT:
1357 		break;
1358 
1359 	case IEEE80211_S_SCAN:
1360 		otus_set_chan(sc, ic->ic_curchan, 0);
1361 		if (!sc->sc_dying)
1362 			callout_schedule(&sc->sc_scan_to, hz / 5);
1363 		break;
1364 
1365 	case IEEE80211_S_AUTH:
1366 	case IEEE80211_S_ASSOC:
1367 		otus_set_chan(sc, ic->ic_curchan, 0);
1368 		break;
1369 
1370 	case IEEE80211_S_RUN:
1371 		otus_set_chan(sc, ic->ic_curchan, 1);
1372 
1373 		switch (ic->ic_opmode) {
1374 		case IEEE80211_M_STA:
1375 			otus_updateslot_cb_locked(sc);
1376 			otus_set_bssid(sc, ni->ni_bssid);
1377 
1378 			/* Fake a join to init the Tx rate. */
1379 			otus_newassoc(ni, 1);
1380 
1381 			/* Start calibration timer. */
1382 			if (!sc->sc_dying)
1383 				callout_schedule(&sc->sc_calib_to, hz);
1384 			break;
1385 
1386 		case IEEE80211_M_IBSS:
1387 		case IEEE80211_M_AHDEMO:
1388 		case IEEE80211_M_HOSTAP:
1389 		case IEEE80211_M_MONITOR:
1390 			break;
1391 		}
1392 		break;
1393 	}
1394 	(void)sc->sc_newstate(ic, nstate, cmd->arg);
1395 	sc->sc_led_newstate(sc);
1396 	mutex_exit(&sc->sc_write_mtx);
1397 
1398 	splx(s);
1399 }
1400 
1401 Static int
otus_cmd(struct otus_softc * sc,uint8_t code,const void * idata,int ilen,void * odata)1402 otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen,
1403     void *odata)
1404 {
1405 	struct otus_tx_cmd *cmd;
1406 	struct ar_cmd_hdr *hdr;
1407 	int xferlen, error;
1408 
1409 	DPRINTFN(DBG_FN, sc, "\n");
1410 
1411 	cmd = &sc->sc_tx_cmd;
1412 
1413 	mutex_enter(&sc->sc_cmd_mtx);
1414 
1415 	/* Always bulk-out a multiple of 4 bytes. */
1416 	xferlen = roundup2(sizeof(*hdr) + ilen, 4);
1417 
1418 	hdr = (void *)cmd->buf;
1419 	if (hdr == NULL) {	/* we may have been freed while detaching */
1420 		mutex_exit(&sc->sc_cmd_mtx);
1421 		DPRINTFN(DBG_CMD, sc, "tx_cmd freed with commands pending\n");
1422 		return 0;
1423 	}
1424 	hdr->code  = code;
1425 	hdr->len   = ilen;
1426 	hdr->token = ++cmd->token;	/* Don't care about endianness. */
1427 	KASSERT(sizeof(hdr) + ilen <= OTUS_MAX_TXCMDSZ);
1428 	memcpy(cmd->buf + sizeof(hdr[0]), idata, ilen);
1429 
1430 	DPRINTFN(DBG_CMD, sc, "sending command code=0x%02x len=%d token=%d\n",
1431 	    code, ilen, hdr->token);
1432 
1433 	cmd->odata = odata;
1434 	cmd->done = 0;
1435 	usbd_setup_xfer(cmd->xfer, cmd, cmd->buf, xferlen,
1436 	    USBD_FORCE_SHORT_XFER, OTUS_CMD_TIMEOUT, NULL);
1437 	error = usbd_sync_transfer(cmd->xfer);
1438 	if (error != 0) {
1439 		mutex_exit(&sc->sc_cmd_mtx);
1440 #if defined(DIAGNOSTIC) || defined(OTUS_DEBUG)	/* XXX: kill some noise */
1441 		aprint_error_dev(sc->sc_dev,
1442 		    "could not send command %#x (error=%s)\n",
1443 		    code, usbd_errstr(error));
1444 #endif
1445 		return EIO;
1446 	}
1447 	if (!cmd->done)
1448 		error = cv_timedwait_sig(&sc->sc_cmd_cv, &sc->sc_cmd_mtx, hz);
1449 	cmd->odata = NULL;	/* In case answer is received too late. */
1450 	mutex_exit(&sc->sc_cmd_mtx);
1451 	if (error != 0) {
1452 		aprint_error_dev(sc->sc_dev,
1453 		    "timeout waiting for command 0x%02x reply\n", code);
1454 	}
1455 	return error;
1456 }
1457 
1458 Static void
otus_write(struct otus_softc * sc,uint32_t reg,uint32_t val)1459 otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val)
1460 {
1461 
1462 	DPRINTFN(DBG_FN | DBG_REG, sc, "reg=%#x, val=%#x\n", reg, val);
1463 
1464 	KASSERT(mutex_owned(&sc->sc_write_mtx));
1465 	KASSERT(sc->sc_write_idx < __arraycount(sc->sc_write_buf));
1466 
1467 	sc->sc_write_buf[sc->sc_write_idx].reg = htole32(reg);
1468 	sc->sc_write_buf[sc->sc_write_idx].val = htole32(val);
1469 
1470 	if (++sc->sc_write_idx >= __arraycount(sc->sc_write_buf))
1471 		(void)otus_write_barrier(sc);
1472 }
1473 
1474 Static int
otus_write_barrier(struct otus_softc * sc)1475 otus_write_barrier(struct otus_softc *sc)
1476 {
1477 	int error;
1478 
1479 	DPRINTFN(DBG_FN, sc, "\n");
1480 
1481 	KASSERT(mutex_owned(&sc->sc_write_mtx));
1482 	KASSERT(sc->sc_write_idx <= __arraycount(sc->sc_write_buf));
1483 
1484 	if (sc->sc_write_idx == 0)
1485 		return 0;	/* Nothing to flush. */
1486 
1487 	error = otus_cmd(sc, AR_CMD_WREG, sc->sc_write_buf,
1488 	    sizeof(sc->sc_write_buf[0]) * sc->sc_write_idx, NULL);
1489 
1490 	sc->sc_write_idx = 0;
1491 	if (error)
1492 		DPRINTFN(DBG_REG, sc, "error=%d\n", error);
1493 	return error;
1494 }
1495 
1496 Static struct ieee80211_node *
otus_node_alloc(struct ieee80211_node_table * ntp)1497 otus_node_alloc(struct ieee80211_node_table *ntp)
1498 {
1499 	struct otus_node *on;
1500 
1501 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
1502 
1503 	on = malloc(sizeof(*on), M_DEVBUF, M_NOWAIT | M_ZERO);
1504 	return on ? &on->ni : NULL;
1505 }
1506 
1507 Static int
otus_media_change(struct ifnet * ifp)1508 otus_media_change(struct ifnet *ifp)
1509 {
1510 	struct otus_softc *sc;
1511 	struct ieee80211com *ic;
1512 	uint8_t rate, ridx;
1513 	int error;
1514 
1515 	sc = ifp->if_softc;
1516 
1517 	DPRINTFN(DBG_FN, sc, "\n");
1518 
1519 	error = ieee80211_media_change(ifp);
1520 	if (error != ENETRESET)
1521 		return error;
1522 
1523 	ic = &sc->sc_ic;
1524 	if (ic->ic_fixed_rate != -1) {
1525 		rate = ic->ic_sup_rates[ic->ic_curmode].
1526 		    rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
1527 		for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
1528 			if (otus_rates[ridx].rate == rate)
1529 				break;
1530 		sc->sc_fixed_ridx = ridx;
1531 	}
1532 
1533 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING))
1534 		error = otus_init(ifp);
1535 
1536 	return error;
1537 }
1538 
1539 Static int
otus_read_eeprom(struct otus_softc * sc)1540 otus_read_eeprom(struct otus_softc *sc)
1541 {
1542 	uint32_t regs[8], reg;
1543 	uint8_t *eep;
1544 	int i, j, error;
1545 
1546 	DPRINTFN(DBG_FN, sc, "\n");
1547 
1548 	KASSERT(sizeof(sc->sc_eeprom) % 32 == 0);
1549 
1550 	/* Read EEPROM by blocks of 32 bytes. */
1551 	eep = (uint8_t *)&sc->sc_eeprom;
1552 	reg = AR_EEPROM_OFFSET;
1553 	for (i = 0; i < sizeof(sc->sc_eeprom) / 32; i++) {
1554 		for (j = 0; j < 8; j++, reg += 4)
1555 			regs[j] = htole32(reg);
1556 		error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof(regs), eep);
1557 		if (error != 0)
1558 			break;
1559 		eep += 32;
1560 	}
1561 	return error;
1562 }
1563 
1564 Static void
otus_newassoc(struct ieee80211_node * ni,int isnew)1565 otus_newassoc(struct ieee80211_node *ni, int isnew)
1566 {
1567 	struct ieee80211_rateset *rs;
1568 	struct otus_softc *sc;
1569 	struct otus_node *on;
1570 	uint8_t rate;
1571 	int ridx, i;
1572 
1573 	sc = ni->ni_ic->ic_ifp->if_softc;
1574 
1575 	DPRINTFN(DBG_FN, sc, "isnew=%d addr=%s\n",
1576 	    isnew, ether_sprintf(ni->ni_macaddr));
1577 
1578 	on = (void *)ni;
1579 	ieee80211_amrr_node_init(&sc->sc_amrr, &on->amn);
1580 	/* Start at lowest available bit-rate, AMRR will raise. */
1581 	ni->ni_txrate = 0;
1582 	rs = &ni->ni_rates;
1583 	for (i = 0; i < rs->rs_nrates; i++) {
1584 		rate = rs->rs_rates[i] & IEEE80211_RATE_VAL;
1585 		/* Convert 802.11 rate to hardware rate index. */
1586 		for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++)
1587 			if (otus_rates[ridx].rate == rate)
1588 				break;
1589 		on->ridx[i] = ridx;
1590 		DPRINTFN(DBG_INIT, sc, "rate=0x%02x ridx=%d\n",
1591 		    rs->rs_rates[i], on->ridx[i]);
1592 	}
1593 }
1594 
1595 /* ARGSUSED */
1596 Static void
otus_intr(struct usbd_xfer * xfer,void * priv,usbd_status status)1597 otus_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
1598 {
1599 #if 0
1600 	struct otus_softc *sc;
1601 	int len;
1602 
1603 	sc = priv;
1604 
1605 	DPRINTFN(DBG_FN, sc, "\n");
1606 
1607 	/*
1608 	 * The Rx intr pipe is unused with current firmware.  Notifications
1609 	 * and replies to commands are sent through the Rx bulk pipe instead
1610 	 * (with a magic PLCP header.)
1611 	 */
1612 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1613 		DPRINTFN(DBG_INTR, sc, "status=%d\n", status);
1614 		if (status == USBD_STALLED)
1615 			usbd_clear_endpoint_stall_async(sc->sc_cmd_rx_pipe);
1616 		return;
1617 	}
1618 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1619 
1620 	otus_cmd_rxeof(sc, sc->sc_ibuf, len);
1621 #endif
1622 }
1623 
1624 Static void
otus_cmd_rxeof(struct otus_softc * sc,uint8_t * buf,int len)1625 otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
1626 {
1627 	struct ieee80211com *ic;
1628 	struct otus_tx_cmd *cmd;
1629 	struct ar_cmd_hdr *hdr;
1630 	int s;
1631 
1632 	DPRINTFN(DBG_FN, sc, "\n");
1633 
1634 	ic = &sc->sc_ic;
1635 
1636 	if (__predict_false(len < sizeof(*hdr))) {
1637 		DPRINTFN(DBG_RX, sc, "cmd too small %d\n", len);
1638 		return;
1639 	}
1640 	hdr = (void *)buf;
1641 	if (__predict_false(sizeof(*hdr) + hdr->len > len ||
1642 	    sizeof(*hdr) + hdr->len > 64)) {
1643 		DPRINTFN(DBG_RX, sc, "cmd too large %d\n", hdr->len);
1644 		return;
1645 	}
1646 
1647 	if ((hdr->code & 0xc0) != 0xc0) {
1648 		DPRINTFN(DBG_RX, sc, "received reply code=0x%02x len=%d token=%d\n",
1649 		    hdr->code, hdr->len, hdr->token);
1650 		mutex_enter(&sc->sc_cmd_mtx);
1651 		cmd = &sc->sc_tx_cmd;
1652 		if (__predict_false(hdr->token != cmd->token)) {
1653 			mutex_exit(&sc->sc_cmd_mtx);
1654 			return;
1655 		}
1656 		/* Copy answer into caller's supplied buffer. */
1657 		if (cmd->odata != NULL)
1658 			memcpy(cmd->odata, &hdr[1], hdr->len);
1659 		cmd->done = 1;
1660 		cv_signal(&sc->sc_cmd_cv);
1661 		mutex_exit(&sc->sc_cmd_mtx);
1662 		return;
1663 	}
1664 
1665 	/* Received unsolicited notification. */
1666 	DPRINTFN(DBG_RX, sc, "received notification code=0x%02x len=%d\n",
1667 	    hdr->code, hdr->len);
1668 	switch (hdr->code & 0x3f) {
1669 	case AR_EVT_BEACON:
1670 		break;
1671 	case AR_EVT_TX_COMP:
1672 	{
1673 		struct ar_evt_tx_comp *tx;
1674 		struct ieee80211_node *ni;
1675 		struct otus_node *on;
1676 
1677 		tx = (void *)&hdr[1];
1678 
1679 		DPRINTFN(DBG_RX, sc, "tx completed %s status=%d phy=%#x\n",
1680 		    ether_sprintf(tx->macaddr), le16toh(tx->status),
1681 		    le32toh(tx->phy));
1682 		s = splnet();
1683 #ifdef notyet
1684 #ifndef IEEE80211_STA_ONLY
1685 		if (ic->ic_opmode != IEEE80211_M_STA) {
1686 			ni = ieee80211_find_node(ic, tx->macaddr);
1687 			if (__predict_false(ni == NULL)) {
1688 				splx(s);
1689 				break;
1690 			}
1691 		} else
1692 #endif
1693 #endif
1694 			ni = ic->ic_bss;
1695 		/* Update rate control statistics. */
1696 		on = (void *)ni;
1697 		/* NB: we do not set the TX_MAC_RATE_PROBING flag. */
1698 		if (__predict_true(tx->status != 0))
1699 			on->amn.amn_retrycnt++;
1700 		splx(s);
1701 		break;
1702 	}
1703 	case AR_EVT_TBTT:
1704 		break;
1705 	}
1706 }
1707 
1708 Static void
otus_sub_rxeof(struct otus_softc * sc,uint8_t * buf,int len)1709 otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len)
1710 {
1711 	struct ieee80211com *ic;
1712 	struct ifnet *ifp;
1713 	struct ieee80211_node *ni;
1714 	struct ar_rx_tail *tail;
1715 	struct ieee80211_frame *wh;
1716 	struct mbuf *m;
1717 	uint8_t *plcp;
1718 	int s, mlen, align;
1719 
1720 	DPRINTFN(DBG_FN, sc, "\n");
1721 
1722 	ic = &sc->sc_ic;
1723 	ifp = ic->ic_ifp;
1724 
1725 	if (__predict_false(len < AR_PLCP_HDR_LEN)) {
1726 		DPRINTFN(DBG_RX, sc, "sub-xfer too short %d\n", len);
1727 		return;
1728 	}
1729 	plcp = buf;
1730 
1731 	/* All bits in the PLCP header are set to 1 for non-MPDU. */
1732 	if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) {
1733 		otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN,
1734 		    len - AR_PLCP_HDR_LEN);
1735 		return;
1736 	}
1737 
1738 	/* Received MPDU. */
1739 	if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof(*tail))) {
1740 		DPRINTFN(DBG_RX, sc, "MPDU too short %d\n", len);
1741 		if_statinc(ifp, if_ierrors);
1742 		return;
1743 	}
1744 	tail = (void *)(plcp + len - sizeof(*tail));
1745 	wh = (void *)(plcp + AR_PLCP_HDR_LEN);
1746 
1747 	/* Discard error frames. */
1748 	if (__predict_false((tail->error & sc->sc_rx_error_msk) != 0)) {
1749 		DPRINTFN(DBG_RX, sc, "error frame 0x%02x\n", tail->error);
1750 		if (tail->error & AR_RX_ERROR_FCS) {
1751 			DPRINTFN(DBG_RX, sc, "bad FCS\n");
1752 		} else if (tail->error & AR_RX_ERROR_MMIC) {
1753 			/* Report Michael MIC failures to net80211. */
1754 			ieee80211_notify_michael_failure(ic, wh, 0 /* XXX: keyix */);
1755 		}
1756 		if_statinc(ifp, if_ierrors);
1757 		return;
1758 	}
1759 	/* Compute MPDU's length. */
1760 	mlen = len - AR_PLCP_HDR_LEN - sizeof(*tail);
1761 	if (__predict_false(mlen < IEEE80211_CRC_LEN)) {
1762 		if_statinc(ifp, if_ierrors);
1763 		return;
1764 	}
1765 	mlen -= IEEE80211_CRC_LEN;	/* strip 802.11 FCS */
1766 	/* Make sure there's room for an 802.11 header. */
1767 	/*
1768 	 * XXX: This will drop most control packets.  Do we really
1769 	 * want this in IEEE80211_M_MONITOR mode?
1770 	 */
1771 	if (__predict_false(mlen < sizeof(*wh))) {
1772 		if_statinc(ifp, if_ierrors);
1773 		return;
1774 	}
1775 
1776 	/* Provide a 32-bit aligned protocol header to the stack. */
1777 	align = (ieee80211_has_qos(wh) ^ ieee80211_has_addr4(wh)) ? 2 : 0;
1778 
1779 	MGETHDR(m, M_DONTWAIT, MT_DATA);
1780 	if (__predict_false(m == NULL)) {
1781 		if_statinc(ifp, if_ierrors);
1782 		return;
1783 	}
1784 	if (align + mlen > MHLEN) {
1785 		if (__predict_true(align + mlen <= MCLBYTES))
1786 			MCLGET(m, M_DONTWAIT);
1787 		if (__predict_false(!(m->m_flags & M_EXT))) {
1788 			if_statinc(ifp, if_ierrors);
1789 			m_freem(m);
1790 			return;
1791 		}
1792 	}
1793 	/* Finalize mbuf. */
1794 	m_set_rcvif(m, ifp);
1795 	m->m_data += align;
1796 	memcpy(mtod(m, void *), wh, mlen);
1797 	m->m_pkthdr.len = m->m_len = mlen;
1798 
1799 	s = splnet();
1800 	if (__predict_false(sc->sc_drvbpf != NULL)) {
1801 		struct otus_rx_radiotap_header *tap;
1802 
1803 		tap = &sc->sc_rxtap;
1804 		tap->wr_flags = 0;
1805 		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
1806 		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
1807 		tap->wr_antsignal = tail->rssi;
1808 		tap->wr_rate = 2;	/* In case it can't be found below. */
1809 		switch (tail->status & AR_RX_STATUS_MT_MASK) {
1810 		case AR_RX_STATUS_MT_CCK:
1811 			switch (plcp[0]) {
1812 			case  10: tap->wr_rate =   2; break;
1813 			case  20: tap->wr_rate =   4; break;
1814 			case  55: tap->wr_rate =  11; break;
1815 			case 110: tap->wr_rate =  22; break;
1816 			}
1817 			if (tail->status & AR_RX_STATUS_SHPREAMBLE)
1818 				tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
1819 			break;
1820 		case AR_RX_STATUS_MT_OFDM:
1821 			switch (plcp[0] & 0xf) {
1822 			case 0xb: tap->wr_rate =  12; break;
1823 			case 0xf: tap->wr_rate =  18; break;
1824 			case 0xa: tap->wr_rate =  24; break;
1825 			case 0xe: tap->wr_rate =  36; break;
1826 			case 0x9: tap->wr_rate =  48; break;
1827 			case 0xd: tap->wr_rate =  72; break;
1828 			case 0x8: tap->wr_rate =  96; break;
1829 			case 0xc: tap->wr_rate = 108; break;
1830 			}
1831 			break;
1832 		}
1833 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN);
1834 	}
1835 
1836 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
1837 
1838 	/* push the frame up to the 802.11 stack */
1839 	ieee80211_input(ic, m, ni, tail->rssi, 0);
1840 
1841 	/* Node is no longer needed. */
1842 	ieee80211_free_node(ni);
1843 	splx(s);
1844 }
1845 
1846 Static void
otus_rxeof(struct usbd_xfer * xfer,void * priv,usbd_status status)1847 otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1848 {
1849 	struct otus_rx_data *data;
1850 	struct otus_softc *sc;
1851 	uint8_t *buf;
1852 	struct ar_rx_head *head;
1853 	uint16_t hlen;
1854 	int len;
1855 
1856 	data = priv;
1857 	sc = data->sc;
1858 
1859 	DPRINTFN(DBG_FN, sc, "\n");
1860 
1861 	buf = data->buf;
1862 
1863 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1864 		DPRINTFN(DBG_RX, sc, "RX status=%d\n", status);
1865 		if (status == USBD_STALLED)
1866 			usbd_clear_endpoint_stall_async(sc->sc_data_rx_pipe);
1867 		else if (status != USBD_CANCELLED) {
1868 			DPRINTFN(DBG_RX, sc,
1869 			    "otus_rxeof: goto resubmit: status=%d\n", status);
1870 			goto resubmit;
1871 		}
1872 		return;
1873 	}
1874 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1875 
1876 	while (len >= sizeof(*head)) {
1877 		head = (void *)buf;
1878 		if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) {
1879 			DPRINTFN(DBG_RX, sc, "tag not valid %#x\n",
1880 			    le16toh(head->tag));
1881 			break;
1882 		}
1883 		hlen = le16toh(head->len);
1884 		if (__predict_false(sizeof(*head) + hlen > len)) {
1885 			DPRINTFN(DBG_RX, sc, "xfer too short %d/%d\n",
1886 			    len, hlen);
1887 			break;
1888 		}
1889 		/* Process sub-xfer. */
1890 		otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen);
1891 
1892 		/* Next sub-xfer is aligned on a 32-bit boundary. */
1893 		hlen = roundup2(sizeof(*head) + hlen, 4);
1894 		buf += hlen;
1895 		len -= hlen;
1896 	}
1897 
1898  resubmit:
1899 	usbd_setup_xfer(xfer, data, data->buf, OTUS_RXBUFSZ,
1900 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof);
1901 	(void)usbd_transfer(data->xfer);
1902 }
1903 
1904 Static void
otus_txeof(struct usbd_xfer * xfer,void * priv,usbd_status status)1905 otus_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1906 {
1907 	struct otus_tx_data *data;
1908 	struct otus_softc *sc;
1909 	struct ieee80211com *ic;
1910 	struct ifnet *ifp;
1911 	int s;
1912 
1913 	data = priv;
1914 	sc = data->sc;
1915 
1916 	DPRINTFN(DBG_FN, sc, "\n");
1917 
1918 	/* Put this Tx buffer back to the free list. */
1919 	mutex_enter(&sc->sc_tx_mtx);
1920 	TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
1921 	mutex_exit(&sc->sc_tx_mtx);
1922 
1923 	ic = &sc->sc_ic;
1924 	ifp = ic->ic_ifp;
1925 	if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1926 		DPRINTFN(DBG_TX, sc, "TX status=%d\n", status);
1927 		if (status == USBD_STALLED)
1928 			usbd_clear_endpoint_stall_async(sc->sc_data_tx_pipe);
1929 		if_statinc(ifp, if_oerrors);
1930 		return;
1931 	}
1932 	if_statinc(ifp, if_opackets);
1933 
1934 	s = splnet();
1935 	sc->sc_tx_timer = 0;
1936 	ifp->if_flags &= ~IFF_OACTIVE;	/* XXX: do after freeing Tx buffer? */
1937 	otus_start(ifp);
1938 	splx(s);
1939 }
1940 
1941 Static int
otus_tx(struct otus_softc * sc,struct mbuf * m,struct ieee80211_node * ni,struct otus_tx_data * data)1942 otus_tx(struct otus_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
1943     struct otus_tx_data *data)
1944 {
1945 	struct ieee80211com *ic;
1946 	struct otus_node *on;
1947 	struct ieee80211_frame *wh;
1948 	struct ieee80211_key *k;
1949 	struct ar_tx_head *head;
1950 	uint32_t phyctl;
1951 	uint16_t macctl, qos;
1952 	uint8_t qid;
1953 	int error, ridx, hasqos, xferlen;
1954 
1955 	DPRINTFN(DBG_FN, sc, "\n");
1956 
1957 	ic = &sc->sc_ic;
1958 	on = (void *)ni;
1959 
1960 	wh = mtod(m, struct ieee80211_frame *);
1961 	if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED)) {
1962 		/* XXX: derived from upgt_tx_task() and ural_tx_data() */
1963 		k = ieee80211_crypto_encap(ic, ni, m);
1964 		if (k == NULL)
1965 			return ENOBUFS;
1966 
1967 		/* Packet header may have moved, reset our local pointer. */
1968 		wh = mtod(m, struct ieee80211_frame *);
1969 	}
1970 
1971 #ifdef HAVE_EDCA
1972 	if ((hasqos = ieee80211_has_qos(wh))) {
1973 		qos = ieee80211_get_qos(wh);
1974 		qid = ieee80211_up_to_ac(ic, qos & IEEE80211_QOS_TID);
1975 	} else {
1976 		qos = 0;
1977 		qid = WME_AC_BE;
1978 	}
1979 #else
1980 	hasqos = 0;
1981 	qos = 0;
1982 	qid = WME_AC_BE;
1983 #endif
1984 
1985 	/* Pickup a rate index. */
1986 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
1987 	    (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA)
1988 		ridx = (ic->ic_curmode == IEEE80211_MODE_11A) ?
1989 		    OTUS_RIDX_OFDM6 : OTUS_RIDX_CCK1;
1990 	else if (ic->ic_fixed_rate != -1)
1991 		ridx = sc->sc_fixed_ridx;
1992 	else
1993 		ridx = on->ridx[ni->ni_txrate];
1994 
1995 	phyctl = 0;
1996 	macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid);
1997 
1998 	if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
1999 	    (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY_MASK) ==
2000 	     IEEE80211_QOS_ACKPOLICY_NOACK)))
2001 		macctl |= AR_TX_MAC_NOACK;
2002 
2003 	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2004 		if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= ic->ic_rtsthreshold)
2005 			macctl |= AR_TX_MAC_RTS;
2006 		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
2007 		    ridx >= OTUS_RIDX_OFDM6) {
2008 			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
2009 				macctl |= AR_TX_MAC_CTS;
2010 			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
2011 				macctl |= AR_TX_MAC_RTS;
2012 		}
2013 	}
2014 
2015 	phyctl |= AR_TX_PHY_MCS(otus_rates[ridx].mcs);
2016 	if (ridx >= OTUS_RIDX_OFDM6) {
2017 		phyctl |= AR_TX_PHY_MT_OFDM;
2018 		if (ridx <= OTUS_RIDX_OFDM24)
2019 			phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask);
2020 		else
2021 			phyctl |= AR_TX_PHY_ANTMSK(1);
2022 	} else {	/* CCK */
2023 		phyctl |= AR_TX_PHY_MT_CCK;
2024 		phyctl |= AR_TX_PHY_ANTMSK(sc->sc_txmask);
2025 	}
2026 
2027 	/* Update rate control stats for frames that are ACK'ed. */
2028 	if (!(macctl & AR_TX_MAC_NOACK))
2029 		on->amn.amn_txcnt++;
2030 
2031 	/* Fill Tx descriptor. */
2032 	head = (void *)data->buf;
2033 	head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN);
2034 	head->macctl = htole16(macctl);
2035 	head->phyctl = htole32(phyctl);
2036 
2037 	if (__predict_false(sc->sc_drvbpf != NULL)) {
2038 		struct otus_tx_radiotap_header *tap = &sc->sc_txtap;
2039 
2040 		tap->wt_flags = 0;
2041 		if (wh->i_fc[1] & IEEE80211_FC1_WEP)
2042 			tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2043 		tap->wt_rate = otus_rates[ridx].rate;
2044 		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
2045 		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
2046 
2047 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT);
2048 	}
2049 
2050 	xferlen = sizeof(*head) + m->m_pkthdr.len;
2051 	m_copydata(m, 0, m->m_pkthdr.len, (void *)&head[1]);
2052 
2053 	DPRINTFN(DBG_TX, sc, "queued len=%d mac=0x%04x phy=0x%08x rate=%d\n",
2054 	    head->len, head->macctl, head->phyctl, otus_rates[ridx].rate);
2055 
2056 	usbd_setup_xfer(data->xfer, data, data->buf, xferlen,
2057 	    USBD_FORCE_SHORT_XFER, OTUS_TX_TIMEOUT, otus_txeof);
2058 	error = usbd_transfer(data->xfer);
2059 	if (__predict_false(
2060 		    error != USBD_NORMAL_COMPLETION &&
2061 		    error != USBD_IN_PROGRESS)) {
2062 		DPRINTFN(DBG_TX, sc, "transfer failed %d\n", error);
2063 		return error;
2064 	}
2065 	return 0;
2066 }
2067 
2068 Static void
otus_start(struct ifnet * ifp)2069 otus_start(struct ifnet *ifp)
2070 {
2071 	struct otus_softc *sc;
2072 	struct ieee80211com *ic;
2073 	struct otus_tx_data *data;
2074 	struct ether_header *eh;
2075 	struct ieee80211_node *ni;
2076 	struct mbuf *m;
2077 
2078 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
2079 		return;
2080 
2081 	sc = ifp->if_softc;
2082 	ic = &sc->sc_ic;
2083 
2084 	DPRINTFN(DBG_FN, sc, "\n");
2085 
2086 	data = NULL;
2087 	for (;;) {
2088 		/*
2089 		 * Grab a Tx buffer if we don't already have one.  If
2090 		 * one isn't available, bail out.
2091 		 * NB: We must obtain this Tx buffer _before_
2092 		 * dequeueing anything as one may not be available
2093 		 * later.  Both must be done inside a single lock.
2094 		 */
2095 		mutex_enter(&sc->sc_tx_mtx);
2096 		if (data == NULL && !TAILQ_EMPTY(&sc->sc_tx_free_list)) {
2097 			data = TAILQ_FIRST(&sc->sc_tx_free_list);
2098 			TAILQ_REMOVE(&sc->sc_tx_free_list, data, next);
2099 		}
2100 		mutex_exit(&sc->sc_tx_mtx);
2101 
2102 		if (data == NULL) {
2103 			ifp->if_flags |= IFF_OACTIVE;
2104 			DPRINTFN(DBG_TX, sc, "empty sc_tx_free_list\n");
2105 			return;
2106 		}
2107 
2108 		/* Send pending management frames first. */
2109 		IF_DEQUEUE(&ic->ic_mgtq, m);
2110 		if (m != NULL) {
2111 			ni = M_GETCTX(m, struct ieee80211_node *);
2112 			M_CLEARCTX(m);
2113 			goto sendit;
2114 		}
2115 
2116 		if (ic->ic_state != IEEE80211_S_RUN)
2117 			break;
2118 
2119 		/* Encapsulate and send data frames. */
2120 		IFQ_DEQUEUE(&ifp->if_snd, m);
2121 		if (m == NULL)
2122 			break;
2123 
2124 		if (m->m_len < (int)sizeof(*eh) &&
2125 		    (m = m_pullup(m, sizeof(*eh))) == NULL) {
2126 			if_statinc(ifp, if_oerrors);
2127 			continue;
2128 		}
2129 
2130 		eh = mtod(m, struct ether_header *);
2131 		ni = ieee80211_find_txnode(ic, eh->ether_dhost);
2132 		if (ni == NULL) {
2133 			m_freem(m);
2134 			if_statinc(ifp, if_oerrors);
2135 			continue;
2136 		}
2137 
2138 		bpf_mtap(ifp, m, BPF_D_OUT);
2139 
2140 		if ((m = ieee80211_encap(ic, m, ni)) == NULL) {
2141 			/* original m was freed by ieee80211_encap() */
2142 			ieee80211_free_node(ni);
2143 			if_statinc(ifp, if_oerrors);
2144 			continue;
2145 		}
2146  sendit:
2147 		bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
2148 
2149 		if (otus_tx(sc, m, ni, data) != 0) {
2150 			m_freem(m);
2151 			ieee80211_free_node(ni);
2152 			if_statinc(ifp, if_oerrors);
2153 			continue;
2154 		}
2155 
2156 		data = NULL;	/* we're finished with this data buffer */
2157 		m_freem(m);
2158 		ieee80211_free_node(ni);
2159 		sc->sc_tx_timer = 5;
2160 		ifp->if_timer = 1;
2161 	}
2162 
2163 	/*
2164 	 * If here, we have a Tx buffer, but ran out of mbufs to
2165 	 * transmit.  Put the Tx buffer back to the free list.
2166 	 */
2167 	mutex_enter(&sc->sc_tx_mtx);
2168 	TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next);
2169 	mutex_exit(&sc->sc_tx_mtx);
2170 }
2171 
2172 Static void
otus_watchdog(struct ifnet * ifp)2173 otus_watchdog(struct ifnet *ifp)
2174 {
2175 	struct otus_softc *sc;
2176 
2177 	sc = ifp->if_softc;
2178 
2179 	DPRINTFN(DBG_FN, sc, "\n");
2180 
2181 	ifp->if_timer = 0;
2182 
2183 	if (sc->sc_tx_timer > 0) {
2184 		if (--sc->sc_tx_timer == 0) {
2185 			aprint_error_dev(sc->sc_dev, "device timeout\n");
2186 			/* otus_init(ifp); XXX needs a process context! */
2187 			if_statinc(ifp, if_oerrors);
2188 			return;
2189 		}
2190 		ifp->if_timer = 1;
2191 	}
2192 	ieee80211_watchdog(&sc->sc_ic);
2193 }
2194 
2195 Static int
otus_ioctl(struct ifnet * ifp,u_long cmd,void * data)2196 otus_ioctl(struct ifnet *ifp, u_long cmd, void *data)
2197 {
2198 	struct otus_softc *sc;
2199 	struct ieee80211com *ic;
2200 	int s, error = 0;
2201 
2202 	sc = ifp->if_softc;
2203 
2204 	DPRINTFN(DBG_FN, sc, "%#lx\n", cmd);
2205 
2206 	ic = &sc->sc_ic;
2207 
2208 	s = splnet();
2209 
2210 	switch (cmd) {
2211 	case SIOCSIFADDR:
2212 		ifp->if_flags |= IFF_UP;
2213 #ifdef INET
2214 		struct ifaddr *ifa = data;
2215 		if (ifa->ifa_addr->sa_family == AF_INET)
2216 			arp_ifinit(&ic->ic_ac, ifa);
2217 #endif
2218 		/* FALLTHROUGH */
2219 	case SIOCSIFFLAGS:
2220 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
2221 			break;
2222 
2223 		switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
2224 		case IFF_UP | IFF_RUNNING:
2225 			if (((ifp->if_flags ^ sc->sc_if_flags) &
2226 				(IFF_ALLMULTI | IFF_PROMISC)) != 0)
2227 				otus_set_multi(sc);
2228 			break;
2229 		case IFF_UP:
2230 			otus_init(ifp);
2231 			break;
2232 
2233 		case IFF_RUNNING:
2234 			otus_stop(ifp);
2235 			break;
2236 		case 0:
2237 		default:
2238 			break;
2239 		}
2240 		sc->sc_if_flags = ifp->if_flags;
2241 		break;
2242 
2243 	case SIOCADDMULTI:
2244 	case SIOCDELMULTI:
2245 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
2246 			/* setup multicast filter, etc */
2247 			/* XXX: ??? */
2248 			error = 0;
2249 		}
2250 		break;
2251 
2252 	case SIOCS80211CHANNEL:
2253 		/*
2254 		 * This allows for fast channel switching in monitor mode
2255 		 * (used by kismet). In IBSS mode, we must explicitly reset
2256 		 * the interface to generate a new beacon frame.
2257 		 */
2258 		error = ieee80211_ioctl(ic, cmd, data);
2259 
2260 		DPRINTFN(DBG_CHAN, sc,
2261 		    "ic_curchan=%d ic_ibss_chan=%d ic_des_chan=%d ni_chan=%d error=%d\n",
2262 		    ieee80211_chan2ieee(ic, ic->ic_curchan),
2263 		    ieee80211_chan2ieee(ic, ic->ic_ibss_chan),
2264 		    ieee80211_chan2ieee(ic, ic->ic_des_chan),
2265 		    ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
2266 		    error);
2267 
2268 		if (error == ENETRESET &&
2269 		    ic->ic_opmode == IEEE80211_M_MONITOR) {
2270 			if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2271 			    (IFF_UP | IFF_RUNNING)) {
2272 				mutex_enter(&sc->sc_write_mtx);
2273 				otus_set_chan(sc, ic->ic_curchan, 0);
2274 				mutex_exit(&sc->sc_write_mtx);
2275 			}
2276 			error = 0;
2277 		}
2278 		break;
2279 
2280 	default:
2281 		error = ieee80211_ioctl(ic, cmd, data);
2282 	}
2283 	if (error == ENETRESET) {
2284 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2285 		    (IFF_UP | IFF_RUNNING))
2286 			otus_init(ifp);
2287 		error = 0;
2288 	}
2289 	splx(s);
2290 	return error;
2291 }
2292 
2293 Static int
otus_set_multi(struct otus_softc * sc)2294 otus_set_multi(struct otus_softc *sc)
2295 {
2296 	struct ethercom *ec = &sc->sc_ec;
2297 	struct ifnet *ifp;
2298 	struct ether_multi *enm;
2299 	struct ether_multistep step;
2300 	uint32_t lo, hi;
2301 	uint8_t bit;
2302 	int error;
2303 
2304 	DPRINTFN(DBG_FN, sc, "\n");
2305 
2306 	ifp = sc->sc_ic.ic_ifp;
2307 	if ((ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
2308 		lo = hi = 0xffffffff;
2309 		goto done;
2310 	}
2311 	lo = hi = 0;
2312 	ETHER_LOCK(ec);
2313 	ETHER_FIRST_MULTI(step, ec, enm);
2314 	while (enm != NULL) {
2315 		if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
2316 			ifp->if_flags |= IFF_ALLMULTI;
2317 			lo = hi = 0xffffffff;
2318 			goto done;
2319 		}
2320 		bit = enm->enm_addrlo[5] >> 2;
2321 		if (bit < 32)
2322 			lo |= 1 << bit;
2323 		else
2324 			hi |= 1 << (bit - 32);
2325 		ETHER_NEXT_MULTI(step, enm);
2326 	}
2327  done:
2328 	ETHER_UNLOCK(ec);
2329 	mutex_enter(&sc->sc_write_mtx);
2330 	hi |= 1 << 31;	/* Make sure the broadcast bit is set. */
2331 	otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo);
2332 	otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi);
2333 	error = otus_write_barrier(sc);
2334 	mutex_exit(&sc->sc_write_mtx);
2335 	return error;
2336 }
2337 
2338 #ifdef HAVE_EDCA
2339 Static void
otus_updateedca(struct ieee80211com * ic)2340 otus_updateedca(struct ieee80211com *ic)
2341 {
2342 
2343 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
2344 
2345 	/* Do it in a process context. */
2346 	otus_do_async(ic->ic_ifp->if_softc, otus_updateedca_cb, NULL, 0);
2347 }
2348 
2349 Static void
otus_updateedca_cb(struct otus_softc * sc,void * arg __used)2350 otus_updateedca_cb(struct otus_softc *sc, void *arg __used)
2351 {
2352 
2353 	DPRINTFN(DBG_FN, sc, "\n");
2354 
2355 	mutex_enter(&sc->sc_write_mtx);
2356 	otus_updateedca_cb_locked(sc);
2357 	mutex_exit(&sc->sc_write_mtx);
2358 }
2359 #endif
2360 
2361 Static void
otus_updateedca_cb_locked(struct otus_softc * sc)2362 otus_updateedca_cb_locked(struct otus_softc *sc)
2363 {
2364 #ifdef HAVE_EDCA
2365 	struct ieee80211com *ic;
2366 #endif
2367 	const struct ieee80211_edca_ac_params *edca;
2368 	int s;
2369 
2370 	DPRINTFN(DBG_FN, sc, "\n");
2371 
2372 	KASSERT(mutex_owned(&sc->sc_write_mtx));
2373 
2374 	s = splnet();
2375 
2376 #ifdef HAVE_EDCA
2377 	ic = &sc->sc_ic;
2378 	edca = (ic->ic_flags & IEEE80211_F_QOS) ?
2379 	    ic->ic_edca_ac : otus_edca_def;
2380 #else
2381 	edca = otus_edca_def;
2382 #endif /* HAVE_EDCA */
2383 
2384 #define EXP2(val)	((1 << (val)) - 1)
2385 #define AIFS(val)	((val) * 9 + 10)
2386 
2387 	/* Set CWmin/CWmax values. */
2388 	otus_write(sc, AR_MAC_REG_AC0_CW,
2389 	    EXP2(edca[WME_AC_BE].ac_ecwmax) << 16 |
2390 	    EXP2(edca[WME_AC_BE].ac_ecwmin));
2391 	otus_write(sc, AR_MAC_REG_AC1_CW,
2392 	    EXP2(edca[WME_AC_BK].ac_ecwmax) << 16 |
2393 	    EXP2(edca[WME_AC_BK].ac_ecwmin));
2394 	otus_write(sc, AR_MAC_REG_AC2_CW,
2395 	    EXP2(edca[WME_AC_VI].ac_ecwmax) << 16 |
2396 	    EXP2(edca[WME_AC_VI].ac_ecwmin));
2397 	otus_write(sc, AR_MAC_REG_AC3_CW,
2398 	    EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 |
2399 	    EXP2(edca[WME_AC_VO].ac_ecwmin));
2400 	otus_write(sc, AR_MAC_REG_AC4_CW,		/* Special TXQ. */
2401 	    EXP2(edca[WME_AC_VO].ac_ecwmax) << 16 |
2402 	    EXP2(edca[WME_AC_VO].ac_ecwmin));
2403 
2404 	/* Set AIFSN values. */
2405 	otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS,
2406 	    AIFS(edca[WME_AC_VI].ac_aifsn) << 24 |
2407 	    AIFS(edca[WME_AC_BK].ac_aifsn) << 12 |
2408 	    AIFS(edca[WME_AC_BE].ac_aifsn));
2409 	otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS,
2410 	    AIFS(edca[WME_AC_VO].ac_aifsn) << 16 |	/* Special TXQ. */
2411 	    AIFS(edca[WME_AC_VO].ac_aifsn) <<  4 |
2412 	    AIFS(edca[WME_AC_VI].ac_aifsn) >>  8);
2413 
2414 	/* Set TXOP limit. */
2415 	otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP,
2416 	    edca[WME_AC_BK].ac_txoplimit << 16 |
2417 	    edca[WME_AC_BE].ac_txoplimit);
2418 	otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP,
2419 	    edca[WME_AC_VO].ac_txoplimit << 16 |
2420 	    edca[WME_AC_VI].ac_txoplimit);
2421 #undef AIFS
2422 #undef EXP2
2423 
2424 	splx(s);
2425 
2426 	(void)otus_write_barrier(sc);
2427 }
2428 
2429 Static void
otus_updateslot(struct ifnet * ifp)2430 otus_updateslot(struct ifnet *ifp)
2431 {
2432 	struct otus_softc *sc;
2433 
2434 	sc = ifp->if_softc;
2435 
2436 	DPRINTFN(DBG_FN, sc, "\n");
2437 
2438 	/* Do it in a process context. */
2439 	otus_do_async(sc, otus_updateslot_cb, NULL, 0);
2440 }
2441 
2442 /* ARGSUSED */
2443 Static void
otus_updateslot_cb(struct otus_softc * sc,void * arg)2444 otus_updateslot_cb(struct otus_softc *sc, void *arg)
2445 {
2446 
2447 	DPRINTFN(DBG_FN, sc, "\n");
2448 
2449 	mutex_enter(&sc->sc_write_mtx);
2450 	otus_updateslot_cb_locked(sc);
2451 	mutex_exit(&sc->sc_write_mtx);
2452 }
2453 
2454 Static void
otus_updateslot_cb_locked(struct otus_softc * sc)2455 otus_updateslot_cb_locked(struct otus_softc *sc)
2456 {
2457 	uint32_t slottime;
2458 
2459 	DPRINTFN(DBG_FN, sc, "\n");
2460 
2461 	KASSERT(mutex_owned(&sc->sc_write_mtx));
2462 
2463 	slottime = (sc->sc_ic.ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
2464 	otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10);
2465 	(void)otus_write_barrier(sc);
2466 }
2467 
2468 Static int
otus_init_mac(struct otus_softc * sc)2469 otus_init_mac(struct otus_softc *sc)
2470 {
2471 	int error;
2472 
2473 	DPRINTFN(DBG_FN | DBG_INIT, sc, "\n");
2474 
2475 	KASSERT(mutex_owned(&sc->sc_write_mtx));
2476 
2477 	otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40);
2478 	otus_write(sc, AR_MAC_REG_RETRY_MAX, 0);
2479 	otus_write(sc, AR_MAC_REG_SNIFFER, AR_MAC_REG_SNIFFER_DEFAULTS);
2480 	otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80);
2481 	otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70);
2482 	otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000);
2483 	otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10);
2484 
2485 	/* CF-END mode */
2486 	otus_write(sc, 0x1c3b2c, 0x19000000);
2487 
2488 	/* NAV protects ACK only (in TXOP). */
2489 	otus_write(sc, 0x1c3b38, 0x201);
2490 
2491 	/* Set beacon PHY CTRL's TPC to 0x7, TA1=1 */
2492 	/* OTUS set AM to 0x1 */
2493 	otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170);
2494 
2495 	otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105);
2496 
2497 	/* AGG test code*/
2498 	/* Aggregation MAX number and timeout */
2499 	otus_write(sc, AR_MAC_REG_AMPDU_FACTOR, 0x10000a);
2500 
2501 	/* Filter any control frames, BAR is bit 24. */
2502 	otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, AR_MAC_REG_FTF_DEFAULTS);
2503 
2504 	/* Enable deaggregator, response in sniffer mode */
2505 	otus_write(sc, 0x1c3c40, 0x1 | 1 << 30);	/* XXX: was 0x1 */
2506 
2507 	/* rate sets */
2508 	otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f);
2509 	otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f);
2510 	otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
2511 
2512 	/* MIMO response control */
2513 	otus_write(sc, 0x1c3694, 0x4003c1e);	/* bit 26~28  otus-AM */
2514 
2515 	/* Switch MAC to OTUS interface. */
2516 	otus_write(sc, 0x1c3600, 0x3);
2517 
2518 	otus_write(sc, AR_MAC_REG_AMPDU_RX_THRESH, 0xffff);
2519 
2520 	/* set PHY register read timeout (??) */
2521 	otus_write(sc, AR_MAC_REG_MISC_680, 0xf00008);
2522 
2523 	/* Disable Rx TimeOut, workaround for BB. */
2524 	otus_write(sc, AR_MAC_REG_RX_TIMEOUT, 0x0);
2525 
2526 	/* Set clock frequency to 88/80MHz. */
2527 	otus_write(sc, AR_PWR_REG_CLOCK_SEL,
2528 	    AR_PWR_CLK_AHB_80_88MHZ | AR_PWR_CLK_DAC_160_INV_DLY);
2529 
2530 	/* Set WLAN DMA interrupt mode: generate intr per packet. */
2531 	otus_write(sc, AR_MAC_REG_TXRX_MPI, 0x110011);
2532 
2533 	otus_write(sc, AR_MAC_REG_FCS_SELECT, AR_MAC_FCS_FIFO_PROT);
2534 
2535 	/* Disables the CF_END frame, undocumented register */
2536 	otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48);
2537 
2538 	/* Disable HW decryption for now. */
2539 	otus_write(sc, AR_MAC_REG_ENCRYPTION,
2540 	    AR_MAC_REG_ENCRYPTION_DEFAULTS | AR_MAC_REG_ENCRYPTION_RX_SOFTWARE);
2541 
2542 	/*
2543 	 * XXX: should these be elsewhere?
2544 	 */
2545 	/* Enable LED0 and LED1. */
2546 	otus_write(sc, AR_GPIO_REG_PORT_TYPE, 3);
2547 	otus_write(sc, AR_GPIO_REG_DATA,
2548 	    AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON);
2549 
2550 	/* Set USB Rx stream mode maximum frame number to 2. */
2551 	otus_write(sc, AR_USB_REG_MAX_AGG_UPLOAD, (1 << 2));
2552 
2553 	/* Set USB Rx stream mode timeout to 10us. */
2554 	otus_write(sc, AR_USB_REG_UPLOAD_TIME_CTL, 0x80);
2555 
2556 	if ((error = otus_write_barrier(sc)) != 0)
2557 		return error;
2558 
2559 	/* Set default EDCA parameters. */
2560 	otus_updateedca_cb_locked(sc);
2561 	return 0;
2562 }
2563 
2564 /*
2565  * Return default value for PHY register based on current operating mode.
2566  */
2567 Static uint32_t
otus_phy_get_def(struct otus_softc * sc,uint32_t reg)2568 otus_phy_get_def(struct otus_softc *sc, uint32_t reg)
2569 {
2570 	int i;
2571 
2572 	DPRINTFN(DBG_FN, sc, "\n");
2573 
2574 	for (i = 0; i < __arraycount(ar5416_phy_regs); i++)
2575 		if (AR_PHY(ar5416_phy_regs[i]) == reg)
2576 			return sc->sc_phy_vals[i];
2577 	return 0;	/* Register not found. */
2578 }
2579 
2580 /*
2581  * Update PHY's programming based on vendor-specific data stored in EEPROM.
2582  * This is for FEM-type devices only.
2583  */
2584 Static int
otus_set_board_values(struct otus_softc * sc,struct ieee80211_channel * c)2585 otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c)
2586 {
2587 	const struct ModalEepHeader *eep;
2588 	uint32_t tmp, offset;
2589 
2590 	DPRINTFN(DBG_FN, sc, "\n");
2591 
2592 	if (IEEE80211_IS_CHAN_5GHZ(c))
2593 		eep = &sc->sc_eeprom.modalHeader[0];
2594 	else
2595 		eep = &sc->sc_eeprom.modalHeader[1];
2596 
2597 	/* Offset of chain 2. */
2598 	offset = 2 * 0x1000;
2599 
2600 	tmp = le32toh(eep->antCtrlCommon);
2601 	otus_write(sc, AR_PHY_SWITCH_COM, tmp);
2602 
2603 	tmp = le32toh(eep->antCtrlChain[0]);
2604 	otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp);
2605 
2606 	tmp = le32toh(eep->antCtrlChain[1]);
2607 	otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp);
2608 
2609 	if (1 /* sc->sc_sco == AR_SCO_SCN */) {
2610 		tmp = otus_phy_get_def(sc, AR_PHY_SETTLING);
2611 		tmp &= ~(0x7f << 7);
2612 		tmp |= (eep->switchSettling & 0x7f) << 7;
2613 		otus_write(sc, AR_PHY_SETTLING, tmp);
2614 	}
2615 
2616 	tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ);
2617 	tmp &= ~0xffff;
2618 	tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize;
2619 	otus_write(sc, AR_PHY_DESIRED_SZ, tmp);
2620 
2621 	tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 |
2622 	      eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn;
2623 	otus_write(sc, AR_PHY_RF_CTL4, tmp);
2624 
2625 	tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3);
2626 	tmp &= ~(0xff << 16);
2627 	tmp |= eep->txEndToRxOn << 16;
2628 	otus_write(sc, AR_PHY_RF_CTL3, tmp);
2629 
2630 	tmp = otus_phy_get_def(sc, AR_PHY_CCA);
2631 	tmp &= ~(0x7f << 12);
2632 	tmp |= (eep->thresh62 & 0x7f) << 12;
2633 	otus_write(sc, AR_PHY_CCA, tmp);
2634 
2635 	tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN);
2636 	tmp &= ~(0x3f << 12);
2637 	tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12;
2638 	otus_write(sc, AR_PHY_RXGAIN, tmp);
2639 
2640 	tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset);
2641 	tmp &= ~(0x3f << 12);
2642 	tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12;
2643 	otus_write(sc, AR_PHY_RXGAIN + offset, tmp);
2644 
2645 	tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ);
2646 	tmp &= ~(0x3f << 18);
2647 	tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18;
2648 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
2649 		tmp &= ~(0xf << 10);
2650 		tmp |= (eep->bswMargin[0] & 0xf) << 10;
2651 	}
2652 	otus_write(sc, AR_PHY_GAIN_2GHZ, tmp);
2653 
2654 	tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset);
2655 	tmp &= ~(0x3f << 18);
2656 	tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18;
2657 	otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp);
2658 
2659 	tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4);
2660 	tmp &= ~(0x3f << 5 | 0x1f);
2661 	tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f);
2662 	otus_write(sc, AR_PHY_TIMING_CTRL4, tmp);
2663 
2664 	tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset);
2665 	tmp &= ~(0x3f << 5 | 0x1f);
2666 	tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f);
2667 	otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp);
2668 
2669 	tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1);
2670 	tmp &= ~(0xf << 16);
2671 	tmp |= (eep->xpd & 0xf) << 16;
2672 	otus_write(sc, AR_PHY_TPCRG1, tmp);
2673 
2674 	return otus_write_barrier(sc);
2675 }
2676 
2677 Static int
otus_program_phy(struct otus_softc * sc,struct ieee80211_channel * c)2678 otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c)
2679 {
2680 	const uint32_t *vals;
2681 	int error, i;
2682 
2683 	DPRINTFN(DBG_FN, sc, "\n");
2684 
2685 	/* Select PHY programming based on band and bandwidth. */
2686 	if (IEEE80211_IS_CHAN_2GHZ(c))
2687 		vals = ar5416_phy_vals_2ghz_20mhz;
2688 	else
2689 		vals = ar5416_phy_vals_5ghz_20mhz;
2690 	for (i = 0; i < __arraycount(ar5416_phy_regs); i++)
2691 		otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]);
2692 	sc->sc_phy_vals = vals;
2693 
2694 	if (sc->sc_eeprom.baseEepHeader.deviceType == 0x80)	/* FEM */
2695 		if ((error = otus_set_board_values(sc, c)) != 0)
2696 			return error;
2697 
2698 	/* Initial Tx power settings. */
2699 	otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f);
2700 	otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f);
2701 	otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f);
2702 	otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f);
2703 	otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f);
2704 	otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f);
2705 	otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f);
2706 	otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f);
2707 	otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f);
2708 	otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f);
2709 
2710 	if (IEEE80211_IS_CHAN_2GHZ(c))
2711 		otus_write(sc, 0x1d4014, 0x5163);
2712 	else
2713 		otus_write(sc, 0x1d4014, 0x5143);
2714 
2715 	return otus_write_barrier(sc);
2716 }
2717 
2718 static __inline uint8_t
otus_reverse_bits(uint8_t v)2719 otus_reverse_bits(uint8_t v)
2720 {
2721 
2722 	v = ((v >> 1) & 0x55) | ((v & 0x55) << 1);
2723 	v = ((v >> 2) & 0x33) | ((v & 0x33) << 2);
2724 	v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4);
2725 	return v;
2726 }
2727 
2728 Static int
otus_set_rf_bank4(struct otus_softc * sc,struct ieee80211_channel * c)2729 otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c)
2730 {
2731 	uint8_t chansel, d0, d1;
2732 	uint16_t data;
2733 	int error;
2734 
2735 	DPRINTFN(DBG_FN, sc, "\n");
2736 
2737 	d0 = 0;
2738 	if (IEEE80211_IS_CHAN_5GHZ(c)) {
2739 		chansel = (c->ic_freq - 4800) / 5;
2740 		if (chansel & 1)
2741 			d0 |= AR_BANK4_AMODE_REFSEL(2);
2742 		else
2743 			d0 |= AR_BANK4_AMODE_REFSEL(1);
2744 	} else {
2745 		d0 |= AR_BANK4_AMODE_REFSEL(2);
2746 		if (c->ic_freq == 2484) {	/* CH 14 */
2747 			d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ;
2748 			chansel = 10 + (c->ic_freq - 2274) / 5;
2749 		} else
2750 			chansel = 16 + (c->ic_freq - 2272) / 5;
2751 		chansel <<= 2;
2752 	}
2753 	d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP;
2754 	d1 = otus_reverse_bits(chansel);
2755 
2756 	/* Write bits 0-4 of d0 and d1. */
2757 	data = (d1 & 0x1f) << 5 | (d0 & 0x1f);
2758 	otus_write(sc, AR_PHY(44), data);
2759 	/* Write bits 5-7 of d0 and d1. */
2760 	data = (d1 >> 5) << 5 | (d0 >> 5);
2761 	otus_write(sc, AR_PHY(58), data);
2762 
2763 	if ((error = otus_write_barrier(sc)) == 0)
2764 		usbd_delay_ms(sc->sc_udev, 10);
2765 
2766 	return error;
2767 }
2768 
2769 Static void
otus_get_delta_slope(uint32_t coeff,uint32_t * exponent,uint32_t * mantissa)2770 otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa)
2771 {
2772 #define COEFF_SCALE_SHIFT	24
2773 	uint32_t exp, man;
2774 
2775 	DPRINTFN(DBG_FN, DBG_NO_SC, "\n");
2776 
2777 	/* exponent = 14 - floor(log2(coeff)) */
2778 	for (exp = 31; exp > 0; exp--)
2779 		if (coeff & (1 << exp))
2780 			break;
2781 	KASSERT(exp != 0);
2782 	exp = 14 - (exp - COEFF_SCALE_SHIFT);
2783 
2784 	/* mantissa = floor(coeff * 2^exponent + 0.5) */
2785 	man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1));
2786 
2787 	*mantissa = man >> (COEFF_SCALE_SHIFT - exp);
2788 	*exponent = exp - 16;
2789 #undef COEFF_SCALE_SHIFT
2790 }
2791 
2792 Static int
otus_set_chan(struct otus_softc * sc,struct ieee80211_channel * c,int assoc)2793 otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc)
2794 {
2795 	struct ar_cmd_frequency cmd;
2796 	struct ar_rsp_frequency rsp;
2797 	const uint32_t *vals;
2798 	uint32_t coeff, exp, man, tmp;
2799 	uint8_t code;
2800 	int error, i;
2801 
2802 	DPRINTFN(DBG_FN, sc, "\n");
2803 
2804 
2805 #ifdef OTUS_DEBUG
2806 	struct ieee80211com *ic = &sc->sc_ic;
2807 	int chan = ieee80211_chan2ieee(ic, c);
2808 
2809 	DPRINTFN(DBG_CHAN, sc, "setting channel %d (%dMHz)\n",
2810 	    chan, c->ic_freq);
2811 #endif
2812 
2813 	tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104;
2814 	otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp);
2815 	if ((error = otus_write_barrier(sc)) != 0)
2816 		return error;
2817 
2818 	/* Disable BB Heavy Clip. */
2819 	otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200);
2820 	if ((error = otus_write_barrier(sc)) != 0)
2821 		return error;
2822 
2823 	/* XXX Is that FREQ_START ? */
2824 	error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL);
2825 	if (error != 0)
2826 		return error;
2827 
2828 	/* Reprogram PHY and RF on channel band or bandwidth changes. */
2829 	if (sc->sc_bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) {
2830 		DPRINTFN(DBG_CHAN, sc, "band switch\n");
2831 
2832 		/* Cold/Warm reset BB/ADDA. */
2833 		otus_write(sc, 0x1d4004, sc->sc_bb_reset ? 0x800 : 0x400);
2834 		if ((error = otus_write_barrier(sc)) != 0)
2835 			return error;
2836 
2837 		otus_write(sc, 0x1d4004, 0);
2838 		if ((error = otus_write_barrier(sc)) != 0)
2839 			return error;
2840 		sc->sc_bb_reset = 0;
2841 
2842 		if ((error = otus_program_phy(sc, c)) != 0) {
2843 			aprint_error_dev(sc->sc_dev,
2844 			    "could not program PHY\n");
2845 			return error;
2846 		}
2847 
2848 		/* Select RF programming based on band. */
2849 		if (IEEE80211_IS_CHAN_5GHZ(c))
2850 			vals = ar5416_banks_vals_5ghz;
2851 		else
2852 			vals = ar5416_banks_vals_2ghz;
2853 		for (i = 0; i < __arraycount(ar5416_banks_regs); i++)
2854 			otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]);
2855 		if ((error = otus_write_barrier(sc)) != 0) {
2856 			aprint_error_dev(sc->sc_dev, "could not program RF\n");
2857 			return error;
2858 		}
2859 		code = AR_CMD_RF_INIT;
2860 	} else {
2861 		code = AR_CMD_FREQUENCY;
2862 	}
2863 
2864 	if ((error = otus_set_rf_bank4(sc, c)) != 0)
2865 		return error;
2866 
2867 	tmp = (sc->sc_txmask == 0x5) ? 0x340 : 0x240;
2868 	otus_write(sc, AR_PHY_TURBO, tmp);
2869 	if ((error = otus_write_barrier(sc)) != 0)
2870 		return error;
2871 
2872 	/* Send firmware command to set channel. */
2873 	cmd.freq = htole32((uint32_t)c->ic_freq * 1000);
2874 	cmd.dynht2040 = htole32(0);
2875 	cmd.htena = htole32(1);
2876 
2877 	/* Set Delta Slope (exponent and mantissa). */
2878 	coeff = (100 << 24) / c->ic_freq;
2879 	otus_get_delta_slope(coeff, &exp, &man);
2880 	cmd.dsc_exp = htole32(exp);
2881 	cmd.dsc_man = htole32(man);
2882 	DPRINTFN(DBG_CHAN, sc, "ds coeff=%u exp=%u man=%u\n",
2883 	    coeff, exp, man);
2884 
2885 	/* For Short GI, coeff is 9/10 that of normal coeff. */
2886 	coeff = (9 * coeff) / 10;
2887 	otus_get_delta_slope(coeff, &exp, &man);
2888 	cmd.dsc_shgi_exp = htole32(exp);
2889 	cmd.dsc_shgi_man = htole32(man);
2890 	DPRINTFN(DBG_CHAN, sc, "ds shgi coeff=%u exp=%u man=%u\n",
2891 	    coeff, exp, man);
2892 
2893 	/* Set wait time for AGC and noise calibration (100 or 200ms). */
2894 	cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000);
2895 	DPRINTFN(DBG_CHAN, sc, "%s\n",
2896 	    code == AR_CMD_RF_INIT ? "RF_INIT" : "FREQUENCY");
2897 	error = otus_cmd(sc, code, &cmd, sizeof(cmd), &rsp);
2898 	if (error != 0)
2899 		return error;
2900 
2901 	if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) {
2902 		DPRINTFN(DBG_CHAN, sc, "status=%#x\n", le32toh(rsp.status));
2903 		/* Force cold reset on next channel. */
2904 		sc->sc_bb_reset = 1;
2905 	}
2906 
2907 #ifdef OTUS_DEBUG
2908 	if (otus_debug & DBG_CHAN) {
2909 		DPRINTFN(DBG_CHAN, sc, "calibration status=%#x\n",
2910 		    le32toh(rsp.status));
2911 		for (i = 0; i < 2; i++) {	/* 2 Rx chains */
2912 			/* Sign-extend 9-bit NF values. */
2913 			DPRINTFN(DBG_CHAN, sc, "noisefloor chain %d=%d\n",
2914 			    i, (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23);
2915 			DPRINTFN(DBG_CHAN, sc, "noisefloor ext chain %d=%d\n",
2916 			    i, ((int32_t)le32toh(rsp.nf_ext[i])) >> 23);
2917 		}
2918 	}
2919 #endif
2920 	sc->sc_curchan = c;
2921 	return 0;
2922 }
2923 
2924 #ifdef notyet
2925 Static int
otus_set_key(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_key * k)2926 otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
2927     struct ieee80211_key *k)
2928 {
2929 	struct otus_softc *sc;
2930 	struct otus_cmd_key cmd;
2931 
2932 	sc = ic->ic_ifp->if_softc;
2933 
2934 	DPRINTFN(DBG_FN, sc, "\n");
2935 
2936 	/* Defer setting of WEP keys until interface is brought up. */
2937 	if ((ic->ic_ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
2938 	    (IFF_UP | IFF_RUNNING))
2939 		return 0;
2940 
2941 	/* Do it in a process context. */
2942 	cmd.key = *k;
2943 	cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
2944 	otus_do_async(sc, otus_set_key_cb, &cmd, sizeof(cmd));
2945 	return 0;
2946 }
2947 
2948 Static void
otus_set_key_cb(struct otus_softc * sc,void * arg)2949 otus_set_key_cb(struct otus_softc *sc, void *arg)
2950 {
2951 	struct otus_cmd_key *cmd;
2952 	struct ieee80211_key *k;
2953 	struct ar_cmd_ekey key;
2954 	uint16_t cipher;
2955 	int error;
2956 
2957 	DPRINTFN(DBG_FN, sc, "\n");
2958 
2959 	cmd = arg;
2960 	k = &cmd->key;
2961 
2962 	memset(&key, 0, sizeof(key));
2963 	if (k->k_flags & IEEE80211_KEY_GROUP) {
2964 		key.uid = htole16(k->k_id);
2965 		IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr);
2966 		key.macaddr[0] |= 0x80;
2967 	} else {
2968 		key.uid = htole16(OTUS_UID(cmd->associd));
2969 		IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr);
2970 	}
2971 	key.kix = htole16(0);
2972 	/* Map net80211 cipher to hardware. */
2973 	switch (k->k_cipher) {
2974 	case IEEE80211_CIPHER_WEP40:
2975 		cipher = AR_CIPHER_WEP64;
2976 		break;
2977 	case IEEE80211_CIPHER_WEP104:
2978 		cipher = AR_CIPHER_WEP128;
2979 		break;
2980 	case IEEE80211_CIPHER_TKIP:
2981 		cipher = AR_CIPHER_TKIP;
2982 		break;
2983 	case IEEE80211_CIPHER_CCMP:
2984 		cipher = AR_CIPHER_AES;
2985 		break;
2986 	default:
2987 		return;
2988 	}
2989 	key.cipher = htole16(cipher);
2990 	memcpy(key.key, k->k_key, MIN(k->k_len, 16));
2991 	error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL);
2992 	if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP)
2993 		return;
2994 
2995 	/* TKIP: set Tx/Rx MIC Key. */
2996 	key.kix = htole16(1);
2997 	memcpy(key.key, k->k_key + 16, 16);
2998 	(void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof(key), NULL);
2999 }
3000 
3001 Static void
otus_delete_key(struct ieee80211com * ic,struct ieee80211_node * ni,struct ieee80211_key * k)3002 otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
3003     struct ieee80211_key *k)
3004 {
3005 	struct otus_softc *sc;
3006 	struct otus_cmd_key cmd;
3007 
3008 	sc = ic->ic_ifp->if_softc;
3009 
3010 	DPRINTFN(DBG_FN, sc, "\n");
3011 
3012 	if (!(ic->ic_ifp->if_flags & IFF_RUNNING) ||
3013 	    ic->ic_state != IEEE80211_S_RUN)
3014 		return;	/* Nothing to do. */
3015 
3016 	/* Do it in a process context. */
3017 	cmd.key = *k;
3018 	cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
3019 	otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof(cmd));
3020 }
3021 
3022 Static void
otus_delete_key_cb(struct otus_softc * sc,void * arg)3023 otus_delete_key_cb(struct otus_softc *sc, void *arg)
3024 {
3025 	struct otus_cmd_key *cmd;
3026 	struct ieee80211_key *k;
3027 	uint32_t uid;
3028 
3029 	DPRINTFN(DBG_FN, sc, "\n");
3030 
3031 	cmd = arg;
3032 	k = &cmd->key;
3033 	if (k->k_flags & IEEE80211_KEY_GROUP)
3034 		uid = htole32(k->k_id);
3035 	else
3036 		uid = htole32(OTUS_UID(cmd->associd));
3037 	(void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof(uid), NULL);
3038 }
3039 #endif /* notyet */
3040 
3041 Static void
otus_calib_to(void * arg)3042 otus_calib_to(void *arg)
3043 {
3044 	struct otus_softc *sc;
3045 	struct ieee80211com *ic;
3046 	struct ieee80211_node *ni;
3047 	struct otus_node *on;
3048 	int s;
3049 
3050 	sc = arg;
3051 
3052 	DPRINTFN(DBG_FN, sc, "\n");
3053 
3054 	if (sc->sc_dying)
3055 		return;
3056 
3057 	s = splnet();
3058 	ic = &sc->sc_ic;
3059 	ni = ic->ic_bss;
3060 	on = (void *)ni;
3061 	ieee80211_amrr_choose(&sc->sc_amrr, ni, &on->amn);
3062 	splx(s);
3063 
3064 	if (!sc->sc_dying)
3065 		callout_schedule(&sc->sc_calib_to, hz);
3066 }
3067 
3068 Static int
otus_set_bssid(struct otus_softc * sc,const uint8_t * bssid)3069 otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid)
3070 {
3071 
3072 	DPRINTFN(DBG_FN, sc, "\n");
3073 
3074 	KASSERT(mutex_owned(&sc->sc_write_mtx));
3075 
3076 	otus_write(sc, AR_MAC_REG_BSSID_L,
3077 	    bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
3078 	otus_write(sc, AR_MAC_REG_BSSID_H,
3079 	    bssid[4] | bssid[5] << 8);
3080 	return otus_write_barrier(sc);
3081 }
3082 
3083 Static int
otus_set_macaddr(struct otus_softc * sc,const uint8_t * addr)3084 otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr)
3085 {
3086 
3087 	DPRINTFN(DBG_FN, sc, "\n");
3088 
3089 	KASSERT(mutex_owned(&sc->sc_write_mtx));
3090 
3091 	otus_write(sc, AR_MAC_REG_MAC_ADDR_L,
3092 	    addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
3093 	otus_write(sc, AR_MAC_REG_MAC_ADDR_H,
3094 	    addr[4] | addr[5] << 8);
3095 	return otus_write_barrier(sc);
3096 }
3097 
3098 #ifdef notyet
3099 /* Default single-LED. */
3100 Static void
otus_led_newstate_type1(struct otus_softc * sc)3101 otus_led_newstate_type1(struct otus_softc *sc)
3102 {
3103 
3104 	DPRINTFN(DBG_FN, sc, "\n");
3105 
3106 	/* TBD */
3107 }
3108 
3109 /* NETGEAR, dual-LED. */
3110 Static void
otus_led_newstate_type2(struct otus_softc * sc)3111 otus_led_newstate_type2(struct otus_softc *sc)
3112 {
3113 
3114 	DPRINTFN(DBG_FN, sc, "\n");
3115 
3116 	/* TBD */
3117 }
3118 #endif /* notyet */
3119 
3120 /*
3121  * NETGEAR, single-LED/3 colors (blue, red, purple.)
3122  */
3123 Static void
otus_led_newstate_type3(struct otus_softc * sc)3124 otus_led_newstate_type3(struct otus_softc *sc)
3125 {
3126 	struct ieee80211com *ic;
3127 	uint32_t led_state;
3128 
3129 	DPRINTFN(DBG_FN, sc, "\n");
3130 
3131 	ic = &sc->sc_ic;
3132 	led_state = sc->sc_led_state;
3133 	switch (ic->ic_state) {
3134 	case IEEE80211_S_INIT:
3135 		led_state = 0;
3136 		break;
3137 	case IEEE80211_S_SCAN:
3138 		led_state ^= AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON;
3139 		led_state &= ~(IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ?
3140 		    AR_GPIO_REG_DATA_LED1_ON : AR_GPIO_REG_DATA_LED0_ON);
3141 		break;
3142 	case IEEE80211_S_AUTH:
3143 	case IEEE80211_S_ASSOC:
3144 		/* XXX: Turn both LEDs on for AUTH and ASSOC? */
3145 		led_state = AR_GPIO_REG_DATA_LED0_ON | AR_GPIO_REG_DATA_LED1_ON;
3146 		break;
3147 	case IEEE80211_S_RUN:
3148 		led_state = IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) ?
3149 		    AR_GPIO_REG_DATA_LED0_ON : AR_GPIO_REG_DATA_LED1_ON;
3150 		break;
3151 	}
3152 	if (led_state != sc->sc_led_state) {
3153 		otus_write(sc, AR_GPIO_REG_DATA, led_state);
3154 		if (otus_write_barrier(sc) == 0)
3155 			sc->sc_led_state = led_state;
3156 	}
3157 }
3158 
3159 Static int
otus_init(struct ifnet * ifp)3160 otus_init(struct ifnet *ifp)
3161 {
3162 	struct otus_softc *sc;
3163 	struct ieee80211com *ic;
3164 	uint32_t filter, pm_mode, sniffer;
3165 	int error;
3166 
3167 	sc = ifp->if_softc;
3168 
3169 	DPRINTFN(DBG_FN | DBG_INIT, sc, "\n");
3170 
3171 	ic = &sc->sc_ic;
3172 
3173 	mutex_enter(&sc->sc_write_mtx);
3174 
3175 	/* Init host command ring. */
3176 	mutex_spin_enter(&sc->sc_task_mtx);
3177 	sc->sc_cmdq.cur = sc->sc_cmdq.next = sc->sc_cmdq.queued = 0;
3178 	mutex_spin_exit(&sc->sc_task_mtx);
3179 
3180 	if ((error = otus_init_mac(sc)) != 0) {
3181 		mutex_exit(&sc->sc_write_mtx);
3182 		aprint_error_dev(sc->sc_dev, "could not initialize MAC\n");
3183 		return error;
3184 	}
3185 
3186 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
3187 	(void)otus_set_macaddr(sc, ic->ic_myaddr);
3188 
3189 	pm_mode = AR_MAC_REG_POWERMGT_DEFAULTS;
3190 	sniffer = AR_MAC_REG_SNIFFER_DEFAULTS;
3191 	filter = AR_MAC_REG_FTF_DEFAULTS;
3192 	sc->sc_rx_error_msk = ~0;
3193 
3194 	switch (ic->ic_opmode) {
3195 #ifdef notyet
3196 #ifndef IEEE80211_STA_ONLY
3197 	case IEEE80211_M_HOSTAP:
3198 		pm_mode |= AR_MAC_REG_POWERMGT_AP;
3199 		break;
3200 	case IEEE80211_M_IBSS:
3201 		pm_mode |= AR_MAC_REG_POWERMGT_IBSS;	/* XXX: was 0x0 */
3202 		break;
3203 #endif
3204 #endif
3205 	case IEEE80211_M_STA:
3206 		pm_mode |= AR_MAC_REG_POWERMGT_STA;
3207 		break;
3208 	case IEEE80211_M_MONITOR:
3209 		sc->sc_rx_error_msk = ~AR_RX_ERROR_BAD_RA;
3210 		filter = AR_MAC_REG_FTF_MONITOR;
3211 		sniffer |= AR_MAC_REG_SNIFFER_ENABLE_PROMISC;
3212 		break;
3213 	default:
3214 		aprint_error_dev(sc->sc_dev, "bad opmode: %d", ic->ic_opmode);
3215 		return EOPNOTSUPP;	/* XXX: ??? */
3216 	}
3217 	otus_write(sc, AR_MAC_REG_POWERMANAGEMENT, pm_mode);
3218 	otus_write(sc, AR_MAC_REG_FRAMETYPE_FILTER, filter);
3219 	otus_write(sc, AR_MAC_REG_SNIFFER, sniffer);
3220 	(void)otus_write_barrier(sc);
3221 
3222 	sc->sc_bb_reset = 1;	/* Force cold reset. */
3223 	if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) {
3224 		mutex_exit(&sc->sc_write_mtx);
3225 		aprint_error_dev(sc->sc_dev, "could not set channel\n");
3226 		return error;
3227 	}
3228 
3229 	/* Start Rx. */
3230 	otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_ENABLE);
3231 	(void)otus_write_barrier(sc);
3232 	mutex_exit(&sc->sc_write_mtx);
3233 
3234 	ifp->if_flags &= ~IFF_OACTIVE;
3235 	ifp->if_flags |= IFF_RUNNING;
3236 
3237 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
3238 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
3239 	else
3240 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3241 
3242 	return 0;
3243 }
3244 
3245 Static void
otus_stop(struct ifnet * ifp)3246 otus_stop(struct ifnet *ifp)
3247 {
3248 	struct otus_softc *sc;
3249 	struct ieee80211com *ic;
3250 	int s;
3251 
3252 	sc = ifp->if_softc;
3253 
3254 	DPRINTFN(DBG_FN, sc, "\n");
3255 
3256 	ic = &sc->sc_ic;
3257 
3258 	sc->sc_tx_timer = 0;
3259 	ifp->if_timer = 0;
3260 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
3261 
3262 	callout_halt(&sc->sc_scan_to, NULL);
3263 	callout_halt(&sc->sc_calib_to, NULL);
3264 
3265 	s = splusb();
3266 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
3267 	otus_wait_async(sc);
3268 	splx(s);
3269 
3270 	/* Stop Rx. */
3271 	mutex_enter(&sc->sc_write_mtx);
3272 	otus_write(sc, AR_MAC_REG_DMA, AR_MAC_REG_DMA_OFF);
3273 	(void)otus_write_barrier(sc);
3274 	mutex_exit(&sc->sc_write_mtx);
3275 }
3276