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