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