if_rum.c revision 184610
1/*-
2 * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr>
3 * Copyright (c) 2006 Niall O'Higgins <niallo@openbsd.org>
4 * Copyright (c) 2007-2008 Hans Petter Selasky <hselasky@freebsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * NOTE: all function names beginning like "rum_cfg_" can only
21 * be called from within the config thread function !
22 */
23
24#include <sys/cdefs.h>
25__FBSDID("$FreeBSD: head/sys/dev/usb2/wlan/if_rum2.c 184610 2008-11-04 02:31:03Z alfred $");
26
27/*-
28 * Ralink Technology RT2501USB/RT2601USB chipset driver
29 * http://www.ralinktech.com.tw/
30 */
31
32#include <dev/usb2/include/usb2_devid.h>
33#include <dev/usb2/include/usb2_standard.h>
34#include <dev/usb2/include/usb2_mfunc.h>
35#include <dev/usb2/include/usb2_error.h>
36
37#define	usb2_config_td_cc rum_config_copy
38#define	usb2_config_td_softc rum_softc
39
40#define	USB_DEBUG_VAR rum_debug
41
42#include <dev/usb2/core/usb2_core.h>
43#include <dev/usb2/core/usb2_lookup.h>
44#include <dev/usb2/core/usb2_process.h>
45#include <dev/usb2/core/usb2_config_td.h>
46#include <dev/usb2/core/usb2_debug.h>
47#include <dev/usb2/core/usb2_request.h>
48#include <dev/usb2/core/usb2_busdma.h>
49#include <dev/usb2/core/usb2_util.h>
50
51#include <dev/usb2/wlan/usb2_wlan.h>
52#include <dev/usb2/wlan/if_rum2_reg.h>
53#include <dev/usb2/wlan/if_rum2_var.h>
54#include <dev/usb2/wlan/if_rum2_fw.h>
55
56#if USB_DEBUG
57static int rum_debug = 0;
58
59SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum");
60SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0,
61    "Debug level");
62#endif
63
64/* prototypes */
65
66static device_probe_t rum_probe;
67static device_attach_t rum_attach;
68static device_detach_t rum_detach;
69
70static usb2_callback_t rum_bulk_read_callback;
71static usb2_callback_t rum_bulk_read_clear_stall_callback;
72static usb2_callback_t rum_bulk_write_callback;
73static usb2_callback_t rum_bulk_write_clear_stall_callback;
74
75static usb2_config_td_command_t rum_cfg_first_time_setup;
76static usb2_config_td_command_t rum_config_copy;
77static usb2_config_td_command_t rum_cfg_scan_start;
78static usb2_config_td_command_t rum_cfg_scan_end;
79static usb2_config_td_command_t rum_cfg_select_band;
80static usb2_config_td_command_t rum_cfg_set_chan;
81static usb2_config_td_command_t rum_cfg_enable_tsf_sync;
82static usb2_config_td_command_t rum_cfg_enable_mrr;
83static usb2_config_td_command_t rum_cfg_update_slot;
84static usb2_config_td_command_t rum_cfg_select_antenna;
85static usb2_config_td_command_t rum_cfg_set_txpreamble;
86static usb2_config_td_command_t rum_cfg_update_promisc;
87static usb2_config_td_command_t rum_cfg_pre_init;
88static usb2_config_td_command_t rum_cfg_init;
89static usb2_config_td_command_t rum_cfg_pre_stop;
90static usb2_config_td_command_t rum_cfg_stop;
91static usb2_config_td_command_t rum_cfg_amrr_timeout;
92static usb2_config_td_command_t rum_cfg_prepare_beacon;
93static usb2_config_td_command_t rum_cfg_newstate;
94
95static const char *rum_get_rf(uint32_t rev);
96static int rum_ioctl_cb(struct ifnet *ifp, u_long cmd, caddr_t data);
97static void rum_std_command(struct ieee80211com *ic, usb2_config_td_command_t *func);
98static void rum_scan_start_cb(struct ieee80211com *);
99static void rum_scan_end_cb(struct ieee80211com *);
100static void rum_set_channel_cb(struct ieee80211com *);
101static uint16_t rum_cfg_eeprom_read_2(struct rum_softc *sc, uint16_t addr);
102static uint32_t rum_cfg_bbp_disbusy(struct rum_softc *sc);
103static uint32_t rum_cfg_read(struct rum_softc *sc, uint16_t reg);
104static uint8_t rum_cfg_bbp_init(struct rum_softc *sc);
105static uint8_t rum_cfg_bbp_read(struct rum_softc *sc, uint8_t reg);
106static void rum_cfg_amrr_start(struct rum_softc *sc);
107static void rum_cfg_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val);
108static void rum_cfg_do_request(struct rum_softc *sc, struct usb2_device_request *req, void *data);
109static void rum_cfg_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, uint16_t len);
110static void rum_cfg_load_microcode(struct rum_softc *sc, const uint8_t *ucode, uint16_t size);
111static void rum_cfg_read_eeprom(struct rum_softc *sc);
112static void rum_cfg_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len);
113static void rum_cfg_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val);
114static void rum_cfg_set_bssid(struct rum_softc *sc, uint8_t *bssid);
115static void rum_cfg_set_macaddr(struct rum_softc *sc, uint8_t *addr);
116static void rum_cfg_write(struct rum_softc *sc, uint16_t reg, uint32_t val);
117static void rum_cfg_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len);
118static void rum_end_of_commands(struct rum_softc *sc);
119static void rum_init_cb(void *arg);
120static void rum_start_cb(struct ifnet *ifp);
121static void rum_watchdog(void *arg);
122static uint8_t rum_get_rssi(struct rum_softc *sc, uint8_t raw);
123static struct ieee80211vap *rum_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, int opmode, int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], const uint8_t mac[IEEE80211_ADDR_LEN]);
124static void rum_vap_delete(struct ieee80211vap *);
125static struct ieee80211_node *rum_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]);
126static void rum_newassoc(struct ieee80211_node *, int);
127static void rum_cfg_disable_tsf_sync(struct rum_softc *sc);
128static void rum_cfg_set_run(struct rum_softc *sc, struct rum_config_copy *cc);
129static void rum_fill_write_queue(struct rum_softc *sc);
130static void rum_tx_clean_queue(struct rum_softc *sc);
131static void rum_tx_freem(struct mbuf *m);
132static void rum_tx_mgt(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni);
133static struct ieee80211vap *rum_get_vap(struct rum_softc *sc);
134static void rum_tx_data(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni);
135static void rum_tx_prot(struct rum_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, uint8_t prot, uint16_t rate);
136static void rum_tx_raw(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params);
137static int rum_raw_xmit_cb(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params);
138static void rum_setup_desc_and_tx(struct rum_softc *sc, struct mbuf *m, uint32_t flags, uint16_t xflags, uint16_t rate);
139static int rum_newstate_cb(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg);
140static void rum_update_mcast_cb(struct ifnet *ifp);
141static void rum_update_promisc_cb(struct ifnet *ifp);
142
143/* various supported device vendors/products */
144static const struct usb2_device_id rum_devs[] = {
145	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_HWU54DM, 0)},
146	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_2, 0)},
147	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_3, 0)},
148	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RT2573_4, 0)},
149	{USB_VPI(USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_WUG2700, 0)},
150	{USB_VPI(USB_VENDOR_AMIT, USB_PRODUCT_AMIT_CGWLUSB2GO, 0)},
151	{USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_1, 0)},
152	{USB_VPI(USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RT2573_2, 0)},
153	{USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050A, 0)},
154	{USB_VPI(USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D9050V3, 0)},
155	{USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GC, 0)},
156	{USB_VPI(USB_VENDOR_CISCOLINKSYS, USB_PRODUCT_CISCOLINKSYS_WUSB54GR, 0)},
157	{USB_VPI(USB_VENDOR_CONCEPTRONIC2, USB_PRODUCT_CONCEPTRONIC2_C54RU2, 0)},
158	{USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GL, 0)},
159	{USB_VPI(USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB2GPX, 0)},
160	{USB_VPI(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CWD854F, 0)},
161	{USB_VPI(USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_RT2573, 0)},
162	{USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWLG122C1, 0)},
163	{USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_WUA1340, 0)},
164	{USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA111, 0)},
165	{USB_VPI(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA110, 0)},
166	{USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWB01GS, 0)},
167	{USB_VPI(USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWI05GS, 0)},
168	{USB_VPI(USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_RT2573, 0)},
169	{USB_VPI(USB_VENDOR_GOODWAY, USB_PRODUCT_GOODWAY_RT2573, 0)},
170	{USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254LB, 0)},
171	{USB_VPI(USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254V2AP, 0)},
172	{USB_VPI(USB_VENDOR_HUAWEI3COM, USB_PRODUCT_HUAWEI3COM_WUB320G, 0)},
173	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_G54HP, 0)},
174	{USB_VPI(USB_VENDOR_MELCO, USB_PRODUCT_MELCO_SG54HP, 0)},
175	{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_1, 0)},
176	{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_2, 0)},
177	{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_3, 0)},
178	{USB_VPI(USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2573_4, 0)},
179	{USB_VPI(USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RT2573, 0)},
180	{USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54HP, 0)},
181	{USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUS54MINI2, 0)},
182	{USB_VPI(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSMM, 0)},
183	{USB_VPI(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573, 0)},
184	{USB_VPI(USB_VENDOR_QCOM, USB_PRODUCT_QCOM_RT2573_2, 0)},
185	{USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573, 0)},
186	{USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2573_2, 0)},
187	{USB_VPI(USB_VENDOR_RALINK, USB_PRODUCT_RALINK_RT2671, 0)},
188	{USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL113R2, 0)},
189	{USB_VPI(USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL172, 0)},
190	{USB_VPI(USB_VENDOR_SPARKLAN, USB_PRODUCT_SPARKLAN_RT2573, 0)},
191	{USB_VPI(USB_VENDOR_SURECOM, USB_PRODUCT_SURECOM_RT2573, 0)},
192};
193
194struct rum_def_mac {
195	uint32_t reg;
196	uint32_t val;
197};
198
199static const struct rum_def_mac rum_def_mac[] = {
200	{RT2573_TXRX_CSR0, 0x025fb032},
201	{RT2573_TXRX_CSR1, 0x9eaa9eaf},
202	{RT2573_TXRX_CSR2, 0x8a8b8c8d},
203	{RT2573_TXRX_CSR3, 0x00858687},
204	{RT2573_TXRX_CSR7, 0x2e31353b},
205	{RT2573_TXRX_CSR8, 0x2a2a2a2c},
206	{RT2573_TXRX_CSR15, 0x0000000f},
207	{RT2573_MAC_CSR6, 0x00000fff},
208	{RT2573_MAC_CSR8, 0x016c030a},
209	{RT2573_MAC_CSR10, 0x00000718},
210	{RT2573_MAC_CSR12, 0x00000004},
211	{RT2573_MAC_CSR13, 0x00007f00},
212	{RT2573_SEC_CSR0, 0x00000000},
213	{RT2573_SEC_CSR1, 0x00000000},
214	{RT2573_SEC_CSR5, 0x00000000},
215	{RT2573_PHY_CSR1, 0x000023b0},
216	{RT2573_PHY_CSR5, 0x00040a06},
217	{RT2573_PHY_CSR6, 0x00080606},
218	{RT2573_PHY_CSR7, 0x00000408},
219	{RT2573_AIFSN_CSR, 0x00002273},
220	{RT2573_CWMIN_CSR, 0x00002344},
221	{RT2573_CWMAX_CSR, 0x000034aa}
222};
223
224struct rum_def_bbp {
225	uint8_t	reg;
226	uint8_t	val;
227};
228
229static const struct rum_def_bbp rum_def_bbp[] = {
230	{3, 0x80},
231	{15, 0x30},
232	{17, 0x20},
233	{21, 0xc8},
234	{22, 0x38},
235	{23, 0x06},
236	{24, 0xfe},
237	{25, 0x0a},
238	{26, 0x0d},
239	{32, 0x0b},
240	{34, 0x12},
241	{37, 0x07},
242	{39, 0xf8},
243	{41, 0x60},
244	{53, 0x10},
245	{54, 0x18},
246	{60, 0x10},
247	{61, 0x04},
248	{62, 0x04},
249	{75, 0xfe},
250	{86, 0xfe},
251	{88, 0xfe},
252	{90, 0x0f},
253	{99, 0x00},
254	{102, 0x16},
255	{107, 0x04}
256};
257
258struct rfprog {
259	uint8_t	chan;
260	uint32_t r1, r2, r3, r4;
261};
262
263static const struct rfprog rum_rf5226[] = {
264	{1, 0x00b03, 0x001e1, 0x1a014, 0x30282},
265	{2, 0x00b03, 0x001e1, 0x1a014, 0x30287},
266	{3, 0x00b03, 0x001e2, 0x1a014, 0x30282},
267	{4, 0x00b03, 0x001e2, 0x1a014, 0x30287},
268	{5, 0x00b03, 0x001e3, 0x1a014, 0x30282},
269	{6, 0x00b03, 0x001e3, 0x1a014, 0x30287},
270	{7, 0x00b03, 0x001e4, 0x1a014, 0x30282},
271	{8, 0x00b03, 0x001e4, 0x1a014, 0x30287},
272	{9, 0x00b03, 0x001e5, 0x1a014, 0x30282},
273	{10, 0x00b03, 0x001e5, 0x1a014, 0x30287},
274	{11, 0x00b03, 0x001e6, 0x1a014, 0x30282},
275	{12, 0x00b03, 0x001e6, 0x1a014, 0x30287},
276	{13, 0x00b03, 0x001e7, 0x1a014, 0x30282},
277	{14, 0x00b03, 0x001e8, 0x1a014, 0x30284},
278
279	{34, 0x00b03, 0x20266, 0x36014, 0x30282},
280	{38, 0x00b03, 0x20267, 0x36014, 0x30284},
281	{42, 0x00b03, 0x20268, 0x36014, 0x30286},
282	{46, 0x00b03, 0x20269, 0x36014, 0x30288},
283
284	{36, 0x00b03, 0x00266, 0x26014, 0x30288},
285	{40, 0x00b03, 0x00268, 0x26014, 0x30280},
286	{44, 0x00b03, 0x00269, 0x26014, 0x30282},
287	{48, 0x00b03, 0x0026a, 0x26014, 0x30284},
288	{52, 0x00b03, 0x0026b, 0x26014, 0x30286},
289	{56, 0x00b03, 0x0026c, 0x26014, 0x30288},
290	{60, 0x00b03, 0x0026e, 0x26014, 0x30280},
291	{64, 0x00b03, 0x0026f, 0x26014, 0x30282},
292
293	{100, 0x00b03, 0x0028a, 0x2e014, 0x30280},
294	{104, 0x00b03, 0x0028b, 0x2e014, 0x30282},
295	{108, 0x00b03, 0x0028c, 0x2e014, 0x30284},
296	{112, 0x00b03, 0x0028d, 0x2e014, 0x30286},
297	{116, 0x00b03, 0x0028e, 0x2e014, 0x30288},
298	{120, 0x00b03, 0x002a0, 0x2e014, 0x30280},
299	{124, 0x00b03, 0x002a1, 0x2e014, 0x30282},
300	{128, 0x00b03, 0x002a2, 0x2e014, 0x30284},
301	{132, 0x00b03, 0x002a3, 0x2e014, 0x30286},
302	{136, 0x00b03, 0x002a4, 0x2e014, 0x30288},
303	{140, 0x00b03, 0x002a6, 0x2e014, 0x30280},
304
305	{149, 0x00b03, 0x002a8, 0x2e014, 0x30287},
306	{153, 0x00b03, 0x002a9, 0x2e014, 0x30289},
307	{157, 0x00b03, 0x002ab, 0x2e014, 0x30281},
308	{161, 0x00b03, 0x002ac, 0x2e014, 0x30283},
309	{165, 0x00b03, 0x002ad, 0x2e014, 0x30285}
310};
311
312static const struct rfprog 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	[0] = {
363		.type = UE_BULK,
364		.endpoint = UE_ADDR_ANY,
365		.direction = UE_DIR_OUT,
366		.mh.bufsize = (MCLBYTES + RT2573_TX_DESC_SIZE + 8),
367		.mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,},
368		.mh.callback = &rum_bulk_write_callback,
369		.mh.timeout = 5000,	/* ms */
370	},
371
372	[1] = {
373		.type = UE_BULK,
374		.endpoint = UE_ADDR_ANY,
375		.direction = UE_DIR_IN,
376		.mh.bufsize = (MCLBYTES + RT2573_RX_DESC_SIZE),
377		.mh.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
378		.mh.callback = &rum_bulk_read_callback,
379	},
380
381	[2] = {
382		.type = UE_CONTROL,
383		.endpoint = 0x00,	/* Control pipe */
384		.direction = UE_DIR_ANY,
385		.mh.bufsize = sizeof(struct usb2_device_request),
386		.mh.callback = &rum_bulk_write_clear_stall_callback,
387		.mh.timeout = 1000,	/* 1 second */
388		.mh.interval = 50,	/* 50ms */
389	},
390
391	[3] = {
392		.type = UE_CONTROL,
393		.endpoint = 0x00,	/* Control pipe */
394		.direction = UE_DIR_ANY,
395		.mh.bufsize = sizeof(struct usb2_device_request),
396		.mh.callback = &rum_bulk_read_clear_stall_callback,
397		.mh.timeout = 1000,	/* 1 second */
398		.mh.interval = 50,	/* 50ms */
399	},
400};
401
402static devclass_t rum_devclass;
403
404static device_method_t rum_methods[] = {
405	DEVMETHOD(device_probe, rum_probe),
406	DEVMETHOD(device_attach, rum_attach),
407	DEVMETHOD(device_detach, rum_detach),
408	{0, 0}
409};
410
411static driver_t rum_driver = {
412	.name = "rum",
413	.methods = rum_methods,
414	.size = sizeof(struct rum_softc),
415};
416
417DRIVER_MODULE(rum, ushub, rum_driver, rum_devclass, NULL, 0);
418MODULE_DEPEND(rum, usb2_wlan, 1, 1, 1);
419MODULE_DEPEND(rum, usb2_core, 1, 1, 1);
420MODULE_DEPEND(rum, wlan, 1, 1, 1);
421MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1);
422
423static int
424rum_probe(device_t dev)
425{
426	struct usb2_attach_arg *uaa = device_get_ivars(dev);
427
428	if (uaa->usb2_mode != USB_MODE_HOST) {
429		return (ENXIO);
430	}
431	if (uaa->info.bConfigIndex != 0) {
432		return (ENXIO);
433	}
434	if (uaa->info.bIfaceIndex != RT2573_IFACE_INDEX) {
435		return (ENXIO);
436	}
437	return (usb2_lookup_id_by_uaa(rum_devs, sizeof(rum_devs), uaa));
438}
439
440static int
441rum_attach(device_t dev)
442{
443	struct usb2_attach_arg *uaa = device_get_ivars(dev);
444	struct rum_softc *sc = device_get_softc(dev);
445	int error;
446	uint8_t iface_index;
447
448	if (sc == NULL) {
449		return (ENOMEM);
450	}
451	device_set_usb2_desc(dev);
452
453	mtx_init(&sc->sc_mtx, "rum lock", MTX_NETWORK_LOCK,
454	    MTX_DEF | MTX_RECURSE);
455
456	snprintf(sc->sc_name, sizeof(sc->sc_name), "%s",
457	    device_get_nameunit(dev));
458
459	sc->sc_udev = uaa->device;
460	sc->sc_unit = device_get_unit(dev);
461
462	usb2_callout_init_mtx(&sc->sc_watchdog,
463	    &sc->sc_mtx, CALLOUT_RETURNUNLOCKED);
464
465	iface_index = RT2573_IFACE_INDEX;
466	error = usb2_transfer_setup(uaa->device, &iface_index,
467	    sc->sc_xfer, rum_config, RUM_N_TRANSFER, sc, &sc->sc_mtx);
468	if (error) {
469		device_printf(dev, "could not allocate USB transfers, "
470		    "err=%s\n", usb2_errstr(error));
471		goto detach;
472	}
473	error = usb2_config_td_setup(&sc->sc_config_td, sc, &sc->sc_mtx,
474	    &rum_end_of_commands,
475	    sizeof(struct usb2_config_td_cc), 24);
476	if (error) {
477		device_printf(dev, "could not setup config "
478		    "thread!\n");
479		goto detach;
480	}
481	mtx_lock(&sc->sc_mtx);
482
483	/* start setup */
484
485	usb2_config_td_queue_command
486	    (&sc->sc_config_td, NULL, &rum_cfg_first_time_setup, 0, 0);
487
488	/* start watchdog (will exit mutex) */
489
490	rum_watchdog(sc);
491
492	return (0);			/* success */
493
494detach:
495	rum_detach(dev);
496	return (ENXIO);			/* failure */
497}
498
499static int
500rum_detach(device_t dev)
501{
502	struct rum_softc *sc = device_get_softc(dev);
503	struct ieee80211com *ic;
504	struct ifnet *ifp;
505
506	usb2_config_td_drain(&sc->sc_config_td);
507
508	mtx_lock(&sc->sc_mtx);
509
510	usb2_callout_stop(&sc->sc_watchdog);
511
512	rum_cfg_pre_stop(sc, NULL, 0);
513
514	ifp = sc->sc_ifp;
515	ic = ifp->if_l2com;
516
517	mtx_unlock(&sc->sc_mtx);
518
519	/* stop all USB transfers first */
520	usb2_transfer_unsetup(sc->sc_xfer, RUM_N_TRANSFER);
521
522	/* get rid of any late children */
523	bus_generic_detach(dev);
524
525	if (ifp) {
526		bpfdetach(ifp);
527		ieee80211_ifdetach(ic);
528		if_free(ifp);
529	}
530	usb2_config_td_unsetup(&sc->sc_config_td);
531
532	usb2_callout_drain(&sc->sc_watchdog);
533
534	mtx_destroy(&sc->sc_mtx);
535
536	return (0);
537}
538
539static void
540rum_cfg_do_request(struct rum_softc *sc, struct usb2_device_request *req,
541    void *data)
542{
543	uint16_t length;
544	usb2_error_t err;
545
546repeat:
547
548	if (usb2_config_td_is_gone(&sc->sc_config_td)) {
549		goto error;
550	}
551	err = usb2_do_request_flags
552	    (sc->sc_udev, &sc->sc_mtx, req, data, 0, NULL, 1000);
553
554	if (err) {
555
556		DPRINTF("device request failed, err=%s "
557		    "(ignored)\n", usb2_errstr(err));
558
559		/* wait a little before next try */
560		if (usb2_config_td_sleep(&sc->sc_config_td, hz / 4)) {
561			goto error;
562		}
563		/* try until we are detached */
564		goto repeat;
565
566error:
567		/* the device has been detached */
568		length = UGETW(req->wLength);
569
570		if ((req->bmRequestType & UT_READ) && length) {
571			bzero(data, length);
572		}
573	}
574	return;
575}
576
577static void
578rum_cfg_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, uint16_t len)
579{
580	struct usb2_device_request req;
581
582	req.bmRequestType = UT_READ_VENDOR_DEVICE;
583	req.bRequest = RT2573_READ_EEPROM;
584	USETW(req.wValue, 0);
585	USETW(req.wIndex, addr);
586	USETW(req.wLength, len);
587
588	rum_cfg_do_request(sc, &req, buf);
589	return;
590}
591
592static uint16_t
593rum_cfg_eeprom_read_2(struct rum_softc *sc, uint16_t addr)
594{
595	uint16_t tmp;
596
597	rum_cfg_eeprom_read(sc, addr, &tmp, sizeof(tmp));
598	return (le16toh(tmp));
599}
600
601static uint32_t
602rum_cfg_read(struct rum_softc *sc, uint16_t reg)
603{
604	uint32_t val;
605
606	rum_cfg_read_multi(sc, reg, &val, sizeof(val));
607	return (le32toh(val));
608}
609
610static void
611rum_cfg_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len)
612{
613	struct usb2_device_request req;
614
615	req.bmRequestType = UT_READ_VENDOR_DEVICE;
616	req.bRequest = RT2573_READ_MULTI_MAC;
617	USETW(req.wValue, 0);
618	USETW(req.wIndex, reg);
619	USETW(req.wLength, len);
620
621	rum_cfg_do_request(sc, &req, buf);
622	return;
623}
624
625static void
626rum_cfg_write(struct rum_softc *sc, uint16_t reg, uint32_t val)
627{
628	uint32_t tmp = htole32(val);
629
630	rum_cfg_write_multi(sc, reg, &tmp, sizeof(tmp));
631	return;
632}
633
634static void
635rum_cfg_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, uint16_t len)
636{
637	struct usb2_device_request req;
638
639	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
640	req.bRequest = RT2573_WRITE_MULTI_MAC;
641	USETW(req.wValue, 0);
642	USETW(req.wIndex, reg);
643	USETW(req.wLength, len);
644
645	rum_cfg_do_request(sc, &req, buf);
646	return;
647}
648
649static uint32_t
650rum_cfg_bbp_disbusy(struct rum_softc *sc)
651{
652	uint32_t tmp;
653	uint8_t to;
654
655	for (to = 0;; to++) {
656		if (to < 100) {
657			tmp = rum_cfg_read(sc, RT2573_PHY_CSR3);
658
659			if ((tmp & RT2573_BBP_BUSY) == 0) {
660				return (tmp);
661			}
662			if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
663				break;
664			}
665		} else {
666			break;
667		}
668	}
669	DPRINTF("could not disbusy BBP\n");
670	return (RT2573_BBP_BUSY);	/* failure */
671}
672
673static void
674rum_cfg_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val)
675{
676	uint32_t tmp;
677
678	if (rum_cfg_bbp_disbusy(sc) & RT2573_BBP_BUSY) {
679		return;
680	}
681	tmp = RT2573_BBP_BUSY | ((reg & 0x7f) << 8) | val;
682	rum_cfg_write(sc, RT2573_PHY_CSR3, tmp);
683	return;
684}
685
686static uint8_t
687rum_cfg_bbp_read(struct rum_softc *sc, uint8_t reg)
688{
689	uint32_t val;
690
691	if (rum_cfg_bbp_disbusy(sc) & RT2573_BBP_BUSY) {
692		return (0);
693	}
694	val = RT2573_BBP_BUSY | RT2573_BBP_READ | (reg << 8);
695	rum_cfg_write(sc, RT2573_PHY_CSR3, val);
696
697	val = rum_cfg_bbp_disbusy(sc);
698	return (val & 0xff);
699}
700
701static void
702rum_cfg_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val)
703{
704	uint32_t tmp;
705	uint8_t to;
706
707	reg &= 3;
708
709	for (to = 0;; to++) {
710		if (to < 100) {
711			tmp = rum_cfg_read(sc, RT2573_PHY_CSR4);
712			if (!(tmp & RT2573_RF_BUSY)) {
713				break;
714			}
715			if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
716				return;
717			}
718		} else {
719			DPRINTF("could not write to RF\n");
720			return;
721		}
722	}
723
724	tmp = RT2573_RF_BUSY | RT2573_RF_20BIT | ((val & 0xfffff) << 2) | reg;
725	rum_cfg_write(sc, RT2573_PHY_CSR4, tmp);
726
727	DPRINTFN(16, "RF R[%u] <- 0x%05x\n", reg, val & 0xfffff);
728	return;
729}
730
731static void
732rum_cfg_first_time_setup(struct rum_softc *sc,
733    struct usb2_config_td_cc *cc, uint16_t refcount)
734{
735	struct ieee80211com *ic;
736	struct ifnet *ifp;
737	uint32_t tmp;
738	uint16_t i;
739	uint8_t bands;
740
741	/* setup RX tap header */
742	sc->sc_rxtap_len = sizeof(sc->sc_rxtap);
743	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
744	sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT);
745
746	/* setup TX tap header */
747	sc->sc_txtap_len = sizeof(sc->sc_txtap);
748	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
749	sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT);
750
751	/* retrieve RT2573 rev. no */
752	for (i = 0; i < 100; i++) {
753
754		tmp = rum_cfg_read(sc, RT2573_MAC_CSR0);
755		if (tmp != 0) {
756			break;
757		}
758		/* wait a little */
759		if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
760			/* device detached */
761			goto done;
762		}
763	}
764
765	if (tmp == 0) {
766		DPRINTF("chip is maybe not ready\n");
767	}
768	/* retrieve MAC address and various other things from EEPROM */
769	rum_cfg_read_eeprom(sc);
770
771	printf("%s: MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
772	    sc->sc_name, tmp, rum_get_rf(sc->sc_rf_rev));
773
774	rum_cfg_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode));
775
776	mtx_unlock(&sc->sc_mtx);
777
778	ifp = if_alloc(IFT_IEEE80211);
779
780	mtx_lock(&sc->sc_mtx);
781
782	if (ifp == NULL) {
783		DPRINTFN(0, "could not if_alloc()!\n");
784		goto done;
785	}
786	sc->sc_evilhack = ifp;
787	sc->sc_ifp = ifp;
788	ic = ifp->if_l2com;
789
790	ifp->if_softc = sc;
791	if_initname(ifp, "rum", sc->sc_unit);
792	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
793	ifp->if_init = &rum_init_cb;
794	ifp->if_ioctl = &rum_ioctl_cb;
795	ifp->if_start = &rum_start_cb;
796	ifp->if_watchdog = NULL;
797	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
798	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
799	IFQ_SET_READY(&ifp->if_snd);
800
801	bcopy(sc->sc_myaddr, ic->ic_myaddr, sizeof(ic->ic_myaddr));
802
803	ic->ic_ifp = ifp;
804	ic->ic_phytype = IEEE80211_T_OFDM;	/* not only, but not used */
805	ic->ic_opmode = IEEE80211_M_STA;
806
807	/* set device capabilities */
808	ic->ic_caps =
809	    IEEE80211_C_STA		/* station mode supported */
810	    | IEEE80211_C_IBSS		/* IBSS mode supported */
811	    | IEEE80211_C_MONITOR	/* monitor mode supported */
812	    | IEEE80211_C_HOSTAP	/* HostAp mode supported */
813	    | IEEE80211_C_TXPMGT	/* tx power management */
814	    | IEEE80211_C_SHPREAMBLE	/* short preamble supported */
815	    | IEEE80211_C_SHSLOT	/* short slot time supported */
816	    | IEEE80211_C_BGSCAN	/* bg scanning supported */
817	    | IEEE80211_C_WPA		/* 802.11i */
818	    ;
819
820	bands = 0;
821	setbit(&bands, IEEE80211_MODE_11B);
822	setbit(&bands, IEEE80211_MODE_11G);
823	ieee80211_init_channels(ic, NULL, &bands);
824
825	if ((sc->sc_rf_rev == RT2573_RF_5225) ||
826	    (sc->sc_rf_rev == RT2573_RF_5226)) {
827
828		struct ieee80211_channel *c;
829
830		/* set supported .11a channels */
831		for (i = 34; i <= 46; i += 4) {
832			c = ic->ic_channels + (ic->ic_nchans++);
833			c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
834			c->ic_flags = IEEE80211_CHAN_A;
835			c->ic_ieee = i;
836		}
837		for (i = 36; i <= 64; i += 4) {
838			c = ic->ic_channels + (ic->ic_nchans++);
839			c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
840			c->ic_flags = IEEE80211_CHAN_A;
841			c->ic_ieee = i;
842		}
843		for (i = 100; i <= 140; i += 4) {
844			c = ic->ic_channels + (ic->ic_nchans++);
845			c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
846			c->ic_flags = IEEE80211_CHAN_A;
847			c->ic_ieee = i;
848		}
849		for (i = 149; i <= 165; i += 4) {
850			c = ic->ic_channels + (ic->ic_nchans++);
851			c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ);
852			c->ic_flags = IEEE80211_CHAN_A;
853			c->ic_ieee = i;
854		}
855	}
856	mtx_unlock(&sc->sc_mtx);
857
858	ieee80211_ifattach(ic);
859
860	mtx_lock(&sc->sc_mtx);
861
862	ic->ic_newassoc = &rum_newassoc;
863	ic->ic_raw_xmit = &rum_raw_xmit_cb;
864	ic->ic_node_alloc = &rum_node_alloc;
865	ic->ic_update_mcast = &rum_update_mcast_cb;
866	ic->ic_update_promisc = &rum_update_promisc_cb;
867	ic->ic_scan_start = &rum_scan_start_cb;
868	ic->ic_scan_end = &rum_scan_end_cb;
869	ic->ic_set_channel = &rum_set_channel_cb;
870	ic->ic_vap_create = &rum_vap_create;
871	ic->ic_vap_delete = &rum_vap_delete;
872
873	sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
874
875	mtx_unlock(&sc->sc_mtx);
876
877	bpfattach(ifp, DLT_IEEE802_11_RADIO,
878	    sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap));
879
880	if (bootverbose) {
881		ieee80211_announce(ic);
882	}
883	mtx_lock(&sc->sc_mtx);
884done:
885	return;
886}
887
888static void
889rum_end_of_commands(struct rum_softc *sc)
890{
891	sc->sc_flags &= ~RUM_FLAG_WAIT_COMMAND;
892
893	/* start write transfer, if not started */
894	usb2_transfer_start(sc->sc_xfer[0]);
895	return;
896}
897
898static void
899rum_config_copy_chan(struct rum_config_copy_chan *cc,
900    struct ieee80211com *ic, struct ieee80211_channel *c)
901{
902	if (!c)
903		return;
904	cc->chan_to_ieee =
905	    ieee80211_chan2ieee(ic, c);
906	if (c != IEEE80211_CHAN_ANYC) {
907		cc->chan_to_mode =
908		    ieee80211_chan2mode(c);
909		if (IEEE80211_IS_CHAN_B(c))
910			cc->chan_is_b = 1;
911		if (IEEE80211_IS_CHAN_A(c))
912			cc->chan_is_a = 1;
913		if (IEEE80211_IS_CHAN_2GHZ(c))
914			cc->chan_is_2ghz = 1;
915		if (IEEE80211_IS_CHAN_5GHZ(c))
916			cc->chan_is_5ghz = 1;
917		if (IEEE80211_IS_CHAN_ANYG(c))
918			cc->chan_is_g = 1;
919	}
920	return;
921}
922
923static void
924rum_config_copy(struct rum_softc *sc,
925    struct usb2_config_td_cc *cc, uint16_t refcount)
926{
927	struct ifnet *ifp;
928	struct ieee80211com *ic;
929	struct ieee80211_node *ni;
930	struct ieee80211vap *vap;
931	const struct ieee80211_txparam *tp;
932
933	bzero(cc, sizeof(*cc));
934
935	ifp = sc->sc_ifp;
936	if (ifp) {
937		cc->if_flags = ifp->if_flags;
938		bcopy(ifp->if_broadcastaddr, cc->if_broadcastaddr,
939		    sizeof(cc->if_broadcastaddr));
940
941		ic = ifp->if_l2com;
942		if (ic) {
943			rum_config_copy_chan(&cc->ic_curchan, ic, ic->ic_curchan);
944			rum_config_copy_chan(&cc->ic_bsschan, ic, ic->ic_bsschan);
945			vap = TAILQ_FIRST(&ic->ic_vaps);
946			if (vap) {
947				ni = vap->iv_bss;
948				if (ni) {
949					cc->iv_bss.ni_intval = ni->ni_intval;
950					bcopy(ni->ni_bssid, cc->iv_bss.ni_bssid,
951					    sizeof(cc->iv_bss.ni_bssid));
952				}
953				tp = vap->iv_txparms + cc->ic_bsschan.chan_to_mode;
954				if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) {
955					cc->iv_bss.fixed_rate_none = 1;
956				}
957			}
958			cc->ic_opmode = ic->ic_opmode;
959			cc->ic_flags = ic->ic_flags;
960			cc->ic_txpowlimit = ic->ic_txpowlimit;
961			cc->ic_curmode = ic->ic_curmode;
962
963			bcopy(ic->ic_myaddr, cc->ic_myaddr,
964			    sizeof(cc->ic_myaddr));
965		}
966	}
967	sc->sc_flags |= RUM_FLAG_WAIT_COMMAND;
968	return;
969}
970
971static const char *
972rum_get_rf(uint32_t rev)
973{
974	;				/* indent fix */
975	switch (rev) {
976	case RT2573_RF_2527:
977		return "RT2527 (MIMO XR)";
978	case RT2573_RF_2528:
979		return "RT2528";
980	case RT2573_RF_5225:
981		return "RT5225 (MIMO XR)";
982	case RT2573_RF_5226:
983		return "RT5226";
984	default:
985		return "unknown";
986	}
987}
988
989static void
990rum_bulk_read_callback(struct usb2_xfer *xfer)
991{
992	struct rum_softc *sc = xfer->priv_sc;
993	struct ifnet *ifp = sc->sc_ifp;
994	struct ieee80211com *ic = ifp->if_l2com;
995	struct ieee80211_node *ni;
996
997	struct mbuf *m = NULL;
998	uint32_t flags;
999	uint32_t max_len;
1000	uint8_t rssi = 0;
1001
1002	switch (USB_GET_STATE(xfer)) {
1003	case USB_ST_TRANSFERRED:
1004
1005		DPRINTFN(15, "rx done, actlen=%d\n", xfer->actlen);
1006
1007		if (xfer->actlen < (RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
1008			DPRINTF("too short transfer, "
1009			    "%d bytes\n", xfer->actlen);
1010			ifp->if_ierrors++;
1011			goto tr_setup;
1012		}
1013		usb2_copy_out(xfer->frbuffers, 0,
1014		    &sc->sc_rx_desc, RT2573_RX_DESC_SIZE);
1015
1016		flags = le32toh(sc->sc_rx_desc.flags);
1017
1018		if (flags & RT2573_RX_CRC_ERROR) {
1019			/*
1020		         * This should not happen since we did not
1021		         * request to receive those frames when we
1022		         * filled RAL_TXRX_CSR2:
1023		         */
1024			DPRINTFN(6, "PHY or CRC error\n");
1025			ifp->if_ierrors++;
1026			goto tr_setup;
1027		}
1028		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
1029
1030		if (m == NULL) {
1031			DPRINTF("could not allocate mbuf\n");
1032			ifp->if_ierrors++;
1033			goto tr_setup;
1034		}
1035		max_len = (xfer->actlen - RT2573_RX_DESC_SIZE);
1036
1037		usb2_copy_out(xfer->frbuffers, RT2573_RX_DESC_SIZE,
1038		    m->m_data, max_len);
1039
1040		/* finalize mbuf */
1041		m->m_pkthdr.rcvif = ifp;
1042		m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
1043
1044		if (m->m_len > max_len) {
1045			DPRINTF("invalid length in RX "
1046			    "descriptor, %u bytes, received %u bytes\n",
1047			    m->m_len, max_len);
1048			ifp->if_ierrors++;
1049			m_freem(m);
1050			m = NULL;
1051			goto tr_setup;
1052		}
1053		rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
1054
1055		DPRINTF("real length=%d bytes, rssi=%d\n", m->m_len, rssi);
1056
1057		if (bpf_peers_present(ifp->if_bpf)) {
1058			struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
1059
1060			tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
1061			tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate,
1062			    (sc->sc_rx_desc.flags & htole32(RT2573_RX_OFDM)) ?
1063			    IEEE80211_T_OFDM : IEEE80211_T_CCK);
1064			tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
1065			tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
1066			tap->wr_antenna = sc->sc_rx_ant;
1067			tap->wr_antsignal = rssi;
1068
1069			bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m);
1070		}
1071	case USB_ST_SETUP:
1072tr_setup:
1073
1074		if (sc->sc_flags & RUM_FLAG_READ_STALL) {
1075			usb2_transfer_start(sc->sc_xfer[3]);
1076		} else {
1077			xfer->frlengths[0] = xfer->max_data_length;
1078			usb2_start_hardware(xfer);
1079		}
1080
1081		/*
1082		 * At the end of a USB callback it is always safe to unlock
1083		 * the private mutex of a device! That is why we do the
1084		 * "ieee80211_input" here, and not some lines up!
1085		 */
1086		if (m) {
1087			mtx_unlock(&sc->sc_mtx);
1088
1089			ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *));
1090			if (ni != NULL) {
1091				if (ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR, 0)) {
1092					/* ignore */
1093				}
1094				/* node is no longer needed */
1095				ieee80211_free_node(ni);
1096			} else {
1097				if (ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR, 0)) {
1098					/* ignore */
1099				}
1100			}
1101
1102			mtx_lock(&sc->sc_mtx);
1103		}
1104		return;
1105
1106	default:			/* Error */
1107		if (xfer->error != USB_ERR_CANCELLED) {
1108			/* try to clear stall first */
1109			sc->sc_flags |= RUM_FLAG_READ_STALL;
1110			usb2_transfer_start(sc->sc_xfer[3]);
1111		}
1112		return;
1113
1114	}
1115}
1116
1117static void
1118rum_bulk_read_clear_stall_callback(struct usb2_xfer *xfer)
1119{
1120	struct rum_softc *sc = xfer->priv_sc;
1121	struct usb2_xfer *xfer_other = sc->sc_xfer[1];
1122
1123	if (usb2_clear_stall_callback(xfer, xfer_other)) {
1124		DPRINTF("stall cleared\n");
1125		sc->sc_flags &= ~RUM_FLAG_READ_STALL;
1126		usb2_transfer_start(xfer_other);
1127	}
1128	return;
1129}
1130
1131static uint8_t
1132rum_plcp_signal(uint16_t rate)
1133{
1134	;				/* indent fix */
1135	switch (rate) {
1136		/* CCK rates (NB: not IEEE std, device-specific) */
1137	case 2:
1138		return (0x0);
1139	case 4:
1140		return (0x1);
1141	case 11:
1142		return (0x2);
1143	case 22:
1144		return (0x3);
1145
1146		/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
1147	case 12:
1148		return (0xb);
1149	case 18:
1150		return (0xf);
1151	case 24:
1152		return (0xa);
1153	case 36:
1154		return (0xe);
1155	case 48:
1156		return (0x9);
1157	case 72:
1158		return (0xd);
1159	case 96:
1160		return (0x8);
1161	case 108:
1162		return (0xc);
1163
1164		/* XXX unsupported/unknown rate */
1165	default:
1166		return (0xff);
1167	}
1168}
1169
1170/*
1171 * We assume that "m->m_pkthdr.rcvif" is pointing to the "ni" that
1172 * should be freed, when "rum_setup_desc_and_tx" is called.
1173 */
1174
1175static void
1176rum_setup_desc_and_tx(struct rum_softc *sc, struct mbuf *m, uint32_t flags,
1177    uint16_t xflags, uint16_t rate)
1178{
1179	struct ifnet *ifp = sc->sc_ifp;
1180	struct ieee80211com *ic = ifp->if_l2com;
1181	struct mbuf *mm;
1182	enum ieee80211_phytype phytype;
1183	uint16_t plcp_length;
1184	uint16_t len;
1185	uint8_t remainder;
1186	uint8_t is_beacon;
1187
1188	if (xflags & RT2573_TX_BEACON) {
1189		xflags &= ~RT2573_TX_BEACON;
1190		is_beacon = 1;
1191	} else {
1192		is_beacon = 0;
1193	}
1194
1195	if (sc->sc_tx_queue.ifq_len >= IFQ_MAXLEN) {
1196		/* free packet */
1197		rum_tx_freem(m);
1198		ifp->if_oerrors++;
1199		return;
1200	}
1201	if (!((sc->sc_flags & RUM_FLAG_LL_READY) &&
1202	    (sc->sc_flags & RUM_FLAG_HL_READY))) {
1203		/* free packet */
1204		rum_tx_freem(m);
1205		ifp->if_oerrors++;
1206		return;
1207	}
1208	if (rate < 2) {
1209		DPRINTF("rate < 2!\n");
1210
1211		/* avoid division by zero */
1212		rate = 2;
1213	}
1214	ic->ic_lastdata = ticks;
1215	if (bpf_peers_present(ifp->if_bpf)) {
1216		struct rum_tx_radiotap_header *tap = &sc->sc_txtap;
1217
1218		tap->wt_flags = 0;
1219		tap->wt_rate = rate;
1220		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
1221		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
1222		tap->wt_antenna = sc->sc_tx_ant;
1223
1224		bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m);
1225	}
1226	len = m->m_pkthdr.len;
1227
1228	flags |= RT2573_TX_VALID;
1229	flags |= (len << 16);
1230
1231	sc->sc_tx_desc.flags = htole32(flags);
1232	sc->sc_tx_desc.xflags = htole16(xflags);
1233
1234	sc->sc_tx_desc.wme = htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
1235	    RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
1236
1237	/* setup PLCP fields */
1238	sc->sc_tx_desc.plcp_signal = rum_plcp_signal(rate);
1239	sc->sc_tx_desc.plcp_service = 4;
1240
1241	len += IEEE80211_CRC_LEN;
1242
1243	phytype = ieee80211_rate2phytype(sc->sc_rates, rate);
1244
1245	if (phytype == IEEE80211_T_OFDM) {
1246		sc->sc_tx_desc.flags |= htole32(RT2573_TX_OFDM);
1247
1248		plcp_length = (len & 0xfff);
1249		sc->sc_tx_desc.plcp_length_hi = plcp_length >> 6;
1250		sc->sc_tx_desc.plcp_length_lo = plcp_length & 0x3f;
1251	} else {
1252		plcp_length = ((16 * len) + rate - 1) / rate;
1253		if (rate == 22) {
1254			remainder = (16 * len) % 22;
1255			if ((remainder != 0) && (remainder < 7)) {
1256				sc->sc_tx_desc.plcp_service |=
1257				    RT2573_PLCP_LENGEXT;
1258			}
1259		}
1260		sc->sc_tx_desc.plcp_length_hi = plcp_length >> 8;
1261		sc->sc_tx_desc.plcp_length_lo = plcp_length & 0xff;
1262
1263		if ((rate != 2) && (ic->ic_flags & IEEE80211_F_SHPREAMBLE)) {
1264			sc->sc_tx_desc.plcp_signal |= 0x08;
1265		}
1266	}
1267
1268	if (sizeof(sc->sc_tx_desc) > MHLEN) {
1269		DPRINTF("No room for header structure!\n");
1270		rum_tx_freem(m);
1271		return;
1272	}
1273	mm = m_gethdr(M_NOWAIT, MT_DATA);
1274	if (mm == NULL) {
1275		DPRINTF("Could not allocate header mbuf!\n");
1276		rum_tx_freem(m);
1277		return;
1278	}
1279	bcopy(&sc->sc_tx_desc, mm->m_data, sizeof(sc->sc_tx_desc));
1280	mm->m_len = sizeof(sc->sc_tx_desc);
1281	mm->m_next = m;
1282	mm->m_pkthdr.len = mm->m_len + m->m_pkthdr.len;
1283	mm->m_pkthdr.rcvif = NULL;
1284
1285	if (is_beacon) {
1286
1287		if (mm->m_pkthdr.len > sizeof(sc->sc_beacon_buf)) {
1288			DPRINTFN(0, "Truncating beacon"
1289			    ", %u bytes!\n", mm->m_pkthdr.len);
1290			mm->m_pkthdr.len = sizeof(sc->sc_beacon_buf);
1291		}
1292		m_copydata(mm, 0, mm->m_pkthdr.len, sc->sc_beacon_buf);
1293
1294		/* copy the first 24 bytes of Tx descriptor into NIC memory */
1295		rum_cfg_write_multi(sc, RT2573_HW_BEACON_BASE0,
1296		    sc->sc_beacon_buf, mm->m_pkthdr.len);
1297		rum_tx_freem(mm);
1298		return;
1299	}
1300	/* start write transfer, if not started */
1301	_IF_ENQUEUE(&sc->sc_tx_queue, mm);
1302
1303	usb2_transfer_start(sc->sc_xfer[0]);
1304	return;
1305}
1306
1307static void
1308rum_bulk_write_callback(struct usb2_xfer *xfer)
1309{
1310	struct rum_softc *sc = xfer->priv_sc;
1311	struct ifnet *ifp = sc->sc_ifp;
1312	struct mbuf *m;
1313	uint16_t temp_len;
1314	uint8_t align;
1315
1316	switch (USB_GET_STATE(xfer)) {
1317	case USB_ST_TRANSFERRED:
1318		DPRINTFN(11, "transfer complete\n");
1319
1320		ifp->if_opackets++;
1321
1322	case USB_ST_SETUP:
1323		if (sc->sc_flags & RUM_FLAG_WRITE_STALL) {
1324			usb2_transfer_start(sc->sc_xfer[2]);
1325			break;
1326		}
1327		if (sc->sc_flags & RUM_FLAG_WAIT_COMMAND) {
1328			/*
1329			 * don't send anything while a command is pending !
1330			 */
1331			break;
1332		}
1333		rum_fill_write_queue(sc);
1334
1335		_IF_DEQUEUE(&sc->sc_tx_queue, m);
1336
1337		if (m) {
1338
1339			if (m->m_pkthdr.len > (MCLBYTES + RT2573_TX_DESC_SIZE)) {
1340				DPRINTFN(0, "data overflow, %u bytes\n",
1341				    m->m_pkthdr.len);
1342				m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE);
1343			}
1344			usb2_m_copy_in(xfer->frbuffers, 0,
1345			    m, 0, m->m_pkthdr.len);
1346
1347			/* compute transfer length */
1348			temp_len = m->m_pkthdr.len;
1349
1350			/* make transfer length 32-bit aligned */
1351			align = (-(temp_len)) & 3;
1352
1353			/* check if we need to add four extra bytes */
1354			if (((temp_len + align) % 64) == 0) {
1355				align += 4;
1356			}
1357			/* check if we need to align length */
1358			if (align != 0) {
1359				/* zero the extra bytes */
1360				usb2_bzero(xfer->frbuffers, temp_len, align);
1361				temp_len += align;
1362			}
1363			DPRINTFN(11, "sending frame len=%u ferlen=%u\n",
1364			    m->m_pkthdr.len, temp_len);
1365
1366			xfer->frlengths[0] = temp_len;
1367			usb2_start_hardware(xfer);
1368
1369			/* free mbuf and node */
1370			rum_tx_freem(m);
1371
1372		}
1373		break;
1374
1375	default:			/* Error */
1376		DPRINTFN(11, "transfer error, %s\n",
1377		    usb2_errstr(xfer->error));
1378
1379		if (xfer->error != USB_ERR_CANCELLED) {
1380			/* try to clear stall first */
1381			sc->sc_flags |= RUM_FLAG_WRITE_STALL;
1382			usb2_transfer_start(sc->sc_xfer[2]);
1383		}
1384		ifp->if_oerrors++;
1385		break;
1386	}
1387	return;
1388}
1389
1390static void
1391rum_bulk_write_clear_stall_callback(struct usb2_xfer *xfer)
1392{
1393	struct rum_softc *sc = xfer->priv_sc;
1394	struct usb2_xfer *xfer_other = sc->sc_xfer[0];
1395
1396	if (usb2_clear_stall_callback(xfer, xfer_other)) {
1397		DPRINTF("stall cleared\n");
1398		sc->sc_flags &= ~RUM_FLAG_WRITE_STALL;
1399		usb2_transfer_start(xfer_other);
1400	}
1401	return;
1402}
1403
1404static void
1405rum_watchdog(void *arg)
1406{
1407	struct rum_softc *sc = arg;
1408
1409	mtx_assert(&sc->sc_mtx, MA_OWNED);
1410
1411	if (sc->sc_amrr_timer) {
1412		usb2_config_td_queue_command
1413		    (&sc->sc_config_td, NULL,
1414		    &rum_cfg_amrr_timeout, 0, 0);
1415	}
1416	usb2_callout_reset(&sc->sc_watchdog,
1417	    hz, &rum_watchdog, sc);
1418
1419	mtx_unlock(&sc->sc_mtx);
1420
1421	return;
1422}
1423
1424static void
1425rum_init_cb(void *arg)
1426{
1427	struct rum_softc *sc = arg;
1428
1429	mtx_lock(&sc->sc_mtx);
1430	usb2_config_td_queue_command
1431	    (&sc->sc_config_td, &rum_cfg_pre_init,
1432	    &rum_cfg_init, 0, 0);
1433	mtx_unlock(&sc->sc_mtx);
1434
1435	return;
1436}
1437
1438static int
1439rum_ioctl_cb(struct ifnet *ifp, u_long cmd, caddr_t data)
1440{
1441	struct rum_softc *sc = ifp->if_softc;
1442	struct ieee80211com *ic = ifp->if_l2com;
1443	int error;
1444
1445	switch (cmd) {
1446	case SIOCSIFFLAGS:
1447		mtx_lock(&sc->sc_mtx);
1448		if (ifp->if_flags & IFF_UP) {
1449			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
1450				usb2_config_td_queue_command
1451				    (&sc->sc_config_td, &rum_cfg_pre_init,
1452				    &rum_cfg_init, 0, 0);
1453			}
1454		} else {
1455			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1456				usb2_config_td_queue_command
1457				    (&sc->sc_config_td, &rum_cfg_pre_stop,
1458				    &rum_cfg_stop, 0, 0);
1459			}
1460		}
1461		mtx_unlock(&sc->sc_mtx);
1462		error = 0;
1463		break;
1464
1465	case SIOCGIFMEDIA:
1466	case SIOCSIFMEDIA:
1467		error = ifmedia_ioctl(ifp, (void *)data, &ic->ic_media, cmd);
1468		break;
1469
1470	default:
1471		error = ether_ioctl(ifp, cmd, data);
1472	}
1473	return (error);
1474}
1475
1476static void
1477rum_start_cb(struct ifnet *ifp)
1478{
1479	struct rum_softc *sc = ifp->if_softc;
1480
1481	mtx_lock(&sc->sc_mtx);
1482	/* start write transfer, if not started */
1483	usb2_transfer_start(sc->sc_xfer[0]);
1484	mtx_unlock(&sc->sc_mtx);
1485
1486	return;
1487}
1488
1489static void
1490rum_cfg_newstate(struct rum_softc *sc,
1491    struct usb2_config_td_cc *cc, uint16_t refcount)
1492{
1493	struct ifnet *ifp = sc->sc_ifp;
1494	struct ieee80211com *ic = ifp->if_l2com;
1495	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);
1496	struct rum_vap *uvp = RUM_VAP(vap);
1497	enum ieee80211_state ostate;
1498	enum ieee80211_state nstate;
1499	int arg;
1500
1501	ostate = vap->iv_state;
1502	nstate = sc->sc_ns_state;
1503	arg = sc->sc_ns_arg;
1504
1505	if (ostate == IEEE80211_S_INIT) {
1506		/* We are leaving INIT. TSF sync should be off. */
1507		rum_cfg_disable_tsf_sync(sc);
1508	}
1509	switch (nstate) {
1510	case IEEE80211_S_INIT:
1511		break;
1512
1513	case IEEE80211_S_RUN:
1514		rum_cfg_set_run(sc, cc);
1515		break;
1516
1517	default:
1518		break;
1519	}
1520
1521	mtx_unlock(&sc->sc_mtx);
1522	IEEE80211_LOCK(ic);
1523	uvp->newstate(vap, nstate, arg);
1524	if (vap->iv_newstate_cb != NULL)
1525		vap->iv_newstate_cb(vap, nstate, arg);
1526	IEEE80211_UNLOCK(ic);
1527	mtx_lock(&sc->sc_mtx);
1528	return;
1529}
1530
1531static int
1532rum_newstate_cb(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1533{
1534	struct rum_vap *uvp = RUM_VAP(vap);
1535	struct ieee80211com *ic = vap->iv_ic;
1536	struct rum_softc *sc = ic->ic_ifp->if_softc;
1537
1538	DPRINTF("setting new state: %d\n", nstate);
1539
1540	/* Special case - cannot defer this call and cannot block ! */
1541	if (nstate == IEEE80211_S_INIT) {
1542		/* stop timers */
1543		mtx_lock(&sc->sc_mtx);
1544		sc->sc_amrr_timer = 0;
1545		mtx_unlock(&sc->sc_mtx);
1546		return (uvp->newstate(vap, nstate, arg));
1547	}
1548	mtx_lock(&sc->sc_mtx);
1549	if (usb2_config_td_is_gone(&sc->sc_config_td)) {
1550		mtx_unlock(&sc->sc_mtx);
1551		return (0);		/* nothing to do */
1552	}
1553	/* store next state */
1554	sc->sc_ns_state = nstate;
1555	sc->sc_ns_arg = arg;
1556
1557	/* stop timers */
1558	sc->sc_amrr_timer = 0;
1559
1560	/*
1561	 * USB configuration can only be done from the USB configuration
1562	 * thread:
1563	 */
1564	usb2_config_td_queue_command
1565	    (&sc->sc_config_td, &rum_config_copy,
1566	    &rum_cfg_newstate, 0, 0);
1567
1568	mtx_unlock(&sc->sc_mtx);
1569
1570	return (EINPROGRESS);
1571}
1572
1573static void
1574rum_std_command(struct ieee80211com *ic, usb2_config_td_command_t *func)
1575{
1576	struct rum_softc *sc = ic->ic_ifp->if_softc;
1577
1578	mtx_lock(&sc->sc_mtx);
1579
1580	sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
1581
1582	usb2_config_td_queue_command
1583	    (&sc->sc_config_td, &rum_config_copy, func, 0, 0);
1584
1585	mtx_unlock(&sc->sc_mtx);
1586
1587	return;
1588}
1589
1590static void
1591rum_scan_start_cb(struct ieee80211com *ic)
1592{
1593	rum_std_command(ic, &rum_cfg_scan_start);
1594	return;
1595}
1596
1597static void
1598rum_scan_end_cb(struct ieee80211com *ic)
1599{
1600	rum_std_command(ic, &rum_cfg_scan_end);
1601	return;
1602}
1603
1604static void
1605rum_set_channel_cb(struct ieee80211com *ic)
1606{
1607	rum_std_command(ic, &rum_cfg_set_chan);
1608	return;
1609}
1610
1611static void
1612rum_cfg_scan_start(struct rum_softc *sc,
1613    struct usb2_config_td_cc *cc, uint16_t refcount)
1614{
1615	/* abort TSF synchronization */
1616	rum_cfg_disable_tsf_sync(sc);
1617	rum_cfg_set_bssid(sc, cc->if_broadcastaddr);
1618	return;
1619}
1620
1621static void
1622rum_cfg_scan_end(struct rum_softc *sc,
1623    struct usb2_config_td_cc *cc, uint16_t refcount)
1624{
1625	/* enable TSF synchronization */
1626	rum_cfg_enable_tsf_sync(sc, cc, 0);
1627	rum_cfg_set_bssid(sc, cc->iv_bss.ni_bssid);
1628	return;
1629}
1630
1631/*
1632 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
1633 * driver.
1634 */
1635static void
1636rum_cfg_select_band(struct rum_softc *sc,
1637    struct usb2_config_td_cc *cc, uint16_t refcount)
1638{
1639	uint32_t tmp;
1640	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
1641
1642	/* update all BBP registers that depend on the band */
1643	bbp17 = 0x20;
1644	bbp96 = 0x48;
1645	bbp104 = 0x2c;
1646	bbp35 = 0x50;
1647	bbp97 = 0x48;
1648	bbp98 = 0x48;
1649
1650	if (cc->ic_curchan.chan_is_5ghz) {
1651		bbp17 += 0x08;
1652		bbp96 += 0x10;
1653		bbp104 += 0x0c;
1654		bbp35 += 0x10;
1655		bbp97 += 0x10;
1656		bbp98 += 0x10;
1657	}
1658	if ((cc->ic_curchan.chan_is_2ghz && sc->sc_ext_2ghz_lna) ||
1659	    (cc->ic_curchan.chan_is_5ghz && sc->sc_ext_5ghz_lna)) {
1660		bbp17 += 0x10;
1661		bbp96 += 0x10;
1662		bbp104 += 0x10;
1663	}
1664	sc->sc_bbp17 = bbp17;
1665	rum_cfg_bbp_write(sc, 17, bbp17);
1666	rum_cfg_bbp_write(sc, 96, bbp96);
1667	rum_cfg_bbp_write(sc, 104, bbp104);
1668
1669	if ((cc->ic_curchan.chan_is_2ghz && sc->sc_ext_2ghz_lna) ||
1670	    (cc->ic_curchan.chan_is_5ghz && sc->sc_ext_5ghz_lna)) {
1671		rum_cfg_bbp_write(sc, 75, 0x80);
1672		rum_cfg_bbp_write(sc, 86, 0x80);
1673		rum_cfg_bbp_write(sc, 88, 0x80);
1674	}
1675	rum_cfg_bbp_write(sc, 35, bbp35);
1676	rum_cfg_bbp_write(sc, 97, bbp97);
1677	rum_cfg_bbp_write(sc, 98, bbp98);
1678
1679	tmp = rum_cfg_read(sc, RT2573_PHY_CSR0);
1680	tmp &= ~(RT2573_PA_PE_2GHZ | RT2573_PA_PE_5GHZ);
1681	if (cc->ic_curchan.chan_is_2ghz)
1682		tmp |= RT2573_PA_PE_2GHZ;
1683	else
1684		tmp |= RT2573_PA_PE_5GHZ;
1685	rum_cfg_write(sc, RT2573_PHY_CSR0, tmp);
1686
1687	/* 802.11a uses a 16 microseconds short interframe space */
1688	sc->sc_sifs = cc->ic_curchan.chan_is_5ghz ? 16 : 10;
1689
1690	return;
1691}
1692
1693static void
1694rum_cfg_set_chan(struct rum_softc *sc,
1695    struct usb2_config_td_cc *cc, uint16_t refcount)
1696{
1697	enum {
1698	N_RF5225 = (sizeof(rum_rf5225) / sizeof(rum_rf5225[0]))};
1699	const struct rfprog *rfprog;
1700	uint32_t chan;
1701	uint16_t i;
1702	uint8_t bbp3;
1703	uint8_t bbp94 = RT2573_BBPR94_DEFAULT;
1704	int8_t power;
1705
1706	chan = cc->ic_curchan.chan_to_ieee;
1707
1708	if ((chan == 0) ||
1709	    (chan == IEEE80211_CHAN_ANY)) {
1710		/* nothing to do */
1711		return;
1712	}
1713	if (chan == sc->sc_last_chan) {
1714		return;
1715	}
1716	sc->sc_last_chan = chan;
1717
1718	/* select the appropriate RF settings based on what EEPROM says */
1719	rfprog = ((sc->sc_rf_rev == RT2573_RF_5225) ||
1720	    (sc->sc_rf_rev == RT2573_RF_2527)) ? rum_rf5225 : rum_rf5226;
1721
1722	/* find the settings for this channel */
1723	for (i = 0;; i++) {
1724		if (i == (N_RF5225 - 1))
1725			break;
1726		if (rfprog[i].chan == chan)
1727			break;
1728	}
1729
1730	DPRINTF("chan=%d, i=%d\n", chan, i);
1731
1732	power = sc->sc_txpow[i];
1733	if (power < 0) {
1734		bbp94 += power;
1735		power = 0;
1736	} else if (power > 31) {
1737		bbp94 += power - 31;
1738		power = 31;
1739	}
1740	/*
1741	 * If we are switching from the 2GHz band to the 5GHz band or
1742	 * vice-versa, BBP registers need to be reprogrammed.
1743	 */
1744	rum_cfg_select_band(sc, cc, 0);
1745	rum_cfg_select_antenna(sc, cc, 0);
1746
1747	rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1748	rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1749	rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7));
1750	rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
1751
1752	rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1753	rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1754	rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7) | 1);
1755	rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
1756
1757	rum_cfg_rf_write(sc, RT2573_RF1, rfprog[i].r1);
1758	rum_cfg_rf_write(sc, RT2573_RF2, rfprog[i].r2);
1759	rum_cfg_rf_write(sc, RT2573_RF3, rfprog[i].r3 | (power << 7));
1760	rum_cfg_rf_write(sc, RT2573_RF4, rfprog[i].r4 | (sc->sc_rffreq << 10));
1761
1762	if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
1763		return;
1764	}
1765	/* enable smart mode for MIMO-capable RFs */
1766	bbp3 = rum_cfg_bbp_read(sc, 3);
1767
1768	if ((sc->sc_rf_rev == RT2573_RF_5225) ||
1769	    (sc->sc_rf_rev == RT2573_RF_2527))
1770		bbp3 &= ~RT2573_SMART_MODE;
1771	else
1772		bbp3 |= RT2573_SMART_MODE;
1773
1774	rum_cfg_bbp_write(sc, 3, bbp3);
1775
1776	rum_cfg_bbp_write(sc, 94, bbp94);
1777
1778	/* update basic rate set */
1779
1780	if (cc->ic_curchan.chan_is_b) {
1781		/* 11b basic rates: 1, 2Mbps */
1782		rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x3);
1783	} else if (cc->ic_curchan.chan_is_a) {
1784		/* 11a basic rates: 6, 12, 24Mbps */
1785		rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x150);
1786	} else {
1787		/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1788		rum_cfg_write(sc, RT2573_TXRX_CSR5, 0xf);
1789	}
1790
1791	if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
1792		return;
1793	}
1794	return;
1795}
1796
1797static void
1798rum_cfg_set_run(struct rum_softc *sc,
1799    struct usb2_config_td_cc *cc)
1800{
1801
1802	if (cc->ic_opmode != IEEE80211_M_MONITOR) {
1803		rum_cfg_update_slot(sc, cc, 0);
1804		rum_cfg_enable_mrr(sc, cc, 0);
1805		rum_cfg_set_txpreamble(sc, cc, 0);
1806
1807		/* update basic rate set */
1808
1809		if (cc->ic_bsschan.chan_is_5ghz) {
1810			/* 11a basic rates: 6, 12, 24Mbps */
1811			rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x150);
1812		} else if (cc->ic_bsschan.chan_is_g) {
1813			/* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1814			rum_cfg_write(sc, RT2573_TXRX_CSR5, 0xf);
1815		} else {
1816			/* 11b basic rates: 1, 2Mbps */
1817			rum_cfg_write(sc, RT2573_TXRX_CSR5, 0x3);
1818		}
1819		rum_cfg_set_bssid(sc, cc->iv_bss.ni_bssid);
1820	}
1821	if ((cc->ic_opmode == IEEE80211_M_HOSTAP) ||
1822	    (cc->ic_opmode == IEEE80211_M_IBSS)) {
1823		rum_cfg_prepare_beacon(sc, cc, 0);
1824	}
1825	if (cc->ic_opmode != IEEE80211_M_MONITOR) {
1826		rum_cfg_enable_tsf_sync(sc, cc, 0);
1827	}
1828	if (cc->iv_bss.fixed_rate_none) {
1829		/* enable automatic rate adaptation */
1830		rum_cfg_amrr_start(sc);
1831	}
1832	return;
1833}
1834
1835static void
1836rum_cfg_enable_tsf_sync(struct rum_softc *sc,
1837    struct usb2_config_td_cc *cc, uint16_t refcount)
1838{
1839	uint32_t tmp;
1840
1841	if (cc->ic_opmode != IEEE80211_M_STA) {
1842		/*
1843		 * Change default 16ms TBTT adjustment to 8ms.
1844		 * Must be done before enabling beacon generation.
1845		 */
1846		rum_cfg_write(sc, RT2573_TXRX_CSR10, (1 << 12) | 8);
1847	}
1848	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR9) & 0xff000000;
1849
1850	/* set beacon interval (in 1/16ms unit) */
1851	tmp |= cc->iv_bss.ni_intval * 16;
1852
1853	tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT;
1854	if (cc->ic_opmode == IEEE80211_M_STA)
1855		tmp |= RT2573_TSF_MODE(1);
1856	else
1857		tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON;
1858
1859	rum_cfg_write(sc, RT2573_TXRX_CSR9, tmp);
1860
1861	return;
1862}
1863
1864static void
1865rum_cfg_disable_tsf_sync(struct rum_softc *sc)
1866{
1867	uint32_t tmp;
1868
1869	/* abort TSF synchronization */
1870	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR9);
1871	rum_cfg_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff);
1872	return;
1873}
1874
1875/*
1876 * Enable multi-rate retries for frames sent at OFDM rates.
1877 * In 802.11b/g mode, allow fallback to CCK rates.
1878 */
1879static void
1880rum_cfg_enable_mrr(struct rum_softc *sc,
1881    struct usb2_config_td_cc *cc, uint16_t refcount)
1882{
1883	uint32_t tmp;
1884
1885	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR4);
1886
1887	if (cc->ic_curchan.chan_is_5ghz)
1888		tmp &= ~RT2573_MRR_CCK_FALLBACK;
1889	else
1890		tmp |= RT2573_MRR_CCK_FALLBACK;
1891
1892	tmp |= RT2573_MRR_ENABLED;
1893
1894	rum_cfg_write(sc, RT2573_TXRX_CSR4, tmp);
1895
1896	return;
1897}
1898
1899static void
1900rum_cfg_update_slot(struct rum_softc *sc,
1901    struct usb2_config_td_cc *cc, uint16_t refcount)
1902{
1903	uint32_t tmp;
1904	uint8_t slottime;
1905
1906	slottime = (cc->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1907
1908	tmp = rum_cfg_read(sc, RT2573_MAC_CSR9);
1909	tmp = (tmp & ~0xff) | slottime;
1910	rum_cfg_write(sc, RT2573_MAC_CSR9, tmp);
1911
1912	DPRINTF("setting slot time to %u us\n", slottime);
1913
1914	return;
1915}
1916
1917static void
1918rum_cfg_set_txpreamble(struct rum_softc *sc,
1919    struct usb2_config_td_cc *cc, uint16_t refcount)
1920{
1921	uint32_t tmp;
1922
1923	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR4);
1924
1925	if (cc->ic_flags & IEEE80211_F_SHPREAMBLE)
1926		tmp |= RT2573_SHORT_PREAMBLE;
1927	else
1928		tmp &= ~RT2573_SHORT_PREAMBLE;
1929
1930	rum_cfg_write(sc, RT2573_TXRX_CSR4, tmp);
1931
1932	return;
1933}
1934
1935static void
1936rum_cfg_set_bssid(struct rum_softc *sc, uint8_t *bssid)
1937{
1938	uint32_t tmp;
1939
1940	tmp = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24);
1941	rum_cfg_write(sc, RT2573_MAC_CSR4, tmp);
1942
1943	tmp = (bssid[4]) | (bssid[5] << 8) | (RT2573_ONE_BSSID << 16);
1944	rum_cfg_write(sc, RT2573_MAC_CSR5, tmp);
1945
1946	return;
1947}
1948
1949static void
1950rum_cfg_set_macaddr(struct rum_softc *sc, uint8_t *addr)
1951{
1952	uint32_t tmp;
1953
1954	tmp = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24);
1955	rum_cfg_write(sc, RT2573_MAC_CSR2, tmp);
1956
1957	tmp = addr[4] | (addr[5] << 8) | (0xff << 16);
1958	rum_cfg_write(sc, RT2573_MAC_CSR3, tmp);
1959
1960	return;
1961}
1962
1963static void
1964rum_cfg_update_promisc(struct rum_softc *sc,
1965    struct usb2_config_td_cc *cc, uint16_t refcount)
1966{
1967	uint32_t tmp;
1968
1969	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0);
1970
1971	if (cc->if_flags & IFF_PROMISC)
1972		tmp &= ~RT2573_DROP_NOT_TO_ME;
1973	else
1974		tmp |= RT2573_DROP_NOT_TO_ME;
1975
1976	rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
1977
1978	DPRINTF("%s promiscuous mode\n",
1979	    (cc->if_flags & IFF_PROMISC) ?
1980	    "entering" : "leaving");
1981	return;
1982}
1983
1984static void
1985rum_cfg_select_antenna(struct rum_softc *sc,
1986    struct usb2_config_td_cc *cc, uint16_t refcount)
1987{
1988	uint32_t tmp;
1989	uint8_t bbp3;
1990	uint8_t bbp4;
1991	uint8_t bbp77;
1992	uint8_t rx_ant;
1993	uint8_t is_5ghz;
1994
1995	bbp3 = rum_cfg_bbp_read(sc, 3);
1996	bbp4 = rum_cfg_bbp_read(sc, 4);
1997	bbp77 = rum_cfg_bbp_read(sc, 77);
1998
1999	bbp3 &= ~0x01;
2000	bbp4 &= ~0x23;
2001
2002	rx_ant = sc->sc_rx_ant;
2003	is_5ghz = cc->ic_curchan.chan_is_5ghz;
2004
2005	switch (sc->sc_rf_rev) {
2006	case RT2573_RF_5226:
2007	case RT2573_RF_5225:
2008		if (rx_ant == 0) {
2009			/* Diversity */
2010			bbp4 |= 0x02;
2011			if (is_5ghz == 0)
2012				bbp4 |= 0x20;
2013		} else if (rx_ant == 1) {
2014			/* RX: Antenna A */
2015			bbp4 |= 0x01;
2016			if (is_5ghz)
2017				bbp77 &= ~0x03;
2018			else
2019				bbp77 |= 0x03;
2020		} else if (rx_ant == 2) {
2021			/* RX: Antenna B */
2022			bbp4 |= 0x01;
2023			if (is_5ghz)
2024				bbp77 |= 0x03;
2025			else
2026				bbp77 &= ~0x03;
2027		}
2028		break;
2029
2030	case RT2573_RF_2528:
2031	case RT2573_RF_2527:
2032		if (rx_ant == 0) {
2033			/* Diversity */
2034			bbp4 |= 0x22;
2035		} else if (rx_ant == 1) {
2036			/* RX: Antenna A */
2037			bbp4 |= 0x21;
2038			bbp77 |= 0x03;
2039		} else if (rx_ant == 2) {
2040			/* RX: Antenna B */
2041			bbp4 |= 0x21;
2042			bbp77 &= ~0x03;
2043		}
2044		break;
2045	default:
2046		break;
2047	}
2048	bbp4 &= ~(sc->sc_ftype << 5);
2049
2050	/* make sure Rx is disabled before switching antenna */
2051	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0);
2052	rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
2053
2054	rum_cfg_bbp_write(sc, 3, bbp3);
2055	rum_cfg_bbp_write(sc, 4, bbp4);
2056	rum_cfg_bbp_write(sc, 77, bbp77);
2057
2058	rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
2059
2060	return;
2061}
2062
2063static void
2064rum_cfg_read_eeprom(struct rum_softc *sc)
2065{
2066	uint16_t val;
2067
2068	/* read MAC address */
2069	rum_cfg_eeprom_read(sc, RT2573_EEPROM_ADDRESS, sc->sc_myaddr, 6);
2070
2071	val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_ANTENNA);
2072	sc->sc_rf_rev = (val >> 11) & 0x1f;
2073	sc->sc_hw_radio = (val >> 10) & 0x1;
2074	sc->sc_ftype = (val >> 6) & 0x1;
2075	sc->sc_rx_ant = (val >> 4) & 0x3;
2076	sc->sc_tx_ant = (val >> 2) & 0x3;
2077	sc->sc_nb_ant = (val & 0x3);
2078
2079	DPRINTF("RF revision=%d\n", sc->sc_rf_rev);
2080
2081	val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_CONFIG2);
2082	sc->sc_ext_5ghz_lna = (val >> 6) & 0x1;
2083	sc->sc_ext_2ghz_lna = (val >> 4) & 0x1;
2084
2085	DPRINTF("External 2GHz LNA=%d, External 5GHz LNA=%d\n",
2086	    sc->sc_ext_2ghz_lna, sc->sc_ext_5ghz_lna);
2087
2088	val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_RSSI_2GHZ_OFFSET);
2089	if ((val & 0xff) != 0xff)
2090		sc->sc_rssi_2ghz_corr = (int8_t)(val & 0xff);	/* signed */
2091	else
2092		sc->sc_rssi_2ghz_corr = 0;
2093
2094	/* range check */
2095	if ((sc->sc_rssi_2ghz_corr < -10) ||
2096	    (sc->sc_rssi_2ghz_corr > 10)) {
2097		sc->sc_rssi_2ghz_corr = 0;
2098	}
2099	val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_RSSI_5GHZ_OFFSET);
2100	if ((val & 0xff) != 0xff)
2101		sc->sc_rssi_5ghz_corr = (int8_t)(val & 0xff);	/* signed */
2102	else
2103		sc->sc_rssi_5ghz_corr = 0;
2104
2105	/* range check */
2106	if ((sc->sc_rssi_5ghz_corr < -10) ||
2107	    (sc->sc_rssi_5ghz_corr > 10)) {
2108		sc->sc_rssi_5ghz_corr = 0;
2109	}
2110	if (sc->sc_ext_2ghz_lna) {
2111		sc->sc_rssi_2ghz_corr -= 14;
2112	}
2113	if (sc->sc_ext_5ghz_lna) {
2114		sc->sc_rssi_5ghz_corr -= 14;
2115	}
2116	DPRINTF("RSSI 2GHz corr=%d, RSSI 5GHz corr=%d\n",
2117	    sc->sc_rssi_2ghz_corr, sc->sc_rssi_5ghz_corr);
2118
2119	val = rum_cfg_eeprom_read_2(sc, RT2573_EEPROM_FREQ_OFFSET);
2120	if ((val & 0xff) != 0xff)
2121		sc->sc_rffreq = (val & 0xff);
2122	else
2123		sc->sc_rffreq = 0;
2124
2125	DPRINTF("RF freq=%d\n", sc->sc_rffreq);
2126
2127	/* read Tx power for all a/b/g channels */
2128	rum_cfg_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->sc_txpow, 14);
2129
2130	/* XXX default Tx power for 802.11a channels */
2131	memset(sc->sc_txpow + 14, 24, sizeof(sc->sc_txpow) - 14);
2132
2133	/* read default values for BBP registers */
2134	rum_cfg_eeprom_read(sc, RT2573_EEPROM_BBP_BASE, sc->sc_bbp_prom, 2 * 16);
2135
2136	return;
2137}
2138
2139static uint8_t
2140rum_cfg_bbp_init(struct rum_softc *sc)
2141{
2142	enum {
2143		N_DEF_BBP = (sizeof(rum_def_bbp) / sizeof(rum_def_bbp[0])),
2144	};
2145	uint16_t i;
2146	uint8_t to;
2147	uint8_t tmp;
2148
2149	/* wait for BBP to become ready */
2150	for (to = 0;; to++) {
2151		if (to < 100) {
2152			tmp = rum_cfg_bbp_read(sc, 0);
2153			if ((tmp != 0x00) &&
2154			    (tmp != 0xff)) {
2155				break;
2156			}
2157			if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
2158				return (1);	/* failure */
2159			}
2160		} else {
2161			DPRINTF("timeout waiting for BBP\n");
2162			return (1);	/* failure */
2163		}
2164	}
2165
2166	/* initialize BBP registers to default values */
2167	for (i = 0; i < N_DEF_BBP; i++) {
2168		rum_cfg_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val);
2169	}
2170
2171	/* write vendor-specific BBP values (from EEPROM) */
2172	for (i = 0; i < 16; i++) {
2173		if ((sc->sc_bbp_prom[i].reg == 0) ||
2174		    (sc->sc_bbp_prom[i].reg == 0xff)) {
2175			continue;
2176		}
2177		rum_cfg_bbp_write(sc, sc->sc_bbp_prom[i].reg, sc->sc_bbp_prom[i].val);
2178	}
2179	return (0);
2180}
2181
2182static void
2183rum_cfg_pre_init(struct rum_softc *sc,
2184    struct usb2_config_td_cc *cc, uint16_t refcount)
2185{
2186	struct ifnet *ifp = sc->sc_ifp;
2187	struct ieee80211com *ic = ifp->if_l2com;
2188
2189	/* immediate configuration */
2190
2191	rum_cfg_pre_stop(sc, cc, 0);
2192
2193	ifp->if_drv_flags |= IFF_DRV_RUNNING;
2194
2195	sc->sc_flags |= RUM_FLAG_HL_READY;
2196
2197	IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
2198	return;
2199}
2200
2201static void
2202rum_cfg_init(struct rum_softc *sc,
2203    struct usb2_config_td_cc *cc, uint16_t refcount)
2204{
2205	enum {
2206		N_DEF_MAC = (sizeof(rum_def_mac) / sizeof(rum_def_mac[0])),
2207	};
2208
2209	uint32_t tmp;
2210	uint16_t i;
2211	uint8_t to;
2212
2213	/* delayed configuration */
2214
2215	rum_cfg_stop(sc, cc, 0);
2216
2217	/* initialize MAC registers to default values */
2218	for (i = 0; i < N_DEF_MAC; i++) {
2219		rum_cfg_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val);
2220	}
2221
2222	/* set host ready */
2223	rum_cfg_write(sc, RT2573_MAC_CSR1, 3);
2224	rum_cfg_write(sc, RT2573_MAC_CSR1, 0);
2225
2226	/* wait for BBP/RF to wakeup */
2227	for (to = 0;; to++) {
2228		if (to < 100) {
2229			if (rum_cfg_read(sc, RT2573_MAC_CSR12) & 8) {
2230				break;
2231			}
2232			rum_cfg_write(sc, RT2573_MAC_CSR12, 4);	/* force wakeup */
2233
2234			if (usb2_config_td_sleep(&sc->sc_config_td, hz / 100)) {
2235				goto fail;
2236			}
2237		} else {
2238			DPRINTF("timeout waiting for "
2239			    "BBP/RF to wakeup\n");
2240			goto fail;
2241		}
2242	}
2243
2244	if (rum_cfg_bbp_init(sc)) {
2245		goto fail;
2246	}
2247	/* select default channel */
2248
2249	sc->sc_last_chan = 0;
2250
2251	rum_cfg_set_chan(sc, cc, 0);
2252
2253	/* clear STA registers */
2254	rum_cfg_read_multi(sc, RT2573_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta));
2255	/* set MAC address */
2256	rum_cfg_set_macaddr(sc, cc->ic_myaddr);
2257
2258	/* initialize ASIC */
2259	rum_cfg_write(sc, RT2573_MAC_CSR1, 4);
2260
2261	/*
2262	 * make sure that the first transaction
2263	 * clears the stall:
2264	 */
2265	sc->sc_flags |= (RUM_FLAG_READ_STALL |
2266	    RUM_FLAG_WRITE_STALL |
2267	    RUM_FLAG_LL_READY);
2268
2269	if ((sc->sc_flags & RUM_FLAG_LL_READY) &&
2270	    (sc->sc_flags & RUM_FLAG_HL_READY)) {
2271		struct ifnet *ifp = sc->sc_ifp;
2272		struct ieee80211com *ic = ifp->if_l2com;
2273
2274		/*
2275		 * start the USB transfers, if not already started:
2276		 */
2277		usb2_transfer_start(sc->sc_xfer[1]);
2278		usb2_transfer_start(sc->sc_xfer[0]);
2279
2280		/*
2281		 * start IEEE802.11 layer
2282		 */
2283		mtx_unlock(&sc->sc_mtx);
2284		ieee80211_start_all(ic);
2285		mtx_lock(&sc->sc_mtx);
2286	}
2287	/* update Rx filter */
2288	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0) & 0xffff;
2289
2290	tmp |= RT2573_DROP_PHY_ERROR | RT2573_DROP_CRC_ERROR;
2291
2292	if (cc->ic_opmode != IEEE80211_M_MONITOR) {
2293		tmp |= RT2573_DROP_CTL | RT2573_DROP_VER_ERROR |
2294		    RT2573_DROP_ACKCTS;
2295		if (cc->ic_opmode != IEEE80211_M_HOSTAP) {
2296			tmp |= RT2573_DROP_TODS;
2297		}
2298		if (!(cc->if_flags & IFF_PROMISC)) {
2299			tmp |= RT2573_DROP_NOT_TO_ME;
2300		}
2301	}
2302	rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp);
2303
2304	return;
2305
2306fail:
2307	rum_cfg_pre_stop(sc, NULL, 0);
2308
2309	if (cc) {
2310		rum_cfg_stop(sc, cc, 0);
2311	}
2312	return;
2313}
2314
2315static void
2316rum_cfg_pre_stop(struct rum_softc *sc,
2317    struct usb2_config_td_cc *cc, uint16_t refcount)
2318{
2319	struct ifnet *ifp = sc->sc_ifp;
2320
2321	if (cc) {
2322		/* copy the needed configuration */
2323		rum_config_copy(sc, cc, refcount);
2324	}
2325	/* immediate configuration */
2326
2327	if (ifp) {
2328		/* clear flags */
2329		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2330	}
2331	sc->sc_flags &= ~(RUM_FLAG_HL_READY |
2332	    RUM_FLAG_LL_READY);
2333
2334	/*
2335	 * stop all the transfers, if not already stopped:
2336	 */
2337	usb2_transfer_stop(sc->sc_xfer[0]);
2338	usb2_transfer_stop(sc->sc_xfer[1]);
2339	usb2_transfer_stop(sc->sc_xfer[2]);
2340	usb2_transfer_stop(sc->sc_xfer[3]);
2341
2342	/* clean up transmission */
2343	rum_tx_clean_queue(sc);
2344	return;
2345}
2346
2347static void
2348rum_cfg_stop(struct rum_softc *sc,
2349    struct usb2_config_td_cc *cc, uint16_t refcount)
2350{
2351	uint32_t tmp;
2352
2353	/* disable Rx */
2354	tmp = rum_cfg_read(sc, RT2573_TXRX_CSR0);
2355	rum_cfg_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX);
2356
2357	/* reset ASIC */
2358	rum_cfg_write(sc, RT2573_MAC_CSR1, 3);
2359
2360	/* wait a little */
2361	usb2_config_td_sleep(&sc->sc_config_td, hz / 10);
2362
2363	rum_cfg_write(sc, RT2573_MAC_CSR1, 0);
2364
2365	/* wait a little */
2366	usb2_config_td_sleep(&sc->sc_config_td, hz / 10);
2367
2368	return;
2369}
2370
2371static void
2372rum_cfg_amrr_start(struct rum_softc *sc)
2373{
2374	struct ieee80211vap *vap;
2375	struct ieee80211_node *ni;
2376
2377	vap = rum_get_vap(sc);
2378
2379	if (vap == NULL) {
2380		return;
2381	}
2382	ni = vap->iv_bss;
2383	if (ni == NULL) {
2384		return;
2385	}
2386	/* init AMRR */
2387
2388	ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
2389
2390	/* enable AMRR timer */
2391
2392	sc->sc_amrr_timer = 1;
2393	return;
2394}
2395
2396static void
2397rum_cfg_amrr_timeout(struct rum_softc *sc,
2398    struct usb2_config_td_cc *cc, uint16_t refcount)
2399{
2400	struct ifnet *ifp = sc->sc_ifp;
2401	struct ieee80211vap *vap;
2402	struct ieee80211_node *ni;
2403	uint32_t ok;
2404	uint32_t fail;
2405
2406	/* clear statistic registers (STA_CSR0 to STA_CSR5) */
2407	rum_cfg_read_multi(sc, RT2573_STA_CSR0, sc->sc_sta, sizeof(sc->sc_sta));
2408
2409	vap = rum_get_vap(sc);
2410	if (vap == NULL) {
2411		return;
2412	}
2413	ni = vap->iv_bss;
2414	if (ni == NULL) {
2415		return;
2416	}
2417	if ((sc->sc_flags & RUM_FLAG_LL_READY) &&
2418	    (sc->sc_flags & RUM_FLAG_HL_READY)) {
2419
2420		ok = (le32toh(sc->sc_sta[4]) >> 16) +	/* TX ok w/o retry */
2421		    (le32toh(sc->sc_sta[5]) & 0xffff);	/* TX ok w/ retry */
2422		fail = (le32toh(sc->sc_sta[5]) >> 16);	/* TX retry-fail count */
2423
2424		if (sc->sc_amrr_timer) {
2425			ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn,
2426			    ok + fail, ok, (le32toh(sc->sc_sta[5]) & 0xffff) + fail);
2427
2428			if (ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn)) {
2429				/* ignore */
2430			}
2431		}
2432		ifp->if_oerrors += fail;/* count TX retry-fail as Tx errors */
2433	}
2434	return;
2435}
2436
2437static void
2438rum_cfg_load_microcode(struct rum_softc *sc, const uint8_t *ucode, uint16_t size)
2439{
2440	struct usb2_device_request req;
2441	uint16_t reg = RT2573_MCU_CODE_BASE;
2442
2443	/* copy firmware image into NIC */
2444	while (size >= 4) {
2445		rum_cfg_write(sc, reg, UGETDW(ucode));
2446		reg += 4;
2447		ucode += 4;
2448		size -= 4;
2449	}
2450
2451	if (size != 0) {
2452		DPRINTF("possibly invalid firmware\n");
2453	}
2454	req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
2455	req.bRequest = RT2573_MCU_CNTL;
2456	USETW(req.wValue, RT2573_MCU_RUN);
2457	USETW(req.wIndex, 0);
2458	USETW(req.wLength, 0);
2459
2460	rum_cfg_do_request(sc, &req, NULL);
2461
2462	return;
2463}
2464
2465static void
2466rum_cfg_prepare_beacon(struct rum_softc *sc,
2467    struct usb2_config_td_cc *cc, uint16_t refcount)
2468{
2469	struct ieee80211_node *ni;
2470	struct ieee80211vap *vap;
2471	struct ieee80211com *ic;
2472	const struct ieee80211_txparam *tp;
2473	struct mbuf *m;
2474
2475	vap = rum_get_vap(sc);
2476	if (vap == NULL) {
2477		return;
2478	}
2479	ni = vap->iv_bss;
2480	if (ni == NULL) {
2481		return;
2482	}
2483	ic = vap->iv_ic;
2484	if (ic == NULL) {
2485		return;
2486	}
2487	DPRINTFN(11, "Sending beacon frame.\n");
2488
2489	m = ieee80211_beacon_alloc(ni, &RUM_VAP(vap)->bo);
2490	if (m == NULL) {
2491		DPRINTFN(0, "could not allocate beacon\n");
2492		return;
2493	}
2494	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)];
2495
2496	m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni);
2497	rum_setup_desc_and_tx(sc, m, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ | RT2573_TX_BEACON, tp->mgmtrate);
2498	return;
2499}
2500
2501static uint8_t
2502rum_get_rssi(struct rum_softc *sc, uint8_t raw)
2503{
2504	struct ifnet *ifp = sc->sc_ifp;
2505	struct ieee80211com *ic = ifp->if_l2com;
2506	int16_t rssi;
2507	uint8_t lna;
2508	uint8_t agc;
2509
2510	lna = (raw >> 5) & 0x3;
2511	agc = raw & 0x1f;
2512
2513	if (lna == 0) {
2514		/*
2515                 * No RSSI mapping
2516                 *
2517                 * NB: Since RSSI is relative to noise floor, -1 is
2518                 *     adequate for caller to know error happened.
2519                 */
2520		return (0);
2521	}
2522	rssi = (2 * agc) - RT2573_NOISE_FLOOR;
2523
2524	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2525
2526		rssi += sc->sc_rssi_2ghz_corr;
2527
2528		if (lna == 1)
2529			rssi -= 64;
2530		else if (lna == 2)
2531			rssi -= 74;
2532		else if (lna == 3)
2533			rssi -= 90;
2534	} else {
2535
2536		rssi += sc->sc_rssi_5ghz_corr;
2537
2538		if ((!sc->sc_ext_5ghz_lna) && (lna != 1))
2539			rssi += 4;
2540
2541		if (lna == 1)
2542			rssi -= 64;
2543		else if (lna == 2)
2544			rssi -= 86;
2545		else if (lna == 3)
2546			rssi -= 100;
2547	}
2548
2549	/* range check */
2550
2551	if (rssi < 0)
2552		rssi = 0;
2553	else if (rssi > 255)
2554		rssi = 255;
2555
2556	return (rssi);
2557}
2558
2559static struct ieee80211vap *
2560rum_vap_create(struct ieee80211com *ic,
2561    const char name[IFNAMSIZ], int unit, int opmode, int flags,
2562    const uint8_t bssid[IEEE80211_ADDR_LEN],
2563    const uint8_t mac[IEEE80211_ADDR_LEN])
2564{
2565	struct rum_vap *rvp;
2566	struct ieee80211vap *vap;
2567	struct rum_softc *sc = ic->ic_ifp->if_softc;
2568
2569	DPRINTF("\n");
2570
2571	/* Need to sync with config thread: */
2572	mtx_lock(&sc->sc_mtx);
2573	if (usb2_config_td_sync(&sc->sc_config_td)) {
2574		mtx_unlock(&sc->sc_mtx);
2575		/* config thread is gone */
2576		return (NULL);
2577	}
2578	mtx_unlock(&sc->sc_mtx);
2579
2580	if (!TAILQ_EMPTY(&ic->ic_vaps))	/* only one at a time */
2581		return NULL;
2582	rvp = (struct rum_vap *)malloc(sizeof(struct rum_vap),
2583	    M_80211_VAP, M_NOWAIT | M_ZERO);
2584	if (rvp == NULL)
2585		return NULL;
2586	vap = &rvp->vap;
2587	/* enable s/w bmiss handling for sta mode */
2588	ieee80211_vap_setup(ic, vap, name, unit, opmode,
2589	    flags | IEEE80211_CLONE_NOBEACONS, bssid, mac);
2590
2591	/* override state transition machine */
2592	rvp->newstate = vap->iv_newstate;
2593	vap->iv_newstate = &rum_newstate_cb;
2594
2595	ieee80211_amrr_init(&rvp->amrr, vap,
2596	    IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
2597	    IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
2598	    1000 /* 1 sec */ );
2599
2600	/* complete setup */
2601	ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status);
2602
2603	/* store current operation mode */
2604	ic->ic_opmode = opmode;
2605
2606	return (vap);
2607}
2608
2609static void
2610rum_vap_delete(struct ieee80211vap *vap)
2611{
2612	struct rum_vap *rvp = RUM_VAP(vap);
2613	struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc;
2614
2615	DPRINTF("\n");
2616
2617	/* Need to sync with config thread: */
2618	mtx_lock(&sc->sc_mtx);
2619	if (usb2_config_td_sync(&sc->sc_config_td)) {
2620		/* ignore */
2621	}
2622	mtx_unlock(&sc->sc_mtx);
2623
2624	ieee80211_amrr_cleanup(&rvp->amrr);
2625	ieee80211_vap_detach(vap);
2626	free(rvp, M_80211_VAP);
2627	return;
2628}
2629
2630/* ARGUSED */
2631static struct ieee80211_node *
2632rum_node_alloc(struct ieee80211vap *vap __unused,
2633    const uint8_t mac[IEEE80211_ADDR_LEN] __unused)
2634{
2635	struct rum_node *rn;
2636
2637	rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO);
2638	return ((rn != NULL) ? &rn->ni : NULL);
2639}
2640
2641static void
2642rum_newassoc(struct ieee80211_node *ni, int isnew)
2643{
2644	struct ieee80211vap *vap = ni->ni_vap;
2645
2646	ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni);
2647	return;
2648}
2649
2650static void
2651rum_fill_write_queue(struct rum_softc *sc)
2652{
2653	struct ifnet *ifp = sc->sc_ifp;
2654	struct ieee80211_node *ni;
2655	struct mbuf *m;
2656
2657	/*
2658	 * We only fill up half of the queue with data frames. The rest is
2659	 * reserved for other kinds of frames.
2660	 */
2661
2662	while (sc->sc_tx_queue.ifq_len < (IFQ_MAXLEN / 2)) {
2663
2664		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
2665		if (m == NULL)
2666			break;
2667
2668		ni = (void *)(m->m_pkthdr.rcvif);
2669		m = ieee80211_encap(ni, m);
2670		if (m == NULL) {
2671			ieee80211_free_node(ni);
2672			continue;
2673		}
2674		rum_tx_data(sc, m, ni);
2675	}
2676	return;
2677}
2678
2679static void
2680rum_tx_clean_queue(struct rum_softc *sc)
2681{
2682	struct mbuf *m;
2683
2684	for (;;) {
2685		_IF_DEQUEUE(&sc->sc_tx_queue, m);
2686
2687		if (!m) {
2688			break;
2689		}
2690		rum_tx_freem(m);
2691	}
2692	return;
2693}
2694
2695static void
2696rum_tx_freem(struct mbuf *m)
2697{
2698	struct ieee80211_node *ni;
2699
2700	while (m) {
2701		ni = (void *)(m->m_pkthdr.rcvif);
2702		if (!ni) {
2703			m = m_free(m);
2704			continue;
2705		}
2706		if (m->m_flags & M_TXCB) {
2707			ieee80211_process_callback(ni, m, 0);
2708		}
2709		m_freem(m);
2710		ieee80211_free_node(ni);
2711
2712		break;
2713	}
2714	return;
2715}
2716
2717static void
2718rum_tx_mgt(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
2719{
2720	struct ieee80211vap *vap = ni->ni_vap;
2721	struct ieee80211com *ic = ni->ni_ic;
2722	const struct ieee80211_txparam *tp;
2723	struct ieee80211_frame *wh;
2724	struct ieee80211_key *k;
2725	uint32_t flags;
2726	uint16_t dur;
2727
2728	tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)];
2729
2730	wh = mtod(m, struct ieee80211_frame *);
2731	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2732		k = ieee80211_crypto_encap(ni, m);
2733		if (k == NULL) {
2734			m_freem(m);
2735			ieee80211_free_node(ni);
2736			return;
2737		}
2738		wh = mtod(m, struct ieee80211_frame *);
2739	}
2740	flags = 0;
2741	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2742		flags |= RT2573_TX_NEED_ACK;
2743
2744		dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate,
2745		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
2746		USETW(wh->i_dur, dur);
2747
2748		/* tell hardware to add timestamp for probe responses */
2749		if ((wh->i_fc[0] &
2750		    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
2751		    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
2752			flags |= RT2573_TX_TIMESTAMP;
2753	}
2754	m->m_pkthdr.rcvif = (void *)ni;
2755	rum_setup_desc_and_tx(sc, m, flags, 0, tp->mgmtrate);
2756	return;
2757}
2758
2759static struct ieee80211vap *
2760rum_get_vap(struct rum_softc *sc)
2761{
2762	struct ifnet *ifp;
2763	struct ieee80211com *ic;
2764
2765	if (sc == NULL) {
2766		return NULL;
2767	}
2768	ifp = sc->sc_ifp;
2769	if (ifp == NULL) {
2770		return NULL;
2771	}
2772	ic = ifp->if_l2com;
2773	if (ic == NULL) {
2774		return NULL;
2775	}
2776	return TAILQ_FIRST(&ic->ic_vaps);
2777}
2778
2779static void
2780rum_tx_data(struct rum_softc *sc, struct mbuf *m,
2781    struct ieee80211_node *ni)
2782{
2783	struct ieee80211vap *vap = ni->ni_vap;
2784	struct ieee80211com *ic = ni->ni_ic;
2785	const struct ieee80211_txparam *tp;
2786	struct ieee80211_frame *wh;
2787	struct ieee80211_key *k;
2788	uint32_t flags = 0;
2789	uint16_t dur;
2790	uint16_t rate;
2791
2792	DPRINTFN(11, "Sending data.\n");
2793
2794	wh = mtod(m, struct ieee80211_frame *);
2795
2796	tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)];
2797	if (IEEE80211_IS_MULTICAST(wh->i_addr1))
2798		rate = tp->mcastrate;
2799	else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
2800		rate = tp->ucastrate;
2801	else
2802		rate = ni->ni_txrate;
2803
2804	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
2805		k = ieee80211_crypto_encap(ni, m);
2806		if (k == NULL) {
2807			m_freem(m);
2808			ieee80211_free_node(ni);
2809			return;
2810		}
2811		/* packet header may have moved, reset our local pointer */
2812		wh = mtod(m, struct ieee80211_frame *);
2813	}
2814	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
2815		uint8_t prot = IEEE80211_PROT_NONE;
2816
2817		if (m->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold)
2818			prot = IEEE80211_PROT_RTSCTS;
2819		else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
2820		    ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
2821			prot = ic->ic_protmode;
2822		if (prot != IEEE80211_PROT_NONE) {
2823			rum_tx_prot(sc, m, ni, prot, rate);
2824			flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
2825		}
2826		flags |= RT2573_TX_NEED_ACK;
2827		flags |= RT2573_TX_MORE_FRAG;
2828
2829		dur = ieee80211_ack_duration(sc->sc_rates, rate,
2830		    ic->ic_flags & IEEE80211_F_SHPREAMBLE);
2831		USETW(wh->i_dur, dur);
2832	}
2833	m->m_pkthdr.rcvif = (void *)ni;
2834	rum_setup_desc_and_tx(sc, m, flags, 0, rate);
2835	return;
2836}
2837
2838static void
2839rum_tx_prot(struct rum_softc *sc,
2840    const struct mbuf *m, struct ieee80211_node *ni,
2841    uint8_t prot, uint16_t rate)
2842{
2843	struct ieee80211com *ic = ni->ni_ic;
2844	const struct ieee80211_frame *wh;
2845	struct mbuf *mprot;
2846	uint32_t flags;
2847	uint16_t protrate;
2848	uint16_t ackrate;
2849	uint16_t pktlen;
2850	uint16_t dur;
2851	uint8_t isshort;
2852
2853	KASSERT((prot == IEEE80211_PROT_RTSCTS) ||
2854	    (prot == IEEE80211_PROT_CTSONLY),
2855	    ("protection %u", prot));
2856
2857	DPRINTFN(11, "Sending protection frame.\n");
2858
2859	wh = mtod(m, const struct ieee80211_frame *);
2860	pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN;
2861
2862	protrate = ieee80211_ctl_rate(sc->sc_rates, rate);
2863	ackrate = ieee80211_ack_rate(sc->sc_rates, rate);
2864
2865	isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0;
2866	dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort);
2867	+ieee80211_ack_duration(sc->sc_rates, rate, isshort);
2868	flags = RT2573_TX_MORE_FRAG;
2869	if (prot == IEEE80211_PROT_RTSCTS) {
2870		/* NB: CTS is the same size as an ACK */
2871		dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort);
2872		flags |= RT2573_TX_NEED_ACK;
2873		mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur);
2874	} else {
2875		mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur);
2876	}
2877	if (mprot == NULL) {
2878		return;
2879	}
2880	mprot->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ni);
2881	rum_setup_desc_and_tx(sc, mprot, flags, 0, protrate);
2882	return;
2883}
2884
2885static void
2886rum_tx_raw(struct rum_softc *sc, struct mbuf *m, struct ieee80211_node *ni,
2887    const struct ieee80211_bpf_params *params)
2888{
2889	uint32_t flags;
2890	uint16_t rate;
2891
2892	DPRINTFN(11, "Sending raw frame.\n");
2893
2894	rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
2895
2896	/* XXX validate */
2897	if (rate == 0) {
2898		m_freem(m);
2899		ieee80211_free_node(ni);
2900		return;
2901	}
2902	flags = 0;
2903	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
2904		flags |= RT2573_TX_NEED_ACK;
2905	if (params->ibp_flags & (IEEE80211_BPF_RTS | IEEE80211_BPF_CTS)) {
2906		rum_tx_prot(sc, m, ni,
2907		    params->ibp_flags & IEEE80211_BPF_RTS ?
2908		    IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY,
2909		    rate);
2910		flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS;
2911	}
2912	m->m_pkthdr.rcvif = (void *)ni;
2913	rum_setup_desc_and_tx(sc, m, flags, 0, rate);
2914	return;
2915}
2916
2917static int
2918rum_raw_xmit_cb(struct ieee80211_node *ni, struct mbuf *m,
2919    const struct ieee80211_bpf_params *params)
2920{
2921	struct ieee80211com *ic = ni->ni_ic;
2922	struct ifnet *ifp = ic->ic_ifp;
2923	struct rum_softc *sc = ifp->if_softc;
2924
2925	mtx_lock(&sc->sc_mtx);
2926	if (params == NULL) {
2927		/*
2928		 * Legacy path; interpret frame contents to decide
2929		 * precisely how to send the frame.
2930		 */
2931		rum_tx_mgt(sc, m, ni);
2932	} else {
2933		/*
2934		 * Caller supplied explicit parameters to use in
2935		 * sending the frame.
2936		 */
2937		rum_tx_raw(sc, m, ni, params);
2938	}
2939	mtx_unlock(&sc->sc_mtx);
2940	return (0);
2941}
2942
2943static void
2944rum_update_mcast_cb(struct ifnet *ifp)
2945{
2946	/* not supported */
2947	return;
2948}
2949
2950static void
2951rum_update_promisc_cb(struct ifnet *ifp)
2952{
2953	struct rum_softc *sc = ifp->if_softc;
2954
2955	mtx_lock(&sc->sc_mtx);
2956	usb2_config_td_queue_command
2957	    (&sc->sc_config_td, &rum_config_copy,
2958	    &rum_cfg_update_promisc, 0, 0);
2959	mtx_unlock(&sc->sc_mtx);
2960	return;
2961}
2962