if_rum.c revision 292165
1/*	$FreeBSD: head/sys/dev/usb/wlan/if_rum.c 292165 2015-12-13 20:48:24Z avos $	*/
2
3/*-
4 * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
5 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
6 * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@FreeBSD.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/cdefs.h>
22__FBSDID("$FreeBSD: head/sys/dev/usb/wlan/if_rum.c 292165 2015-12-13 20:48:24Z avos $");
23
24/*-
25 * Ralink Technology RT2501USB/RT2601USB chipset driver
26 * http://www.ralinktech.com.tw/
27 */
28
29#include <sys/param.h>
30#include <sys/sockio.h>
31#include <sys/sysctl.h>
32#include <sys/lock.h>
33#include <sys/mutex.h>
34#include <sys/mbuf.h>
35#include <sys/kernel.h>
36#include <sys/socket.h>
37#include <sys/systm.h>
38#include <sys/malloc.h>
39#include <sys/module.h>
40#include <sys/bus.h>
41#include <sys/endian.h>
42#include <sys/kdb.h>
43
44#include <machine/bus.h>
45#include <machine/resource.h>
46#include <sys/rman.h>
47
48#include <net/bpf.h>
49#include <net/if.h>
50#include <net/if_var.h>
51#include <net/if_arp.h>
52#include <net/ethernet.h>
53#include <net/if_dl.h>
54#include <net/if_media.h>
55#include <net/if_types.h>
56
57#ifdef INET
58#include <netinet/in.h>
59#include <netinet/in_systm.h>
60#include <netinet/in_var.h>
61#include <netinet/if_ether.h>
62#include <netinet/ip.h>
63#endif
64
65#include <net80211/ieee80211_var.h>
66#include <net80211/ieee80211_regdomain.h>
67#include <net80211/ieee80211_radiotap.h>
68#include <net80211/ieee80211_ratectl.h>
69
70#include <dev/usb/usb.h>
71#include <dev/usb/usbdi.h>
72#include "usbdevs.h"
73
74#define	USB_DEBUG_VAR rum_debug
75#include <dev/usb/usb_debug.h>
76
77#include <dev/usb/wlan/if_rumreg.h>
78#include <dev/usb/wlan/if_rumvar.h>
79#include <dev/usb/wlan/if_rumfw.h>
80
81#ifdef USB_DEBUG
82static int rum_debug = 0;
83
84static SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
85SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RWTUN, &rum_debug, 0,
86    "Debug level");
87#endif
88
89static const STRUCT_USB_HOST_ID rum_devs[] = {
90#define	RUM_DEV(v,p)  { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
91    RUM_DEV(ABOCOM, HWU54DM),
92    RUM_DEV(ABOCOM, RT2573_2),
93    RUM_DEV(ABOCOM, RT2573_3),
94    RUM_DEV(ABOCOM, RT2573_4),
95    RUM_DEV(ABOCOM, WUG2700),
96    RUM_DEV(AMIT, CGWLUSB2GO),
97    RUM_DEV(ASUS, RT2573_1),
98    RUM_DEV(ASUS, RT2573_2),
99    RUM_DEV(BELKIN, F5D7050A),
100    RUM_DEV(BELKIN, F5D9050V3),
101    RUM_DEV(CISCOLINKSYS, WUSB54GC),
102    RUM_DEV(CISCOLINKSYS, WUSB54GR),
103    RUM_DEV(CONCEPTRONIC2, C54RU2),
104    RUM_DEV(COREGA, CGWLUSB2GL),
105    RUM_DEV(COREGA, CGWLUSB2GPX),
106    RUM_DEV(DICKSMITH, CWD854F),
107    RUM_DEV(DICKSMITH, RT2573),
108    RUM_DEV(EDIMAX, EW7318USG),
109    RUM_DEV(DLINK2, DWLG122C1),
110    RUM_DEV(DLINK2, WUA1340),
111    RUM_DEV(DLINK2, DWA111),
112    RUM_DEV(DLINK2, DWA110),
113    RUM_DEV(GIGABYTE, GNWB01GS),
114    RUM_DEV(GIGABYTE, GNWI05GS),
115    RUM_DEV(GIGASET, RT2573),
116    RUM_DEV(GOODWAY, RT2573),
117    RUM_DEV(GUILLEMOT, HWGUSB254LB),
118    RUM_DEV(GUILLEMOT, HWGUSB254V2AP),
119    RUM_DEV(HUAWEI3COM, WUB320G),
120    RUM_DEV(MELCO, G54HP),
121    RUM_DEV(MELCO, SG54HP),
122    RUM_DEV(MELCO, SG54HG),
123    RUM_DEV(MELCO, WLIUCG),
124    RUM_DEV(MELCO, WLRUCG),
125    RUM_DEV(MELCO, WLRUCGAOSS),
126    RUM_DEV(MSI, RT2573_1),
127    RUM_DEV(MSI, RT2573_2),
128    RUM_DEV(MSI, RT2573_3),
129    RUM_DEV(MSI, RT2573_4),
130    RUM_DEV(NOVATECH, RT2573),
131    RUM_DEV(PLANEX2, GWUS54HP),
132    RUM_DEV(PLANEX2, GWUS54MINI2),
133    RUM_DEV(PLANEX2, GWUSMM),
134    RUM_DEV(QCOM, RT2573),
135    RUM_DEV(QCOM, RT2573_2),
136    RUM_DEV(QCOM, RT2573_3),
137    RUM_DEV(RALINK, RT2573),
138    RUM_DEV(RALINK, RT2573_2),
139    RUM_DEV(RALINK, RT2671),
140    RUM_DEV(SITECOMEU, WL113R2),
141    RUM_DEV(SITECOMEU, WL172),
142    RUM_DEV(SPARKLAN, RT2573),
143    RUM_DEV(SURECOM, RT2573),
144#undef RUM_DEV
145};
146
147static device_probe_t rum_match;
148static device_attach_t rum_attach;
149static device_detach_t rum_detach;
150
151static usb_callback_t rum_bulk_read_callback;
152static usb_callback_t rum_bulk_write_callback;
153
154static usb_error_t	rum_do_request(struct rum_softc *sc,
155			    struct usb_device_request *req, void *data);
156static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
157			    const char [IFNAMSIZ], int, enum ieee80211_opmode,
158			    int, const uint8_t [IEEE80211_ADDR_LEN],
159			    const uint8_t [IEEE80211_ADDR_LEN]);
160static void		rum_vap_delete(struct ieee80211vap *);
161static void		rum_cmdq_cb(void *, int);
162static int		rum_cmd_sleepable(struct rum_softc *, const void *,
163			    size_t, uint8_t, CMD_FUNC_PROTO);
164static void		rum_tx_free(struct rum_tx_data *, int);
165static void		rum_setup_tx_list(struct rum_softc *);
166static void		rum_unsetup_tx_list(struct rum_softc *);
167static int		rum_newstate(struct ieee80211vap *,
168			    enum ieee80211_state, int);
169static uint8_t		rum_crypto_mode(struct rum_softc *, u_int, int);
170static void		rum_setup_tx_desc(struct rum_softc *,
171			    struct rum_tx_desc *, struct ieee80211_key *,
172			    uint32_t, uint8_t, uint8_t, int, int, int);
173static uint32_t		rum_tx_crypto_flags(struct rum_softc *,
174			    struct ieee80211_node *,
175			    const struct ieee80211_key *);
176static int		rum_tx_mgt(struct rum_softc *, struct mbuf *,
177			    struct ieee80211_node *);
178static int		rum_tx_raw(struct rum_softc *, struct mbuf *,
179			    struct ieee80211_node *,
180			    const struct ieee80211_bpf_params *);
181static int		rum_tx_data(struct rum_softc *, struct mbuf *,
182			    struct ieee80211_node *);
183static int		rum_transmit(struct ieee80211com *, struct mbuf *);
184static void		rum_start(struct rum_softc *);
185static void		rum_parent(struct ieee80211com *);
186static void		rum_eeprom_read(struct rum_softc *, uint16_t, void *,
187			    int);
188static uint32_t		rum_read(struct rum_softc *, uint16_t);
189static void		rum_read_multi(struct rum_softc *, uint16_t, void *,
190			    int);
191static usb_error_t	rum_write(struct rum_softc *, uint16_t, uint32_t);
192static usb_error_t	rum_write_multi(struct rum_softc *, uint16_t, void *,
193			    size_t);
194static usb_error_t	rum_setbits(struct rum_softc *, uint16_t, uint32_t);
195static usb_error_t	rum_clrbits(struct rum_softc *, uint16_t, uint32_t);
196static usb_error_t	rum_modbits(struct rum_softc *, uint16_t, uint32_t,
197			    uint32_t);
198static int		rum_bbp_busy(struct rum_softc *);
199static void		rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
200static uint8_t		rum_bbp_read(struct rum_softc *, uint8_t);
201static void		rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
202static void		rum_select_antenna(struct rum_softc *);
203static void		rum_enable_mrr(struct rum_softc *);
204static void		rum_set_txpreamble(struct rum_softc *);
205static void		rum_set_basicrates(struct rum_softc *);
206static void		rum_select_band(struct rum_softc *,
207			    struct ieee80211_channel *);
208static void		rum_set_chan(struct rum_softc *,
209			    struct ieee80211_channel *);
210static void		rum_set_maxretry(struct rum_softc *,
211			    struct ieee80211vap *);
212static int		rum_enable_tsf_sync(struct rum_softc *);
213static void		rum_enable_tsf(struct rum_softc *);
214static void		rum_abort_tsf_sync(struct rum_softc *);
215static void		rum_get_tsf(struct rum_softc *, uint64_t *);
216static void		rum_update_slot_cb(struct rum_softc *,
217			    union sec_param *, uint8_t);
218static void		rum_update_slot(struct ieee80211com *);
219static int		rum_wme_update(struct ieee80211com *);
220static void		rum_set_bssid(struct rum_softc *, const uint8_t *);
221static void		rum_set_macaddr(struct rum_softc *, const uint8_t *);
222static void		rum_update_mcast(struct ieee80211com *);
223static void		rum_update_promisc(struct ieee80211com *);
224static void		rum_setpromisc(struct rum_softc *);
225static const char	*rum_get_rf(int);
226static void		rum_read_eeprom(struct rum_softc *);
227static int		rum_bbp_wakeup(struct rum_softc *);
228static int		rum_bbp_init(struct rum_softc *);
229static void		rum_clr_shkey_regs(struct rum_softc *);
230static int		rum_init(struct rum_softc *);
231static void		rum_stop(struct rum_softc *);
232static void		rum_load_microcode(struct rum_softc *, const uint8_t *,
233			    size_t);
234static int		rum_set_beacon(struct rum_softc *,
235			    struct ieee80211vap *);
236static int		rum_alloc_beacon(struct rum_softc *,
237			    struct ieee80211vap *);
238static void		rum_update_beacon_cb(struct rum_softc *,
239			    union sec_param *, uint8_t);
240static void		rum_update_beacon(struct ieee80211vap *, int);
241static int		rum_common_key_set(struct rum_softc *,
242			    struct ieee80211_key *, uint16_t);
243static void		rum_group_key_set_cb(struct rum_softc *,
244			    union sec_param *, uint8_t);
245static void		rum_group_key_del_cb(struct rum_softc *,
246			    union sec_param *, uint8_t);
247static void		rum_pair_key_set_cb(struct rum_softc *,
248			    union sec_param *, uint8_t);
249static void		rum_pair_key_del_cb(struct rum_softc *,
250			    union sec_param *, uint8_t);
251static int		rum_key_alloc(struct ieee80211vap *,
252			    struct ieee80211_key *, ieee80211_keyix *,
253			    ieee80211_keyix *);
254static int		rum_key_set(struct ieee80211vap *,
255			    const struct ieee80211_key *);
256static int		rum_key_delete(struct ieee80211vap *,
257			    const struct ieee80211_key *);
258static int		rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
259			    const struct ieee80211_bpf_params *);
260static void		rum_scan_start(struct ieee80211com *);
261static void		rum_scan_end(struct ieee80211com *);
262static void		rum_set_channel(struct ieee80211com *);
263static int		rum_get_rssi(struct rum_softc *, uint8_t);
264static void		rum_ratectl_start(struct rum_softc *,
265			    struct ieee80211_node *);
266static void		rum_ratectl_timeout(void *);
267static void		rum_ratectl_task(void *, int);
268static int		rum_pause(struct rum_softc *, int);
269
270static const struct {
271	uint32_t	reg;
272	uint32_t	val;
273} rum_def_mac[] = {
274	{ RT2573_TXRX_CSR0,  0x025fb032 },
275	{ RT2573_TXRX_CSR1,  0x9eaa9eaf },
276	{ RT2573_TXRX_CSR2,  0x8a8b8c8d },
277	{ RT2573_TXRX_CSR3,  0x00858687 },
278	{ RT2573_TXRX_CSR7,  0x2e31353b },
279	{ RT2573_TXRX_CSR8,  0x2a2a2a2c },
280	{ RT2573_TXRX_CSR15, 0x0000000f },
281	{ RT2573_MAC_CSR6,   0x00000fff },
282	{ RT2573_MAC_CSR8,   0x016c030a },
283	{ RT2573_MAC_CSR10,  0x00000718 },
284	{ RT2573_MAC_CSR12,  0x00000004 },
285	{ RT2573_MAC_CSR13,  0x00007f00 },
286	{ RT2573_SEC_CSR2,   0x00000000 },
287	{ RT2573_SEC_CSR3,   0x00000000 },
288	{ RT2573_SEC_CSR4,   0x00000000 },
289	{ RT2573_PHY_CSR1,   0x000023b0 },
290	{ RT2573_PHY_CSR5,   0x00040a06 },
291	{ RT2573_PHY_CSR6,   0x00080606 },
292	{ RT2573_PHY_CSR7,   0x00000408 },
293	{ RT2573_AIFSN_CSR,  0x00002273 },
294	{ RT2573_CWMIN_CSR,  0x00002344 },
295	{ RT2573_CWMAX_CSR,  0x000034aa }
296};
297
298static const struct {
299	uint8_t	reg;
300	uint8_t	val;
301} rum_def_bbp[] = {
302	{   3, 0x80 },
303	{  15, 0x30 },
304	{  17, 0x20 },
305	{  21, 0xc8 },
306	{  22, 0x38 },
307	{  23, 0x06 },
308	{  24, 0xfe },
309	{  25, 0x0a },
310	{  26, 0x0d },
311	{  32, 0x0b },
312	{  34, 0x12 },
313	{  37, 0x07 },
314	{  39, 0xf8 },
315	{  41, 0x60 },
316	{  53, 0x10 },
317	{  54, 0x18 },
318	{  60, 0x10 },
319	{  61, 0x04 },
320	{  62, 0x04 },
321	{  75, 0xfe },
322	{  86, 0xfe },
323	{  88, 0xfe },
324	{  90, 0x0f },
325	{  99, 0x00 },
326	{ 102, 0x16 },
327	{ 107, 0x04 }
328};
329
330static const struct rfprog {
331	uint8_t		chan;
332	uint32_t	r1, r2, r3, r4;
333}  rum_rf5226[] = {
334	{   1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
335	{   2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
336	{   3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
337	{   4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
338	{   5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
339	{   6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
340	{   7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
341	{   8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
342	{   9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
343	{  10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
344	{  11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
345	{  12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
346	{  13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
347	{  14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
348
349	{  34, 0x00b03, 0x20266, 0x36014, 0x30282 },
350	{  38, 0x00b03, 0x20267, 0x36014, 0x30284 },
351	{  42, 0x00b03, 0x20268, 0x36014, 0x30286 },
352	{  46, 0x00b03, 0x20269, 0x36014, 0x30288 },
353
354	{  36, 0x00b03, 0x00266, 0x26014, 0x30288 },
355	{  40, 0x00b03, 0x00268, 0x26014, 0x30280 },
356	{  44, 0x00b03, 0x00269, 0x26014, 0x30282 },
357	{  48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
358	{  52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
359	{  56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
360	{  60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
361	{  64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
362
363	{ 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
364	{ 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
365	{ 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
366	{ 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
367	{ 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
368	{ 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
369	{ 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
370	{ 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
371	{ 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
372	{ 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
373	{ 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
374
375	{ 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
376	{ 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
377	{ 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
378	{ 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
379	{ 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
380}, rum_rf5225[] = {
381	{   1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
382	{   2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
383	{   3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
384	{   4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
385	{   5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
386	{   6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
387	{   7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
388	{   8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
389	{   9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
390	{  10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
391	{  11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
392	{  12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
393	{  13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
394	{  14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
395
396	{  34, 0x00b33, 0x01266, 0x26014, 0x30282 },
397	{  38, 0x00b33, 0x01267, 0x26014, 0x30284 },
398	{  42, 0x00b33, 0x01268, 0x26014, 0x30286 },
399	{  46, 0x00b33, 0x01269, 0x26014, 0x30288 },
400
401	{  36, 0x00b33, 0x01266, 0x26014, 0x30288 },
402	{  40, 0x00b33, 0x01268, 0x26014, 0x30280 },
403	{  44, 0x00b33, 0x01269, 0x26014, 0x30282 },
404	{  48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
405	{  52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
406	{  56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
407	{  60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
408	{  64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
409
410	{ 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
411	{ 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
412	{ 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
413	{ 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
414	{ 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
415	{ 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
416	{ 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
417	{ 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
418	{ 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
419	{ 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
420	{ 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
421
422	{ 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
423	{ 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
424	{ 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
425	{ 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
426	{ 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
427};
428
429static const struct usb_config rum_config[RUM_N_TRANSFER] = {
430	[RUM_BULK_WR] = {
431		.type = UE_BULK,
432		.endpoint = UE_ADDR_ANY,
433		.direction = UE_DIR_OUT,
434		.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8),
435		.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
436		.callback = rum_bulk_write_callback,
437		.timeout = 5000,	/* ms */
438	},
439	[RUM_BULK_RD] = {
440		.type = UE_BULK,
441		.endpoint = UE_ADDR_ANY,
442		.direction = UE_DIR_IN,
443		.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE),
444		.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
445		.callback = rum_bulk_read_callback,
446	},
447};
448
449static int
450rum_match(device_t self)
451{
452	struct usb_attach_arg *uaa = device_get_ivars(self);
453
454	if (uaa->usb_mode != USB_MODE_HOST)
455		return (ENXIO);
456	if (uaa->info.bConfigIndex != 0)
457		return (ENXIO);
458	if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
459		return (ENXIO);
460
461	return (usbd_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
462}
463
464static int
465rum_attach(device_t self)
466{
467	struct usb_attach_arg *uaa = device_get_ivars(self);
468	struct rum_softc *sc = device_get_softc(self);
469	struct ieee80211com *ic = &sc->sc_ic;
470	uint8_t iface_index, bands;
471	uint32_t tmp;
472	int error, ntries;
473
474	device_set_usb_desc(self);
475	sc->sc_udev = uaa->device;
476	sc->sc_dev = self;
477
478	RUM_LOCK_INIT(sc);
479	RUM_CMDQ_LOCK_INIT(sc);
480	mbufq_init(&sc->sc_snd, ifqmaxlen);
481
482	iface_index = RT2573_IFACE_INDEX;
483	error = usbd_transfer_setup(uaa->device, &iface_index,
484	    sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx);
485	if (error) {
486		device_printf(self, "could not allocate USB transfers, "
487		    "err=%s\n", usbd_errstr(error));
488		goto detach;
489	}
490
491	RUM_LOCK(sc);
492	/* retrieve RT2573 rev. no */
493	for (ntries = 0; ntries < 100; ntries++) {
494		if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
495			break;
496		if (rum_pause(sc, hz / 100))
497			break;
498	}
499	if (ntries == 100) {
500		device_printf(sc->sc_dev, "timeout waiting for chip to settle\n");
501		RUM_UNLOCK(sc);
502		goto detach;
503	}
504
505	/* retrieve MAC address and various other things from EEPROM */
506	rum_read_eeprom(sc);
507
508	device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
509	    tmp, rum_get_rf(sc->rf_rev));
510
511	rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
512	RUM_UNLOCK(sc);
513
514	ic->ic_softc = sc;
515	ic->ic_name = device_get_nameunit(self);
516	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
517
518	/* set device capabilities */
519	ic->ic_caps =
520	      IEEE80211_C_STA		/* station mode supported */
521	    | IEEE80211_C_IBSS		/* IBSS mode supported */
522	    | IEEE80211_C_MONITOR	/* monitor mode supported */
523	    | IEEE80211_C_HOSTAP	/* HostAp mode supported */
524	    | IEEE80211_C_AHDEMO	/* adhoc demo mode */
525	    | IEEE80211_C_TXPMGT	/* tx power management */
526	    | IEEE80211_C_SHPREAMBLE	/* short preamble supported */
527	    | IEEE80211_C_SHSLOT	/* short slot time supported */
528	    | IEEE80211_C_BGSCAN	/* bg scanning supported */
529	    | IEEE80211_C_WPA		/* 802.11i */
530	    | IEEE80211_C_WME		/* 802.11e */
531	    ;
532
533	ic->ic_cryptocaps =
534	    IEEE80211_CRYPTO_WEP |
535	    IEEE80211_CRYPTO_AES_CCM |
536	    IEEE80211_CRYPTO_TKIPMIC |
537	    IEEE80211_CRYPTO_TKIP;
538
539	bands = 0;
540	setbit(&bands, IEEE80211_MODE_11B);
541	setbit(&bands, IEEE80211_MODE_11G);
542	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226)
543		setbit(&bands, IEEE80211_MODE_11A);
544	ieee80211_init_channels(ic, NULL, &bands);
545
546	ieee80211_ifattach(ic);
547	ic->ic_update_promisc = rum_update_promisc;
548	ic->ic_raw_xmit = rum_raw_xmit;
549	ic->ic_scan_start = rum_scan_start;
550	ic->ic_scan_end = rum_scan_end;
551	ic->ic_set_channel = rum_set_channel;
552	ic->ic_transmit = rum_transmit;
553	ic->ic_parent = rum_parent;
554	ic->ic_vap_create = rum_vap_create;
555	ic->ic_vap_delete = rum_vap_delete;
556	ic->ic_updateslot = rum_update_slot;
557	ic->ic_wme.wme_update = rum_wme_update;
558	ic->ic_update_mcast = rum_update_mcast;
559
560	ieee80211_radiotap_attach(ic,
561	    &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap),
562		RT2573_TX_RADIOTAP_PRESENT,
563	    &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap),
564		RT2573_RX_RADIOTAP_PRESENT);
565
566	TASK_INIT(&sc->cmdq_task, 0, rum_cmdq_cb, sc);
567
568	if (bootverbose)
569		ieee80211_announce(ic);
570
571	return (0);
572
573detach:
574	rum_detach(self);
575	return (ENXIO);			/* failure */
576}
577
578static int
579rum_detach(device_t self)
580{
581	struct rum_softc *sc = device_get_softc(self);
582	struct ieee80211com *ic = &sc->sc_ic;
583
584	/* Prevent further ioctls */
585	RUM_LOCK(sc);
586	sc->sc_detached = 1;
587	RUM_UNLOCK(sc);
588
589	/* stop all USB transfers */
590	usbd_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
591
592	/* free TX list, if any */
593	RUM_LOCK(sc);
594	rum_unsetup_tx_list(sc);
595	RUM_UNLOCK(sc);
596
597	if (ic->ic_softc == sc) {
598		ieee80211_draintask(ic, &sc->cmdq_task);
599		ieee80211_ifdetach(ic);
600	}
601
602	mbufq_drain(&sc->sc_snd);
603	RUM_CMDQ_LOCK_DESTROY(sc);
604	RUM_LOCK_DESTROY(sc);
605
606	return (0);
607}
608
609static usb_error_t
610rum_do_request(struct rum_softc *sc,
611    struct usb_device_request *req, void *data)
612{
613	usb_error_t err;
614	int ntries = 10;
615
616	while (ntries--) {
617		err = usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx,
618		    req, data, 0, NULL, 250 /* ms */);
619		if (err == 0)
620			break;
621
622		DPRINTFN(1, "Control request failed, %s (retrying)\n",
623		    usbd_errstr(err));
624		if (rum_pause(sc, hz / 100))
625			break;
626	}
627	return (err);
628}
629
630static struct ieee80211vap *
631rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
632    enum ieee80211_opmode opmode, int flags,
633    const uint8_t bssid[IEEE80211_ADDR_LEN],
634    const uint8_t mac[IEEE80211_ADDR_LEN])
635{
636	struct rum_softc *sc = ic->ic_softc;
637	struct rum_vap *rvp;
638	struct ieee80211vap *vap;
639
640	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
641		return NULL;
642	rvp = malloc(sizeof(struct rum_vap), M_80211_VAP, M_WAITOK | M_ZERO);
643	vap = &rvp->vap;
644	/* enable s/w bmiss handling for sta mode */
645
646	if (ieee80211_vap_setup(ic, vap, name, unit, opmode,
647	    flags | IEEE80211_CLONE_NOBEACONS, bssid) != 0) {
648		/* out of memory */
649		free(rvp, M_80211_VAP);
650		return (NULL);
651	}
652
653	/* override state transition machine */
654	rvp->newstate = vap->iv_newstate;
655	vap->iv_newstate = rum_newstate;
656	vap->iv_key_alloc = rum_key_alloc;
657	vap->iv_key_set = rum_key_set;
658	vap->iv_key_delete = rum_key_delete;
659	vap->iv_update_beacon = rum_update_beacon;
660	vap->iv_max_aid = RT2573_ADDR_MAX;
661
662	usb_callout_init_mtx(&rvp->ratectl_ch, &sc->sc_mtx, 0);
663	TASK_INIT(&rvp->ratectl_task, 0, rum_ratectl_task, rvp);
664	ieee80211_ratectl_init(vap);
665	ieee80211_ratectl_setinterval(vap, 1000 /* 1 sec */);
666	/* complete setup */
667	ieee80211_vap_attach(vap, ieee80211_media_change,
668	    ieee80211_media_status, mac);
669	ic->ic_opmode = opmode;
670	return vap;
671}
672
673static void
674rum_vap_delete(struct ieee80211vap *vap)
675{
676	struct rum_vap *rvp = RUM_VAP(vap);
677	struct ieee80211com *ic = vap->iv_ic;
678
679	m_freem(rvp->bcn_mbuf);
680	usb_callout_drain(&rvp->ratectl_ch);
681	ieee80211_draintask(ic, &rvp->ratectl_task);
682	ieee80211_ratectl_deinit(vap);
683	ieee80211_vap_detach(vap);
684	free(rvp, M_80211_VAP);
685}
686
687static void
688rum_cmdq_cb(void *arg, int pending)
689{
690	struct rum_softc *sc = arg;
691	struct rum_cmdq *rc;
692
693	RUM_CMDQ_LOCK(sc);
694	while (sc->cmdq[sc->cmdq_first].func != NULL) {
695		rc = &sc->cmdq[sc->cmdq_first];
696		RUM_CMDQ_UNLOCK(sc);
697
698		RUM_LOCK(sc);
699		rc->func(sc, &rc->data, rc->rvp_id);
700		RUM_UNLOCK(sc);
701
702		RUM_CMDQ_LOCK(sc);
703		memset(rc, 0, sizeof (*rc));
704		sc->cmdq_first = (sc->cmdq_first + 1) % RUM_CMDQ_SIZE;
705	}
706	RUM_CMDQ_UNLOCK(sc);
707}
708
709static int
710rum_cmd_sleepable(struct rum_softc *sc, const void *ptr, size_t len,
711    uint8_t rvp_id, CMD_FUNC_PROTO)
712{
713	struct ieee80211com *ic = &sc->sc_ic;
714
715	KASSERT(len <= sizeof(union sec_param), ("buffer overflow"));
716
717	RUM_CMDQ_LOCK(sc);
718	if (sc->cmdq[sc->cmdq_last].func != NULL) {
719		device_printf(sc->sc_dev, "%s: cmdq overflow\n", __func__);
720		RUM_CMDQ_UNLOCK(sc);
721
722		return EAGAIN;
723	}
724
725	if (ptr != NULL)
726		memcpy(&sc->cmdq[sc->cmdq_last].data, ptr, len);
727	sc->cmdq[sc->cmdq_last].rvp_id = rvp_id;
728	sc->cmdq[sc->cmdq_last].func = func;
729	sc->cmdq_last = (sc->cmdq_last + 1) % RUM_CMDQ_SIZE;
730	RUM_CMDQ_UNLOCK(sc);
731
732	ieee80211_runtask(ic, &sc->cmdq_task);
733
734	return 0;
735}
736
737static void
738rum_tx_free(struct rum_tx_data *data, int txerr)
739{
740	struct rum_softc *sc = data->sc;
741
742	if (data->m != NULL) {
743		ieee80211_tx_complete(data->ni, data->m, txerr);
744		data->m = NULL;
745		data->ni = NULL;
746	}
747	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
748	sc->tx_nfree++;
749}
750
751static void
752rum_setup_tx_list(struct rum_softc *sc)
753{
754	struct rum_tx_data *data;
755	int i;
756
757	sc->tx_nfree = 0;
758	STAILQ_INIT(&sc->tx_q);
759	STAILQ_INIT(&sc->tx_free);
760
761	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
762		data = &sc->tx_data[i];
763
764		data->sc = sc;
765		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
766		sc->tx_nfree++;
767	}
768}
769
770static void
771rum_unsetup_tx_list(struct rum_softc *sc)
772{
773	struct rum_tx_data *data;
774	int i;
775
776	/* make sure any subsequent use of the queues will fail */
777	sc->tx_nfree = 0;
778	STAILQ_INIT(&sc->tx_q);
779	STAILQ_INIT(&sc->tx_free);
780
781	/* free up all node references and mbufs */
782	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
783		data = &sc->tx_data[i];
784
785		if (data->m != NULL) {
786			m_freem(data->m);
787			data->m = NULL;
788		}
789		if (data->ni != NULL) {
790			ieee80211_free_node(data->ni);
791			data->ni = NULL;
792		}
793	}
794}
795
796static int
797rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
798{
799	struct rum_vap *rvp = RUM_VAP(vap);
800	struct ieee80211com *ic = vap->iv_ic;
801	struct rum_softc *sc = ic->ic_softc;
802	const struct ieee80211_txparam *tp;
803	enum ieee80211_state ostate;
804	struct ieee80211_node *ni;
805	int ret;
806
807	ostate = vap->iv_state;
808	DPRINTF("%s -> %s\n",
809		ieee80211_state_name[ostate],
810		ieee80211_state_name[nstate]);
811
812	IEEE80211_UNLOCK(ic);
813	RUM_LOCK(sc);
814	usb_callout_stop(&rvp->ratectl_ch);
815
816	switch (nstate) {
817	case IEEE80211_S_INIT:
818		if (ostate == IEEE80211_S_RUN)
819			rum_abort_tsf_sync(sc);
820
821		break;
822
823	case IEEE80211_S_RUN:
824		ni = ieee80211_ref_node(vap->iv_bss);
825
826		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
827			if (ic->ic_bsschan == IEEE80211_CHAN_ANYC ||
828			    ni->ni_chan == IEEE80211_CHAN_ANYC) {
829				ret = EINVAL;
830				goto run_fail;
831			}
832			rum_update_slot_cb(sc, NULL, 0);
833			rum_enable_mrr(sc);
834			rum_set_txpreamble(sc);
835			rum_set_basicrates(sc);
836			rum_set_maxretry(sc, vap);
837			IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid);
838			rum_set_bssid(sc, sc->sc_bssid);
839		}
840
841		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
842		    vap->iv_opmode == IEEE80211_M_IBSS) {
843			if ((ret = rum_alloc_beacon(sc, vap)) != 0)
844				goto run_fail;
845		}
846
847		if (vap->iv_opmode != IEEE80211_M_MONITOR &&
848		    vap->iv_opmode != IEEE80211_M_AHDEMO) {
849			if ((ret = rum_enable_tsf_sync(sc)) != 0)
850				goto run_fail;
851		} else
852			rum_enable_tsf(sc);
853
854		/* enable automatic rate adaptation */
855		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
856		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
857			rum_ratectl_start(sc, ni);
858		ieee80211_free_node(ni);
859		break;
860	default:
861		break;
862	}
863	RUM_UNLOCK(sc);
864	IEEE80211_LOCK(ic);
865	return (rvp->newstate(vap, nstate, arg));
866
867run_fail:
868	RUM_UNLOCK(sc);
869	IEEE80211_LOCK(ic);
870	ieee80211_free_node(ni);
871	return ret;
872}
873
874static void
875rum_bulk_write_callback(struct usb_xfer *xfer, usb_error_t error)
876{
877	struct rum_softc *sc = usbd_xfer_softc(xfer);
878	struct ieee80211vap *vap;
879	struct rum_tx_data *data;
880	struct mbuf *m;
881	struct usb_page_cache *pc;
882	unsigned int len;
883	int actlen, sumlen;
884
885	usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL);
886
887	switch (USB_GET_STATE(xfer)) {
888	case USB_ST_TRANSFERRED:
889		DPRINTFN(11, "transfer complete, %d bytes\n", actlen);
890
891		/* free resources */
892		data = usbd_xfer_get_priv(xfer);
893		rum_tx_free(data, 0);
894		usbd_xfer_set_priv(xfer, NULL);
895
896		/* FALLTHROUGH */
897	case USB_ST_SETUP:
898tr_setup:
899		data = STAILQ_FIRST(&sc->tx_q);
900		if (data) {
901			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
902			m = data->m;
903
904			if (m->m_pkthdr.len > (int)(MCLBYTES + RT2573_TX_DESC_SIZE)) {
905				DPRINTFN(0, "data overflow, %u bytes\n",
906				    m->m_pkthdr.len);
907				m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
908			}
909			pc = usbd_xfer_get_frame(xfer, 0);
910			usbd_copy_in(pc, 0, &data->desc, RT2573_TX_DESC_SIZE);
911			usbd_m_copy_in(pc, RT2573_TX_DESC_SIZE, m, 0,
912			    m->m_pkthdr.len);
913
914			vap = data->ni->ni_vap;
915			if (ieee80211_radiotap_active_vap(vap)) {
916				struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
917
918				tap->wt_flags = 0;
919				tap->wt_rate = data->rate;
920				rum_get_tsf(sc, &tap->wt_tsf);
921				tap->wt_antenna = sc->tx_ant;
922
923				ieee80211_radiotap_tx(vap, m);
924			}
925
926			/* align end on a 4-bytes boundary */
927			len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3;
928			if ((len % 64) == 0)
929				len += 4;
930
931			DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
932			    m->m_pkthdr.len, len);
933
934			usbd_xfer_set_frame_len(xfer, 0, len);
935			usbd_xfer_set_priv(xfer, data);
936
937			usbd_transfer_submit(xfer);
938		}
939		rum_start(sc);
940		break;
941
942	default:			/* Error */
943		DPRINTFN(11, "transfer error, %s\n",
944		    usbd_errstr(error));
945
946		counter_u64_add(sc->sc_ic.ic_oerrors, 1);
947		data = usbd_xfer_get_priv(xfer);
948		if (data != NULL) {
949			rum_tx_free(data, error);
950			usbd_xfer_set_priv(xfer, NULL);
951		}
952
953		if (error != USB_ERR_CANCELLED) {
954			if (error == USB_ERR_TIMEOUT)
955				device_printf(sc->sc_dev, "device timeout\n");
956
957			/*
958			 * Try to clear stall first, also if other
959			 * errors occur, hence clearing stall
960			 * introduces a 50 ms delay:
961			 */
962			usbd_xfer_set_stall(xfer);
963			goto tr_setup;
964		}
965		break;
966	}
967}
968
969static void
970rum_bulk_read_callback(struct usb_xfer *xfer, usb_error_t error)
971{
972	struct rum_softc *sc = usbd_xfer_softc(xfer);
973	struct ieee80211com *ic = &sc->sc_ic;
974	struct ieee80211_frame_min *wh;
975	struct ieee80211_node *ni;
976	struct mbuf *m = NULL;
977	struct usb_page_cache *pc;
978	uint32_t flags;
979	uint8_t rssi = 0;
980	int len;
981
982	usbd_xfer_status(xfer, &len, NULL, NULL, NULL);
983
984	switch (USB_GET_STATE(xfer)) {
985	case USB_ST_TRANSFERRED:
986
987		DPRINTFN(15, "rx done, actlen=%d\n", len);
988
989		if (len < (int)(RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
990			DPRINTF("%s: xfer too short %d\n",
991			    device_get_nameunit(sc->sc_dev), len);
992			counter_u64_add(ic->ic_ierrors, 1);
993			goto tr_setup;
994		}
995
996		len -= RT2573_RX_DESC_SIZE;
997		pc = usbd_xfer_get_frame(xfer, 0);
998		usbd_copy_out(pc, 0, &sc->sc_rx_desc, RT2573_RX_DESC_SIZE);
999
1000		rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
1001		flags = le32toh(sc->sc_rx_desc.flags);
1002		if (flags & RT2573_RX_CRC_ERROR) {
1003			/*
1004		         * This should not happen since we did not
1005		         * request to receive those frames when we
1006		         * filled RUM_TXRX_CSR2:
1007		         */
1008			DPRINTFN(5, "PHY or CRC error\n");
1009			counter_u64_add(ic->ic_ierrors, 1);
1010			goto tr_setup;
1011		}
1012		if ((flags & RT2573_RX_DEC_MASK) != RT2573_RX_DEC_OK) {
1013			switch (flags & RT2573_RX_DEC_MASK) {
1014			case RT2573_RX_IV_ERROR:
1015				DPRINTFN(5, "IV/EIV error\n");
1016				break;
1017			case RT2573_RX_MIC_ERROR:
1018				DPRINTFN(5, "MIC error\n");
1019				break;
1020			case RT2573_RX_KEY_ERROR:
1021				DPRINTFN(5, "Key error\n");
1022				break;
1023			}
1024			counter_u64_add(ic->ic_ierrors, 1);
1025			goto tr_setup;
1026		}
1027
1028		m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
1029		if (m == NULL) {
1030			DPRINTF("could not allocate mbuf\n");
1031			counter_u64_add(ic->ic_ierrors, 1);
1032			goto tr_setup;
1033		}
1034		usbd_copy_out(pc, RT2573_RX_DESC_SIZE,
1035		    mtod(m, uint8_t *), len);
1036
1037		wh = mtod(m, struct ieee80211_frame_min *);
1038
1039		if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) &&
1040		    (flags & RT2573_RX_CIP_MASK) !=
1041		     RT2573_RX_CIP_MODE(RT2573_MODE_NOSEC)) {
1042			wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
1043			m->m_flags |= M_WEP;
1044		}
1045
1046		/* finalize mbuf */
1047		m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
1048
1049		if (ieee80211_radiotap_active(ic)) {
1050			struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
1051
1052			tap->wr_flags = 0;
1053			tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
1054			    (flags & RT2573_RX_OFDM) ?
1055			    IEEE80211_T_OFDM : IEEE80211_T_CCK);
1056			rum_get_tsf(sc, &tap->wr_tsf);
1057			tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi;
1058			tap->wr_antnoise = RT2573_NOISE_FLOOR;
1059			tap->wr_antenna = sc->rx_ant;
1060		}
1061		/* FALLTHROUGH */
1062	case USB_ST_SETUP:
1063tr_setup:
1064		usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
1065		usbd_transfer_submit(xfer);
1066
1067		/*
1068		 * At the end of a USB callback it is always safe to unlock
1069		 * the private mutex of a device! That is why we do the
1070		 * "ieee80211_input" here, and not some lines up!
1071		 */
1072		RUM_UNLOCK(sc);
1073		if (m) {
1074			if (m->m_len >= sizeof(struct ieee80211_frame_min))
1075				ni = ieee80211_find_rxnode(ic, wh);
1076			else
1077				ni = NULL;
1078
1079			if (ni != NULL) {
1080				(void) ieee80211_input(ni, m, rssi,
1081				    RT2573_NOISE_FLOOR);
1082				ieee80211_free_node(ni);
1083			} else
1084				(void) ieee80211_input_all(ic, m, rssi,
1085				    RT2573_NOISE_FLOOR);
1086		}
1087		RUM_LOCK(sc);
1088		rum_start(sc);
1089		return;
1090
1091	default:			/* Error */
1092		if (error != USB_ERR_CANCELLED) {
1093			/* try to clear stall first */
1094			usbd_xfer_set_stall(xfer);
1095			goto tr_setup;
1096		}
1097		return;
1098	}
1099}
1100
1101static uint8_t
1102rum_plcp_signal(int rate)
1103{
1104	switch (rate) {
1105	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1106	case 12:	return 0xb;
1107	case 18:	return 0xf;
1108	case 24:	return 0xa;
1109	case 36:	return 0xe;
1110	case 48:	return 0x9;
1111	case 72:	return 0xd;
1112	case 96:	return 0x8;
1113	case 108:	return 0xc;
1114
1115	/* CCK rates (NB: not IEEE std, device-specific) */
1116	case 2:		return 0x0;
1117	case 4:		return 0x1;
1118	case 11:	return 0x2;
1119	case 22:	return 0x3;
1120	}
1121	return 0xff;		/* XXX unsupported/unknown rate */
1122}
1123
1124/*
1125 * Map net80211 cipher to RT2573 security mode.
1126 */
1127static uint8_t
1128rum_crypto_mode(struct rum_softc *sc, u_int cipher, int keylen)
1129{
1130	switch (cipher) {
1131	case IEEE80211_CIPHER_WEP:
1132		return (keylen < 8 ? RT2573_MODE_WEP40 : RT2573_MODE_WEP104);
1133	case IEEE80211_CIPHER_TKIP:
1134		return RT2573_MODE_TKIP;
1135	case IEEE80211_CIPHER_AES_CCM:
1136		return RT2573_MODE_AES_CCMP;
1137	default:
1138		device_printf(sc->sc_dev, "unknown cipher %d\n", cipher);
1139		return 0;
1140	}
1141}
1142
1143static void
1144rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
1145    struct ieee80211_key *k, uint32_t flags, uint8_t xflags, uint8_t qid,
1146    int hdrlen, int len, int rate)
1147{
1148	struct ieee80211com *ic = &sc->sc_ic;
1149	struct wmeParams *wmep = &sc->wme_params[qid];
1150	uint16_t plcp_length;
1151	int remainder;
1152
1153	flags |= RT2573_TX_VALID;
1154	flags |= len << 16;
1155
1156	if (k != NULL && !(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
1157		const struct ieee80211_cipher *cip = k->wk_cipher;
1158
1159		len += cip->ic_header + cip->ic_trailer + cip->ic_miclen;
1160
1161		desc->eiv = 0;		/* for WEP */
1162		cip->ic_setiv(k, (uint8_t *)&desc->iv);
1163	}
1164
1165	/* setup PLCP fields */
1166	desc->plcp_signal  = rum_plcp_signal(rate);
1167	desc->plcp_service = 4;
1168
1169	len += IEEE80211_CRC_LEN;
1170	if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM) {
1171		flags |= RT2573_TX_OFDM;
1172
1173		plcp_length = len & 0xfff;
1174		desc->plcp_length_hi = plcp_length >> 6;
1175		desc->plcp_length_lo = plcp_length & 0x3f;
1176	} else {
1177		if (rate == 0)
1178			rate = 2;	/* avoid division by zero */
1179		plcp_length = (16 * len + rate - 1) / rate;
1180		if (rate == 22) {
1181			remainder = (16 * len) % 22;
1182			if (remainder != 0 && remainder < 7)
1183				desc->plcp_service |= RT2573_PLCP_LENGEXT;
1184		}
1185		desc->plcp_length_hi = plcp_length >> 8;
1186		desc->plcp_length_lo = plcp_length & 0xff;
1187
1188		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1189			desc->plcp_signal |= 0x08;
1190	}
1191
1192	desc->flags = htole32(flags);
1193	desc->hdrlen = hdrlen;
1194	desc->xflags = xflags;
1195
1196	desc->wme = htole16(RT2573_QID(qid) |
1197	    RT2573_AIFSN(wmep->wmep_aifsn) |
1198	    RT2573_LOGCWMIN(wmep->wmep_logcwmin) |
1199	    RT2573_LOGCWMAX(wmep->wmep_logcwmax));
1200}
1201
1202static int
1203rum_sendprot(struct rum_softc *sc,
1204    const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
1205{
1206	struct ieee80211com *ic = ni->ni_ic;
1207	const struct ieee80211_frame *wh;
1208	struct rum_tx_data *data;
1209	struct mbuf *mprot;
1210	int protrate, pktlen, flags, isshort;
1211	uint16_t dur;
1212
1213	RUM_LOCK_ASSERT(sc);
1214	KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
1215	    ("protection %d", prot));
1216
1217	wh = mtod(m, const struct ieee80211_frame *);
1218	pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
1219
1220	protrate = ieee80211_ctl_rate(ic->ic_rt, rate);
1221
1222	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
1223	dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort)
1224	    + ieee80211_ack_duration(ic->ic_rt, rate, isshort);
1225	flags = 0;
1226	if (prot == IEEE80211_PROT_RTSCTS) {
1227		/* NB: CTS is the same size as an ACK */
1228		dur += ieee80211_ack_duration(ic->ic_rt, rate, isshort);
1229		flags |= RT2573_TX_NEED_ACK;
1230		mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
1231	} else {
1232		mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
1233	}
1234	if (mprot == NULL) {
1235		/* XXX stat + msg */
1236		return (ENOBUFS);
1237	}
1238	data = STAILQ_FIRST(&sc->tx_free);
1239	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1240	sc->tx_nfree--;
1241
1242	data->m = mprot;
1243	data->ni = ieee80211_ref_node(ni);
1244	data->rate = protrate;
1245	rum_setup_tx_desc(sc, &data->desc, NULL, flags, 0, 0, 0,
1246	    mprot->m_pkthdr.len, protrate);
1247
1248	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1249	usbd_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1250
1251	return 0;
1252}
1253
1254static uint32_t
1255rum_tx_crypto_flags(struct rum_softc *sc, struct ieee80211_node *ni,
1256    const struct ieee80211_key *k)
1257{
1258	struct ieee80211vap *vap = ni->ni_vap;
1259	u_int cipher;
1260	uint32_t flags = 0;
1261	uint8_t mode, pos;
1262
1263	if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
1264		cipher = k->wk_cipher->ic_cipher;
1265		pos = k->wk_keyix;
1266		mode = rum_crypto_mode(sc, cipher, k->wk_keylen);
1267		if (mode == 0)
1268			return 0;
1269
1270		flags |= RT2573_TX_CIP_MODE(mode);
1271
1272		/* Do not trust GROUP flag */
1273		if (!(k >= &vap->iv_nw_keys[0] &&
1274		      k < &vap->iv_nw_keys[IEEE80211_WEP_NKID]))
1275			flags |= RT2573_TX_KEY_PAIR;
1276		else
1277			pos += 0 * RT2573_SKEY_MAX;	/* vap id */
1278
1279		flags |= RT2573_TX_KEY_ID(pos);
1280
1281		if (cipher == IEEE80211_CIPHER_TKIP)
1282			flags |= RT2573_TX_TKIPMIC;
1283	}
1284
1285	return flags;
1286}
1287
1288static int
1289rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1290{
1291	struct ieee80211vap *vap = ni->ni_vap;
1292	struct ieee80211com *ic = &sc->sc_ic;
1293	struct rum_tx_data *data;
1294	struct ieee80211_frame *wh;
1295	const struct ieee80211_txparam *tp;
1296	struct ieee80211_key *k = NULL;
1297	uint32_t flags = 0;
1298	uint16_t dur;
1299	uint8_t ac, type, xflags = 0;
1300	int hdrlen;
1301
1302	RUM_LOCK_ASSERT(sc);
1303
1304	data = STAILQ_FIRST(&sc->tx_free);
1305	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1306	sc->tx_nfree--;
1307
1308	wh = mtod(m0, struct ieee80211_frame *);
1309	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1310	hdrlen = ieee80211_anyhdrsize(wh);
1311	ac = M_WME_GETAC(m0);
1312
1313	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1314		k = ieee80211_crypto_get_txkey(ni, m0);
1315		if (k == NULL)
1316			return (ENOENT);
1317
1318		if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
1319		    !k->wk_cipher->ic_encap(k, m0))
1320			return (ENOBUFS);
1321
1322		wh = mtod(m0, struct ieee80211_frame *);
1323	}
1324
1325	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1326
1327	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1328		flags |= RT2573_TX_NEED_ACK;
1329
1330		dur = ieee80211_ack_duration(ic->ic_rt, tp->mgmtrate,
1331		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
1332		USETW(wh->i_dur, dur);
1333
1334		/* tell hardware to add timestamp for probe responses */
1335		if (type == IEEE80211_FC0_TYPE_MGT &&
1336		    (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
1337		    IEEE80211_FC0_SUBTYPE_PROBE_RESP)
1338			flags |= RT2573_TX_TIMESTAMP;
1339	}
1340
1341	if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh))
1342		xflags |= RT2573_TX_HWSEQ;
1343
1344	if (k != NULL)
1345		flags |= rum_tx_crypto_flags(sc, ni, k);
1346
1347	data->m = m0;
1348	data->ni = ni;
1349	data->rate = tp->mgmtrate;
1350
1351	rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, ac, hdrlen,
1352	    m0->m_pkthdr.len, tp->mgmtrate);
1353
1354	DPRINTFN(10, "sending mgt frame len=%d rate=%d\n",
1355	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate);
1356
1357	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1358	usbd_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1359
1360	return (0);
1361}
1362
1363static int
1364rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
1365    const struct ieee80211_bpf_params *params)
1366{
1367	struct ieee80211com *ic = ni->ni_ic;
1368	struct ieee80211_frame *wh;
1369	struct rum_tx_data *data;
1370	uint32_t flags;
1371	uint8_t ac, type, xflags = 0;
1372	int rate, error;
1373
1374	RUM_LOCK_ASSERT(sc);
1375
1376	wh = mtod(m0, struct ieee80211_frame *);
1377	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1378
1379	ac = params->ibp_pri & 3;
1380
1381	rate = params->ibp_rate0;
1382	if (!ieee80211_isratevalid(ic->ic_rt, rate))
1383		return (EINVAL);
1384
1385	flags = 0;
1386	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
1387		flags |= RT2573_TX_NEED_ACK;
1388	if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
1389		error = rum_sendprot(sc, m0, ni,
1390		    params->ibp_flags & IEEE80211_BPF_RTS ?
1391			 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
1392		    rate);
1393		if (error || sc->tx_nfree == 0)
1394			return (ENOBUFS);
1395
1396		flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
1397	}
1398
1399	if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh))
1400		xflags |= RT2573_TX_HWSEQ;
1401
1402	data = STAILQ_FIRST(&sc->tx_free);
1403	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1404	sc->tx_nfree--;
1405
1406	data->m = m0;
1407	data->ni = ni;
1408	data->rate = rate;
1409
1410	/* XXX need to setup descriptor ourself */
1411	rum_setup_tx_desc(sc, &data->desc, NULL, flags, xflags, ac, 0,
1412	    m0->m_pkthdr.len, rate);
1413
1414	DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
1415	    m0->m_pkthdr.len, rate);
1416
1417	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1418	usbd_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1419
1420	return 0;
1421}
1422
1423static int
1424rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1425{
1426	struct ieee80211vap *vap = ni->ni_vap;
1427	struct ieee80211com *ic = &sc->sc_ic;
1428	struct rum_tx_data *data;
1429	struct ieee80211_frame *wh;
1430	const struct ieee80211_txparam *tp;
1431	struct ieee80211_key *k = NULL;
1432	uint32_t flags = 0;
1433	uint16_t dur;
1434	uint8_t ac, type, qos, xflags = 0;
1435	int error, hdrlen, rate;
1436
1437	RUM_LOCK_ASSERT(sc);
1438
1439	wh = mtod(m0, struct ieee80211_frame *);
1440	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1441	hdrlen = ieee80211_anyhdrsize(wh);
1442
1443	if (IEEE80211_QOS_HAS_SEQ(wh))
1444		qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0];
1445	else
1446		qos = 0;
1447	ac = M_WME_GETAC(m0);
1448
1449	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1450	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1451		rate = tp->mcastrate;
1452	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1453		rate = tp->ucastrate;
1454	else
1455		rate = ni->ni_txrate;
1456
1457	if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1458		k = ieee80211_crypto_get_txkey(ni, m0);
1459		if (k == NULL) {
1460			m_freem(m0);
1461			return (ENOENT);
1462		}
1463		if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) &&
1464		    !k->wk_cipher->ic_encap(k, m0)) {
1465			m_freem(m0);
1466			return (ENOBUFS);
1467		}
1468
1469		/* packet header may have moved, reset our local pointer */
1470		wh = mtod(m0, struct ieee80211_frame *);
1471	}
1472
1473	if (type != IEEE80211_FC0_TYPE_CTL && !IEEE80211_QOS_HAS_SEQ(wh))
1474		xflags |= RT2573_TX_HWSEQ;
1475
1476	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1477		int prot = IEEE80211_PROT_NONE;
1478		if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
1479			prot = IEEE80211_PROT_RTSCTS;
1480		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1481		    ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_OFDM)
1482			prot = ic->ic_protmode;
1483		if (prot != IEEE80211_PROT_NONE) {
1484			error = rum_sendprot(sc, m0, ni, prot, rate);
1485			if (error || sc->tx_nfree == 0) {
1486				m_freem(m0);
1487				return ENOBUFS;
1488			}
1489			flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
1490		}
1491	}
1492
1493	if (k != NULL)
1494		flags |= rum_tx_crypto_flags(sc, ni, k);
1495
1496	data = STAILQ_FIRST(&sc->tx_free);
1497	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1498	sc->tx_nfree--;
1499
1500	data->m = m0;
1501	data->ni = ni;
1502	data->rate = rate;
1503
1504	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1505		/* Unicast frame, check if an ACK is expected. */
1506		if (!qos || (qos & IEEE80211_QOS_ACKPOLICY) !=
1507		    IEEE80211_QOS_ACKPOLICY_NOACK)
1508			flags |= RT2573_TX_NEED_ACK;
1509
1510		dur = ieee80211_ack_duration(ic->ic_rt, rate,
1511		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
1512		USETW(wh->i_dur, dur);
1513	}
1514
1515	rum_setup_tx_desc(sc, &data->desc, k, flags, xflags, ac, hdrlen,
1516	    m0->m_pkthdr.len, rate);
1517
1518	DPRINTFN(10, "sending frame len=%d rate=%d\n",
1519	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
1520
1521	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1522	usbd_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1523
1524	return 0;
1525}
1526
1527static int
1528rum_transmit(struct ieee80211com *ic, struct mbuf *m)
1529{
1530	struct rum_softc *sc = ic->ic_softc;
1531	int error;
1532
1533	RUM_LOCK(sc);
1534	if (!sc->sc_running) {
1535		RUM_UNLOCK(sc);
1536		return (ENXIO);
1537	}
1538	error = mbufq_enqueue(&sc->sc_snd, m);
1539	if (error) {
1540		RUM_UNLOCK(sc);
1541		return (error);
1542	}
1543	rum_start(sc);
1544	RUM_UNLOCK(sc);
1545
1546	return (0);
1547}
1548
1549static void
1550rum_start(struct rum_softc *sc)
1551{
1552	struct ieee80211_node *ni;
1553	struct mbuf *m;
1554
1555	RUM_LOCK_ASSERT(sc);
1556
1557	if (!sc->sc_running)
1558		return;
1559
1560	while (sc->tx_nfree >= RUM_TX_MINFREE &&
1561	    (m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1562		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1563		if (rum_tx_data(sc, m, ni) != 0) {
1564			if_inc_counter(ni->ni_vap->iv_ifp,
1565			    IFCOUNTER_OERRORS, 1);
1566			ieee80211_free_node(ni);
1567			break;
1568		}
1569	}
1570}
1571
1572static void
1573rum_parent(struct ieee80211com *ic)
1574{
1575	struct rum_softc *sc = ic->ic_softc;
1576	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1577
1578	RUM_LOCK(sc);
1579	if (sc->sc_detached) {
1580		RUM_UNLOCK(sc);
1581		return;
1582	}
1583	RUM_UNLOCK(sc);
1584
1585	if (ic->ic_nrunning > 0) {
1586		if (rum_init(sc) == 0)
1587			ieee80211_start_all(ic);
1588		else
1589			ieee80211_stop(vap);
1590	} else
1591		rum_stop(sc);
1592}
1593
1594static void
1595rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
1596{
1597	struct usb_device_request req;
1598	usb_error_t error;
1599
1600	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1601	req.bRequest = RT2573_READ_EEPROM;
1602	USETW(req.wValue, 0);
1603	USETW(req.wIndex, addr);
1604	USETW(req.wLength, len);
1605
1606	error = rum_do_request(sc, &req, buf);
1607	if (error != 0) {
1608		device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
1609		    usbd_errstr(error));
1610	}
1611}
1612
1613static uint32_t
1614rum_read(struct rum_softc *sc, uint16_t reg)
1615{
1616	uint32_t val;
1617
1618	rum_read_multi(sc, reg, &val, sizeof val);
1619
1620	return le32toh(val);
1621}
1622
1623static void
1624rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
1625{
1626	struct usb_device_request req;
1627	usb_error_t error;
1628
1629	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1630	req.bRequest = RT2573_READ_MULTI_MAC;
1631	USETW(req.wValue, 0);
1632	USETW(req.wIndex, reg);
1633	USETW(req.wLength, len);
1634
1635	error = rum_do_request(sc, &req, buf);
1636	if (error != 0) {
1637		device_printf(sc->sc_dev,
1638		    "could not multi read MAC register: %s\n",
1639		    usbd_errstr(error));
1640	}
1641}
1642
1643static usb_error_t
1644rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
1645{
1646	uint32_t tmp = htole32(val);
1647
1648	return (rum_write_multi(sc, reg, &tmp, sizeof tmp));
1649}
1650
1651static usb_error_t
1652rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
1653{
1654	struct usb_device_request req;
1655	usb_error_t error;
1656	size_t offset;
1657
1658	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1659	req.bRequest = RT2573_WRITE_MULTI_MAC;
1660	USETW(req.wValue, 0);
1661
1662	/* write at most 64 bytes at a time */
1663	for (offset = 0; offset < len; offset += 64) {
1664		USETW(req.wIndex, reg + offset);
1665		USETW(req.wLength, MIN(len - offset, 64));
1666
1667		error = rum_do_request(sc, &req, (char *)buf + offset);
1668		if (error != 0) {
1669			device_printf(sc->sc_dev,
1670			    "could not multi write MAC register: %s\n",
1671			    usbd_errstr(error));
1672			return (error);
1673		}
1674	}
1675
1676	return (USB_ERR_NORMAL_COMPLETION);
1677}
1678
1679static usb_error_t
1680rum_setbits(struct rum_softc *sc, uint16_t reg, uint32_t mask)
1681{
1682	return (rum_write(sc, reg, rum_read(sc, reg) | mask));
1683}
1684
1685static usb_error_t
1686rum_clrbits(struct rum_softc *sc, uint16_t reg, uint32_t mask)
1687{
1688	return (rum_write(sc, reg, rum_read(sc, reg) & ~mask));
1689}
1690
1691static usb_error_t
1692rum_modbits(struct rum_softc *sc, uint16_t reg, uint32_t set, uint32_t unset)
1693{
1694	return (rum_write(sc, reg, (rum_read(sc, reg) & ~unset) | set));
1695}
1696
1697static int
1698rum_bbp_busy(struct rum_softc *sc)
1699{
1700	int ntries;
1701
1702	for (ntries = 0; ntries < 100; ntries++) {
1703		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
1704			break;
1705		if (rum_pause(sc, hz / 100))
1706			break;
1707	}
1708	if (ntries == 100)
1709		return (ETIMEDOUT);
1710
1711	return (0);
1712}
1713
1714static void
1715rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
1716{
1717	uint32_t tmp;
1718
1719	DPRINTFN(2, "reg=0x%08x\n", reg);
1720
1721	if (rum_bbp_busy(sc) != 0) {
1722		device_printf(sc->sc_dev, "could not write to BBP\n");
1723		return;
1724	}
1725
1726	tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
1727	rum_write(sc, RT2573_PHY_CSR3, tmp);
1728}
1729
1730static uint8_t
1731rum_bbp_read(struct rum_softc *sc, uint8_t reg)
1732{
1733	uint32_t val;
1734	int ntries;
1735
1736	DPRINTFN(2, "reg=0x%08x\n", reg);
1737
1738	if (rum_bbp_busy(sc) != 0) {
1739		device_printf(sc->sc_dev, "could not read BBP\n");
1740		return 0;
1741	}
1742
1743	val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
1744	rum_write(sc, RT2573_PHY_CSR3, val);
1745
1746	for (ntries = 0; ntries < 100; ntries++) {
1747		val = rum_read(sc, RT2573_PHY_CSR3);
1748		if (!(val & RT2573_BBP_BUSY))
1749			return val & 0xff;
1750		if (rum_pause(sc, hz / 100))
1751			break;
1752	}
1753
1754	device_printf(sc->sc_dev, "could not read BBP\n");
1755	return 0;
1756}
1757
1758static void
1759rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
1760{
1761	uint32_t tmp;
1762	int ntries;
1763
1764	for (ntries = 0; ntries < 100; ntries++) {
1765		if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
1766			break;
1767		if (rum_pause(sc, hz / 100))
1768			break;
1769	}
1770	if (ntries == 100) {
1771		device_printf(sc->sc_dev, "could not write to RF\n");
1772		return;
1773	}
1774
1775	tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
1776	    (reg & 3);
1777	rum_write(sc, RT2573_PHY_CSR4, tmp);
1778
1779	/* remember last written value in sc */
1780	sc->rf_regs[reg] = val;
1781
1782	DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
1783}
1784
1785static void
1786rum_select_antenna(struct rum_softc *sc)
1787{
1788	uint8_t bbp4, bbp77;
1789	uint32_t tmp;
1790
1791	bbp4  = rum_bbp_read(sc, 4);
1792	bbp77 = rum_bbp_read(sc, 77);
1793
1794	/* TBD */
1795
1796	/* make sure Rx is disabled before switching antenna */
1797	tmp = rum_read(sc, RT2573_TXRX_CSR0);
1798	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1799
1800	rum_bbp_write(sc,  4, bbp4);
1801	rum_bbp_write(sc, 77, bbp77);
1802
1803	rum_write(sc, RT2573_TXRX_CSR0, tmp);
1804}
1805
1806/*
1807 * Enable multi-rate retries for frames sent at OFDM rates.
1808 * In 802.11b/g mode, allow fallback to CCK rates.
1809 */
1810static void
1811rum_enable_mrr(struct rum_softc *sc)
1812{
1813	struct ieee80211com *ic = &sc->sc_ic;
1814
1815	if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) {
1816		rum_setbits(sc, RT2573_TXRX_CSR4,
1817		    RT2573_MRR_ENABLED | RT2573_MRR_CCK_FALLBACK);
1818	} else {
1819		rum_modbits(sc, RT2573_TXRX_CSR4,
1820		    RT2573_MRR_ENABLED, RT2573_MRR_CCK_FALLBACK);
1821	}
1822}
1823
1824static void
1825rum_set_txpreamble(struct rum_softc *sc)
1826{
1827	struct ieee80211com *ic = &sc->sc_ic;
1828
1829	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1830		rum_setbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_PREAMBLE);
1831	else
1832		rum_clrbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_PREAMBLE);
1833}
1834
1835static void
1836rum_set_basicrates(struct rum_softc *sc)
1837{
1838	struct ieee80211com *ic = &sc->sc_ic;
1839
1840	/* update basic rate set */
1841	if (ic->ic_curmode == IEEE80211_MODE_11B) {
1842		/* 11b basic rates: 1, 2Mbps */
1843		rum_write(sc, RT2573_TXRX_CSR5, 0x3);
1844	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) {
1845		/* 11a basic rates: 6, 12, 24Mbps */
1846		rum_write(sc, RT2573_TXRX_CSR5, 0x150);
1847	} else {
1848		/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1849		rum_write(sc, RT2573_TXRX_CSR5, 0xf);
1850	}
1851}
1852
1853/*
1854 * Reprogram MAC/BBP to switch to a new band.  Values taken from the reference
1855 * driver.
1856 */
1857static void
1858rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
1859{
1860	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
1861
1862	/* update all BBP registers that depend on the band */
1863	bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
1864	bbp35 = 0x50; bbp97 = 0x48; bbp98  = 0x48;
1865	if (IEEE80211_IS_CHAN_5GHZ(c)) {
1866		bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
1867		bbp35 += 0x10; bbp97 += 0x10; bbp98  += 0x10;
1868	}
1869	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1870	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1871		bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
1872	}
1873
1874	sc->bbp17 = bbp17;
1875	rum_bbp_write(sc,  17, bbp17);
1876	rum_bbp_write(sc,  96, bbp96);
1877	rum_bbp_write(sc, 104, bbp104);
1878
1879	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1880	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1881		rum_bbp_write(sc, 75, 0x80);
1882		rum_bbp_write(sc, 86, 0x80);
1883		rum_bbp_write(sc, 88, 0x80);
1884	}
1885
1886	rum_bbp_write(sc, 35, bbp35);
1887	rum_bbp_write(sc, 97, bbp97);
1888	rum_bbp_write(sc, 98, bbp98);
1889
1890	if (IEEE80211_IS_CHAN_2GHZ(c)) {
1891		rum_modbits(sc, RT2573_PHY_CSR0, RT2573_PA_PE_2GHZ,
1892		    RT2573_PA_PE_5GHZ);
1893	} else {
1894		rum_modbits(sc, RT2573_PHY_CSR0, RT2573_PA_PE_5GHZ,
1895		    RT2573_PA_PE_2GHZ);
1896	}
1897}
1898
1899static void
1900rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
1901{
1902	struct ieee80211com *ic = &sc->sc_ic;
1903	const struct rfprog *rfprog;
1904	uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
1905	int8_t power;
1906	int i, chan;
1907
1908	chan = ieee80211_chan2ieee(ic, c);
1909	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1910		return;
1911
1912	/* select the appropriate RF settings based on what EEPROM says */
1913	rfprog = (sc->rf_rev == RT2573_RF_5225 ||
1914		  sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
1915
1916	/* find the settings for this channel (we know it exists) */
1917	for (i = 0; rfprog[i].chan != chan; i++);
1918
1919	power = sc->txpow[i];
1920	if (power < 0) {
1921		bbp94 += power;
1922		power = 0;
1923	} else if (power > 31) {
1924		bbp94 += power - 31;
1925		power = 31;
1926	}
1927
1928	/*
1929	 * If we are switching from the 2GHz band to the 5GHz band or
1930	 * vice-versa, BBP registers need to be reprogrammed.
1931	 */
1932	if (c->ic_flags != ic->ic_curchan->ic_flags) {
1933		rum_select_band(sc, c);
1934		rum_select_antenna(sc);
1935	}
1936	ic->ic_curchan = c;
1937
1938	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1939	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1940	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1941	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1942
1943	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1944	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1945	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
1946	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1947
1948	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1949	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1950	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1951	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1952
1953	rum_pause(sc, hz / 100);
1954
1955	/* enable smart mode for MIMO-capable RFs */
1956	bbp3 = rum_bbp_read(sc, 3);
1957
1958	bbp3 &= ~RT2573_SMART_MODE;
1959	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
1960		bbp3 |= RT2573_SMART_MODE;
1961
1962	rum_bbp_write(sc, 3, bbp3);
1963
1964	if (bbp94 != RT2573_BBPR94_DEFAULT)
1965		rum_bbp_write(sc, 94, bbp94);
1966
1967	/* give the chip some extra time to do the switchover */
1968	rum_pause(sc, hz / 100);
1969}
1970
1971static void
1972rum_set_maxretry(struct rum_softc *sc, struct ieee80211vap *vap)
1973{
1974	const struct ieee80211_txparam *tp;
1975	struct ieee80211_node *ni = vap->iv_bss;
1976	struct rum_vap *rvp = RUM_VAP(vap);
1977
1978	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1979	rvp->maxretry = tp->maxretry < 0xf ? tp->maxretry : 0xf;
1980
1981	rum_modbits(sc, RT2573_TXRX_CSR4, RT2573_SHORT_RETRY(rvp->maxretry) |
1982	    RT2573_LONG_RETRY(rvp->maxretry),
1983	    RT2573_SHORT_RETRY_MASK | RT2573_LONG_RETRY_MASK);
1984}
1985
1986/*
1987 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1988 * and HostAP operating modes.
1989 */
1990static int
1991rum_enable_tsf_sync(struct rum_softc *sc)
1992{
1993	struct ieee80211com *ic = &sc->sc_ic;
1994	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1995	uint32_t tmp;
1996
1997	if (vap->iv_opmode != IEEE80211_M_STA) {
1998		/*
1999		 * Change default 16ms TBTT adjustment to 8ms.
2000		 * Must be done before enabling beacon generation.
2001		 */
2002		if (rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8) != 0)
2003			return EIO;
2004	}
2005
2006	tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
2007
2008	/* set beacon interval (in 1/16ms unit) */
2009	tmp |= vap->iv_bss->ni_intval * 16;
2010	tmp |= RT2573_TSF_TIMER_EN | RT2573_TBTT_TIMER_EN;
2011
2012	switch (vap->iv_opmode) {
2013	case IEEE80211_M_STA:
2014		/*
2015		 * Local TSF is always updated with remote TSF on beacon
2016		 * reception.
2017		 */
2018		tmp |= RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_STA);
2019		break;
2020	case IEEE80211_M_IBSS:
2021		/*
2022		 * Local TSF is updated with remote TSF on beacon reception
2023		 * only if the remote TSF is greater than local TSF.
2024		 */
2025		tmp |= RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_IBSS);
2026		tmp |= RT2573_BCN_TX_EN;
2027		break;
2028	case IEEE80211_M_HOSTAP:
2029		/* SYNC with nobody */
2030		tmp |= RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_HOSTAP);
2031		tmp |= RT2573_BCN_TX_EN;
2032		break;
2033	default:
2034		device_printf(sc->sc_dev,
2035		    "Enabling TSF failed. undefined opmode %d\n",
2036		    vap->iv_opmode);
2037		return EINVAL;
2038	}
2039
2040	if (rum_write(sc, RT2573_TXRX_CSR9, tmp) != 0)
2041		return EIO;
2042
2043	return 0;
2044}
2045
2046static void
2047rum_enable_tsf(struct rum_softc *sc)
2048{
2049	rum_modbits(sc, RT2573_TXRX_CSR9, RT2573_TSF_TIMER_EN |
2050	    RT2573_TSF_SYNC_MODE(RT2573_TSF_SYNC_MODE_DIS), 0x00ffffff);
2051}
2052
2053static void
2054rum_abort_tsf_sync(struct rum_softc *sc)
2055{
2056	rum_clrbits(sc, RT2573_TXRX_CSR9, 0x00ffffff);
2057}
2058
2059static void
2060rum_get_tsf(struct rum_softc *sc, uint64_t *buf)
2061{
2062	rum_read_multi(sc, RT2573_TXRX_CSR12, buf, sizeof (*buf));
2063}
2064
2065static void
2066rum_update_slot_cb(struct rum_softc *sc, union sec_param *data, uint8_t rvp_id)
2067{
2068	struct ieee80211com *ic = &sc->sc_ic;
2069	uint8_t slottime;
2070
2071	slottime = IEEE80211_GET_SLOTTIME(ic);
2072
2073	rum_modbits(sc, RT2573_MAC_CSR9, slottime, 0xff);
2074
2075	DPRINTF("setting slot time to %uus\n", slottime);
2076}
2077
2078static void
2079rum_update_slot(struct ieee80211com *ic)
2080{
2081	rum_cmd_sleepable(ic->ic_softc, NULL, 0, 0, rum_update_slot_cb);
2082}
2083
2084static int
2085rum_wme_update(struct ieee80211com *ic)
2086{
2087	const struct wmeParams *chanp =
2088	    ic->ic_wme.wme_chanParams.cap_wmeParams;
2089	struct rum_softc *sc = ic->ic_softc;
2090	int error = 0;
2091
2092	RUM_LOCK(sc);
2093	error = rum_write(sc, RT2573_AIFSN_CSR,
2094	    chanp[WME_AC_VO].wmep_aifsn  << 12 |
2095	    chanp[WME_AC_VI].wmep_aifsn  <<  8 |
2096	    chanp[WME_AC_BK].wmep_aifsn  <<  4 |
2097	    chanp[WME_AC_BE].wmep_aifsn);
2098	if (error)
2099		goto print_err;
2100	error = rum_write(sc, RT2573_CWMIN_CSR,
2101	    chanp[WME_AC_VO].wmep_logcwmin << 12 |
2102	    chanp[WME_AC_VI].wmep_logcwmin <<  8 |
2103	    chanp[WME_AC_BK].wmep_logcwmin <<  4 |
2104	    chanp[WME_AC_BE].wmep_logcwmin);
2105	if (error)
2106		goto print_err;
2107	error = rum_write(sc, RT2573_CWMAX_CSR,
2108	    chanp[WME_AC_VO].wmep_logcwmax << 12 |
2109	    chanp[WME_AC_VI].wmep_logcwmax <<  8 |
2110	    chanp[WME_AC_BK].wmep_logcwmax <<  4 |
2111	    chanp[WME_AC_BE].wmep_logcwmax);
2112	if (error)
2113		goto print_err;
2114	error = rum_write(sc, RT2573_TXOP01_CSR,
2115	    chanp[WME_AC_BK].wmep_txopLimit << 16 |
2116	    chanp[WME_AC_BE].wmep_txopLimit);
2117	if (error)
2118		goto print_err;
2119	error = rum_write(sc, RT2573_TXOP23_CSR,
2120	    chanp[WME_AC_VO].wmep_txopLimit << 16 |
2121	    chanp[WME_AC_VI].wmep_txopLimit);
2122	if (error)
2123		goto print_err;
2124
2125	memcpy(sc->wme_params, chanp, sizeof(*chanp) * WME_NUM_AC);
2126
2127print_err:
2128	RUM_UNLOCK(sc);
2129	if (error != 0) {
2130		device_printf(sc->sc_dev, "%s: WME update failed, error %d\n",
2131		    __func__, error);
2132	}
2133
2134	return (error);
2135}
2136
2137static void
2138rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
2139{
2140
2141	rum_write(sc, RT2573_MAC_CSR4,
2142	    bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24);
2143	rum_write(sc, RT2573_MAC_CSR5,
2144	    bssid[4] | bssid[5] << 8 | RT2573_NUM_BSSID_MSK(1));
2145}
2146
2147static void
2148rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
2149{
2150
2151	rum_write(sc, RT2573_MAC_CSR2,
2152	    addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24);
2153	rum_write(sc, RT2573_MAC_CSR3,
2154	    addr[4] | addr[5] << 8 | 0xff << 16);
2155}
2156
2157static void
2158rum_setpromisc(struct rum_softc *sc)
2159{
2160	struct ieee80211com *ic = &sc->sc_ic;
2161
2162	if (ic->ic_promisc == 0)
2163		rum_setbits(sc, RT2573_TXRX_CSR0, RT2573_DROP_NOT_TO_ME);
2164	else
2165		rum_clrbits(sc, RT2573_TXRX_CSR0, RT2573_DROP_NOT_TO_ME);
2166
2167	DPRINTF("%s promiscuous mode\n", ic->ic_promisc > 0 ?
2168	    "entering" : "leaving");
2169}
2170
2171static void
2172rum_update_promisc(struct ieee80211com *ic)
2173{
2174	struct rum_softc *sc = ic->ic_softc;
2175
2176	RUM_LOCK(sc);
2177	if (sc->sc_running)
2178		rum_setpromisc(sc);
2179	RUM_UNLOCK(sc);
2180}
2181
2182static void
2183rum_update_mcast(struct ieee80211com *ic)
2184{
2185	/* Ignore. */
2186}
2187
2188static const char *
2189rum_get_rf(int rev)
2190{
2191	switch (rev) {
2192	case RT2573_RF_2527:	return "RT2527 (MIMO XR)";
2193	case RT2573_RF_2528:	return "RT2528";
2194	case RT2573_RF_5225:	return "RT5225 (MIMO XR)";
2195	case RT2573_RF_5226:	return "RT5226";
2196	default:		return "unknown";
2197	}
2198}
2199
2200static void
2201rum_read_eeprom(struct rum_softc *sc)
2202{
2203	uint16_t val;
2204#ifdef RUM_DEBUG
2205	int i;
2206#endif
2207
2208	/* read MAC address */
2209	rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_ic.ic_macaddr, 6);
2210
2211	rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
2212	val = le16toh(val);
2213	sc->rf_rev =   (val >> 11) & 0x1f;
2214	sc->hw_radio = (val >> 10) & 0x1;
2215	sc->rx_ant =   (val >> 4)  & 0x3;
2216	sc->tx_ant =   (val >> 2)  & 0x3;
2217	sc->nb_ant =   val & 0x3;
2218
2219	DPRINTF("RF revision=%d\n", sc->rf_rev);
2220
2221	rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
2222	val = le16toh(val);
2223	sc->ext_5ghz_lna = (val >> 6) & 0x1;
2224	sc->ext_2ghz_lna = (val >> 4) & 0x1;
2225
2226	DPRINTF("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
2227	    sc->ext_2ghz_lna, sc->ext_5ghz_lna);
2228
2229	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
2230	val = le16toh(val);
2231	if ((val & 0xff) != 0xff)
2232		sc->rssi_2ghz_corr = (int8_t)(val & 0xff);	/* signed */
2233
2234	/* Only [-10, 10] is valid */
2235	if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10)
2236		sc->rssi_2ghz_corr = 0;
2237
2238	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
2239	val = le16toh(val);
2240	if ((val & 0xff) != 0xff)
2241		sc->rssi_5ghz_corr = (int8_t)(val & 0xff);	/* signed */
2242
2243	/* Only [-10, 10] is valid */
2244	if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10)
2245		sc->rssi_5ghz_corr = 0;
2246
2247	if (sc->ext_2ghz_lna)
2248		sc->rssi_2ghz_corr -= 14;
2249	if (sc->ext_5ghz_lna)
2250		sc->rssi_5ghz_corr -= 14;
2251
2252	DPRINTF("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
2253	    sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
2254
2255	rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
2256	val = le16toh(val);
2257	if ((val & 0xff) != 0xff)
2258		sc->rffreq = val & 0xff;
2259
2260	DPRINTF("RF freq=%d\n", sc->rffreq);
2261
2262	/* read Tx power for all a/b/g channels */
2263	rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
2264	/* XXX default Tx power for 802.11a channels */
2265	memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
2266#ifdef RUM_DEBUG
2267	for (i = 0; i < 14; i++)
2268		DPRINTF("Channel=%d Tx power=%d\n", i + 1,  sc->txpow[i]);
2269#endif
2270
2271	/* read default values for BBP registers */
2272	rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
2273#ifdef RUM_DEBUG
2274	for (i = 0; i < 14; i++) {
2275		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
2276			continue;
2277		DPRINTF("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
2278		    sc->bbp_prom[i].val);
2279	}
2280#endif
2281}
2282
2283static int
2284rum_bbp_wakeup(struct rum_softc *sc)
2285{
2286	unsigned int ntries;
2287
2288	for (ntries = 0; ntries < 100; ntries++) {
2289		if (rum_read(sc, RT2573_MAC_CSR12) & 8)
2290			break;
2291		rum_write(sc, RT2573_MAC_CSR12, 4);	/* force wakeup */
2292		if (rum_pause(sc, hz / 100))
2293			break;
2294	}
2295	if (ntries == 100) {
2296		device_printf(sc->sc_dev,
2297		    "timeout waiting for BBP/RF to wakeup\n");
2298		return (ETIMEDOUT);
2299	}
2300
2301	return (0);
2302}
2303
2304static int
2305rum_bbp_init(struct rum_softc *sc)
2306{
2307	int i, ntries;
2308
2309	/* wait for BBP to be ready */
2310	for (ntries = 0; ntries < 100; ntries++) {
2311		const uint8_t val = rum_bbp_read(sc, 0);
2312		if (val != 0 && val != 0xff)
2313			break;
2314		if (rum_pause(sc, hz / 100))
2315			break;
2316	}
2317	if (ntries == 100) {
2318		device_printf(sc->sc_dev, "timeout waiting for BBP\n");
2319		return EIO;
2320	}
2321
2322	/* initialize BBP registers to default values */
2323	for (i = 0; i < nitems(rum_def_bbp); i++)
2324		rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
2325
2326	/* write vendor-specific BBP values (from EEPROM) */
2327	for (i = 0; i < 16; i++) {
2328		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
2329			continue;
2330		rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
2331	}
2332
2333	return 0;
2334}
2335
2336static void
2337rum_clr_shkey_regs(struct rum_softc *sc)
2338{
2339	rum_write(sc, RT2573_SEC_CSR0, 0);
2340	rum_write(sc, RT2573_SEC_CSR1, 0);
2341	rum_write(sc, RT2573_SEC_CSR5, 0);
2342}
2343
2344static int
2345rum_init(struct rum_softc *sc)
2346{
2347	struct ieee80211com *ic = &sc->sc_ic;
2348	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2349	uint32_t tmp;
2350	int i, ret;
2351
2352	RUM_LOCK(sc);
2353	if (sc->sc_running) {
2354		ret = 0;
2355		goto end;
2356	}
2357
2358	/* initialize MAC registers to default values */
2359	for (i = 0; i < nitems(rum_def_mac); i++)
2360		rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
2361
2362	/* reset some WME parameters to default values */
2363	sc->wme_params[0].wmep_aifsn = 2;
2364	sc->wme_params[0].wmep_logcwmin = 4;
2365	sc->wme_params[0].wmep_logcwmax = 10;
2366
2367	/* set host ready */
2368	rum_write(sc, RT2573_MAC_CSR1, RT2573_RESET_ASIC | RT2573_RESET_BBP);
2369	rum_write(sc, RT2573_MAC_CSR1, 0);
2370
2371	/* wait for BBP/RF to wakeup */
2372	if ((ret = rum_bbp_wakeup(sc)) != 0)
2373		goto end;
2374
2375	if ((ret = rum_bbp_init(sc)) != 0)
2376		goto end;
2377
2378	/* select default channel */
2379	rum_select_band(sc, ic->ic_curchan);
2380	rum_select_antenna(sc);
2381	rum_set_chan(sc, ic->ic_curchan);
2382
2383	/* clear STA registers */
2384	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
2385
2386	/* clear security registers (if required) */
2387	if (sc->sc_clr_shkeys == 0) {
2388		rum_clr_shkey_regs(sc);
2389		sc->sc_clr_shkeys = 1;
2390	}
2391
2392	rum_set_macaddr(sc, vap ? vap->iv_myaddr : ic->ic_macaddr);
2393
2394	/* initialize ASIC */
2395	rum_write(sc, RT2573_MAC_CSR1, RT2573_HOST_READY);
2396
2397	/*
2398	 * Allocate Tx and Rx xfer queues.
2399	 */
2400	rum_setup_tx_list(sc);
2401
2402	/* update Rx filter */
2403	tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
2404
2405	tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
2406	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2407		tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
2408		       RT2573_DROP_ACKCTS;
2409		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2410			tmp |= RT2573_DROP_TODS;
2411		if (ic->ic_promisc == 0)
2412			tmp |= RT2573_DROP_NOT_TO_ME;
2413	}
2414	rum_write(sc, RT2573_TXRX_CSR0, tmp);
2415
2416	sc->sc_running = 1;
2417	usbd_xfer_set_stall(sc->sc_xfer[RUM_BULK_WR]);
2418	usbd_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
2419
2420end:	RUM_UNLOCK(sc);
2421
2422	if (ret != 0)
2423		rum_stop(sc);
2424
2425	return ret;
2426}
2427
2428static void
2429rum_stop(struct rum_softc *sc)
2430{
2431
2432	RUM_LOCK(sc);
2433	if (!sc->sc_running) {
2434		RUM_UNLOCK(sc);
2435		return;
2436	}
2437	sc->sc_running = 0;
2438	RUM_UNLOCK(sc);
2439
2440	/*
2441	 * Drain the USB transfers, if not already drained:
2442	 */
2443	usbd_transfer_drain(sc->sc_xfer[RUM_BULK_WR]);
2444	usbd_transfer_drain(sc->sc_xfer[RUM_BULK_RD]);
2445
2446	RUM_LOCK(sc);
2447	rum_unsetup_tx_list(sc);
2448
2449	/* disable Rx */
2450	rum_setbits(sc, RT2573_TXRX_CSR0, RT2573_DISABLE_RX);
2451
2452	/* reset ASIC */
2453	rum_write(sc, RT2573_MAC_CSR1, RT2573_RESET_ASIC | RT2573_RESET_BBP);
2454	rum_write(sc, RT2573_MAC_CSR1, 0);
2455	RUM_UNLOCK(sc);
2456}
2457
2458static void
2459rum_load_microcode(struct rum_softc *sc, const uint8_t *ucode, size_t size)
2460{
2461	struct usb_device_request req;
2462	uint16_t reg = RT2573_MCU_CODE_BASE;
2463	usb_error_t err;
2464
2465	/* copy firmware image into NIC */
2466	for (; size >= 4; reg += 4, ucode += 4, size -= 4) {
2467		err = rum_write(sc, reg, UGETDW(ucode));
2468		if (err) {
2469			/* firmware already loaded ? */
2470			device_printf(sc->sc_dev, "Firmware load "
2471			    "failure! (ignored)\n");
2472			break;
2473		}
2474	}
2475
2476	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2477	req.bRequest = RT2573_MCU_CNTL;
2478	USETW(req.wValue, RT2573_MCU_RUN);
2479	USETW(req.wIndex, 0);
2480	USETW(req.wLength, 0);
2481
2482	err = rum_do_request(sc, &req, NULL);
2483	if (err != 0) {
2484		device_printf(sc->sc_dev, "could not run firmware: %s\n",
2485		    usbd_errstr(err));
2486	}
2487
2488	/* give the chip some time to boot */
2489	rum_pause(sc, hz / 8);
2490}
2491
2492static int
2493rum_set_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
2494{
2495	struct ieee80211com *ic = vap->iv_ic;
2496	struct rum_vap *rvp = RUM_VAP(vap);
2497	struct mbuf *m = rvp->bcn_mbuf;
2498	const struct ieee80211_txparam *tp;
2499	struct rum_tx_desc desc;
2500
2501	RUM_LOCK_ASSERT(sc);
2502
2503	if (m == NULL)
2504		return EINVAL;
2505	if (ic->ic_bsschan == IEEE80211_CHAN_ANYC)
2506		return EINVAL;
2507
2508	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
2509	rum_setup_tx_desc(sc, &desc, NULL, RT2573_TX_TIMESTAMP,
2510	    RT2573_TX_HWSEQ, 0, 0, m->m_pkthdr.len, tp->mgmtrate);
2511
2512	/* copy the Tx descriptor into NIC memory */
2513	if (rum_write_multi(sc, RT2573_HW_BCN_BASE(0), (uint8_t *)&desc,
2514	    RT2573_TX_DESC_SIZE) != 0)
2515		return EIO;
2516
2517	/* copy beacon header and payload into NIC memory */
2518	if (rum_write_multi(sc, RT2573_HW_BCN_BASE(0) + RT2573_TX_DESC_SIZE,
2519	    mtod(m, uint8_t *), m->m_pkthdr.len) != 0)
2520		return EIO;
2521
2522	return 0;
2523}
2524
2525static int
2526rum_alloc_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
2527{
2528	struct rum_vap *rvp = RUM_VAP(vap);
2529	struct ieee80211_node *ni = vap->iv_bss;
2530	struct mbuf *m;
2531
2532	if (ni->ni_chan == IEEE80211_CHAN_ANYC)
2533		return EINVAL;
2534
2535	m = ieee80211_beacon_alloc(ni);
2536	if (m == NULL)
2537		return ENOMEM;
2538
2539	if (rvp->bcn_mbuf != NULL)
2540		m_freem(rvp->bcn_mbuf);
2541
2542	rvp->bcn_mbuf = m;
2543
2544	return (rum_set_beacon(sc, vap));
2545}
2546
2547static void
2548rum_update_beacon_cb(struct rum_softc *sc, union sec_param *data,
2549    uint8_t rvp_id)
2550{
2551	struct ieee80211vap *vap = data->vap;
2552
2553	rum_set_beacon(sc, vap);
2554}
2555
2556static void
2557rum_update_beacon(struct ieee80211vap *vap, int item)
2558{
2559	struct ieee80211com *ic = vap->iv_ic;
2560	struct rum_softc *sc = ic->ic_softc;
2561	struct rum_vap *rvp = RUM_VAP(vap);
2562	struct ieee80211_beacon_offsets *bo = &vap->iv_bcn_off;
2563	struct ieee80211_node *ni = vap->iv_bss;
2564	struct mbuf *m = rvp->bcn_mbuf;
2565	int mcast = 0;
2566
2567	RUM_LOCK(sc);
2568	if (m == NULL) {
2569		m = ieee80211_beacon_alloc(ni);
2570		if (m == NULL) {
2571			device_printf(sc->sc_dev,
2572			    "%s: could not allocate beacon frame\n", __func__);
2573			RUM_UNLOCK(sc);
2574			return;
2575		}
2576		rvp->bcn_mbuf = m;
2577	}
2578
2579	switch (item) {
2580	case IEEE80211_BEACON_ERP:
2581		rum_update_slot(ic);
2582		break;
2583	case IEEE80211_BEACON_TIM:
2584		mcast = 1;	/*TODO*/
2585		break;
2586	default:
2587		break;
2588	}
2589	RUM_UNLOCK(sc);
2590
2591	setbit(bo->bo_flags, item);
2592	ieee80211_beacon_update(ni, m, mcast);
2593
2594	rum_cmd_sleepable(sc, &vap, sizeof(vap), 0, rum_update_beacon_cb);
2595}
2596
2597static int
2598rum_common_key_set(struct rum_softc *sc, struct ieee80211_key *k,
2599    uint16_t base)
2600{
2601
2602	if (rum_write_multi(sc, base, k->wk_key, k->wk_keylen))
2603		return EIO;
2604
2605	if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) {
2606		if (rum_write_multi(sc, base + IEEE80211_KEYBUF_SIZE,
2607		    k->wk_txmic, 8))
2608			return EIO;
2609		if (rum_write_multi(sc, base + IEEE80211_KEYBUF_SIZE + 8,
2610		    k->wk_rxmic, 8))
2611			return EIO;
2612	}
2613
2614	return 0;
2615}
2616
2617static void
2618rum_group_key_set_cb(struct rum_softc *sc, union sec_param *data,
2619    uint8_t rvp_id)
2620{
2621	struct ieee80211_key *k = &data->key;
2622	uint8_t mode;
2623
2624	if (sc->sc_clr_shkeys == 0) {
2625		rum_clr_shkey_regs(sc);
2626		sc->sc_clr_shkeys = 1;
2627	}
2628
2629	mode = rum_crypto_mode(sc, k->wk_cipher->ic_cipher, k->wk_keylen);
2630	if (mode == 0)
2631		goto print_err;
2632
2633	DPRINTFN(1, "setting group key %d for vap %d, mode %d "
2634	    "(tx %s, rx %s)\n", k->wk_keyix, rvp_id, mode,
2635	    (k->wk_flags & IEEE80211_KEY_XMIT) ? "on" : "off",
2636	    (k->wk_flags & IEEE80211_KEY_RECV) ? "on" : "off");
2637
2638	/* Install the key. */
2639	if (rum_common_key_set(sc, k, RT2573_SKEY(rvp_id, k->wk_keyix)) != 0)
2640		goto print_err;
2641
2642	/* Set cipher mode. */
2643	if (rum_modbits(sc, rvp_id < 2 ? RT2573_SEC_CSR1 : RT2573_SEC_CSR5,
2644	      mode << (rvp_id % 2 + k->wk_keyix) * RT2573_SKEY_MAX,
2645	      RT2573_MODE_MASK << (rvp_id % 2 + k->wk_keyix) * RT2573_SKEY_MAX)
2646	    != 0)
2647		goto print_err;
2648
2649	/* Mark this key as valid. */
2650	if (rum_setbits(sc, RT2573_SEC_CSR0,
2651	      1 << (rvp_id * RT2573_SKEY_MAX + k->wk_keyix)) != 0)
2652		goto print_err;
2653
2654	return;
2655
2656print_err:
2657	device_printf(sc->sc_dev, "%s: cannot set group key %d for vap %d\n",
2658	    __func__, k->wk_keyix, rvp_id);
2659}
2660
2661static void
2662rum_group_key_del_cb(struct rum_softc *sc, union sec_param *data,
2663    uint8_t rvp_id)
2664{
2665	struct ieee80211_key *k = &data->key;
2666
2667	DPRINTF("%s: removing group key %d for vap %d\n", __func__,
2668	    k->wk_keyix, rvp_id);
2669	rum_clrbits(sc,
2670	    rvp_id < 2 ? RT2573_SEC_CSR1 : RT2573_SEC_CSR5,
2671	    RT2573_MODE_MASK << (rvp_id % 2 + k->wk_keyix) * RT2573_SKEY_MAX);
2672	rum_clrbits(sc, RT2573_SEC_CSR0,
2673	    rvp_id * RT2573_SKEY_MAX + k->wk_keyix);
2674}
2675
2676static void
2677rum_pair_key_set_cb(struct rum_softc *sc, union sec_param *data,
2678    uint8_t rvp_id)
2679{
2680	struct ieee80211_key *k = &data->key;
2681	uint8_t buf[IEEE80211_ADDR_LEN + 1];
2682	uint8_t mode;
2683
2684	mode = rum_crypto_mode(sc, k->wk_cipher->ic_cipher, k->wk_keylen);
2685	if (mode == 0)
2686		goto print_err;
2687
2688	DPRINTFN(1, "setting pairwise key %d for vap %d, mode %d "
2689	    "(tx %s, rx %s)\n", k->wk_keyix, rvp_id, mode,
2690	    (k->wk_flags & IEEE80211_KEY_XMIT) ? "on" : "off",
2691	    (k->wk_flags & IEEE80211_KEY_RECV) ? "on" : "off");
2692
2693	/* Install the key. */
2694	if (rum_common_key_set(sc, k, RT2573_PKEY(k->wk_keyix)) != 0)
2695		goto print_err;
2696
2697	IEEE80211_ADDR_COPY(buf, k->wk_macaddr);
2698	buf[IEEE80211_ADDR_LEN] = mode;
2699
2700	/* Set transmitter address and cipher mode. */
2701	if (rum_write_multi(sc, RT2573_ADDR_ENTRY(k->wk_keyix),
2702	      buf, sizeof buf) != 0)
2703		goto print_err;
2704
2705	/* Enable key table lookup for this vap. */
2706	if (sc->vap_key_count[rvp_id]++ == 0)
2707		if (rum_setbits(sc, RT2573_SEC_CSR4, 1 << rvp_id) != 0)
2708			goto print_err;
2709
2710	/* Mark this key as valid. */
2711	if (rum_setbits(sc,
2712	      k->wk_keyix < 32 ? RT2573_SEC_CSR2 : RT2573_SEC_CSR3,
2713	      1 << (k->wk_keyix % 32)) != 0)
2714		goto print_err;
2715
2716	return;
2717
2718print_err:
2719	device_printf(sc->sc_dev,
2720	    "%s: cannot set pairwise key %d, vap %d\n", __func__, k->wk_keyix,
2721	    rvp_id);
2722}
2723
2724static void
2725rum_pair_key_del_cb(struct rum_softc *sc, union sec_param *data,
2726    uint8_t rvp_id)
2727{
2728	struct ieee80211_key *k = &data->key;
2729
2730	DPRINTF("%s: removing key %d\n", __func__, k->wk_keyix);
2731	rum_clrbits(sc, (k->wk_keyix < 32) ? RT2573_SEC_CSR2 : RT2573_SEC_CSR3,
2732	    1 << (k->wk_keyix % 32));
2733	sc->keys_bmap &= ~(1 << k->wk_keyix);
2734	if (--sc->vap_key_count[rvp_id] == 0)
2735		rum_clrbits(sc, RT2573_SEC_CSR4, 1 << rvp_id);
2736}
2737
2738static int
2739rum_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k,
2740    ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix)
2741{
2742	struct rum_softc *sc = vap->iv_ic->ic_softc;
2743	uint8_t i;
2744
2745	if (!(&vap->iv_nw_keys[0] <= k &&
2746	     k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) {
2747		if (!(k->wk_flags & IEEE80211_KEY_SWCRYPT)) {
2748			RUM_LOCK(sc);
2749			for (i = 0; i < RT2573_ADDR_MAX; i++) {
2750				if ((sc->keys_bmap & (1 << i)) == 0) {
2751					sc->keys_bmap |= 1 << i;
2752					*keyix = i;
2753					break;
2754				}
2755			}
2756			RUM_UNLOCK(sc);
2757			if (i == RT2573_ADDR_MAX) {
2758				device_printf(sc->sc_dev,
2759				    "%s: no free space in the key table\n",
2760				    __func__);
2761				return 0;
2762			}
2763		} else
2764			*keyix = 0;
2765	} else {
2766		*keyix = k - vap->iv_nw_keys;
2767	}
2768	*rxkeyix = *keyix;
2769	return 1;
2770}
2771
2772static int
2773rum_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
2774{
2775	struct rum_softc *sc = vap->iv_ic->ic_softc;
2776	int group;
2777
2778	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
2779		/* Not for us. */
2780		return 1;
2781	}
2782
2783	group = k >= &vap->iv_nw_keys[0] && k < &vap->iv_nw_keys[IEEE80211_WEP_NKID];
2784
2785	return !rum_cmd_sleepable(sc, k, sizeof(*k), 0,
2786		   group ? rum_group_key_set_cb : rum_pair_key_set_cb);
2787}
2788
2789static int
2790rum_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
2791{
2792	struct rum_softc *sc = vap->iv_ic->ic_softc;
2793	int group;
2794
2795	if (k->wk_flags & IEEE80211_KEY_SWCRYPT) {
2796		/* Not for us. */
2797		return 1;
2798	}
2799
2800	group = k >= &vap->iv_nw_keys[0] && k < &vap->iv_nw_keys[IEEE80211_WEP_NKID];
2801
2802	return !rum_cmd_sleepable(sc, k, sizeof(*k), 0,
2803		   group ? rum_group_key_del_cb : rum_pair_key_del_cb);
2804}
2805
2806static int
2807rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2808    const struct ieee80211_bpf_params *params)
2809{
2810	struct rum_softc *sc = ni->ni_ic->ic_softc;
2811	int ret;
2812
2813	RUM_LOCK(sc);
2814	/* prevent management frames from being sent if we're not ready */
2815	if (!sc->sc_running) {
2816		ret = ENETDOWN;
2817		goto bad;
2818	}
2819	if (sc->tx_nfree < RUM_TX_MINFREE) {
2820		ret = EIO;
2821		goto bad;
2822	}
2823
2824	if (params == NULL) {
2825		/*
2826		 * Legacy path; interpret frame contents to decide
2827		 * precisely how to send the frame.
2828		 */
2829		if ((ret = rum_tx_mgt(sc, m, ni)) != 0)
2830			goto bad;
2831	} else {
2832		/*
2833		 * Caller supplied explicit parameters to use in
2834		 * sending the frame.
2835		 */
2836		if ((ret = rum_tx_raw(sc, m, ni, params)) != 0)
2837			goto bad;
2838	}
2839	RUM_UNLOCK(sc);
2840
2841	return 0;
2842bad:
2843	RUM_UNLOCK(sc);
2844	m_freem(m);
2845	return ret;
2846}
2847
2848static void
2849rum_ratectl_start(struct rum_softc *sc, struct ieee80211_node *ni)
2850{
2851	struct ieee80211vap *vap = ni->ni_vap;
2852	struct rum_vap *rvp = RUM_VAP(vap);
2853
2854	/* clear statistic registers (STA_CSR0 to STA_CSR5) */
2855	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
2856
2857	usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
2858}
2859
2860static void
2861rum_ratectl_timeout(void *arg)
2862{
2863	struct rum_vap *rvp = arg;
2864	struct ieee80211vap *vap = &rvp->vap;
2865	struct ieee80211com *ic = vap->iv_ic;
2866
2867	ieee80211_runtask(ic, &rvp->ratectl_task);
2868}
2869
2870static void
2871rum_ratectl_task(void *arg, int pending)
2872{
2873	struct rum_vap *rvp = arg;
2874	struct ieee80211vap *vap = &rvp->vap;
2875	struct rum_softc *sc = vap->iv_ic->ic_softc;
2876	struct ieee80211_node *ni;
2877	int ok[3], fail;
2878	int sum, success, retrycnt;
2879
2880	RUM_LOCK(sc);
2881	/* read and clear statistic registers (STA_CSR0 to STA_CSR5) */
2882	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta));
2883
2884	ok[0] = (le32toh(sc->sta[4]) & 0xffff);	/* TX ok w/o retry */
2885	ok[1] = (le32toh(sc->sta[4]) >> 16);	/* TX ok w/ one retry */
2886	ok[2] = (le32toh(sc->sta[5]) & 0xffff);	/* TX ok w/ multiple retries */
2887	fail =  (le32toh(sc->sta[5]) >> 16);	/* TX retry-fail count */
2888
2889	success = ok[0] + ok[1] + ok[2];
2890	sum = success + fail;
2891	/* XXX at least */
2892	retrycnt = ok[1] + ok[2] * 2 + fail * (rvp->maxretry + 1);
2893
2894	if (sum != 0) {
2895		ni = ieee80211_ref_node(vap->iv_bss);
2896		ieee80211_ratectl_tx_update(vap, ni, &sum, &ok, &retrycnt);
2897		(void) ieee80211_ratectl_rate(ni, NULL, 0);
2898		ieee80211_free_node(ni);
2899	}
2900
2901	/* count TX retry-fail as Tx errors */
2902	if_inc_counter(vap->iv_ifp, IFCOUNTER_OERRORS, fail);
2903
2904	usb_callout_reset(&rvp->ratectl_ch, hz, rum_ratectl_timeout, rvp);
2905	RUM_UNLOCK(sc);
2906}
2907
2908static void
2909rum_scan_start(struct ieee80211com *ic)
2910{
2911	struct rum_softc *sc = ic->ic_softc;
2912
2913	RUM_LOCK(sc);
2914	rum_abort_tsf_sync(sc);
2915	rum_set_bssid(sc, ieee80211broadcastaddr);
2916	RUM_UNLOCK(sc);
2917
2918}
2919
2920static void
2921rum_scan_end(struct ieee80211com *ic)
2922{
2923	struct rum_softc *sc = ic->ic_softc;
2924
2925	RUM_LOCK(sc);
2926	if (ic->ic_opmode != IEEE80211_M_AHDEMO)
2927		rum_enable_tsf_sync(sc);
2928	else
2929		rum_enable_tsf(sc);
2930	rum_set_bssid(sc, sc->sc_bssid);
2931	RUM_UNLOCK(sc);
2932
2933}
2934
2935static void
2936rum_set_channel(struct ieee80211com *ic)
2937{
2938	struct rum_softc *sc = ic->ic_softc;
2939
2940	RUM_LOCK(sc);
2941	rum_set_chan(sc, ic->ic_curchan);
2942	RUM_UNLOCK(sc);
2943}
2944
2945static int
2946rum_get_rssi(struct rum_softc *sc, uint8_t raw)
2947{
2948	struct ieee80211com *ic = &sc->sc_ic;
2949	int lna, agc, rssi;
2950
2951	lna = (raw >> 5) & 0x3;
2952	agc = raw & 0x1f;
2953
2954	if (lna == 0) {
2955		/*
2956		 * No RSSI mapping
2957		 *
2958		 * NB: Since RSSI is relative to noise floor, -1 is
2959		 *     adequate for caller to know error happened.
2960		 */
2961		return -1;
2962	}
2963
2964	rssi = (2 * agc) - RT2573_NOISE_FLOOR;
2965
2966	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2967		rssi += sc->rssi_2ghz_corr;
2968
2969		if (lna == 1)
2970			rssi -= 64;
2971		else if (lna == 2)
2972			rssi -= 74;
2973		else if (lna == 3)
2974			rssi -= 90;
2975	} else {
2976		rssi += sc->rssi_5ghz_corr;
2977
2978		if (!sc->ext_5ghz_lna && lna != 1)
2979			rssi += 4;
2980
2981		if (lna == 1)
2982			rssi -= 64;
2983		else if (lna == 2)
2984			rssi -= 86;
2985		else if (lna == 3)
2986			rssi -= 100;
2987	}
2988	return rssi;
2989}
2990
2991static int
2992rum_pause(struct rum_softc *sc, int timeout)
2993{
2994
2995	usb_pause_mtx(&sc->sc_mtx, timeout);
2996	return (0);
2997}
2998
2999static device_method_t rum_methods[] = {
3000	/* Device interface */
3001	DEVMETHOD(device_probe,		rum_match),
3002	DEVMETHOD(device_attach,	rum_attach),
3003	DEVMETHOD(device_detach,	rum_detach),
3004	DEVMETHOD_END
3005};
3006
3007static driver_t rum_driver = {
3008	.name = "rum",
3009	.methods = rum_methods,
3010	.size = sizeof(struct rum_softc),
3011};
3012
3013static devclass_t rum_devclass;
3014
3015DRIVER_MODULE(rum, uhub, rum_driver, rum_devclass, NULL, 0);
3016MODULE_DEPEND(rum, wlan, 1, 1, 1);
3017MODULE_DEPEND(rum, usb, 1, 1, 1);
3018MODULE_VERSION(rum, 1);
3019USB_PNP_HOST_INFO(rum_devs);
3020