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