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