if_rum.c revision 188418
1/*	$FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 188418 2009-02-09 22:14:38Z thompsa $	*/
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/usb2/wlan/if_rum2.c 188418 2009-02-09 22:14:38Z thompsa $");
23
24/*-
25 * Ralink Technology RT2501USB/RT2601USB chipset driver
26 * http://www.ralinktech.com.tw/
27 */
28
29#include <dev/usb2/include/usb2_devid.h>
30#include <dev/usb2/include/usb2_standard.h>
31#include <dev/usb2/include/usb2_mfunc.h>
32#include <dev/usb2/include/usb2_error.h>
33
34#define	USB_DEBUG_VAR rum_debug
35
36#include <dev/usb2/core/usb2_core.h>
37#include <dev/usb2/core/usb2_lookup.h>
38#include <dev/usb2/core/usb2_process.h>
39#include <dev/usb2/core/usb2_debug.h>
40#include <dev/usb2/core/usb2_request.h>
41#include <dev/usb2/core/usb2_busdma.h>
42#include <dev/usb2/core/usb2_util.h>
43
44#include <dev/usb2/wlan/usb2_wlan.h>
45#include <dev/usb2/wlan/if_rumreg.h>
46#include <dev/usb2/wlan/if_rumvar.h>
47#include <dev/usb2/wlan/if_rumfw.h>
48
49#if USB_DEBUG
50static int rum_debug = 0;
51
52SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
53SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0,
54    "Debug level");
55#endif
56
57static const struct usb2_device_id rum_devs[] = {
58    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_HWU54DM) },
59    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_2) },
60    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_3) },
61    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_RT2573_4) },
62    { USB_VP(USB_VENDOR_ABOCOM,		USB_PRODUCT_ABOCOM_WUG2700) },
63    { USB_VP(USB_VENDOR_AMIT,		USB_PRODUCT_AMIT_CGWLUSB2GO) },
64    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2573_1) },
65    { USB_VP(USB_VENDOR_ASUS,		USB_PRODUCT_ASUS_RT2573_2) },
66    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D7050A) },
67    { USB_VP(USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D9050V3) },
68    { USB_VP(USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GC) },
69    { USB_VP(USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GR) },
70    { USB_VP(USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_C54RU2) },
71    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GL) },
72    { USB_VP(USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GPX) },
73    { USB_VP(USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_CWD854F) },
74    { USB_VP(USB_VENDOR_DICKSMITH,	USB_PRODUCT_DICKSMITH_RT2573) },
75    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWLG122C1) },
76    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_WUA1340) },
77    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA111) },
78    { USB_VP(USB_VENDOR_DLINK2,		USB_PRODUCT_DLINK2_DWA110) },
79    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWB01GS) },
80    { USB_VP(USB_VENDOR_GIGABYTE,	USB_PRODUCT_GIGABYTE_GNWI05GS) },
81    { USB_VP(USB_VENDOR_GIGASET,	USB_PRODUCT_GIGASET_RT2573) },
82    { USB_VP(USB_VENDOR_GOODWAY,	USB_PRODUCT_GOODWAY_RT2573) },
83    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWGUSB254LB) },
84    { USB_VP(USB_VENDOR_GUILLEMOT,	USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP) },
85    { USB_VP(USB_VENDOR_HUAWEI3COM,	USB_PRODUCT_HUAWEI3COM_WUB320G) },
86    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_G54HP) },
87    { USB_VP(USB_VENDOR_MELCO,		USB_PRODUCT_MELCO_SG54HP) },
88    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_1) },
89    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_2) },
90    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_3) },
91    { USB_VP(USB_VENDOR_MSI,		USB_PRODUCT_MSI_RT2573_4) },
92    { USB_VP(USB_VENDOR_NOVATECH,	USB_PRODUCT_NOVATECH_RT2573) },
93    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS54HP) },
94    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUS54MINI2) },
95    { USB_VP(USB_VENDOR_PLANEX2,	USB_PRODUCT_PLANEX2_GWUSMM) },
96    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573) },
97    { USB_VP(USB_VENDOR_QCOM,		USB_PRODUCT_QCOM_RT2573_2) },
98    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573) },
99    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2573_2) },
100    { USB_VP(USB_VENDOR_RALINK,		USB_PRODUCT_RALINK_RT2671) },
101    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL113R2) },
102    { USB_VP(USB_VENDOR_SITECOMEU,	USB_PRODUCT_SITECOMEU_WL172) },
103    { USB_VP(USB_VENDOR_SPARKLAN,	USB_PRODUCT_SPARKLAN_RT2573) },
104    { USB_VP(USB_VENDOR_SURECOM,	USB_PRODUCT_SURECOM_RT2573) },
105};
106
107MODULE_DEPEND(rum, wlan, 1, 1, 1);
108MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
109MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1);
110MODULE_DEPEND(rum, usb2_core, 1, 1, 1);
111
112static device_probe_t rum_match;
113static device_attach_t rum_attach;
114static device_detach_t rum_detach;
115
116static usb2_callback_t rum_bulk_read_callback;
117static usb2_callback_t rum_bulk_write_callback;
118
119static usb2_proc_callback_t rum_task;
120static usb2_proc_callback_t rum_scantask;
121static usb2_proc_callback_t rum_promisctask;
122static usb2_proc_callback_t rum_amrr_task;
123
124static struct ieee80211vap *rum_vap_create(struct ieee80211com *,
125			    const char name[IFNAMSIZ], int unit, int opmode,
126			    int flags, const uint8_t bssid[IEEE80211_ADDR_LEN],
127			    const uint8_t mac[IEEE80211_ADDR_LEN]);
128static void		rum_vap_delete(struct ieee80211vap *);
129static void		rum_tx_free(struct rum_tx_data *, int);
130static int		rum_alloc_tx_list(struct rum_softc *);
131static void		rum_free_tx_list(struct rum_softc *);
132static int		rum_newstate(struct ieee80211vap *,
133			    enum ieee80211_state, int);
134static void		rum_setup_tx_desc(struct rum_softc *,
135			    struct rum_tx_desc *, uint32_t, uint16_t, int,
136			    int);
137static int		rum_tx_mgt(struct rum_softc *, struct mbuf *,
138			    struct ieee80211_node *);
139static int		rum_tx_raw(struct rum_softc *, struct mbuf *,
140			    struct ieee80211_node *,
141			    const struct ieee80211_bpf_params *);
142static int		rum_tx_data(struct rum_softc *, struct mbuf *,
143			    struct ieee80211_node *);
144static void		rum_start(struct ifnet *);
145static int		rum_ioctl(struct ifnet *, u_long, caddr_t);
146static void		rum_eeprom_read(struct rum_softc *, uint16_t, void *,
147			    int);
148static uint32_t		rum_read(struct rum_softc *, uint16_t);
149static void		rum_read_multi(struct rum_softc *, uint16_t, void *,
150			    int);
151static void		rum_write(struct rum_softc *, uint16_t, uint32_t);
152static void		rum_write_multi(struct rum_softc *, uint16_t, void *,
153			    size_t);
154static void		rum_bbp_write(struct rum_softc *, uint8_t, uint8_t);
155static uint8_t		rum_bbp_read(struct rum_softc *, uint8_t);
156static void		rum_rf_write(struct rum_softc *, uint8_t, uint32_t);
157static void		rum_select_antenna(struct rum_softc *);
158static void		rum_enable_mrr(struct rum_softc *);
159static void		rum_set_txpreamble(struct rum_softc *);
160static void		rum_set_basicrates(struct rum_softc *);
161static void		rum_select_band(struct rum_softc *,
162			    struct ieee80211_channel *);
163static void		rum_set_chan(struct rum_softc *,
164			    struct ieee80211_channel *);
165static void		rum_enable_tsf_sync(struct rum_softc *);
166static void		rum_update_slot(struct ifnet *);
167static void		rum_set_bssid(struct rum_softc *, const uint8_t *);
168static void		rum_set_macaddr(struct rum_softc *, const uint8_t *);
169static const char	*rum_get_rf(int);
170static void		rum_read_eeprom(struct rum_softc *);
171static int		rum_bbp_init(struct rum_softc *);
172static void		rum_init_locked(struct rum_softc *);
173static void		rum_init(void *);
174static void		rum_stop(void *);
175static int		rum_load_microcode(struct rum_softc *, const u_char *,
176			    size_t);
177static int		rum_prepare_beacon(struct rum_softc *,
178			    struct ieee80211vap *);
179static int		rum_raw_xmit(struct ieee80211_node *, struct mbuf *,
180			    const struct ieee80211_bpf_params *);
181static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *,
182			    const uint8_t mac[IEEE80211_ADDR_LEN]);
183static void		rum_newassoc(struct ieee80211_node *, int);
184static void		rum_scan_start(struct ieee80211com *);
185static void		rum_scan_end(struct ieee80211com *);
186static void		rum_set_channel(struct ieee80211com *);
187static int		rum_get_rssi(struct rum_softc *, uint8_t);
188static void		rum_amrr_start(struct rum_softc *,
189			    struct ieee80211_node *);
190static void		rum_amrr_timeout(void *);
191static void		rum_queue_command(struct rum_softc *,
192			    usb2_proc_callback_t *, struct usb2_proc_msg *,
193			    struct usb2_proc_msg *);
194
195static const struct {
196	uint32_t	reg;
197	uint32_t	val;
198} rum_def_mac[] = {
199	{ RT2573_TXRX_CSR0,  0x025fb032 },
200	{ RT2573_TXRX_CSR1,  0x9eaa9eaf },
201	{ RT2573_TXRX_CSR2,  0x8a8b8c8d },
202	{ RT2573_TXRX_CSR3,  0x00858687 },
203	{ RT2573_TXRX_CSR7,  0x2e31353b },
204	{ RT2573_TXRX_CSR8,  0x2a2a2a2c },
205	{ RT2573_TXRX_CSR15, 0x0000000f },
206	{ RT2573_MAC_CSR6,   0x00000fff },
207	{ RT2573_MAC_CSR8,   0x016c030a },
208	{ RT2573_MAC_CSR10,  0x00000718 },
209	{ RT2573_MAC_CSR12,  0x00000004 },
210	{ RT2573_MAC_CSR13,  0x00007f00 },
211	{ RT2573_SEC_CSR0,   0x00000000 },
212	{ RT2573_SEC_CSR1,   0x00000000 },
213	{ RT2573_SEC_CSR5,   0x00000000 },
214	{ RT2573_PHY_CSR1,   0x000023b0 },
215	{ RT2573_PHY_CSR5,   0x00040a06 },
216	{ RT2573_PHY_CSR6,   0x00080606 },
217	{ RT2573_PHY_CSR7,   0x00000408 },
218	{ RT2573_AIFSN_CSR,  0x00002273 },
219	{ RT2573_CWMIN_CSR,  0x00002344 },
220	{ RT2573_CWMAX_CSR,  0x000034aa }
221};
222
223static const struct {
224	uint8_t	reg;
225	uint8_t	val;
226} rum_def_bbp[] = {
227	{   3, 0x80 },
228	{  15, 0x30 },
229	{  17, 0x20 },
230	{  21, 0xc8 },
231	{  22, 0x38 },
232	{  23, 0x06 },
233	{  24, 0xfe },
234	{  25, 0x0a },
235	{  26, 0x0d },
236	{  32, 0x0b },
237	{  34, 0x12 },
238	{  37, 0x07 },
239	{  39, 0xf8 },
240	{  41, 0x60 },
241	{  53, 0x10 },
242	{  54, 0x18 },
243	{  60, 0x10 },
244	{  61, 0x04 },
245	{  62, 0x04 },
246	{  75, 0xfe },
247	{  86, 0xfe },
248	{  88, 0xfe },
249	{  90, 0x0f },
250	{  99, 0x00 },
251	{ 102, 0x16 },
252	{ 107, 0x04 }
253};
254
255static const struct rfprog {
256	uint8_t		chan;
257	uint32_t	r1, r2, r3, r4;
258}  rum_rf5226[] = {
259	{   1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
260	{   2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
261	{   3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
262	{   4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
263	{   5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
264	{   6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
265	{   7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
266	{   8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
267	{   9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
268	{  10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
269	{  11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
270	{  12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
271	{  13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
272	{  14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
273
274	{  34, 0x00b03, 0x20266, 0x36014, 0x30282 },
275	{  38, 0x00b03, 0x20267, 0x36014, 0x30284 },
276	{  42, 0x00b03, 0x20268, 0x36014, 0x30286 },
277	{  46, 0x00b03, 0x20269, 0x36014, 0x30288 },
278
279	{  36, 0x00b03, 0x00266, 0x26014, 0x30288 },
280	{  40, 0x00b03, 0x00268, 0x26014, 0x30280 },
281	{  44, 0x00b03, 0x00269, 0x26014, 0x30282 },
282	{  48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
283	{  52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
284	{  56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
285	{  60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
286	{  64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
287
288	{ 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
289	{ 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
290	{ 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
291	{ 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
292	{ 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
293	{ 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
294	{ 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
295	{ 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
296	{ 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
297	{ 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
298	{ 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
299
300	{ 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
301	{ 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
302	{ 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
303	{ 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
304	{ 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
305}, rum_rf5225[] = {
306	{   1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
307	{   2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
308	{   3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
309	{   4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
310	{   5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
311	{   6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
312	{   7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
313	{   8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
314	{   9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
315	{  10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
316	{  11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
317	{  12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
318	{  13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
319	{  14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
320
321	{  34, 0x00b33, 0x01266, 0x26014, 0x30282 },
322	{  38, 0x00b33, 0x01267, 0x26014, 0x30284 },
323	{  42, 0x00b33, 0x01268, 0x26014, 0x30286 },
324	{  46, 0x00b33, 0x01269, 0x26014, 0x30288 },
325
326	{  36, 0x00b33, 0x01266, 0x26014, 0x30288 },
327	{  40, 0x00b33, 0x01268, 0x26014, 0x30280 },
328	{  44, 0x00b33, 0x01269, 0x26014, 0x30282 },
329	{  48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
330	{  52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
331	{  56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
332	{  60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
333	{  64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
334
335	{ 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
336	{ 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
337	{ 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
338	{ 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
339	{ 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
340	{ 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
341	{ 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
342	{ 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
343	{ 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
344	{ 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
345	{ 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
346
347	{ 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
348	{ 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
349	{ 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
350	{ 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
351	{ 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
352};
353
354static const struct usb2_config rum_config[RUM_N_TRANSFER] = {
355	[RUM_BULK_WR] = {
356		.type = UE_BULK,
357		.endpoint = UE_ADDR_ANY,
358		.direction = UE_DIR_OUT,
359		.mh.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8),
360		.mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
361		.mh.callback = rum_bulk_write_callback,
362		.mh.timeout = 5000,	/* ms */
363	},
364	[RUM_BULK_RD] = {
365		.type = UE_BULK,
366		.endpoint = UE_ADDR_ANY,
367		.direction = UE_DIR_IN,
368		.mh.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE),
369		.mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
370		.mh.callback = rum_bulk_read_callback,
371	},
372};
373
374static int
375rum_match(device_t self)
376{
377	struct usb2_attach_arg *uaa = device_get_ivars(self);
378
379	if (uaa->usb2_mode != USB_MODE_HOST)
380		return (ENXIO);
381	if (uaa->info.bConfigIndex != 0)
382		return (ENXIO);
383	if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX)
384		return (ENXIO);
385
386	return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
387}
388
389static int
390rum_attach(device_t self)
391{
392	struct usb2_attach_arg *uaa = device_get_ivars(self);
393	struct rum_softc *sc = device_get_softc(self);
394	struct ieee80211com *ic;
395	struct ifnet *ifp;
396	const uint8_t *ucode = NULL;
397	uint8_t bands, iface_index;
398	uint32_t tmp;
399	int error, ntries, size;
400
401	device_set_usb2_desc(self);
402	sc->sc_udev = uaa->device;
403	sc->sc_dev = self;
404
405	mtx_init(&sc->sc_mtx, device_get_nameunit(self),
406	    MTX_NETWORK_LOCK, MTX_DEF);
407
408	iface_index = RT2573_IFACE_INDEX;
409	error = usb2_transfer_setup(uaa->device, &iface_index,
410	    sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx);
411	if (error) {
412		device_printf(self, "could not allocate USB transfers, "
413		    "err=%s\n", usb2_errstr(error));
414		goto detach;
415	}
416	error = usb2_proc_create(&sc->sc_tq, &sc->sc_mtx,
417	    device_get_nameunit(self), USB_PRI_MED);
418	if (error) {
419		device_printf(self, "could not setup config thread!\n");
420		goto detach;
421	}
422
423	ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211);
424	if (ifp == NULL) {
425		device_printf(sc->sc_dev, "can not if_alloc()\n");
426		goto detach;
427	}
428	ic = ifp->if_l2com;
429
430	RUM_LOCK(sc);
431	/* retrieve RT2573 rev. no */
432	for (ntries = 0; ntries < 1000; ntries++) {
433		if ((tmp = rum_read(sc, RT2573_MAC_CSR0)) != 0)
434			break;
435		DELAY(1000);
436	}
437	if (ntries == 1000) {
438		device_printf(self, "timeout waiting for chip to settle\n");
439		RUM_UNLOCK(sc);
440		goto detach;
441	}
442
443	/* retrieve MAC address and various other things from EEPROM */
444	rum_read_eeprom(sc);
445
446	device_printf(self, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
447	    tmp, rum_get_rf(sc->rf_rev));
448
449	ucode = rt2573_ucode;
450	size = sizeof rt2573_ucode;
451	error = rum_load_microcode(sc, ucode, size);
452	if (error != 0) {
453		device_printf(self, "could not load 8051 microcode\n");
454		RUM_UNLOCK(sc);
455		goto detach;
456	}
457	RUM_UNLOCK(sc);
458
459	ifp->if_softc = sc;
460	if_initname(ifp, "rum", device_get_unit(sc->sc_dev));
461	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
462	ifp->if_init = rum_init;
463	ifp->if_ioctl = rum_ioctl;
464	ifp->if_start = rum_start;
465	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
466	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
467	IFQ_SET_READY(&ifp->if_snd);
468
469	ic->ic_ifp = ifp;
470	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
471
472	/* set device capabilities */
473	ic->ic_caps =
474	      IEEE80211_C_STA		/* station mode supported */
475	    | IEEE80211_C_IBSS		/* IBSS mode supported */
476	    | IEEE80211_C_MONITOR	/* monitor mode supported */
477	    | IEEE80211_C_HOSTAP	/* HostAp mode supported */
478	    | IEEE80211_C_TXPMGT	/* tx power management */
479	    | IEEE80211_C_SHPREAMBLE	/* short preamble supported */
480	    | IEEE80211_C_SHSLOT	/* short slot time supported */
481	    | IEEE80211_C_BGSCAN	/* bg scanning supported */
482	    | IEEE80211_C_WPA		/* 802.11i */
483	    ;
484
485	bands = 0;
486	setbit(&bands, IEEE80211_MODE_11B);
487	setbit(&bands, IEEE80211_MODE_11G);
488	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226)
489		setbit(&bands, IEEE80211_MODE_11A);
490	ieee80211_init_channels(ic, NULL, &bands);
491
492	ieee80211_ifattach(ic);
493	ic->ic_newassoc = rum_newassoc;
494	ic->ic_raw_xmit = rum_raw_xmit;
495	ic->ic_node_alloc = rum_node_alloc;
496	ic->ic_scan_start = rum_scan_start;
497	ic->ic_scan_end = rum_scan_end;
498	ic->ic_set_channel = rum_set_channel;
499
500	ic->ic_vap_create = rum_vap_create;
501	ic->ic_vap_delete = rum_vap_delete;
502
503	sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
504
505	bpfattach(ifp, DLT_IEEE802_11_RADIO,
506	    sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap));
507
508	sc->sc_rxtap_len = sizeof sc->sc_rxtap;
509	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
510	sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
511
512	sc->sc_txtap_len = sizeof sc->sc_txtap;
513	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
514	sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
515
516	if (bootverbose)
517		ieee80211_announce(ic);
518
519	return 0;
520detach:
521	rum_detach(self);
522	return (ENXIO);			/* failure */
523}
524
525static int
526rum_detach(device_t self)
527{
528	struct rum_softc *sc = device_get_softc(self);
529	struct ifnet *ifp = sc->sc_ifp;
530	struct ieee80211com *ic = ifp->if_l2com;
531
532	RUM_LOCK(sc);
533	sc->sc_flags |= RUM_FLAG_DETACH;
534	rum_stop(sc);
535	RUM_UNLOCK(sc);
536
537	/* stop all USB transfers first */
538	usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
539	usb2_proc_free(&sc->sc_tq);
540
541	if (ifp) {
542		bpfdetach(ifp);
543		ieee80211_ifdetach(ic);
544		if_free(ifp);
545	}
546	mtx_destroy(&sc->sc_mtx);
547
548	return (0);
549}
550
551static struct ieee80211vap *
552rum_vap_create(struct ieee80211com *ic,
553	const char name[IFNAMSIZ], int unit, int opmode, int flags,
554	const uint8_t bssid[IEEE80211_ADDR_LEN],
555	const uint8_t mac[IEEE80211_ADDR_LEN])
556{
557	struct rum_softc *sc = ic->ic_ifp->if_softc;
558	struct rum_vap *rvp;
559	struct ieee80211vap *vap;
560
561	if (!TAILQ_EMPTY(&ic->ic_vaps))		/* only one at a time */
562		return NULL;
563	rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap),
564	    M_80211_VAP, M_NOWAIT | M_ZERO);
565	if (rvp == NULL)
566		return NULL;
567	vap = &rvp->vap;
568	/* enable s/w bmiss handling for sta mode */
569	ieee80211_vap_setup(ic, vap, name, unit, opmode,
570	    flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
571
572	/* override state transition machine */
573	rvp->newstate = vap->iv_newstate;
574	vap->iv_newstate = rum_newstate;
575
576	rvp->sc = sc;
577	usb2_callout_init_mtx(&rvp->amrr_ch, &sc->sc_mtx, 0);
578	ieee80211_amrr_init(&rvp->amrr, vap,
579	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
580	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
581	    1000 /* 1 sec */);
582
583	/* complete setup */
584	ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
585	ic->ic_opmode = opmode;
586	return vap;
587}
588
589static void
590rum_vap_delete(struct ieee80211vap *vap)
591{
592	struct rum_vap *rvp = RUM_VAP(vap);
593	struct rum_softc *sc = rvp->sc;
594
595	RUM_LOCK(sc);
596	usb2_callout_stop(&rvp->amrr_ch);
597	RUM_UNLOCK(sc);
598	ieee80211_amrr_cleanup(&rvp->amrr);
599	ieee80211_vap_detach(vap);
600	free(rvp, M_80211_VAP);
601}
602
603static void
604rum_tx_free(struct rum_tx_data *data, int txerr)
605{
606	struct rum_softc *sc = data->sc;
607
608	if (data->m != NULL) {
609		if (data->m->m_flags & M_TXCB)
610			ieee80211_process_callback(data->ni, data->m,
611			    txerr ? ETIMEDOUT : 0);
612		m_freem(data->m);
613		data->m = NULL;
614
615		ieee80211_free_node(data->ni);
616		data->ni = NULL;
617	}
618	STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
619	sc->tx_nfree++;
620}
621
622static int
623rum_alloc_tx_list(struct rum_softc *sc)
624{
625	struct rum_tx_data *data;
626	int i;
627
628	sc->tx_data = malloc(sizeof(struct rum_tx_data) * RUM_TX_LIST_COUNT,
629	    M_USB, M_NOWAIT|M_ZERO);
630	if (sc->tx_data == NULL)
631		return (ENOMEM);
632
633	sc->tx_nfree = 0;
634	STAILQ_INIT(&sc->tx_q);
635	STAILQ_INIT(&sc->tx_free);
636
637	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
638		data = &sc->tx_data[i];
639
640		data->sc = sc;
641		STAILQ_INSERT_TAIL(&sc->tx_free, data, next);
642		sc->tx_nfree++;
643	}
644	return 0;
645}
646
647static void
648rum_free_tx_list(struct rum_softc *sc)
649{
650	struct rum_tx_data *data;
651	int i;
652
653	if (sc->tx_data == NULL)
654		return;
655
656	for (i = 0; i < RUM_TX_LIST_COUNT; i++) {
657		data = &sc->tx_data[i];
658
659		if (data->m != NULL) {
660			m_freem(data->m);
661			data->m = NULL;
662		}
663		if (data->ni != NULL) {
664			ieee80211_free_node(data->ni);
665			data->ni = NULL;
666		}
667	}
668	free(sc->tx_data, M_USB);
669	sc->tx_data = NULL;
670}
671
672static void
673rum_task(struct usb2_proc_msg *pm)
674{
675	struct rum_task *task = (struct rum_task *)pm;
676	struct rum_softc *sc = task->sc;
677	struct ifnet *ifp = sc->sc_ifp;
678	struct ieee80211com *ic = ifp->if_l2com;
679	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
680	struct rum_vap *rvp = RUM_VAP(vap);
681	const struct ieee80211_txparam *tp;
682	enum ieee80211_state ostate;
683	struct ieee80211_node *ni;
684	uint32_t tmp;
685
686	if (sc->sc_flags & RUM_FLAG_DETACH)
687		return;
688
689	ostate = vap->iv_state;
690
691	switch (sc->sc_state) {
692	case IEEE80211_S_INIT:
693		if (ostate == IEEE80211_S_RUN) {
694			/* abort TSF synchronization */
695			tmp = rum_read(sc, RT2573_TXRX_CSR9);
696			rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
697		}
698		break;
699
700	case IEEE80211_S_RUN:
701		ni = vap->iv_bss;
702
703		if (vap->iv_opmode != IEEE80211_M_MONITOR) {
704			rum_update_slot(ic->ic_ifp);
705			rum_enable_mrr(sc);
706			rum_set_txpreamble(sc);
707			rum_set_basicrates(sc);
708			rum_set_bssid(sc, ni->ni_bssid);
709		}
710
711		if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
712		    vap->iv_opmode == IEEE80211_M_IBSS)
713			rum_prepare_beacon(sc, vap);
714
715		if (vap->iv_opmode != IEEE80211_M_MONITOR)
716			rum_enable_tsf_sync(sc);
717
718		/* enable automatic rate adaptation */
719		tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
720		if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE)
721			rum_amrr_start(sc, ni);
722		break;
723	default:
724		break;
725	}
726
727	RUM_UNLOCK(sc);
728	IEEE80211_LOCK(ic);
729	rvp->newstate(vap, sc->sc_state, sc->sc_arg);
730	if (vap->iv_newstate_cb != NULL)
731		vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg);
732	IEEE80211_UNLOCK(ic);
733	RUM_LOCK(sc);
734}
735
736static int
737rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
738{
739	struct rum_vap *rvp = RUM_VAP(vap);
740	struct ieee80211com *ic = vap->iv_ic;
741	struct rum_softc *sc = ic->ic_ifp->if_softc;
742
743	DPRINTF("%s -> %s\n",
744		ieee80211_state_name[vap->iv_state],
745		ieee80211_state_name[nstate]);
746
747	RUM_LOCK(sc);
748	usb2_callout_stop(&rvp->amrr_ch);
749
750	/* do it in a process context */
751	sc->sc_state = nstate;
752	sc->sc_arg = arg;
753	RUM_UNLOCK(sc);
754
755	if (nstate == IEEE80211_S_INIT) {
756		rvp->newstate(vap, nstate, arg);
757		return 0;
758	} else {
759		RUM_LOCK(sc);
760		rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr,
761		    &sc->sc_task[1].hdr);
762		RUM_UNLOCK(sc);
763		return EINPROGRESS;
764	}
765}
766
767static void
768rum_bulk_write_callback(struct usb2_xfer *xfer)
769{
770	struct rum_softc *sc = xfer->priv_sc;
771	struct ifnet *ifp = sc->sc_ifp;
772	struct ieee80211com *ic = ifp->if_l2com;
773	struct ieee80211_channel *c = ic->ic_curchan;
774	struct rum_tx_data *data;
775	struct mbuf *m;
776	int len;
777
778	switch (USB_GET_STATE(xfer)) {
779	case USB_ST_TRANSFERRED:
780		DPRINTFN(11, "transfer complete, %d bytes\n", xfer->actlen);
781
782		/* free resources */
783		data = xfer->priv_fifo;
784		rum_tx_free(data, 0);
785		xfer->priv_fifo = NULL;
786
787		ifp->if_opackets++;
788		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
789
790		/* FALLTHROUGH */
791	case USB_ST_SETUP:
792tr_setup:
793#if 0
794		if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) {
795			/*
796			 * don't send anything while a command is pending !
797			 */
798			break;
799		}
800#endif
801
802		data = STAILQ_FIRST(&sc->tx_q);
803		if (data) {
804			STAILQ_REMOVE_HEAD(&sc->tx_q, next);
805			m = data->m;
806
807			if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
808				DPRINTFN(0, "data overflow, %u bytes\n",
809				    m->m_pkthdr.len);
810				m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
811			}
812			usb2_copy_in(xfer->frbuffers, 0, &data->desc,
813			    RT2573_TX_DESC_SIZE);
814			usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m,
815			    0, m->m_pkthdr.len);
816
817			if (bpf_peers_present(ifp->if_bpf)) {
818				struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
819
820				tap->wt_flags = 0;
821				tap->wt_rate = data->rate;
822				tap->wt_chan_freq = htole16(c->ic_freq);
823				tap->wt_chan_flags = htole16(c->ic_flags);
824				tap->wt_antenna = sc->tx_ant;
825
826				bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
827			}
828
829			/* align end on a 4-bytes boundary */
830			len = (RT2573_TX_DESC_SIZE + m->m_pkthdr.len + 3) & ~3;
831			if ((len % 64) == 0)
832				len += 4;
833
834			DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
835			    m->m_pkthdr.len, len);
836
837			xfer->frlengths[0] = len;
838			xfer->priv_fifo = data;
839
840			usb2_start_hardware(xfer);
841		}
842		break;
843
844	default:			/* Error */
845		DPRINTFN(11, "transfer error, %s\n",
846		    usb2_errstr(xfer->error));
847
848		if (xfer->error == USB_ERR_STALLED) {
849			/* try to clear stall first */
850			xfer->flags.stall_pipe = 1;
851			goto tr_setup;
852		}
853		if (xfer->error == USB_ERR_TIMEOUT)
854			device_printf(sc->sc_dev, "device timeout\n");
855
856		ifp->if_oerrors++;
857		data = xfer->priv_fifo;
858		if (data != NULL) {
859			rum_tx_free(data, xfer->error);
860			xfer->priv_fifo = NULL;
861		}
862		break;
863	}
864}
865
866static void
867rum_bulk_read_callback(struct usb2_xfer *xfer)
868{
869	struct rum_softc *sc = xfer->priv_sc;
870	struct ifnet *ifp = sc->sc_ifp;
871	struct ieee80211com *ic = ifp->if_l2com;
872	struct ieee80211_node *ni;
873	struct mbuf *m = NULL;
874	uint32_t flags;
875	uint8_t rssi = 0;
876	int len;
877
878	switch (USB_GET_STATE(xfer)) {
879	case USB_ST_TRANSFERRED:
880
881		DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen);
882
883		len = xfer->actlen;
884		if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
885			DPRINTF("%s: xfer too short %d\n",
886			    device_get_nameunit(sc->sc_dev), len);
887			ifp->if_ierrors++;
888			goto tr_setup;
889		}
890
891		len -= RT2573_RX_DESC_SIZE;
892		usb2_copy_out(xfer->frbuffers, 0, &sc->sc_rx_desc,
893		    RT2573_RX_DESC_SIZE);
894
895		rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
896		flags = le32toh(sc->sc_rx_desc.flags);
897		if (flags & RT2573_RX_CRC_ERROR) {
898			/*
899		         * This should not happen since we did not
900		         * request to receive those frames when we
901		         * filled RUM_TXRX_CSR2:
902		         */
903			DPRINTFN(5, "PHY or CRC error\n");
904			ifp->if_ierrors++;
905			goto tr_setup;
906		}
907
908		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
909		if (m == NULL) {
910			DPRINTF("could not allocate mbuf\n");
911			ifp->if_ierrors++;
912			goto tr_setup;
913		}
914		usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
915		    mtod(m, uint8_t *), len);
916
917		/* finalize mbuf */
918		m->m_pkthdr.rcvif = ifp;
919		m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
920
921		if (bpf_peers_present(ifp->if_bpf)) {
922			struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
923
924			tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
925			tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
926			    (flags & RT2573_RX_OFDM) ?
927			    IEEE80211_T_OFDM : IEEE80211_T_CCK);
928			tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
929			tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
930			tap->wr_antenna = sc->rx_ant;
931			tap->wr_antsignal = rssi;
932
933			bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
934		}
935		/* FALLTHROUGH */
936	case USB_ST_SETUP:
937tr_setup:
938		xfer->frlengths[0] = xfer->max_data_length;
939		usb2_start_hardware(xfer);
940
941		/*
942		 * At the end of a USB callback it is always safe to unlock
943		 * the private mutex of a device! That is why we do the
944		 * "ieee80211_input" here, and not some lines up!
945		 */
946		if (m) {
947			RUM_UNLOCK(sc);
948			ni = ieee80211_find_rxnode(ic,
949			    mtod(m, struct ieee80211_frame_min *));
950			if (ni != NULL) {
951				(void) ieee80211_input(ni, m, rssi,
952				    RT2573_NOISE_FLOOR, 0);
953				ieee80211_free_node(ni);
954			} else
955				(void) ieee80211_input_all(ic, m, rssi,
956				    RT2573_NOISE_FLOOR, 0);
957			RUM_LOCK(sc);
958		}
959		return;
960
961	default:			/* Error */
962		if (xfer->error != USB_ERR_CANCELLED) {
963			/* try to clear stall first */
964			xfer->flags.stall_pipe = 1;
965			goto tr_setup;
966		}
967		return;
968
969	}
970}
971
972static uint8_t
973rum_plcp_signal(int rate)
974{
975	switch (rate) {
976	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
977	case 12:	return 0xb;
978	case 18:	return 0xf;
979	case 24:	return 0xa;
980	case 36:	return 0xe;
981	case 48:	return 0x9;
982	case 72:	return 0xd;
983	case 96:	return 0x8;
984	case 108:	return 0xc;
985
986	/* CCK rates (NB: not IEEE std, device-specific) */
987	case 2:		return 0x0;
988	case 4:		return 0x1;
989	case 11:	return 0x2;
990	case 22:	return 0x3;
991	}
992	return 0xff;		/* XXX unsupported/unknown rate */
993}
994
995static void
996rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc,
997    uint32_t flags, uint16_t xflags, int len, int rate)
998{
999	struct ifnet *ifp = sc->sc_ifp;
1000	struct ieee80211com *ic = ifp->if_l2com;
1001	uint16_t plcp_length;
1002	int remainder;
1003
1004	desc->flags = htole32(flags);
1005	desc->flags |= htole32(RT2573_TX_VALID);
1006	desc->flags |= htole32(len << 16);
1007
1008	desc->xflags = htole16(xflags);
1009
1010	desc->wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
1011	    RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
1012
1013	/* setup PLCP fields */
1014	desc->plcp_signal  = rum_plcp_signal(rate);
1015	desc->plcp_service = 4;
1016
1017	len += IEEE80211_CRC_LEN;
1018	if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
1019		desc->flags |= htole32(RT2573_TX_OFDM);
1020
1021		plcp_length = len & 0xfff;
1022		desc->plcp_length_hi = plcp_length >> 6;
1023		desc->plcp_length_lo = plcp_length & 0x3f;
1024	} else {
1025		plcp_length = (16 * len + rate - 1) / rate;
1026		if (rate == 22) {
1027			remainder = (16 * len) % 22;
1028			if (remainder != 0 && remainder < 7)
1029				desc->plcp_service |= RT2573_PLCP_LENGEXT;
1030		}
1031		desc->plcp_length_hi = plcp_length >> 8;
1032		desc->plcp_length_lo = plcp_length & 0xff;
1033
1034		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
1035			desc->plcp_signal |= 0x08;
1036	}
1037}
1038
1039#define RUM_TX_TIMEOUT	5000
1040
1041static int
1042rum_sendprot(struct rum_softc *sc,
1043    const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate)
1044{
1045	struct ieee80211com *ic = ni->ni_ic;
1046	const struct ieee80211_frame *wh;
1047	struct rum_tx_data *data;
1048	struct mbuf *mprot;
1049	int protrate, ackrate, pktlen, flags, isshort;
1050	uint16_t dur;
1051
1052	RUM_LOCK_ASSERT(sc, MA_OWNED);
1053	KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY,
1054	    ("protection %d", prot));
1055
1056	wh = mtod(m, const struct ieee80211_frame *);
1057	pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
1058
1059	protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
1060	ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
1061
1062	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
1063	dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
1064	    + ieee80211_ack_duration(sc->sc_rates, rate, isshort);
1065	flags = RT2573_TX_MORE_FRAG;
1066	if (prot == IEEE80211_PROT_RTSCTS) {
1067		/* NB: CTS is the same size as an ACK */
1068		dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
1069		flags |= RT2573_TX_NEED_ACK;
1070		mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
1071	} else {
1072		mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
1073	}
1074	if (mprot == NULL) {
1075		/* XXX stat + msg */
1076		return ENOBUFS;
1077	}
1078	data = STAILQ_FIRST(&sc->tx_free);
1079	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1080	sc->tx_nfree--;
1081
1082	data->m = mprot;
1083	data->ni = ieee80211_ref_node(ni);
1084	data->rate = protrate;
1085	rum_setup_tx_desc(sc, &data->desc, flags, 0, mprot->m_pkthdr.len, protrate);
1086
1087	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1088	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1089
1090	return 0;
1091}
1092
1093static int
1094rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1095{
1096	struct ieee80211vap *vap = ni->ni_vap;
1097	struct ifnet *ifp = sc->sc_ifp;
1098	struct ieee80211com *ic = ifp->if_l2com;
1099	struct rum_tx_data *data;
1100	struct ieee80211_frame *wh;
1101	const struct ieee80211_txparam *tp;
1102	struct ieee80211_key *k;
1103	uint32_t flags = 0;
1104	uint16_t dur;
1105
1106	RUM_LOCK_ASSERT(sc, MA_OWNED);
1107
1108	data = STAILQ_FIRST(&sc->tx_free);
1109	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1110	sc->tx_nfree--;
1111
1112	wh = mtod(m0, struct ieee80211_frame *);
1113	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1114		k = ieee80211_crypto_encap(ni, m0);
1115		if (k == NULL) {
1116			m_freem(m0);
1117			return ENOBUFS;
1118		}
1119		wh = mtod(m0, struct ieee80211_frame *);
1120	}
1121
1122	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
1123
1124	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1125		flags |= RT2573_TX_NEED_ACK;
1126
1127		dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
1128		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
1129		*(uint16_t *)wh->i_dur = htole16(dur);
1130
1131		/* tell hardware to add timestamp for probe responses */
1132		if ((wh->i_fc[0] &
1133		    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
1134		    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
1135			flags |= RT2573_TX_TIMESTAMP;
1136	}
1137
1138	data->m = m0;
1139	data->ni = ni;
1140	data->rate = tp->mgmtrate;
1141
1142	rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate);
1143
1144	DPRINTFN(10, "sending mgt frame len=%d rate=%d\n",
1145	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate);
1146
1147	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1148	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1149
1150	return 0;
1151}
1152
1153static int
1154rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
1155    const struct ieee80211_bpf_params *params)
1156{
1157	struct rum_tx_data *data;
1158	uint32_t flags;
1159	int rate, error;
1160
1161	RUM_LOCK_ASSERT(sc, MA_OWNED);
1162	KASSERT(params != NULL, ("no raw xmit params"));
1163
1164	data = STAILQ_FIRST(&sc->tx_free);
1165	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1166	sc->tx_nfree--;
1167
1168	rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
1169	/* XXX validate */
1170	if (rate == 0) {
1171		m_freem(m0);
1172		return EINVAL;
1173	}
1174	flags = 0;
1175	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
1176		flags |= RT2573_TX_NEED_ACK;
1177	if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) {
1178		error = rum_sendprot(sc, m0, ni,
1179		    params->ibp_flags & IEEE80211_BPF_RTS ?
1180			 IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
1181		    rate);
1182		if (error) {
1183			m_freem(m0);
1184			return error;
1185		}
1186		flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
1187	}
1188
1189	data->m = m0;
1190	data->ni = ni;
1191	data->rate = rate;
1192
1193	/* XXX need to setup descriptor ourself */
1194	rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
1195
1196	DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
1197	    m0->m_pkthdr.len, rate);
1198
1199	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1200	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1201
1202	return 0;
1203}
1204
1205static int
1206rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
1207{
1208	struct ieee80211vap *vap = ni->ni_vap;
1209	struct ifnet *ifp = sc->sc_ifp;
1210	struct ieee80211com *ic = ifp->if_l2com;
1211	struct rum_tx_data *data;
1212	struct ieee80211_frame *wh;
1213	const struct ieee80211_txparam *tp;
1214	struct ieee80211_key *k;
1215	uint32_t flags = 0;
1216	uint16_t dur;
1217	int error, rate;
1218
1219	RUM_LOCK_ASSERT(sc, MA_OWNED);
1220
1221	wh = mtod(m0, struct ieee80211_frame *);
1222
1223	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
1224	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1225		rate = tp->mcastrate;
1226	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
1227		rate = tp->ucastrate;
1228	else
1229		rate = ni->ni_txrate;
1230
1231	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1232		k = ieee80211_crypto_encap(ni, m0);
1233		if (k == NULL) {
1234			m_freem(m0);
1235			return ENOBUFS;
1236		}
1237
1238		/* packet header may have moved, reset our local pointer */
1239		wh = mtod(m0, struct ieee80211_frame *);
1240	}
1241
1242	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1243		int prot = IEEE80211_PROT_NONE;
1244		if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
1245			prot = IEEE80211_PROT_RTSCTS;
1246		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
1247		    ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
1248			prot = ic->ic_protmode;
1249		if (prot != IEEE80211_PROT_NONE) {
1250			error = rum_sendprot(sc, m0, ni, prot, rate);
1251			if (error) {
1252				m_freem(m0);
1253				return error;
1254			}
1255			flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
1256		}
1257	}
1258
1259	data = STAILQ_FIRST(&sc->tx_free);
1260	STAILQ_REMOVE_HEAD(&sc->tx_free, next);
1261	sc->tx_nfree--;
1262
1263	data->m = m0;
1264	data->ni = ni;
1265	data->rate = rate;
1266
1267	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
1268		flags |= RT2573_TX_NEED_ACK;
1269		flags |= RT2573_TX_MORE_FRAG;
1270
1271		dur = ieee80211_ack_duration(sc->sc_rates, rate,
1272		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
1273		*(uint16_t *)wh->i_dur = htole16(dur);
1274	}
1275
1276	rum_setup_tx_desc(sc, &data->desc, flags, 0, m0->m_pkthdr.len, rate);
1277
1278	DPRINTFN(10, "sending frame len=%d rate=%d\n",
1279	    m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate);
1280
1281	STAILQ_INSERT_TAIL(&sc->tx_q, data, next);
1282	usb2_transfer_start(sc->sc_xfer[RUM_BULK_WR]);
1283
1284	return 0;
1285}
1286
1287static void
1288rum_start(struct ifnet *ifp)
1289{
1290	struct rum_softc *sc = ifp->if_softc;
1291	struct ieee80211_node *ni;
1292	struct mbuf *m;
1293
1294	RUM_LOCK(sc);
1295	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1296		RUM_UNLOCK(sc);
1297		return;
1298	}
1299	for (;;) {
1300		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1301		if (m == NULL)
1302			break;
1303		if (sc->tx_nfree == 0) {
1304			IFQ_DRV_PREPEND(&ifp->if_snd, m);
1305			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1306			break;
1307		}
1308		ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1309		m = ieee80211_encap(ni, m);
1310		if (m == NULL) {
1311			ieee80211_free_node(ni);
1312			continue;
1313		}
1314		if (rum_tx_data(sc, m, ni) != 0) {
1315			ieee80211_free_node(ni);
1316			ifp->if_oerrors++;
1317			break;
1318		}
1319	}
1320	RUM_UNLOCK(sc);
1321}
1322
1323static int
1324rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1325{
1326	struct rum_softc *sc = ifp->if_softc;
1327	struct ieee80211com *ic = ifp->if_l2com;
1328	struct ifreq *ifr = (struct ifreq *) data;
1329	int error = 0, startall = 0;
1330
1331	switch (cmd) {
1332	case SIOCSIFFLAGS:
1333		RUM_LOCK(sc);
1334		if (ifp->if_flags & IFF_UP) {
1335			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1336				rum_init_locked(sc);
1337				startall = 1;
1338			} else
1339				rum_queue_command(sc, rum_promisctask,
1340				    &sc->sc_promisctask[0].hdr,
1341				    &sc->sc_promisctask[1].hdr);
1342		} else {
1343			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1344				rum_stop(sc);
1345		}
1346		RUM_UNLOCK(sc);
1347		if (startall)
1348			ieee80211_start_all(ic);
1349		break;
1350	case SIOCGIFMEDIA:
1351		error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
1352		break;
1353	case SIOCGIFADDR:
1354		error = ether_ioctl(ifp, cmd, data);
1355		break;
1356	default:
1357		error = EINVAL;
1358		break;
1359	}
1360	return error;
1361}
1362
1363static void
1364rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len)
1365{
1366	struct usb2_device_request req;
1367	usb2_error_t error;
1368
1369	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1370	req.bRequest = RT2573_READ_EEPROM;
1371	USETW(req.wValue, 0);
1372	USETW(req.wIndex, addr);
1373	USETW(req.wLength, len);
1374
1375	error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf);
1376	if (error != 0) {
1377		device_printf(sc->sc_dev, "could not read EEPROM: %s\n",
1378		    usb2_errstr(error));
1379	}
1380}
1381
1382static uint32_t
1383rum_read(struct rum_softc *sc, uint16_t reg)
1384{
1385	uint32_t val;
1386
1387	rum_read_multi(sc, reg, &val, sizeof val);
1388
1389	return le32toh(val);
1390}
1391
1392static void
1393rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len)
1394{
1395	struct usb2_device_request req;
1396	usb2_error_t error;
1397
1398	req.bmRequestType = UT_READ_VENDOR_DEVICE;
1399	req.bRequest = RT2573_READ_MULTI_MAC;
1400	USETW(req.wValue, 0);
1401	USETW(req.wIndex, reg);
1402	USETW(req.wLength, len);
1403
1404	error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf);
1405	if (error != 0) {
1406		device_printf(sc->sc_dev,
1407		    "could not multi read MAC register: %s\n",
1408		    usb2_errstr(error));
1409	}
1410}
1411
1412static void
1413rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
1414{
1415	uint32_t tmp = htole32(val);
1416
1417	rum_write_multi(sc, reg, &tmp, sizeof tmp);
1418}
1419
1420static void
1421rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len)
1422{
1423	struct usb2_device_request req;
1424	usb2_error_t error;
1425
1426	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
1427	req.bRequest = RT2573_WRITE_MULTI_MAC;
1428	USETW(req.wValue, 0);
1429	USETW(req.wIndex, reg);
1430	USETW(req.wLength, len);
1431
1432	error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, buf);
1433	if (error != 0) {
1434		device_printf(sc->sc_dev,
1435		    "could not multi write MAC register: %s\n",
1436		    usb2_errstr(error));
1437	}
1438}
1439
1440static void
1441rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
1442{
1443	uint32_t tmp;
1444	int ntries;
1445
1446	for (ntries = 0; ntries < 5; ntries++) {
1447		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
1448			break;
1449	}
1450	if (ntries == 5) {
1451		device_printf(sc->sc_dev, "could not write to BBP\n");
1452		return;
1453	}
1454
1455	tmp = RT2573_BBP_BUSY | (reg & 0x7f) << 8 | val;
1456	rum_write(sc, RT2573_PHY_CSR3, tmp);
1457}
1458
1459static uint8_t
1460rum_bbp_read(struct rum_softc *sc, uint8_t reg)
1461{
1462	uint32_t val;
1463	int ntries;
1464
1465	for (ntries = 0; ntries < 5; ntries++) {
1466		if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY))
1467			break;
1468	}
1469	if (ntries == 5) {
1470		device_printf(sc->sc_dev, "could not read BBP\n");
1471		return 0;
1472	}
1473
1474	val = RT2573_BBP_BUSY | RT2573_BBP_READ | reg << 8;
1475	rum_write(sc, RT2573_PHY_CSR3, val);
1476
1477	for (ntries = 0; ntries < 100; ntries++) {
1478		val = rum_read(sc, RT2573_PHY_CSR3);
1479		if (!(val & RT2573_BBP_BUSY))
1480			return val & 0xff;
1481		DELAY(1);
1482	}
1483
1484	device_printf(sc->sc_dev, "could not read BBP\n");
1485	return 0;
1486}
1487
1488static void
1489rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
1490{
1491	uint32_t tmp;
1492	int ntries;
1493
1494	for (ntries = 0; ntries < 5; ntries++) {
1495		if (!(rum_read(sc, RT2573_PHY_CSR4) & RT2573_RF_BUSY))
1496			break;
1497	}
1498	if (ntries == 5) {
1499		device_printf(sc->sc_dev, "could not write to RF\n");
1500		return;
1501	}
1502
1503	tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | (val & 0xfffff) << 2 |
1504	    (reg & 3);
1505	rum_write(sc, RT2573_PHY_CSR4, tmp);
1506
1507	/* remember last written value in sc */
1508	sc->rf_regs[reg] = val;
1509
1510	DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0xfffff);
1511}
1512
1513static void
1514rum_select_antenna(struct rum_softc *sc)
1515{
1516	uint8_t bbp4, bbp77;
1517	uint32_t tmp;
1518
1519	bbp4  = rum_bbp_read(sc, 4);
1520	bbp77 = rum_bbp_read(sc, 77);
1521
1522	/* TBD */
1523
1524	/* make sure Rx is disabled before switching antenna */
1525	tmp = rum_read(sc, RT2573_TXRX_CSR0);
1526	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
1527
1528	rum_bbp_write(sc,  4, bbp4);
1529	rum_bbp_write(sc, 77, bbp77);
1530
1531	rum_write(sc, RT2573_TXRX_CSR0, tmp);
1532}
1533
1534/*
1535 * Enable multi-rate retries for frames sent at OFDM rates.
1536 * In 802.11b/g mode, allow fallback to CCK rates.
1537 */
1538static void
1539rum_enable_mrr(struct rum_softc *sc)
1540{
1541	struct ifnet *ifp = sc->sc_ifp;
1542	struct ieee80211com *ic = ifp->if_l2com;
1543	uint32_t tmp;
1544
1545	tmp = rum_read(sc, RT2573_TXRX_CSR4);
1546
1547	tmp &= ~RT2573_MRR_CCK_FALLBACK;
1548	if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan))
1549		tmp |= RT2573_MRR_CCK_FALLBACK;
1550	tmp |= RT2573_MRR_ENABLED;
1551
1552	rum_write(sc, RT2573_TXRX_CSR4, tmp);
1553}
1554
1555static void
1556rum_set_txpreamble(struct rum_softc *sc)
1557{
1558	struct ifnet *ifp = sc->sc_ifp;
1559	struct ieee80211com *ic = ifp->if_l2com;
1560	uint32_t tmp;
1561
1562	tmp = rum_read(sc, RT2573_TXRX_CSR4);
1563
1564	tmp &= ~RT2573_SHORT_PREAMBLE;
1565	if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
1566		tmp |= RT2573_SHORT_PREAMBLE;
1567
1568	rum_write(sc, RT2573_TXRX_CSR4, tmp);
1569}
1570
1571static void
1572rum_set_basicrates(struct rum_softc *sc)
1573{
1574	struct ifnet *ifp = sc->sc_ifp;
1575	struct ieee80211com *ic = ifp->if_l2com;
1576
1577	/* update basic rate set */
1578	if (ic->ic_curmode == IEEE80211_MODE_11B) {
1579		/* 11b basic rates: 1, 2Mbps */
1580		rum_write(sc, RT2573_TXRX_CSR5, 0x3);
1581	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) {
1582		/* 11a basic rates: 6, 12, 24Mbps */
1583		rum_write(sc, RT2573_TXRX_CSR5, 0x150);
1584	} else {
1585		/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1586		rum_write(sc, RT2573_TXRX_CSR5, 0xf);
1587	}
1588}
1589
1590/*
1591 * Reprogram MAC/BBP to switch to a new band.  Values taken from the reference
1592 * driver.
1593 */
1594static void
1595rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c)
1596{
1597	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
1598	uint32_t tmp;
1599
1600	/* update all BBP registers that depend on the band */
1601	bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
1602	bbp35 = 0x50; bbp97 = 0x48; bbp98  = 0x48;
1603	if (IEEE80211_IS_CHAN_5GHZ(c)) {
1604		bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
1605		bbp35 += 0x10; bbp97 += 0x10; bbp98  += 0x10;
1606	}
1607	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1608	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1609		bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
1610	}
1611
1612	sc->bbp17 = bbp17;
1613	rum_bbp_write(sc,  17, bbp17);
1614	rum_bbp_write(sc,  96, bbp96);
1615	rum_bbp_write(sc, 104, bbp104);
1616
1617	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
1618	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
1619		rum_bbp_write(sc, 75, 0x80);
1620		rum_bbp_write(sc, 86, 0x80);
1621		rum_bbp_write(sc, 88, 0x80);
1622	}
1623
1624	rum_bbp_write(sc, 35, bbp35);
1625	rum_bbp_write(sc, 97, bbp97);
1626	rum_bbp_write(sc, 98, bbp98);
1627
1628	tmp = rum_read(sc, RT2573_PHY_CSR0);
1629	tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
1630	if (IEEE80211_IS_CHAN_2GHZ(c))
1631		tmp |= RT2573_PA_PE_2GHZ;
1632	else
1633		tmp |= RT2573_PA_PE_5GHZ;
1634	rum_write(sc, RT2573_PHY_CSR0, tmp);
1635}
1636
1637static void
1638rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c)
1639{
1640	struct ifnet *ifp = sc->sc_ifp;
1641	struct ieee80211com *ic = ifp->if_l2com;
1642	const struct rfprog *rfprog;
1643	uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT;
1644	int8_t power;
1645	u_int i, chan;
1646
1647	chan = ieee80211_chan2ieee(ic, c);
1648	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
1649		return;
1650
1651	/* select the appropriate RF settings based on what EEPROM says */
1652	rfprog = (sc->rf_rev == RT2573_RF_5225 ||
1653		  sc->rf_rev == RT2573_RF_2527) ? rum_rf5225 : rum_rf5226;
1654
1655	/* find the settings for this channel (we know it exists) */
1656	for (i = 0; rfprog[i].chan != chan; i++);
1657
1658	power = sc->txpow[i];
1659	if (power < 0) {
1660		bbp94 += power;
1661		power = 0;
1662	} else if (power > 31) {
1663		bbp94 += power - 31;
1664		power = 31;
1665	}
1666
1667	/*
1668	 * If we are switching from the 2GHz band to the 5GHz band or
1669	 * vice-versa, BBP registers need to be reprogrammed.
1670	 */
1671	if (c->ic_flags != ic->ic_curchan->ic_flags) {
1672		rum_select_band(sc, c);
1673		rum_select_antenna(sc);
1674	}
1675	ic->ic_curchan = c;
1676
1677	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1678	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1679	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1680	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1681
1682	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1683	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1684	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7 | 1);
1685	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1686
1687	rum_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1688	rum_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1689	rum_rf_write(sc, RT2573_RF3, rfprog[i].r3 | power << 7);
1690	rum_rf_write(sc, RT2573_RF4, rfprog[i].r4 | sc->rffreq << 10);
1691
1692	DELAY(10);
1693
1694	/* enable smart mode for MIMO-capable RFs */
1695	bbp3 = rum_bbp_read(sc, 3);
1696
1697	bbp3 &= ~RT2573_SMART_MODE;
1698	if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_2527)
1699		bbp3 |= RT2573_SMART_MODE;
1700
1701	rum_bbp_write(sc, 3, bbp3);
1702
1703	if (bbp94 != RT2573_BBPR94_DEFAULT)
1704		rum_bbp_write(sc, 94, bbp94);
1705}
1706
1707/*
1708 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1709 * and HostAP operating modes.
1710 */
1711static void
1712rum_enable_tsf_sync(struct rum_softc *sc)
1713{
1714	struct ifnet *ifp = sc->sc_ifp;
1715	struct ieee80211com *ic = ifp->if_l2com;
1716	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1717	uint32_t tmp;
1718
1719	if (vap->iv_opmode != IEEE80211_M_STA) {
1720		/*
1721		 * Change default 16ms TBTT adjustment to 8ms.
1722		 * Must be done before enabling beacon generation.
1723		 */
1724		rum_write(sc, RT2573_TXRX_CSR10, 1 << 12 | 8);
1725	}
1726
1727	tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
1728
1729	/* set beacon interval (in 1/16ms unit) */
1730	tmp |= vap->iv_bss->ni_intval * 16;
1731
1732	tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
1733	if (vap->iv_opmode == IEEE80211_M_STA)
1734		tmp |= RT2573_TSF_MODE(1);
1735	else
1736		tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
1737
1738	rum_write(sc, RT2573_TXRX_CSR9, tmp);
1739}
1740
1741static void
1742rum_update_slot(struct ifnet *ifp)
1743{
1744	struct rum_softc *sc = ifp->if_softc;
1745	struct ieee80211com *ic = ifp->if_l2com;
1746	uint8_t slottime;
1747	uint32_t tmp;
1748
1749	slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1750
1751	tmp = rum_read(sc, RT2573_MAC_CSR9);
1752	tmp = (tmp & ~0xff) | slottime;
1753	rum_write(sc, RT2573_MAC_CSR9, tmp);
1754
1755	DPRINTF("setting slot time to %uus\n", slottime);
1756}
1757
1758static void
1759rum_set_bssid(struct rum_softc *sc, const uint8_t *bssid)
1760{
1761	uint32_t tmp;
1762
1763	tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
1764	rum_write(sc, RT2573_MAC_CSR4, tmp);
1765
1766	tmp = bssid[4] | bssid[5] << 8 | RT2573_ONE_BSSID << 16;
1767	rum_write(sc, RT2573_MAC_CSR5, tmp);
1768}
1769
1770static void
1771rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr)
1772{
1773	uint32_t tmp;
1774
1775	tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
1776	rum_write(sc, RT2573_MAC_CSR2, tmp);
1777
1778	tmp = addr[4] | addr[5] << 8 | 0xff << 16;
1779	rum_write(sc, RT2573_MAC_CSR3, tmp);
1780}
1781
1782static void
1783rum_promisctask(struct usb2_proc_msg *pm)
1784{
1785	struct rum_task *task = (struct rum_task *)pm;
1786	struct rum_softc *sc = task->sc;
1787	struct ifnet *ifp = sc->sc_ifp;
1788	uint32_t tmp;
1789
1790	if (sc->sc_flags & RUM_FLAG_DETACH)
1791		return;
1792
1793	tmp = rum_read(sc, RT2573_TXRX_CSR0);
1794
1795	tmp &= ~RT2573_DROP_NOT_TO_ME;
1796	if (!(ifp->if_flags & IFF_PROMISC))
1797		tmp |= RT2573_DROP_NOT_TO_ME;
1798
1799	rum_write(sc, RT2573_TXRX_CSR0, tmp);
1800
1801	DPRINTF("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
1802	    "entering" : "leaving");
1803}
1804
1805static const char *
1806rum_get_rf(int rev)
1807{
1808	switch (rev) {
1809	case RT2573_RF_2527:	return "RT2527 (MIMO XR)";
1810	case RT2573_RF_2528:	return "RT2528";
1811	case RT2573_RF_5225:	return "RT5225 (MIMO XR)";
1812	case RT2573_RF_5226:	return "RT5226";
1813	default:		return "unknown";
1814	}
1815}
1816
1817static void
1818rum_read_eeprom(struct rum_softc *sc)
1819{
1820	struct ifnet *ifp = sc->sc_ifp;
1821	struct ieee80211com *ic = ifp->if_l2com;
1822	uint16_t val;
1823#ifdef RUM_DEBUG
1824	int i;
1825#endif
1826
1827	/* read MAC address */
1828	rum_eeprom_read(sc, RT2573_EEPROM_ADDRESS, ic->ic_myaddr, 6);
1829
1830	rum_eeprom_read(sc, RT2573_EEPROM_ANTENNA, &val, 2);
1831	val = le16toh(val);
1832	sc->rf_rev =   (val >> 11) & 0x1f;
1833	sc->hw_radio = (val >> 10) & 0x1;
1834	sc->rx_ant =   (val >> 4)  & 0x3;
1835	sc->tx_ant =   (val >> 2)  & 0x3;
1836	sc->nb_ant =   val & 0x3;
1837
1838	DPRINTF("RF revision=%d\n", sc->rf_rev);
1839
1840	rum_eeprom_read(sc, RT2573_EEPROM_CONFIG2, &val, 2);
1841	val = le16toh(val);
1842	sc->ext_5ghz_lna = (val >> 6) & 0x1;
1843	sc->ext_2ghz_lna = (val >> 4) & 0x1;
1844
1845	DPRINTF("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
1846	    sc->ext_2ghz_lna, sc->ext_5ghz_lna);
1847
1848	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET, &val, 2);
1849	val = le16toh(val);
1850	if ((val & 0xff) != 0xff)
1851		sc->rssi_2ghz_corr = (int8_t)(val & 0xff);	/* signed */
1852
1853	/* Only [-10, 10] is valid */
1854	if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10)
1855		sc->rssi_2ghz_corr = 0;
1856
1857	rum_eeprom_read(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET, &val, 2);
1858	val = le16toh(val);
1859	if ((val & 0xff) != 0xff)
1860		sc->rssi_5ghz_corr = (int8_t)(val & 0xff);	/* signed */
1861
1862	/* Only [-10, 10] is valid */
1863	if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10)
1864		sc->rssi_5ghz_corr = 0;
1865
1866	if (sc->ext_2ghz_lna)
1867		sc->rssi_2ghz_corr -= 14;
1868	if (sc->ext_5ghz_lna)
1869		sc->rssi_5ghz_corr -= 14;
1870
1871	DPRINTF("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
1872	    sc->rssi_2ghz_corr, sc->rssi_5ghz_corr);
1873
1874	rum_eeprom_read(sc, RT2573_EEPROM_FREQ_OFFSET, &val, 2);
1875	val = le16toh(val);
1876	if ((val & 0xff) != 0xff)
1877		sc->rffreq = val & 0xff;
1878
1879	DPRINTF("RF freq=%d\n", sc->rffreq);
1880
1881	/* read Tx power for all a/b/g channels */
1882	rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14);
1883	/* XXX default Tx power for 802.11a channels */
1884	memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14);
1885#ifdef RUM_DEBUG
1886	for (i = 0; i < 14; i++)
1887		DPRINTF("Channel=%d Tx power=%d\n", i + 1,  sc->txpow[i]);
1888#endif
1889
1890	/* read default values for BBP registers */
1891	rum_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->bbp_prom, 2 * 16);
1892#ifdef RUM_DEBUG
1893	for (i = 0; i < 14; i++) {
1894		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
1895			continue;
1896		DPRINTF("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
1897		    sc->bbp_prom[i].val);
1898	}
1899#endif
1900}
1901
1902static int
1903rum_bbp_init(struct rum_softc *sc)
1904{
1905#define N(a)	(sizeof (a) / sizeof ((a)[0]))
1906	int i, ntries;
1907
1908	/* wait for BBP to be ready */
1909	for (ntries = 0; ntries < 100; ntries++) {
1910		const uint8_t val = rum_bbp_read(sc, 0);
1911		if (val != 0 && val != 0xff)
1912			break;
1913		DELAY(1000);
1914	}
1915	if (ntries == 100) {
1916		device_printf(sc->sc_dev, "timeout waiting for BBP\n");
1917		return EIO;
1918	}
1919
1920	/* initialize BBP registers to default values */
1921	for (i = 0; i < N(rum_def_bbp); i++)
1922		rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
1923
1924	/* write vendor-specific BBP values (from EEPROM) */
1925	for (i = 0; i < 16; i++) {
1926		if (sc->bbp_prom[i].reg == 0 || sc->bbp_prom[i].reg == 0xff)
1927			continue;
1928		rum_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
1929	}
1930
1931	return 0;
1932#undef N
1933}
1934
1935static void
1936rum_init_locked(struct rum_softc *sc)
1937{
1938#define N(a)	(sizeof (a) / sizeof ((a)[0]))
1939	struct ifnet *ifp = sc->sc_ifp;
1940	struct ieee80211com *ic = ifp->if_l2com;
1941	uint32_t tmp;
1942	usb2_error_t error;
1943	int i, ntries;
1944
1945	RUM_LOCK_ASSERT(sc, MA_OWNED);
1946
1947	if (sc->sc_flags & RUM_FLAG_DETACH)
1948		return;
1949
1950	rum_stop(sc);
1951
1952	/* initialize MAC registers to default values */
1953	for (i = 0; i < N(rum_def_mac); i++)
1954		rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
1955
1956	/* set host ready */
1957	rum_write(sc, RT2573_MAC_CSR1, 3);
1958	rum_write(sc, RT2573_MAC_CSR1, 0);
1959
1960	/* wait for BBP/RF to wakeup */
1961	for (ntries = 0; ntries < 1000; ntries++) {
1962		if (rum_read(sc, RT2573_MAC_CSR12) & 8)
1963			break;
1964		rum_write(sc, RT2573_MAC_CSR12, 4);	/* force wakeup */
1965		DELAY(1000);
1966	}
1967	if (ntries == 1000) {
1968		device_printf(sc->sc_dev,
1969		    "timeout waiting for BBP/RF to wakeup\n");
1970		goto fail;
1971	}
1972
1973	if ((error = rum_bbp_init(sc)) != 0)
1974		goto fail;
1975
1976	/* select default channel */
1977	rum_select_band(sc, ic->ic_curchan);
1978	rum_select_antenna(sc);
1979	rum_set_chan(sc, ic->ic_curchan);
1980
1981	/* clear STA registers */
1982	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
1983
1984	IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
1985	rum_set_macaddr(sc, ic->ic_myaddr);
1986
1987	/* initialize ASIC */
1988	rum_write(sc, RT2573_MAC_CSR1, 4);
1989
1990	/*
1991	 * Allocate Tx and Rx xfer queues.
1992	 */
1993	error = rum_alloc_tx_list(sc);
1994	if (error != 0) {
1995		device_printf(sc->sc_dev, "could not allocate Tx list\n");
1996		goto fail;
1997	}
1998
1999	/* update Rx filter */
2000	tmp = rum_read(sc, RT2573_TXRX_CSR0) & 0xffff;
2001
2002	tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
2003	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
2004		tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
2005		       RT2573_DROP_ACKCTS;
2006		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
2007			tmp |= RT2573_DROP_TODS;
2008		if (!(ifp->if_flags & IFF_PROMISC))
2009			tmp |= RT2573_DROP_NOT_TO_ME;
2010	}
2011	rum_write(sc, RT2573_TXRX_CSR0, tmp);
2012
2013	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2014	ifp->if_drv_flags |= IFF_DRV_RUNNING;
2015	usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]);
2016	return;
2017
2018fail:	rum_stop(sc);
2019#undef N
2020}
2021
2022static void
2023rum_init(void *priv)
2024{
2025	struct rum_softc *sc = priv;
2026	struct ifnet *ifp = sc->sc_ifp;
2027	struct ieee80211com *ic = ifp->if_l2com;
2028
2029	RUM_LOCK(sc);
2030	rum_init_locked(sc);
2031	RUM_UNLOCK(sc);
2032
2033	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
2034		ieee80211_start_all(ic);		/* start all vap's */
2035}
2036
2037static void
2038rum_stop(void *priv)
2039{
2040	struct rum_softc *sc = priv;
2041	struct ifnet *ifp = sc->sc_ifp;
2042	uint32_t tmp;
2043
2044	RUM_LOCK_ASSERT(sc, MA_OWNED);
2045
2046	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
2047
2048	/*
2049	 * stop all the transfers, if not already stopped:
2050	 */
2051	usb2_transfer_stop(sc->sc_xfer[RUM_BULK_WR]);
2052	usb2_transfer_stop(sc->sc_xfer[RUM_BULK_RD]);
2053
2054	rum_free_tx_list(sc);
2055
2056	/* Stop now if the device has vanished */
2057	if (sc->sc_flags & RUM_FLAG_DETACH)
2058		return;
2059
2060	/* disable Rx */
2061	tmp = rum_read(sc, RT2573_TXRX_CSR0);
2062	rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
2063
2064	/* reset ASIC */
2065	rum_write(sc, RT2573_MAC_CSR1, 3);
2066	rum_write(sc, RT2573_MAC_CSR1, 0);
2067}
2068
2069static int
2070rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size)
2071{
2072	struct usb2_device_request req;
2073	uint16_t reg = RT2573_MCU_CODE_BASE;
2074	usb2_error_t error;
2075
2076	/* copy firmware image into NIC */
2077	for (; size >= 4; reg += 4, ucode += 4, size -= 4)
2078		rum_write(sc, reg, UGETDW(ucode));
2079
2080	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2081	req.bRequest = RT2573_MCU_CNTL;
2082	USETW(req.wValue, RT2573_MCU_RUN);
2083	USETW(req.wIndex, 0);
2084	USETW(req.wLength, 0);
2085
2086	error = usb2_do_request(sc->sc_udev, &sc->sc_mtx, &req, NULL);
2087	if (error != 0) {
2088		device_printf(sc->sc_dev, "could not run firmware: %s\n",
2089		    usb2_errstr(error));
2090	}
2091	return error;
2092}
2093
2094static int
2095rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap)
2096{
2097	struct ieee80211com *ic = vap->iv_ic;
2098	const struct ieee80211_txparam *tp;
2099	struct rum_tx_desc desc;
2100	struct mbuf *m0;
2101
2102	m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo);
2103	if (m0 == NULL) {
2104		return ENOBUFS;
2105	}
2106
2107	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
2108	rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ,
2109	    m0->m_pkthdr.len, tp->mgmtrate);
2110
2111	/* copy the first 24 bytes of Tx descriptor into NIC memory */
2112	rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
2113
2114	/* copy beacon header and payload into NIC memory */
2115	rum_write_multi(sc, RT2573_HW_BEACON_BASE0 + 24, mtod(m0, uint8_t *),
2116	    m0->m_pkthdr.len);
2117
2118	m_freem(m0);
2119
2120	return 0;
2121}
2122
2123static int
2124rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
2125    const struct ieee80211_bpf_params *params)
2126{
2127	struct ifnet *ifp = ni->ni_ic->ic_ifp;
2128	struct rum_softc *sc = ifp->if_softc;
2129
2130	RUM_LOCK(sc);
2131	/* prevent management frames from being sent if we're not ready */
2132	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
2133		RUM_UNLOCK(sc);
2134		m_freem(m);
2135		ieee80211_free_node(ni);
2136		return ENETDOWN;
2137	}
2138	if (sc->tx_nfree == 0) {
2139		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2140		RUM_UNLOCK(sc);
2141		m_freem(m);
2142		ieee80211_free_node(ni);
2143		return EIO;
2144	}
2145
2146	ifp->if_opackets++;
2147
2148	if (params == NULL) {
2149		/*
2150		 * Legacy path; interpret frame contents to decide
2151		 * precisely how to send the frame.
2152		 */
2153		if (rum_tx_mgt(sc, m, ni) != 0)
2154			goto bad;
2155	} else {
2156		/*
2157		 * Caller supplied explicit parameters to use in
2158		 * sending the frame.
2159		 */
2160		if (rum_tx_raw(sc, m, ni, params) != 0)
2161			goto bad;
2162	}
2163	RUM_UNLOCK(sc);
2164
2165	return 0;
2166bad:
2167	ifp->if_oerrors++;
2168	RUM_UNLOCK(sc);
2169	ieee80211_free_node(ni);
2170	return EIO;
2171}
2172
2173static void
2174rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni)
2175{
2176	struct ieee80211vap *vap = ni->ni_vap;
2177	struct rum_vap *rvp = RUM_VAP(vap);
2178
2179	/* clear statistic registers (STA_CSR0 to STA_CSR5) */
2180	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta);
2181
2182	ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni);
2183
2184	usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
2185}
2186
2187static void
2188rum_amrr_timeout(void *arg)
2189{
2190	struct rum_vap *rvp = arg;
2191	struct rum_softc *sc = rvp->sc;
2192
2193	rum_queue_command(sc, rum_amrr_task,
2194	    &rvp->amrr_task[0].hdr, &rvp->amrr_task[1].hdr);
2195}
2196
2197static void
2198rum_amrr_task(struct usb2_proc_msg *pm)
2199{
2200	struct rum_task *task = (struct rum_task *)pm;
2201	struct rum_softc *sc = task->sc;
2202	struct ifnet *ifp = sc->sc_ifp;
2203	struct ieee80211com *ic = ifp->if_l2com;
2204	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2205	struct rum_vap *rvp = RUM_VAP(vap);
2206	struct ieee80211_node *ni = vap->iv_bss;
2207	int ok, fail;
2208
2209	/* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
2210	rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta));
2211
2212	ok = (le32toh(sc->sta[4]) >> 16) +	/* TX ok w/o retry */
2213	    (le32toh(sc->sta[5]) & 0xffff);	/* TX ok w/ retry */
2214	fail = (le32toh(sc->sta[5]) >> 16);	/* TX retry-fail count */
2215
2216	ieee80211_amrr_tx_update(&RUM_NODE(ni)->amn,
2217	    ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail);
2218	(void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn);
2219
2220	ifp->if_oerrors += fail;	/* count TX retry-fail as Tx errors */
2221
2222	usb2_callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, rvp);
2223}
2224
2225/* ARGUSED */
2226static struct ieee80211_node *
2227rum_node_alloc(struct ieee80211vap *vap __unused,
2228	const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
2229{
2230	struct rum_node *rn;
2231
2232	rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
2233	return rn != NULL ? &rn->ni : NULL;
2234}
2235
2236static void
2237rum_newassoc(struct ieee80211_node *ni, int isnew)
2238{
2239	struct ieee80211vap *vap = ni->ni_vap;
2240
2241	ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
2242}
2243
2244static void
2245rum_scan_start(struct ieee80211com *ic)
2246{
2247	struct rum_softc *sc = ic->ic_ifp->if_softc;
2248
2249	RUM_LOCK(sc);
2250	/* do it in a process context */
2251	sc->sc_scan_action = RUM_SCAN_START;
2252	rum_queue_command(sc, rum_scantask,
2253	    &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
2254	RUM_UNLOCK(sc);
2255
2256}
2257
2258static void
2259rum_scan_end(struct ieee80211com *ic)
2260{
2261	struct rum_softc *sc = ic->ic_ifp->if_softc;
2262
2263	RUM_LOCK(sc);
2264	/* do it in a process context */
2265	sc->sc_scan_action = RUM_SCAN_END;
2266	rum_queue_command(sc, rum_scantask,
2267	    &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
2268	RUM_UNLOCK(sc);
2269
2270}
2271
2272static void
2273rum_set_channel(struct ieee80211com *ic)
2274{
2275	struct rum_softc *sc = ic->ic_ifp->if_softc;
2276
2277	RUM_LOCK(sc);
2278	/* do it in a process context */
2279	sc->sc_scan_action = RUM_SET_CHANNEL;
2280	rum_queue_command(sc, rum_scantask,
2281	    &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr);
2282
2283	sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
2284	RUM_UNLOCK(sc);
2285}
2286
2287static void
2288rum_scantask(struct usb2_proc_msg *pm)
2289{
2290	struct rum_task *task = (struct rum_task *)pm;
2291	struct rum_softc *sc = task->sc;
2292	struct ifnet *ifp = sc->sc_ifp;
2293	struct ieee80211com *ic = ifp->if_l2com;
2294	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
2295	uint32_t tmp;
2296
2297	RUM_LOCK_ASSERT(sc, MA_OWNED);
2298
2299	if (sc->sc_flags & RUM_FLAG_DETACH)
2300		return;
2301
2302	switch (sc->sc_scan_action) {
2303	case RUM_SCAN_START:
2304		/* abort TSF synchronization */
2305		tmp = rum_read(sc, RT2573_TXRX_CSR9);
2306		rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
2307		rum_set_bssid(sc, ifp->if_broadcastaddr);
2308		break;
2309
2310	case RUM_SCAN_END:
2311		rum_enable_tsf_sync(sc);
2312		/* XXX keep local copy */
2313		rum_set_bssid(sc, vap->iv_bss->ni_bssid);
2314		break;
2315
2316	case RUM_SET_CHANNEL:
2317		rum_set_chan(sc, ic->ic_curchan);
2318		break;
2319
2320	default:
2321		panic("unknown scan action %d\n", sc->sc_scan_action);
2322		/* NEVER REACHED */
2323		break;
2324	}
2325}
2326
2327static int
2328rum_get_rssi(struct rum_softc *sc, uint8_t raw)
2329{
2330	struct ifnet *ifp = sc->sc_ifp;
2331	struct ieee80211com *ic = ifp->if_l2com;
2332	int lna, agc, rssi;
2333
2334	lna = (raw >> 5) & 0x3;
2335	agc = raw & 0x1f;
2336
2337	if (lna == 0) {
2338		/*
2339		 * No RSSI mapping
2340		 *
2341		 * NB: Since RSSI is relative to noise floor, -1 is
2342		 *     adequate for caller to know error happened.
2343		 */
2344		return -1;
2345	}
2346
2347	rssi = (2 * agc) - RT2573_NOISE_FLOOR;
2348
2349	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2350		rssi += sc->rssi_2ghz_corr;
2351
2352		if (lna == 1)
2353			rssi -= 64;
2354		else if (lna == 2)
2355			rssi -= 74;
2356		else if (lna == 3)
2357			rssi -= 90;
2358	} else {
2359		rssi += sc->rssi_5ghz_corr;
2360
2361		if (!sc->ext_5ghz_lna && lna != 1)
2362			rssi += 4;
2363
2364		if (lna == 1)
2365			rssi -= 64;
2366		else if (lna == 2)
2367			rssi -= 86;
2368		else if (lna == 3)
2369			rssi -= 100;
2370	}
2371	return rssi;
2372}
2373
2374static void
2375rum_queue_command(struct rum_softc *sc, usb2_proc_callback_t *fn,
2376    struct usb2_proc_msg *t0, struct usb2_proc_msg *t1)
2377{
2378	struct rum_task *task;
2379
2380	RUM_LOCK_ASSERT(sc, MA_OWNED);
2381
2382	if (usb2_proc_is_gone(&sc->sc_tq)) {
2383		DPRINTF("proc is gone\n");
2384		return;         /* nothing to do */
2385	}
2386	/*
2387	 * NOTE: The task cannot get executed before we drop the
2388	 * "sc_mtx" mutex. It is safe to update fields in the message
2389	 * structure after that the message got queued.
2390	 */
2391	task = (struct rum_task *)
2392	  usb2_proc_msignal(&sc->sc_tq, t0, t1);
2393
2394	/* Setup callback and softc pointers */
2395	task->hdr.pm_callback = fn;
2396	task->sc = sc;
2397
2398}
2399
2400static device_method_t rum_methods[] = {
2401	/* Device interface */
2402	DEVMETHOD(device_probe,		rum_match),
2403	DEVMETHOD(device_attach,	rum_attach),
2404	DEVMETHOD(device_detach,	rum_detach),
2405
2406	{ 0, 0 }
2407};
2408
2409static driver_t rum_driver = {
2410	.name = "rum",
2411	.methods = rum_methods,
2412	.size = sizeof(struct rum_softc),
2413};
2414
2415static devclass_t rum_devclass;
2416
2417DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0);
2418