1 /* $FreeBSD: head/sys/dev/usb/wlan/if_rum.c 276701 2015-01-05 15:04:17Z hselasky $ */
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>
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.
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.
22 * Ralink Technology RT2501USB/RT2601USB chipset driver
23 * http://www.ralinktech.com.tw/
26 #include <sys/param.h>
27 #include <sys/sockio.h>
28 #include <sys/sysctl.h>
31 #include <sys/kernel.h>
32 #include <sys/socket.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
37 #include <sys/endian.h>
43 #include <net/if_arp.h>
44 #include <net/ethernet.h>
45 #include <net/if_dl.h>
46 #include <net/if_media.h>
47 #include <net/if_types.h>
48 #include <net/ifq_var.h>
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/in_var.h>
54 #include <netinet/if_ether.h>
55 #include <netinet/ip.h>
58 #include <netproto/802_11/ieee80211_var.h>
59 #include <netproto/802_11/ieee80211_regdomain.h>
60 #include <netproto/802_11/ieee80211_radiotap.h>
61 #include <netproto/802_11/ieee80211_ratectl.h>
63 #include <bus/u4b/usb.h>
64 #include <bus/u4b/usbdi.h>
67 #define USB_DEBUG_VAR rum_debug
68 #include <bus/u4b/usb_debug.h>
70 #include <bus/u4b/wlan/if_rumreg.h>
71 #include <bus/u4b/wlan/if_rumvar.h>
72 #include <bus/u4b/wlan/if_rumfw.h>
75 static int rum_debug
= 0;
77 static SYSCTL_NODE(_hw_usb
, OID_AUTO
, rum
, CTLFLAG_RW
, 0, "USB rum");
78 SYSCTL_INT(_hw_usb_rum
, OID_AUTO
, debug
, CTLFLAG_RW
, &rum_debug
, 0,
82 #define N(a) ((int)(sizeof (a) / sizeof ((a)[0])))
84 static const STRUCT_USB_HOST_ID rum_devs
[] = {
85 #define RUM_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
86 RUM_DEV(ABOCOM
, HWU54DM
),
87 RUM_DEV(ABOCOM
, RT2573_2
),
88 RUM_DEV(ABOCOM
, RT2573_3
),
89 RUM_DEV(ABOCOM
, RT2573_4
),
90 RUM_DEV(ABOCOM
, WUG2700
),
91 RUM_DEV(AMIT
, CGWLUSB2GO
),
92 RUM_DEV(ASUS
, RT2573_1
),
93 RUM_DEV(ASUS
, RT2573_2
),
94 RUM_DEV(BELKIN
, F5D7050A
),
95 RUM_DEV(BELKIN
, F5D9050V3
),
96 RUM_DEV(CISCOLINKSYS
, WUSB54GC
),
97 RUM_DEV(CISCOLINKSYS
, WUSB54GR
),
98 RUM_DEV(CONCEPTRONIC2
, C54RU2
),
99 RUM_DEV(COREGA
, CGWLUSB2GL
),
100 RUM_DEV(COREGA
, CGWLUSB2GPX
),
101 RUM_DEV(DICKSMITH
, CWD854F
),
102 RUM_DEV(DICKSMITH
, RT2573
),
103 RUM_DEV(EDIMAX
, EW7318USG
),
104 RUM_DEV(DLINK2
, DWLG122C1
),
105 RUM_DEV(DLINK2
, WUA1340
),
106 RUM_DEV(DLINK2
, DWA111
),
107 RUM_DEV(DLINK2
, DWA110
),
108 RUM_DEV(GIGABYTE
, GNWB01GS
),
109 RUM_DEV(GIGABYTE
, GNWI05GS
),
110 RUM_DEV(GIGASET
, RT2573
),
111 RUM_DEV(GOODWAY
, RT2573
),
112 RUM_DEV(GUILLEMOT
, HWGUSB254LB
),
113 RUM_DEV(GUILLEMOT
, HWGUSB254V2AP
),
114 RUM_DEV(HUAWEI3COM
, WUB320G
),
115 RUM_DEV(MELCO
, G54HP
),
116 RUM_DEV(MELCO
, SG54HP
),
117 RUM_DEV(MELCO
, SG54HG
),
118 RUM_DEV(MELCO
, WLIUCG
),
119 RUM_DEV(MELCO
, WLRUCG
),
120 RUM_DEV(MELCO
, WLRUCGAOSS
),
121 RUM_DEV(MSI
, RT2573_1
),
122 RUM_DEV(MSI
, RT2573_2
),
123 RUM_DEV(MSI
, RT2573_3
),
124 RUM_DEV(MSI
, RT2573_4
),
125 RUM_DEV(NOVATECH
, RT2573
),
126 RUM_DEV(PLANEX2
, GWUS54HP
),
127 RUM_DEV(PLANEX2
, GWUS54MINI2
),
128 RUM_DEV(PLANEX2
, GWUSMM
),
129 RUM_DEV(QCOM
, RT2573
),
130 RUM_DEV(QCOM
, RT2573_2
),
131 RUM_DEV(QCOM
, RT2573_3
),
132 RUM_DEV(RALINK
, RT2573
),
133 RUM_DEV(RALINK
, RT2573_2
),
134 RUM_DEV(RALINK
, RT2671
),
135 RUM_DEV(SITECOMEU
, WL113R2
),
136 RUM_DEV(SITECOMEU
, WL172
),
137 RUM_DEV(SPARKLAN
, RT2573
),
138 RUM_DEV(SURECOM
, RT2573
),
142 static device_probe_t rum_match
;
143 static device_attach_t rum_attach
;
144 static device_detach_t rum_detach
;
146 static usb_callback_t rum_bulk_read_callback
;
147 static usb_callback_t rum_bulk_write_callback
;
149 static usb_error_t
rum_do_request(struct rum_softc
*sc
,
150 struct usb_device_request
*req
, void *data
);
151 static struct ieee80211vap
*rum_vap_create(struct ieee80211com
*,
152 const char [IFNAMSIZ
], int,
153 enum ieee80211_opmode
,
154 int, const uint8_t [IEEE80211_ADDR_LEN
],
155 const uint8_t [IEEE80211_ADDR_LEN
]);
156 static void rum_vap_delete(struct ieee80211vap
*);
157 static void rum_tx_free(struct rum_tx_data
*, int);
158 static void rum_setup_tx_list(struct rum_softc
*);
159 static void rum_unsetup_tx_list(struct rum_softc
*);
160 static int rum_newstate(struct ieee80211vap
*,
161 enum ieee80211_state
, int);
162 static void rum_setup_tx_desc(struct rum_softc
*,
163 struct rum_tx_desc
*, uint32_t, uint16_t, int,
165 static int rum_tx_mgt(struct rum_softc
*, struct mbuf
*,
166 struct ieee80211_node
*);
167 static int rum_tx_raw(struct rum_softc
*, struct mbuf
*,
168 struct ieee80211_node
*,
169 const struct ieee80211_bpf_params
*);
170 static int rum_tx_data(struct rum_softc
*, struct mbuf
*,
171 struct ieee80211_node
*);
172 static void rum_start(struct ifnet
*, struct ifaltq_subque
*);
173 static int rum_ioctl(struct ifnet
*, u_long
, caddr_t
,
175 static void rum_eeprom_read(struct rum_softc
*, uint16_t, void *,
177 static uint32_t rum_read(struct rum_softc
*, uint16_t);
178 static void rum_read_multi(struct rum_softc
*, uint16_t, void *,
180 static usb_error_t
rum_write(struct rum_softc
*, uint16_t, uint32_t);
181 static usb_error_t
rum_write_multi(struct rum_softc
*, uint16_t, void *,
183 static void rum_bbp_write(struct rum_softc
*, uint8_t, uint8_t);
184 static uint8_t rum_bbp_read(struct rum_softc
*, uint8_t);
185 static void rum_rf_write(struct rum_softc
*, uint8_t, uint32_t);
186 static void rum_select_antenna(struct rum_softc
*);
187 static void rum_enable_mrr(struct rum_softc
*);
188 static void rum_set_txpreamble(struct rum_softc
*);
189 static void rum_set_basicrates(struct rum_softc
*);
190 static void rum_select_band(struct rum_softc
*,
191 struct ieee80211_channel
*);
192 static void rum_set_chan(struct rum_softc
*,
193 struct ieee80211_channel
*);
194 static void rum_enable_tsf_sync(struct rum_softc
*);
195 static void rum_enable_tsf(struct rum_softc
*);
196 static void rum_update_slot(struct ifnet
*);
197 static void rum_set_bssid(struct rum_softc
*, const uint8_t *);
198 static void rum_set_macaddr(struct rum_softc
*, const uint8_t *);
199 static void rum_update_mcast(struct ifnet
*);
200 static void rum_update_promisc(struct ifnet
*);
201 static void rum_setpromisc(struct rum_softc
*);
202 static const char *rum_get_rf(int);
203 static void rum_read_eeprom(struct rum_softc
*);
204 static int rum_bbp_init(struct rum_softc
*);
205 static void rum_init_locked(struct rum_softc
*);
206 static void rum_init(void *);
207 static void rum_stop(struct rum_softc
*);
208 static void rum_load_microcode(struct rum_softc
*, const uint8_t *,
210 static void rum_prepare_beacon(struct rum_softc
*,
211 struct ieee80211vap
*);
212 static int rum_raw_xmit(struct ieee80211_node
*, struct mbuf
*,
213 const struct ieee80211_bpf_params
*);
214 static void rum_scan_start(struct ieee80211com
*);
215 static void rum_scan_end(struct ieee80211com
*);
216 static void rum_set_channel(struct ieee80211com
*);
217 static int rum_get_rssi(struct rum_softc
*, uint8_t);
218 static void rum_ratectl_start(struct rum_softc
*,
219 struct ieee80211_node
*);
220 static void rum_ratectl_timeout(void *);
221 static void rum_ratectl_task(void *, int);
222 static int rum_pause(struct rum_softc
*, int);
224 static const struct {
228 { RT2573_TXRX_CSR0
, 0x025fb032 },
229 { RT2573_TXRX_CSR1
, 0x9eaa9eaf },
230 { RT2573_TXRX_CSR2
, 0x8a8b8c8d },
231 { RT2573_TXRX_CSR3
, 0x00858687 },
232 { RT2573_TXRX_CSR7
, 0x2e31353b },
233 { RT2573_TXRX_CSR8
, 0x2a2a2a2c },
234 { RT2573_TXRX_CSR15
, 0x0000000f },
235 { RT2573_MAC_CSR6
, 0x00000fff },
236 { RT2573_MAC_CSR8
, 0x016c030a },
237 { RT2573_MAC_CSR10
, 0x00000718 },
238 { RT2573_MAC_CSR12
, 0x00000004 },
239 { RT2573_MAC_CSR13
, 0x00007f00 },
240 { RT2573_SEC_CSR0
, 0x00000000 },
241 { RT2573_SEC_CSR1
, 0x00000000 },
242 { RT2573_SEC_CSR5
, 0x00000000 },
243 { RT2573_PHY_CSR1
, 0x000023b0 },
244 { RT2573_PHY_CSR5
, 0x00040a06 },
245 { RT2573_PHY_CSR6
, 0x00080606 },
246 { RT2573_PHY_CSR7
, 0x00000408 },
247 { RT2573_AIFSN_CSR
, 0x00002273 },
248 { RT2573_CWMIN_CSR
, 0x00002344 },
249 { RT2573_CWMAX_CSR
, 0x000034aa }
252 static const struct {
284 static const struct rfprog
{
286 uint32_t r1
, r2
, r3
, r4
;
288 { 1, 0x00b03, 0x001e1, 0x1a014, 0x30282 },
289 { 2, 0x00b03, 0x001e1, 0x1a014, 0x30287 },
290 { 3, 0x00b03, 0x001e2, 0x1a014, 0x30282 },
291 { 4, 0x00b03, 0x001e2, 0x1a014, 0x30287 },
292 { 5, 0x00b03, 0x001e3, 0x1a014, 0x30282 },
293 { 6, 0x00b03, 0x001e3, 0x1a014, 0x30287 },
294 { 7, 0x00b03, 0x001e4, 0x1a014, 0x30282 },
295 { 8, 0x00b03, 0x001e4, 0x1a014, 0x30287 },
296 { 9, 0x00b03, 0x001e5, 0x1a014, 0x30282 },
297 { 10, 0x00b03, 0x001e5, 0x1a014, 0x30287 },
298 { 11, 0x00b03, 0x001e6, 0x1a014, 0x30282 },
299 { 12, 0x00b03, 0x001e6, 0x1a014, 0x30287 },
300 { 13, 0x00b03, 0x001e7, 0x1a014, 0x30282 },
301 { 14, 0x00b03, 0x001e8, 0x1a014, 0x30284 },
303 { 34, 0x00b03, 0x20266, 0x36014, 0x30282 },
304 { 38, 0x00b03, 0x20267, 0x36014, 0x30284 },
305 { 42, 0x00b03, 0x20268, 0x36014, 0x30286 },
306 { 46, 0x00b03, 0x20269, 0x36014, 0x30288 },
308 { 36, 0x00b03, 0x00266, 0x26014, 0x30288 },
309 { 40, 0x00b03, 0x00268, 0x26014, 0x30280 },
310 { 44, 0x00b03, 0x00269, 0x26014, 0x30282 },
311 { 48, 0x00b03, 0x0026a, 0x26014, 0x30284 },
312 { 52, 0x00b03, 0x0026b, 0x26014, 0x30286 },
313 { 56, 0x00b03, 0x0026c, 0x26014, 0x30288 },
314 { 60, 0x00b03, 0x0026e, 0x26014, 0x30280 },
315 { 64, 0x00b03, 0x0026f, 0x26014, 0x30282 },
317 { 100, 0x00b03, 0x0028a, 0x2e014, 0x30280 },
318 { 104, 0x00b03, 0x0028b, 0x2e014, 0x30282 },
319 { 108, 0x00b03, 0x0028c, 0x2e014, 0x30284 },
320 { 112, 0x00b03, 0x0028d, 0x2e014, 0x30286 },
321 { 116, 0x00b03, 0x0028e, 0x2e014, 0x30288 },
322 { 120, 0x00b03, 0x002a0, 0x2e014, 0x30280 },
323 { 124, 0x00b03, 0x002a1, 0x2e014, 0x30282 },
324 { 128, 0x00b03, 0x002a2, 0x2e014, 0x30284 },
325 { 132, 0x00b03, 0x002a3, 0x2e014, 0x30286 },
326 { 136, 0x00b03, 0x002a4, 0x2e014, 0x30288 },
327 { 140, 0x00b03, 0x002a6, 0x2e014, 0x30280 },
329 { 149, 0x00b03, 0x002a8, 0x2e014, 0x30287 },
330 { 153, 0x00b03, 0x002a9, 0x2e014, 0x30289 },
331 { 157, 0x00b03, 0x002ab, 0x2e014, 0x30281 },
332 { 161, 0x00b03, 0x002ac, 0x2e014, 0x30283 },
333 { 165, 0x00b03, 0x002ad, 0x2e014, 0x30285 }
335 { 1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },
336 { 2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },
337 { 3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },
338 { 4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },
339 { 5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },
340 { 6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },
341 { 7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },
342 { 8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },
343 { 9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },
344 { 10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },
345 { 11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },
346 { 12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },
347 { 13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },
348 { 14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },
350 { 34, 0x00b33, 0x01266, 0x26014, 0x30282 },
351 { 38, 0x00b33, 0x01267, 0x26014, 0x30284 },
352 { 42, 0x00b33, 0x01268, 0x26014, 0x30286 },
353 { 46, 0x00b33, 0x01269, 0x26014, 0x30288 },
355 { 36, 0x00b33, 0x01266, 0x26014, 0x30288 },
356 { 40, 0x00b33, 0x01268, 0x26014, 0x30280 },
357 { 44, 0x00b33, 0x01269, 0x26014, 0x30282 },
358 { 48, 0x00b33, 0x0126a, 0x26014, 0x30284 },
359 { 52, 0x00b33, 0x0126b, 0x26014, 0x30286 },
360 { 56, 0x00b33, 0x0126c, 0x26014, 0x30288 },
361 { 60, 0x00b33, 0x0126e, 0x26014, 0x30280 },
362 { 64, 0x00b33, 0x0126f, 0x26014, 0x30282 },
364 { 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },
365 { 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },
366 { 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },
367 { 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },
368 { 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },
369 { 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },
370 { 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },
371 { 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },
372 { 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },
373 { 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },
374 { 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },
376 { 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },
377 { 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },
378 { 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },
379 { 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },
380 { 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
383 static const struct usb_config rum_config
[RUM_N_TRANSFER
] = {
386 .endpoint
= UE_ADDR_ANY
,
387 .direction
= UE_DIR_OUT
,
388 .bufsize
= (MCLBYTES
+ RT2573_TX_DESC_SIZE
+ 8),
389 .flags
= {.pipe_bof
= 1,.force_short_xfer
= 1,},
390 .callback
= rum_bulk_write_callback
,
391 .timeout
= 5000, /* ms */
395 .endpoint
= UE_ADDR_ANY
,
396 .direction
= UE_DIR_IN
,
397 .bufsize
= (MCLBYTES
+ RT2573_RX_DESC_SIZE
),
398 .flags
= {.pipe_bof
= 1,.short_xfer_ok
= 1,},
399 .callback
= rum_bulk_read_callback
,
404 rum_match(device_t self
)
406 struct usb_attach_arg
*uaa
= device_get_ivars(self
);
408 if (uaa
->usb_mode
!= USB_MODE_HOST
)
410 if (uaa
->info
.bConfigIndex
!= 0)
412 if (uaa
->info
.bIfaceIndex
!= RT2573_IFACE_INDEX
)
415 return (usbd_lookup_id_by_uaa(rum_devs
, sizeof(rum_devs
), uaa
));
419 rum_attach(device_t self
)
421 struct usb_attach_arg
*uaa
= device_get_ivars(self
);
422 struct rum_softc
*sc
= device_get_softc(self
);
423 struct ieee80211com
*ic
;
425 uint8_t iface_index
, bands
;
429 wlan_serialize_enter();
430 device_set_usb_desc(self
);
431 sc
->sc_udev
= uaa
->device
;
434 lockinit(&sc
->sc_lock
, device_get_nameunit(self
), 0, LK_CANRECURSE
);
436 iface_index
= RT2573_IFACE_INDEX
;
437 error
= usbd_transfer_setup(uaa
->device
, &iface_index
,
438 sc
->sc_xfer
, rum_config
, RUM_N_TRANSFER
, sc
, &sc
->sc_lock
);
440 device_printf(self
, "could not allocate USB transfers, "
441 "err=%s\n", usbd_errstr(error
));
446 /* retrieve RT2573 rev. no */
447 for (ntries
= 0; ntries
< 100; ntries
++) {
448 if ((tmp
= rum_read(sc
, RT2573_MAC_CSR0
)) != 0)
450 if (rum_pause(sc
, hz
/ 100))
454 device_printf(sc
->sc_dev
, "timeout waiting for chip to settle\n");
459 /* retrieve MAC address and various other things from EEPROM */
462 device_printf(sc
->sc_dev
, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n",
463 tmp
, rum_get_rf(sc
->rf_rev
));
465 rum_load_microcode(sc
, rt2573_ucode
, sizeof(rt2573_ucode
));
468 ifp
= sc
->sc_ifp
= if_alloc(IFT_IEEE80211
);
470 device_printf(sc
->sc_dev
, "can not if_alloc()\n");
476 if_initname(ifp
, "rum", device_get_unit(sc
->sc_dev
));
477 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
478 ifp
->if_init
= rum_init
;
479 ifp
->if_ioctl
= rum_ioctl
;
480 ifp
->if_start
= rum_start
;
481 ifq_set_maxlen(&ifp
->if_snd
, ifqmaxlen
);
482 #if 0 /* XXX swildner: see c3d4131842e47b168d93a0650d58d425ebeef789 */
483 ifq_set_ready(&ifp
->if_snd
);
486 ic
->ic_phytype
= IEEE80211_T_OFDM
; /* not only, but not used */
488 /* set device capabilities */
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_TXPMGT
/* tx power management */
495 | IEEE80211_C_SHPREAMBLE
/* short preamble supported */
496 | IEEE80211_C_SHSLOT
/* short slot time supported */
497 | IEEE80211_C_BGSCAN
/* bg scanning supported */
498 | IEEE80211_C_WPA
/* 802.11i */
502 setbit(&bands
, IEEE80211_MODE_11B
);
503 setbit(&bands
, IEEE80211_MODE_11G
);
504 if (sc
->rf_rev
== RT2573_RF_5225
|| sc
->rf_rev
== RT2573_RF_5226
)
505 setbit(&bands
, IEEE80211_MODE_11A
);
506 ieee80211_init_channels(ic
, NULL
, &bands
);
508 ieee80211_ifattach(ic
, sc
->sc_bssid
);
509 ic
->ic_update_promisc
= rum_update_promisc
;
510 ic
->ic_raw_xmit
= rum_raw_xmit
;
511 ic
->ic_scan_start
= rum_scan_start
;
512 ic
->ic_scan_end
= rum_scan_end
;
513 ic
->ic_set_channel
= rum_set_channel
;
515 ic
->ic_vap_create
= rum_vap_create
;
516 ic
->ic_vap_delete
= rum_vap_delete
;
517 ic
->ic_update_mcast
= rum_update_mcast
;
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
);
526 ieee80211_announce(ic
);
528 wlan_serialize_exit();
532 wlan_serialize_exit();
534 return (ENXIO
); /* failure */
538 rum_detach(device_t self
)
540 struct rum_softc
*sc
= device_get_softc(self
);
541 struct ifnet
*ifp
= sc
->sc_ifp
;
542 struct ieee80211com
*ic
;
544 wlan_serialize_enter();
545 /* Prevent further ioctls */
550 /* stop all USB transfers */
551 usbd_transfer_unsetup(sc
->sc_xfer
, RUM_N_TRANSFER
);
553 /* free TX list, if any */
555 rum_unsetup_tx_list(sc
);
560 ieee80211_ifdetach(ic
);
563 lockuninit(&sc
->sc_lock
);
564 wlan_serialize_exit();
569 rum_do_request(struct rum_softc
*sc
,
570 struct usb_device_request
*req
, void *data
)
576 err
= usbd_do_request_flags(sc
->sc_udev
, &sc
->sc_lock
,
577 req
, data
, 0, NULL
, 250 /* ms */);
581 DPRINTFN(1, "Control request failed, %s (retrying)\n",
583 if (rum_pause(sc
, hz
/ 100))
589 static struct ieee80211vap
*
590 rum_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
])
595 struct rum_softc
*sc
= ic
->ic_ifp
->if_softc
;
597 struct ieee80211vap
*vap
;
599 if (!TAILQ_EMPTY(&ic
->ic_vaps
)) /* only one at a time */
601 rvp
= (struct rum_vap
*) kmalloc(sizeof(struct rum_vap
),
602 M_80211_VAP
, M_INTWAIT
| M_ZERO
);
606 /* enable s/w bmiss handling for sta mode */
608 if (ieee80211_vap_setup(ic
, vap
, name
, unit
, opmode
,
609 flags
| IEEE80211_CLONE_NOBEACONS
, bssid
, mac
) != 0) {
611 kfree(rvp
, M_80211_VAP
);
615 /* override state transition machine */
616 rvp
->newstate
= vap
->iv_newstate
;
617 vap
->iv_newstate
= rum_newstate
;
619 usb_callout_init_mtx(&rvp
->ratectl_ch
, &sc
->sc_lock
, 0);
620 TASK_INIT(&rvp
->ratectl_task
, 0, rum_ratectl_task
, rvp
);
621 ieee80211_ratectl_init(vap
);
622 ieee80211_ratectl_setinterval(vap
, 1000 /* 1 sec */);
624 ieee80211_vap_attach(vap
, ieee80211_media_change
, ieee80211_media_status
);
625 ic
->ic_opmode
= opmode
;
630 rum_vap_delete(struct ieee80211vap
*vap
)
632 struct rum_vap
*rvp
= RUM_VAP(vap
);
633 struct ieee80211com
*ic
= vap
->iv_ic
;
635 usb_callout_drain(&rvp
->ratectl_ch
);
636 ieee80211_draintask(ic
, &rvp
->ratectl_task
);
637 ieee80211_ratectl_deinit(vap
);
638 ieee80211_vap_detach(vap
);
639 kfree(rvp
, M_80211_VAP
);
643 rum_tx_free(struct rum_tx_data
*data
, int txerr
)
645 struct rum_softc
*sc
= data
->sc
;
647 if (data
->m
!= NULL
) {
648 if (data
->m
->m_flags
& M_TXCB
)
649 ieee80211_process_callback(data
->ni
, data
->m
,
650 txerr
? ETIMEDOUT
: 0);
654 ieee80211_free_node(data
->ni
);
657 STAILQ_INSERT_TAIL(&sc
->tx_free
, data
, next
);
662 rum_setup_tx_list(struct rum_softc
*sc
)
664 struct rum_tx_data
*data
;
668 STAILQ_INIT(&sc
->tx_q
);
669 STAILQ_INIT(&sc
->tx_free
);
671 for (i
= 0; i
< RUM_TX_LIST_COUNT
; i
++) {
672 data
= &sc
->tx_data
[i
];
675 STAILQ_INSERT_TAIL(&sc
->tx_free
, data
, next
);
681 rum_unsetup_tx_list(struct rum_softc
*sc
)
683 struct rum_tx_data
*data
;
686 /* make sure any subsequent use of the queues will fail */
688 STAILQ_INIT(&sc
->tx_q
);
689 STAILQ_INIT(&sc
->tx_free
);
691 /* free up all node references and mbufs */
692 for (i
= 0; i
< RUM_TX_LIST_COUNT
; i
++) {
693 data
= &sc
->tx_data
[i
];
695 if (data
->m
!= NULL
) {
699 if (data
->ni
!= NULL
) {
700 ieee80211_free_node(data
->ni
);
707 rum_newstate(struct ieee80211vap
*vap
, enum ieee80211_state nstate
, int arg
)
709 struct rum_vap
*rvp
= RUM_VAP(vap
);
710 struct ieee80211com
*ic
= vap
->iv_ic
;
711 struct rum_softc
*sc
= ic
->ic_ifp
->if_softc
;
712 const struct ieee80211_txparam
*tp
;
713 enum ieee80211_state ostate
;
714 struct ieee80211_node
*ni
;
717 ostate
= vap
->iv_state
;
718 DPRINTF("%s -> %s\n",
719 ieee80211_state_name
[ostate
],
720 ieee80211_state_name
[nstate
]);
722 IEEE80211_UNLOCK(ic
);
724 usb_callout_stop(&rvp
->ratectl_ch
);
727 case IEEE80211_S_INIT
:
728 if (ostate
== IEEE80211_S_RUN
) {
729 /* abort TSF synchronization */
730 tmp
= rum_read(sc
, RT2573_TXRX_CSR9
);
731 rum_write(sc
, RT2573_TXRX_CSR9
, tmp
& ~0x00ffffff);
735 case IEEE80211_S_RUN
:
736 ni
= ieee80211_ref_node(vap
->iv_bss
);
738 if (vap
->iv_opmode
!= IEEE80211_M_MONITOR
) {
739 if (ic
->ic_bsschan
== IEEE80211_CHAN_ANYC
) {
742 ieee80211_free_node(ni
);
745 rum_update_slot(ic
->ic_ifp
);
747 rum_set_txpreamble(sc
);
748 rum_set_basicrates(sc
);
749 IEEE80211_ADDR_COPY(sc
->sc_bssid
, ni
->ni_bssid
);
750 rum_set_bssid(sc
, sc
->sc_bssid
);
753 if (vap
->iv_opmode
== IEEE80211_M_HOSTAP
||
754 vap
->iv_opmode
== IEEE80211_M_IBSS
)
755 rum_prepare_beacon(sc
, vap
);
757 if (vap
->iv_opmode
!= IEEE80211_M_MONITOR
)
758 rum_enable_tsf_sync(sc
);
762 /* enable automatic rate adaptation */
763 tp
= &vap
->iv_txparms
[ieee80211_chan2mode(ic
->ic_curchan
)];
764 if (tp
->ucastrate
== IEEE80211_FIXED_RATE_NONE
)
765 rum_ratectl_start(sc
, ni
);
766 ieee80211_free_node(ni
);
773 return (rvp
->newstate(vap
, nstate
, arg
));
777 rum_bulk_write_callback(struct usb_xfer
*xfer
, usb_error_t error
)
779 struct rum_softc
*sc
= usbd_xfer_softc(xfer
);
780 struct ifnet
*ifp
= sc
->sc_ifp
;
781 struct ieee80211vap
*vap
;
782 struct rum_tx_data
*data
;
784 struct usb_page_cache
*pc
;
788 usbd_xfer_status(xfer
, &actlen
, &sumlen
, NULL
, NULL
);
790 switch (USB_GET_STATE(xfer
)) {
791 case USB_ST_TRANSFERRED
:
792 DPRINTFN(11, "transfer complete, %d bytes\n", actlen
);
795 data
= usbd_xfer_get_priv(xfer
);
796 rum_tx_free(data
, 0);
797 usbd_xfer_set_priv(xfer
, NULL
);
799 IFNET_STAT_INC(ifp
, opackets
, 1);
800 ifq_clr_oactive(&ifp
->if_snd
);
805 data
= STAILQ_FIRST(&sc
->tx_q
);
807 STAILQ_REMOVE_HEAD(&sc
->tx_q
, next
);
810 if (m
->m_pkthdr
.len
> (int)(MCLBYTES
+ RT2573_TX_DESC_SIZE
)) {
811 DPRINTFN(0, "data overflow, %u bytes\n",
813 m
->m_pkthdr
.len
= (MCLBYTES
+ RT2573_TX_DESC_SIZE
);
815 pc
= usbd_xfer_get_frame(xfer
, 0);
816 usbd_copy_in(pc
, 0, &data
->desc
, RT2573_TX_DESC_SIZE
);
817 usbd_m_copy_in(pc
, RT2573_TX_DESC_SIZE
, m
, 0,
820 vap
= data
->ni
->ni_vap
;
821 if (ieee80211_radiotap_active_vap(vap
)) {
822 struct rum_tx_radiotap_header
*tap
= &sc
->sc_txtap
;
825 tap
->wt_rate
= data
->rate
;
826 tap
->wt_antenna
= sc
->tx_ant
;
828 ieee80211_radiotap_tx(vap
, m
);
831 /* align end on a 4-bytes boundary */
832 len
= (RT2573_TX_DESC_SIZE
+ m
->m_pkthdr
.len
+ 3) & ~3;
836 DPRINTFN(11, "sending frame len=%u xferlen=%u\n",
837 m
->m_pkthdr
.len
, len
);
839 usbd_xfer_set_frame_len(xfer
, 0, len
);
840 usbd_xfer_set_priv(xfer
, data
);
842 usbd_transfer_submit(xfer
);
845 rum_start(ifp
, NULL
);
850 DPRINTFN(11, "transfer error, %s\n",
853 IFNET_STAT_INC(ifp
, oerrors
, 1);
854 data
= usbd_xfer_get_priv(xfer
);
856 rum_tx_free(data
, error
);
857 usbd_xfer_set_priv(xfer
, NULL
);
860 if (error
!= USB_ERR_CANCELLED
) {
861 if (error
== USB_ERR_TIMEOUT
)
862 device_printf(sc
->sc_dev
, "device timeout\n");
865 * Try to clear stall first, also if other
866 * errors occur, hence clearing stall
867 * introduces a 50 ms delay:
869 usbd_xfer_set_stall(xfer
);
877 rum_bulk_read_callback(struct usb_xfer
*xfer
, usb_error_t error
)
879 struct rum_softc
*sc
= usbd_xfer_softc(xfer
);
880 struct ifnet
*ifp
= sc
->sc_ifp
;
881 struct ieee80211com
*ic
= ifp
->if_l2com
;
882 struct ieee80211_node
*ni
;
883 struct mbuf
*m
= NULL
;
884 struct usb_page_cache
*pc
;
889 usbd_xfer_status(xfer
, &len
, NULL
, NULL
, NULL
);
891 switch (USB_GET_STATE(xfer
)) {
892 case USB_ST_TRANSFERRED
:
894 DPRINTFN(15, "rx done, actlen=%d\n", len
);
896 if (len
< (int)(RT2573_RX_DESC_SIZE
+ IEEE80211_MIN_LEN
)) {
897 DPRINTF("%s: xfer too short %d\n",
898 device_get_nameunit(sc
->sc_dev
), len
);
899 IFNET_STAT_INC(ifp
, ierrors
, 1);
903 len
-= RT2573_RX_DESC_SIZE
;
904 pc
= usbd_xfer_get_frame(xfer
, 0);
905 usbd_copy_out(pc
, 0, &sc
->sc_rx_desc
, RT2573_RX_DESC_SIZE
);
907 rssi
= rum_get_rssi(sc
, sc
->sc_rx_desc
.rssi
);
908 flags
= le32toh(sc
->sc_rx_desc
.flags
);
909 if (flags
& RT2573_RX_CRC_ERROR
) {
911 * This should not happen since we did not
912 * request to receive those frames when we
913 * filled RUM_TXRX_CSR2:
915 DPRINTFN(5, "PHY or CRC error\n");
916 IFNET_STAT_INC(ifp
, ierrors
, 1);
920 m
= m_getcl(MB_DONTWAIT
, MT_DATA
, M_PKTHDR
);
922 DPRINTF("could not allocate mbuf\n");
923 IFNET_STAT_INC(ifp
, ierrors
, 1);
926 usbd_copy_out(pc
, RT2573_RX_DESC_SIZE
,
927 mtod(m
, uint8_t *), len
);
930 m
->m_pkthdr
.rcvif
= ifp
;
931 m
->m_pkthdr
.len
= m
->m_len
= (flags
>> 16) & 0xfff;
933 if (ieee80211_radiotap_active(ic
)) {
934 struct rum_rx_radiotap_header
*tap
= &sc
->sc_rxtap
;
938 tap
->wr_rate
= ieee80211_plcp2rate(sc
->sc_rx_desc
.rate
,
939 (flags
& RT2573_RX_OFDM
) ?
940 IEEE80211_T_OFDM
: IEEE80211_T_CCK
);
941 tap
->wr_antsignal
= RT2573_NOISE_FLOOR
+ rssi
;
942 tap
->wr_antnoise
= RT2573_NOISE_FLOOR
;
943 tap
->wr_antenna
= sc
->rx_ant
;
948 usbd_xfer_set_frame_len(xfer
, 0, usbd_xfer_max_len(xfer
));
949 usbd_transfer_submit(xfer
);
952 * At the end of a USB callback it is always safe to unlock
953 * the private mutex of a device! That is why we do the
954 * "ieee80211_input" here, and not some lines up!
958 ni
= ieee80211_find_rxnode(ic
,
959 mtod(m
, struct ieee80211_frame_min
*));
961 (void) ieee80211_input(ni
, m
, rssi
,
963 ieee80211_free_node(ni
);
965 (void) ieee80211_input_all(ic
, m
, rssi
,
968 if (!ifq_is_oactive(&ifp
->if_snd
) &&
969 !ifq_is_empty(&ifp
->if_snd
))
970 rum_start(ifp
, NULL
);
975 if (error
!= USB_ERR_CANCELLED
) {
976 /* try to clear stall first */
977 usbd_xfer_set_stall(xfer
);
985 rum_plcp_signal(int rate
)
988 /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
996 case 108: return 0xc;
998 /* CCK rates (NB: not IEEE std, device-specific) */
1001 case 11: return 0x2;
1002 case 22: return 0x3;
1004 return 0xff; /* XXX unsupported/unknown rate */
1008 rum_setup_tx_desc(struct rum_softc
*sc
, struct rum_tx_desc
*desc
,
1009 uint32_t flags
, uint16_t xflags
, int len
, int rate
)
1011 struct ifnet
*ifp
= sc
->sc_ifp
;
1012 struct ieee80211com
*ic
= ifp
->if_l2com
;
1013 uint16_t plcp_length
;
1016 desc
->flags
= htole32(flags
);
1017 desc
->flags
|= htole32(RT2573_TX_VALID
);
1018 desc
->flags
|= htole32(len
<< 16);
1020 desc
->xflags
= htole16(xflags
);
1022 desc
->wme
= htole16(RT2573_QID(0) | RT2573_AIFSN(2) |
1023 RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10));
1025 /* setup PLCP fields */
1026 desc
->plcp_signal
= rum_plcp_signal(rate
);
1027 desc
->plcp_service
= 4;
1029 len
+= IEEE80211_CRC_LEN
;
1030 if (ieee80211_rate2phytype(ic
->ic_rt
, rate
) == IEEE80211_T_OFDM
) {
1031 desc
->flags
|= htole32(RT2573_TX_OFDM
);
1033 plcp_length
= len
& 0xfff;
1034 desc
->plcp_length_hi
= plcp_length
>> 6;
1035 desc
->plcp_length_lo
= plcp_length
& 0x3f;
1038 rate
= 2; /* avoid division by zero */
1039 plcp_length
= (16 * len
+ rate
- 1) / rate
;
1041 remainder
= (16 * len
) % 22;
1042 if (remainder
!= 0 && remainder
< 7)
1043 desc
->plcp_service
|= RT2573_PLCP_LENGEXT
;
1045 desc
->plcp_length_hi
= plcp_length
>> 8;
1046 desc
->plcp_length_lo
= plcp_length
& 0xff;
1048 if (rate
!= 2 && (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
))
1049 desc
->plcp_signal
|= 0x08;
1054 rum_sendprot(struct rum_softc
*sc
,
1055 const struct mbuf
*m
, struct ieee80211_node
*ni
, int prot
, int rate
)
1057 struct ieee80211com
*ic
= ni
->ni_ic
;
1058 const struct ieee80211_frame
*wh
;
1059 struct rum_tx_data
*data
;
1061 int protrate
, ackrate
, pktlen
, flags
, isshort
;
1064 RUM_LOCK_ASSERT(sc
, MA_OWNED
);
1065 KASSERT(prot
== IEEE80211_PROT_RTSCTS
|| prot
== IEEE80211_PROT_CTSONLY
,
1066 ("protection %d", prot
));
1068 wh
= mtod(m
, const struct ieee80211_frame
*);
1069 pktlen
= m
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
;
1071 protrate
= ieee80211_ctl_rate(ic
->ic_rt
, rate
);
1072 ackrate
= ieee80211_ack_rate(ic
->ic_rt
, rate
);
1074 isshort
= (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
) != 0;
1075 dur
= ieee80211_compute_duration(ic
->ic_rt
, pktlen
, rate
, isshort
)
1076 + ieee80211_ack_duration(ic
->ic_rt
, rate
, isshort
);
1077 flags
= RT2573_TX_MORE_FRAG
;
1078 if (prot
== IEEE80211_PROT_RTSCTS
) {
1079 /* NB: CTS is the same size as an ACK */
1080 dur
+= ieee80211_ack_duration(ic
->ic_rt
, rate
, isshort
);
1081 flags
|= RT2573_TX_NEED_ACK
;
1082 mprot
= ieee80211_alloc_rts(ic
, wh
->i_addr1
, wh
->i_addr2
, dur
);
1084 mprot
= ieee80211_alloc_cts(ic
, ni
->ni_vap
->iv_myaddr
, dur
);
1086 if (mprot
== NULL
) {
1087 /* XXX stat + msg */
1090 data
= STAILQ_FIRST(&sc
->tx_free
);
1091 STAILQ_REMOVE_HEAD(&sc
->tx_free
, next
);
1095 data
->ni
= ieee80211_ref_node(ni
);
1096 data
->rate
= protrate
;
1097 rum_setup_tx_desc(sc
, &data
->desc
, flags
, 0, mprot
->m_pkthdr
.len
, protrate
);
1099 STAILQ_INSERT_TAIL(&sc
->tx_q
, data
, next
);
1100 usbd_transfer_start(sc
->sc_xfer
[RUM_BULK_WR
]);
1106 rum_tx_mgt(struct rum_softc
*sc
, struct mbuf
*m0
, struct ieee80211_node
*ni
)
1108 struct ieee80211vap
*vap
= ni
->ni_vap
;
1109 struct ifnet
*ifp
= sc
->sc_ifp
;
1110 struct ieee80211com
*ic
= ifp
->if_l2com
;
1111 struct rum_tx_data
*data
;
1112 struct ieee80211_frame
*wh
;
1113 const struct ieee80211_txparam
*tp
;
1114 struct ieee80211_key
*k
;
1118 RUM_LOCK_ASSERT(sc
, MA_OWNED
);
1120 data
= STAILQ_FIRST(&sc
->tx_free
);
1121 STAILQ_REMOVE_HEAD(&sc
->tx_free
, next
);
1124 wh
= mtod(m0
, struct ieee80211_frame
*);
1125 if (wh
->i_fc
[1] & IEEE80211_FC1_PROTECTED
) {
1126 k
= ieee80211_crypto_encap(ni
, m0
);
1131 wh
= mtod(m0
, struct ieee80211_frame
*);
1134 tp
= &vap
->iv_txparms
[ieee80211_chan2mode(ic
->ic_curchan
)];
1136 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
1137 flags
|= RT2573_TX_NEED_ACK
;
1139 dur
= ieee80211_ack_duration(ic
->ic_rt
, tp
->mgmtrate
,
1140 ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
);
1141 *(uint16_t *)wh
->i_dur
= htole16(dur
);
1143 /* tell hardware to add timestamp for probe responses */
1145 (IEEE80211_FC0_TYPE_MASK
| IEEE80211_FC0_SUBTYPE_MASK
)) ==
1146 (IEEE80211_FC0_TYPE_MGT
| IEEE80211_FC0_SUBTYPE_PROBE_RESP
))
1147 flags
|= RT2573_TX_TIMESTAMP
;
1152 data
->rate
= tp
->mgmtrate
;
1154 rum_setup_tx_desc(sc
, &data
->desc
, flags
, 0, m0
->m_pkthdr
.len
, tp
->mgmtrate
);
1156 DPRINTFN(10, "sending mgt frame len=%d rate=%d\n",
1157 m0
->m_pkthdr
.len
+ (int)RT2573_TX_DESC_SIZE
, tp
->mgmtrate
);
1159 STAILQ_INSERT_TAIL(&sc
->tx_q
, data
, next
);
1160 usbd_transfer_start(sc
->sc_xfer
[RUM_BULK_WR
]);
1166 rum_tx_raw(struct rum_softc
*sc
, struct mbuf
*m0
, struct ieee80211_node
*ni
,
1167 const struct ieee80211_bpf_params
*params
)
1169 struct ieee80211com
*ic
= ni
->ni_ic
;
1170 struct rum_tx_data
*data
;
1174 RUM_LOCK_ASSERT(sc
, MA_OWNED
);
1175 KASSERT(params
!= NULL
, ("no raw xmit params"));
1177 rate
= params
->ibp_rate0
;
1178 if (!ieee80211_isratevalid(ic
->ic_rt
, rate
)) {
1183 if ((params
->ibp_flags
& IEEE80211_BPF_NOACK
) == 0)
1184 flags
|= RT2573_TX_NEED_ACK
;
1185 if (params
->ibp_flags
& (IEEE80211_BPF_RTS
|IEEE80211_BPF_CTS
)) {
1186 error
= rum_sendprot(sc
, m0
, ni
,
1187 params
->ibp_flags
& IEEE80211_BPF_RTS
?
1188 IEEE80211_PROT_RTSCTS
: IEEE80211_PROT_CTSONLY
,
1190 if (error
|| sc
->tx_nfree
== 0) {
1194 flags
|= RT2573_TX_LONG_RETRY
| RT2573_TX_IFS_SIFS
;
1197 data
= STAILQ_FIRST(&sc
->tx_free
);
1198 STAILQ_REMOVE_HEAD(&sc
->tx_free
, next
);
1205 /* XXX need to setup descriptor ourself */
1206 rum_setup_tx_desc(sc
, &data
->desc
, flags
, 0, m0
->m_pkthdr
.len
, rate
);
1208 DPRINTFN(10, "sending raw frame len=%u rate=%u\n",
1209 m0
->m_pkthdr
.len
, rate
);
1211 STAILQ_INSERT_TAIL(&sc
->tx_q
, data
, next
);
1212 usbd_transfer_start(sc
->sc_xfer
[RUM_BULK_WR
]);
1218 rum_tx_data(struct rum_softc
*sc
, struct mbuf
*m0
, struct ieee80211_node
*ni
)
1220 struct ieee80211vap
*vap
= ni
->ni_vap
;
1221 struct ifnet
*ifp
= sc
->sc_ifp
;
1222 struct ieee80211com
*ic
= ifp
->if_l2com
;
1223 struct rum_tx_data
*data
;
1224 struct ieee80211_frame
*wh
;
1225 const struct ieee80211_txparam
*tp
;
1226 struct ieee80211_key
*k
;
1231 RUM_LOCK_ASSERT(sc
, MA_OWNED
);
1233 wh
= mtod(m0
, struct ieee80211_frame
*);
1235 tp
= &vap
->iv_txparms
[ieee80211_chan2mode(ni
->ni_chan
)];
1236 if (IEEE80211_IS_MULTICAST(wh
->i_addr1
))
1237 rate
= tp
->mcastrate
;
1238 else if (tp
->ucastrate
!= IEEE80211_FIXED_RATE_NONE
)
1239 rate
= tp
->ucastrate
;
1241 rate
= ni
->ni_txrate
;
1243 if (wh
->i_fc
[1] & IEEE80211_FC1_PROTECTED
) {
1244 k
= ieee80211_crypto_encap(ni
, m0
);
1250 /* packet header may have moved, reset our local pointer */
1251 wh
= mtod(m0
, struct ieee80211_frame
*);
1254 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
1255 int prot
= IEEE80211_PROT_NONE
;
1256 if (m0
->m_pkthdr
.len
+ IEEE80211_CRC_LEN
> vap
->iv_rtsthreshold
)
1257 prot
= IEEE80211_PROT_RTSCTS
;
1258 else if ((ic
->ic_flags
& IEEE80211_F_USEPROT
) &&
1259 ieee80211_rate2phytype(ic
->ic_rt
, rate
) == IEEE80211_T_OFDM
)
1260 prot
= ic
->ic_protmode
;
1261 if (prot
!= IEEE80211_PROT_NONE
) {
1262 error
= rum_sendprot(sc
, m0
, ni
, prot
, rate
);
1263 if (error
|| sc
->tx_nfree
== 0) {
1267 flags
|= RT2573_TX_LONG_RETRY
| RT2573_TX_IFS_SIFS
;
1271 data
= STAILQ_FIRST(&sc
->tx_free
);
1272 STAILQ_REMOVE_HEAD(&sc
->tx_free
, next
);
1279 if (!IEEE80211_IS_MULTICAST(wh
->i_addr1
)) {
1280 flags
|= RT2573_TX_NEED_ACK
;
1281 flags
|= RT2573_TX_MORE_FRAG
;
1283 dur
= ieee80211_ack_duration(ic
->ic_rt
, rate
,
1284 ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
);
1285 *(uint16_t *)wh
->i_dur
= htole16(dur
);
1288 rum_setup_tx_desc(sc
, &data
->desc
, flags
, 0, m0
->m_pkthdr
.len
, rate
);
1290 DPRINTFN(10, "sending frame len=%d rate=%d\n",
1291 m0
->m_pkthdr
.len
+ (int)RT2573_TX_DESC_SIZE
, rate
);
1293 STAILQ_INSERT_TAIL(&sc
->tx_q
, data
, next
);
1294 usbd_transfer_start(sc
->sc_xfer
[RUM_BULK_WR
]);
1300 rum_start(struct ifnet
*ifp
, struct ifaltq_subque
*ifsq
)
1302 struct rum_softc
*sc
= ifp
->if_softc
;
1303 struct ieee80211_node
*ni
;
1307 if ((ifp
->if_flags
& IFF_RUNNING
) == 0) {
1312 m
= ifq_dequeue(&ifp
->if_snd
);
1315 if (sc
->tx_nfree
< RUM_TX_MINFREE
) {
1316 ifq_prepend(&ifp
->if_snd
, m
);
1317 ifq_set_oactive(&ifp
->if_snd
);
1320 ni
= (struct ieee80211_node
*) m
->m_pkthdr
.rcvif
;
1321 if (rum_tx_data(sc
, m
, ni
) != 0) {
1322 ieee80211_free_node(ni
);
1323 IFNET_STAT_INC(ifp
, oerrors
, 1);
1331 rum_ioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
, struct ucred
*ucred
)
1333 struct rum_softc
*sc
= ifp
->if_softc
;
1334 struct ieee80211com
*ic
= ifp
->if_l2com
;
1335 struct ifreq
*ifr
= (struct ifreq
*) data
;
1340 error
= sc
->sc_detached
? ENXIO
: 0;
1348 if (ifp
->if_flags
& IFF_UP
) {
1349 if ((ifp
->if_flags
& IFF_RUNNING
) == 0) {
1350 rum_init_locked(sc
);
1355 if (ifp
->if_flags
& IFF_RUNNING
)
1360 ieee80211_start_all(ic
);
1363 error
= ifmedia_ioctl(ifp
, ifr
, &ic
->ic_media
, cmd
);
1366 error
= ether_ioctl(ifp
, cmd
, data
);
1376 rum_eeprom_read(struct rum_softc
*sc
, uint16_t addr
, void *buf
, int len
)
1378 struct usb_device_request req
;
1381 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
1382 req
.bRequest
= RT2573_READ_EEPROM
;
1383 USETW(req
.wValue
, 0);
1384 USETW(req
.wIndex
, addr
);
1385 USETW(req
.wLength
, len
);
1387 error
= rum_do_request(sc
, &req
, buf
);
1389 device_printf(sc
->sc_dev
, "could not read EEPROM: %s\n",
1390 usbd_errstr(error
));
1395 rum_read(struct rum_softc
*sc
, uint16_t reg
)
1399 rum_read_multi(sc
, reg
, &val
, sizeof val
);
1401 return le32toh(val
);
1405 rum_read_multi(struct rum_softc
*sc
, uint16_t reg
, void *buf
, int len
)
1407 struct usb_device_request req
;
1410 req
.bmRequestType
= UT_READ_VENDOR_DEVICE
;
1411 req
.bRequest
= RT2573_READ_MULTI_MAC
;
1412 USETW(req
.wValue
, 0);
1413 USETW(req
.wIndex
, reg
);
1414 USETW(req
.wLength
, len
);
1416 error
= rum_do_request(sc
, &req
, buf
);
1418 device_printf(sc
->sc_dev
,
1419 "could not multi read MAC register: %s\n",
1420 usbd_errstr(error
));
1425 rum_write(struct rum_softc
*sc
, uint16_t reg
, uint32_t val
)
1427 uint32_t tmp
= htole32(val
);
1429 return (rum_write_multi(sc
, reg
, &tmp
, sizeof tmp
));
1433 rum_write_multi(struct rum_softc
*sc
, uint16_t reg
, void *buf
, size_t len
)
1435 struct usb_device_request req
;
1439 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
1440 req
.bRequest
= RT2573_WRITE_MULTI_MAC
;
1441 USETW(req
.wValue
, 0);
1443 /* write at most 64 bytes at a time */
1444 for (offset
= 0; offset
< len
; offset
+= 64) {
1445 USETW(req
.wIndex
, reg
+ offset
);
1446 USETW(req
.wLength
, MIN(len
- offset
, 64));
1448 error
= rum_do_request(sc
, &req
, (char *)buf
+ offset
);
1450 device_printf(sc
->sc_dev
,
1451 "could not multi write MAC register: %s\n",
1452 usbd_errstr(error
));
1457 return (USB_ERR_NORMAL_COMPLETION
);
1461 rum_bbp_write(struct rum_softc
*sc
, uint8_t reg
, uint8_t val
)
1466 DPRINTFN(2, "reg=0x%08x\n", reg
);
1468 for (ntries
= 0; ntries
< 100; ntries
++) {
1469 if (!(rum_read(sc
, RT2573_PHY_CSR3
) & RT2573_BBP_BUSY
))
1471 if (rum_pause(sc
, hz
/ 100))
1474 if (ntries
== 100) {
1475 device_printf(sc
->sc_dev
, "could not write to BBP\n");
1479 tmp
= RT2573_BBP_BUSY
| (reg
& 0x7f) << 8 | val
;
1480 rum_write(sc
, RT2573_PHY_CSR3
, tmp
);
1484 rum_bbp_read(struct rum_softc
*sc
, uint8_t reg
)
1489 DPRINTFN(2, "reg=0x%08x\n", reg
);
1491 for (ntries
= 0; ntries
< 100; ntries
++) {
1492 if (!(rum_read(sc
, RT2573_PHY_CSR3
) & RT2573_BBP_BUSY
))
1494 if (rum_pause(sc
, hz
/ 100))
1497 if (ntries
== 100) {
1498 device_printf(sc
->sc_dev
, "could not read BBP\n");
1502 val
= RT2573_BBP_BUSY
| RT2573_BBP_READ
| reg
<< 8;
1503 rum_write(sc
, RT2573_PHY_CSR3
, val
);
1505 for (ntries
= 0; ntries
< 100; ntries
++) {
1506 val
= rum_read(sc
, RT2573_PHY_CSR3
);
1507 if (!(val
& RT2573_BBP_BUSY
))
1509 if (rum_pause(sc
, hz
/ 100))
1513 device_printf(sc
->sc_dev
, "could not read BBP\n");
1518 rum_rf_write(struct rum_softc
*sc
, uint8_t reg
, uint32_t val
)
1523 for (ntries
= 0; ntries
< 100; ntries
++) {
1524 if (!(rum_read(sc
, RT2573_PHY_CSR4
) & RT2573_RF_BUSY
))
1526 if (rum_pause(sc
, hz
/ 100))
1529 if (ntries
== 100) {
1530 device_printf(sc
->sc_dev
, "could not write to RF\n");
1534 tmp
= RT2573_RF_BUSY
| RT2573_RF_20BIT
| (val
& 0xfffff) << 2 |
1536 rum_write(sc
, RT2573_PHY_CSR4
, tmp
);
1538 /* remember last written value in sc */
1539 sc
->rf_regs
[reg
] = val
;
1541 DPRINTFN(15, "RF R[%u] <- 0x%05x\n", reg
& 3, val
& 0xfffff);
1545 rum_select_antenna(struct rum_softc
*sc
)
1547 uint8_t bbp4
, bbp77
;
1550 bbp4
= rum_bbp_read(sc
, 4);
1551 bbp77
= rum_bbp_read(sc
, 77);
1555 /* make sure Rx is disabled before switching antenna */
1556 tmp
= rum_read(sc
, RT2573_TXRX_CSR0
);
1557 rum_write(sc
, RT2573_TXRX_CSR0
, tmp
| RT2573_DISABLE_RX
);
1559 rum_bbp_write(sc
, 4, bbp4
);
1560 rum_bbp_write(sc
, 77, bbp77
);
1562 rum_write(sc
, RT2573_TXRX_CSR0
, tmp
);
1566 * Enable multi-rate retries for frames sent at OFDM rates.
1567 * In 802.11b/g mode, allow fallback to CCK rates.
1570 rum_enable_mrr(struct rum_softc
*sc
)
1572 struct ifnet
*ifp
= sc
->sc_ifp
;
1573 struct ieee80211com
*ic
= ifp
->if_l2com
;
1576 tmp
= rum_read(sc
, RT2573_TXRX_CSR4
);
1578 tmp
&= ~RT2573_MRR_CCK_FALLBACK
;
1579 if (!IEEE80211_IS_CHAN_5GHZ(ic
->ic_bsschan
))
1580 tmp
|= RT2573_MRR_CCK_FALLBACK
;
1581 tmp
|= RT2573_MRR_ENABLED
;
1583 rum_write(sc
, RT2573_TXRX_CSR4
, tmp
);
1587 rum_set_txpreamble(struct rum_softc
*sc
)
1589 struct ifnet
*ifp
= sc
->sc_ifp
;
1590 struct ieee80211com
*ic
= ifp
->if_l2com
;
1593 tmp
= rum_read(sc
, RT2573_TXRX_CSR4
);
1595 tmp
&= ~RT2573_SHORT_PREAMBLE
;
1596 if (ic
->ic_flags
& IEEE80211_F_SHPREAMBLE
)
1597 tmp
|= RT2573_SHORT_PREAMBLE
;
1599 rum_write(sc
, RT2573_TXRX_CSR4
, tmp
);
1603 rum_set_basicrates(struct rum_softc
*sc
)
1605 struct ifnet
*ifp
= sc
->sc_ifp
;
1606 struct ieee80211com
*ic
= ifp
->if_l2com
;
1608 /* update basic rate set */
1609 if (ic
->ic_curmode
== IEEE80211_MODE_11B
) {
1610 /* 11b basic rates: 1, 2Mbps */
1611 rum_write(sc
, RT2573_TXRX_CSR5
, 0x3);
1612 } else if (IEEE80211_IS_CHAN_5GHZ(ic
->ic_bsschan
)) {
1613 /* 11a basic rates: 6, 12, 24Mbps */
1614 rum_write(sc
, RT2573_TXRX_CSR5
, 0x150);
1616 /* 11b/g basic rates: 1, 2, 5.5, 11Mbps */
1617 rum_write(sc
, RT2573_TXRX_CSR5
, 0xf);
1622 * Reprogram MAC/BBP to switch to a new band. Values taken from the reference
1626 rum_select_band(struct rum_softc
*sc
, struct ieee80211_channel
*c
)
1628 uint8_t bbp17
, bbp35
, bbp96
, bbp97
, bbp98
, bbp104
;
1631 /* update all BBP registers that depend on the band */
1632 bbp17
= 0x20; bbp96
= 0x48; bbp104
= 0x2c;
1633 bbp35
= 0x50; bbp97
= 0x48; bbp98
= 0x48;
1634 if (IEEE80211_IS_CHAN_5GHZ(c
)) {
1635 bbp17
+= 0x08; bbp96
+= 0x10; bbp104
+= 0x0c;
1636 bbp35
+= 0x10; bbp97
+= 0x10; bbp98
+= 0x10;
1638 if ((IEEE80211_IS_CHAN_2GHZ(c
) && sc
->ext_2ghz_lna
) ||
1639 (IEEE80211_IS_CHAN_5GHZ(c
) && sc
->ext_5ghz_lna
)) {
1640 bbp17
+= 0x10; bbp96
+= 0x10; bbp104
+= 0x10;
1644 rum_bbp_write(sc
, 17, bbp17
);
1645 rum_bbp_write(sc
, 96, bbp96
);
1646 rum_bbp_write(sc
, 104, bbp104
);
1648 if ((IEEE80211_IS_CHAN_2GHZ(c
) && sc
->ext_2ghz_lna
) ||
1649 (IEEE80211_IS_CHAN_5GHZ(c
) && sc
->ext_5ghz_lna
)) {
1650 rum_bbp_write(sc
, 75, 0x80);
1651 rum_bbp_write(sc
, 86, 0x80);
1652 rum_bbp_write(sc
, 88, 0x80);
1655 rum_bbp_write(sc
, 35, bbp35
);
1656 rum_bbp_write(sc
, 97, bbp97
);
1657 rum_bbp_write(sc
, 98, bbp98
);
1659 tmp
= rum_read(sc
, RT2573_PHY_CSR0
);
1660 tmp
&= ~(RT2573_PA_PE_2GHZ
| RT2573_PA_PE_5GHZ
);
1661 if (IEEE80211_IS_CHAN_2GHZ(c
))
1662 tmp
|= RT2573_PA_PE_2GHZ
;
1664 tmp
|= RT2573_PA_PE_5GHZ
;
1665 rum_write(sc
, RT2573_PHY_CSR0
, tmp
);
1669 rum_set_chan(struct rum_softc
*sc
, struct ieee80211_channel
*c
)
1671 struct ifnet
*ifp
= sc
->sc_ifp
;
1672 struct ieee80211com
*ic
= ifp
->if_l2com
;
1673 const struct rfprog
*rfprog
;
1674 uint8_t bbp3
, bbp94
= RT2573_BBPR94_DEFAULT
;
1678 chan
= ieee80211_chan2ieee(ic
, c
);
1679 if (chan
== 0 || chan
== IEEE80211_CHAN_ANY
)
1682 /* select the appropriate RF settings based on what EEPROM says */
1683 rfprog
= (sc
->rf_rev
== RT2573_RF_5225
||
1684 sc
->rf_rev
== RT2573_RF_2527
) ? rum_rf5225
: rum_rf5226
;
1686 /* find the settings for this channel (we know it exists) */
1687 for (i
= 0; rfprog
[i
].chan
!= chan
; i
++);
1689 power
= sc
->txpow
[i
];
1693 } else if (power
> 31) {
1694 bbp94
+= power
- 31;
1699 * If we are switching from the 2GHz band to the 5GHz band or
1700 * vice-versa, BBP registers need to be reprogrammed.
1702 if (c
->ic_flags
!= ic
->ic_curchan
->ic_flags
) {
1703 rum_select_band(sc
, c
);
1704 rum_select_antenna(sc
);
1708 rum_rf_write(sc
, RT2573_RF1
, rfprog
[i
].r1
);
1709 rum_rf_write(sc
, RT2573_RF2
, rfprog
[i
].r2
);
1710 rum_rf_write(sc
, RT2573_RF3
, rfprog
[i
].r3
| power
<< 7);
1711 rum_rf_write(sc
, RT2573_RF4
, rfprog
[i
].r4
| sc
->rffreq
<< 10);
1713 rum_rf_write(sc
, RT2573_RF1
, rfprog
[i
].r1
);
1714 rum_rf_write(sc
, RT2573_RF2
, rfprog
[i
].r2
);
1715 rum_rf_write(sc
, RT2573_RF3
, rfprog
[i
].r3
| power
<< 7 | 1);
1716 rum_rf_write(sc
, RT2573_RF4
, rfprog
[i
].r4
| sc
->rffreq
<< 10);
1718 rum_rf_write(sc
, RT2573_RF1
, rfprog
[i
].r1
);
1719 rum_rf_write(sc
, RT2573_RF2
, rfprog
[i
].r2
);
1720 rum_rf_write(sc
, RT2573_RF3
, rfprog
[i
].r3
| power
<< 7);
1721 rum_rf_write(sc
, RT2573_RF4
, rfprog
[i
].r4
| sc
->rffreq
<< 10);
1723 rum_pause(sc
, hz
/ 100);
1725 /* enable smart mode for MIMO-capable RFs */
1726 bbp3
= rum_bbp_read(sc
, 3);
1728 bbp3
&= ~RT2573_SMART_MODE
;
1729 if (sc
->rf_rev
== RT2573_RF_5225
|| sc
->rf_rev
== RT2573_RF_2527
)
1730 bbp3
|= RT2573_SMART_MODE
;
1732 rum_bbp_write(sc
, 3, bbp3
);
1734 if (bbp94
!= RT2573_BBPR94_DEFAULT
)
1735 rum_bbp_write(sc
, 94, bbp94
);
1737 /* give the chip some extra time to do the switchover */
1738 rum_pause(sc
, hz
/ 100);
1742 * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
1743 * and HostAP operating modes.
1746 rum_enable_tsf_sync(struct rum_softc
*sc
)
1748 struct ifnet
*ifp
= sc
->sc_ifp
;
1749 struct ieee80211com
*ic
= ifp
->if_l2com
;
1750 struct ieee80211vap
*vap
= TAILQ_FIRST(&ic
->ic_vaps
);
1753 if (vap
->iv_opmode
!= IEEE80211_M_STA
) {
1755 * Change default 16ms TBTT adjustment to 8ms.
1756 * Must be done before enabling beacon generation.
1758 rum_write(sc
, RT2573_TXRX_CSR10
, 1 << 12 | 8);
1761 tmp
= rum_read(sc
, RT2573_TXRX_CSR9
) & 0xff000000;
1763 /* set beacon interval (in 1/16ms unit) */
1764 tmp
|= vap
->iv_bss
->ni_intval
* 16;
1766 tmp
|= RT2573_TSF_TICKING
| RT2573_ENABLE_TBTT
;
1767 if (vap
->iv_opmode
== IEEE80211_M_STA
)
1768 tmp
|= RT2573_TSF_MODE(1);
1770 tmp
|= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON
;
1772 rum_write(sc
, RT2573_TXRX_CSR9
, tmp
);
1776 rum_enable_tsf(struct rum_softc
*sc
)
1778 rum_write(sc
, RT2573_TXRX_CSR9
,
1779 (rum_read(sc
, RT2573_TXRX_CSR9
) & 0xff000000) |
1780 RT2573_TSF_TICKING
| RT2573_TSF_MODE(2));
1784 rum_update_slot(struct ifnet
*ifp
)
1786 struct rum_softc
*sc
= ifp
->if_softc
;
1787 struct ieee80211com
*ic
= ifp
->if_l2com
;
1791 slottime
= (ic
->ic_flags
& IEEE80211_F_SHSLOT
) ? 9 : 20;
1793 tmp
= rum_read(sc
, RT2573_MAC_CSR9
);
1794 tmp
= (tmp
& ~0xff) | slottime
;
1795 rum_write(sc
, RT2573_MAC_CSR9
, tmp
);
1797 DPRINTF("setting slot time to %uus\n", slottime
);
1801 rum_set_bssid(struct rum_softc
*sc
, const uint8_t *bssid
)
1805 tmp
= bssid
[0] | bssid
[1] << 8 | bssid
[2] << 16 | bssid
[3] << 24;
1806 rum_write(sc
, RT2573_MAC_CSR4
, tmp
);
1808 tmp
= bssid
[4] | bssid
[5] << 8 | RT2573_ONE_BSSID
<< 16;
1809 rum_write(sc
, RT2573_MAC_CSR5
, tmp
);
1813 rum_set_macaddr(struct rum_softc
*sc
, const uint8_t *addr
)
1817 tmp
= addr
[0] | addr
[1] << 8 | addr
[2] << 16 | addr
[3] << 24;
1818 rum_write(sc
, RT2573_MAC_CSR2
, tmp
);
1820 tmp
= addr
[4] | addr
[5] << 8 | 0xff << 16;
1821 rum_write(sc
, RT2573_MAC_CSR3
, tmp
);
1825 rum_setpromisc(struct rum_softc
*sc
)
1827 struct ifnet
*ifp
= sc
->sc_ifp
;
1830 tmp
= rum_read(sc
, RT2573_TXRX_CSR0
);
1832 tmp
&= ~RT2573_DROP_NOT_TO_ME
;
1833 if (!(ifp
->if_flags
& IFF_PROMISC
))
1834 tmp
|= RT2573_DROP_NOT_TO_ME
;
1836 rum_write(sc
, RT2573_TXRX_CSR0
, tmp
);
1838 DPRINTF("%s promiscuous mode\n", (ifp
->if_flags
& IFF_PROMISC
) ?
1839 "entering" : "leaving");
1843 rum_update_promisc(struct ifnet
*ifp
)
1845 struct rum_softc
*sc
= ifp
->if_softc
;
1847 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
1856 rum_update_mcast(struct ifnet
*ifp
)
1858 static int warning_printed
;
1860 if (warning_printed
== 0) {
1861 if_printf(ifp
, "need to implement %s\n", __func__
);
1862 warning_printed
= 1;
1870 case RT2573_RF_2527
: return "RT2527 (MIMO XR)";
1871 case RT2573_RF_2528
: return "RT2528";
1872 case RT2573_RF_5225
: return "RT5225 (MIMO XR)";
1873 case RT2573_RF_5226
: return "RT5226";
1874 default: return "unknown";
1879 rum_read_eeprom(struct rum_softc
*sc
)
1886 /* read MAC address */
1887 rum_eeprom_read(sc
, RT2573_EEPROM_ADDRESS
, sc
->sc_bssid
, 6);
1889 rum_eeprom_read(sc
, RT2573_EEPROM_ANTENNA
, &val
, 2);
1891 sc
->rf_rev
= (val
>> 11) & 0x1f;
1892 sc
->hw_radio
= (val
>> 10) & 0x1;
1893 sc
->rx_ant
= (val
>> 4) & 0x3;
1894 sc
->tx_ant
= (val
>> 2) & 0x3;
1895 sc
->nb_ant
= val
& 0x3;
1897 DPRINTF("RF revision=%d\n", sc
->rf_rev
);
1899 rum_eeprom_read(sc
, RT2573_EEPROM_CONFIG2
, &val
, 2);
1901 sc
->ext_5ghz_lna
= (val
>> 6) & 0x1;
1902 sc
->ext_2ghz_lna
= (val
>> 4) & 0x1;
1904 DPRINTF("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
1905 sc
->ext_2ghz_lna
, sc
->ext_5ghz_lna
);
1907 rum_eeprom_read(sc
, RT2573_EEPROM_RSSI_2GHZ_OFFSET
, &val
, 2);
1909 if ((val
& 0xff) != 0xff)
1910 sc
->rssi_2ghz_corr
= (int8_t)(val
& 0xff); /* signed */
1912 /* Only [-10, 10] is valid */
1913 if (sc
->rssi_2ghz_corr
< -10 || sc
->rssi_2ghz_corr
> 10)
1914 sc
->rssi_2ghz_corr
= 0;
1916 rum_eeprom_read(sc
, RT2573_EEPROM_RSSI_5GHZ_OFFSET
, &val
, 2);
1918 if ((val
& 0xff) != 0xff)
1919 sc
->rssi_5ghz_corr
= (int8_t)(val
& 0xff); /* signed */
1921 /* Only [-10, 10] is valid */
1922 if (sc
->rssi_5ghz_corr
< -10 || sc
->rssi_5ghz_corr
> 10)
1923 sc
->rssi_5ghz_corr
= 0;
1925 if (sc
->ext_2ghz_lna
)
1926 sc
->rssi_2ghz_corr
-= 14;
1927 if (sc
->ext_5ghz_lna
)
1928 sc
->rssi_5ghz_corr
-= 14;
1930 DPRINTF("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
1931 sc
->rssi_2ghz_corr
, sc
->rssi_5ghz_corr
);
1933 rum_eeprom_read(sc
, RT2573_EEPROM_FREQ_OFFSET
, &val
, 2);
1935 if ((val
& 0xff) != 0xff)
1936 sc
->rffreq
= val
& 0xff;
1938 DPRINTF("RF freq=%d\n", sc
->rffreq
);
1940 /* read Tx power for all a/b/g channels */
1941 rum_eeprom_read(sc
, RT2573_EEPROM_TXPOWER
, sc
->txpow
, 14);
1942 /* XXX default Tx power for 802.11a channels */
1943 memset(sc
->txpow
+ 14, 24, sizeof (sc
->txpow
) - 14);
1945 for (i
= 0; i
< 14; i
++)
1946 DPRINTF("Channel=%d Tx power=%d\n", i
+ 1, sc
->txpow
[i
]);
1949 /* read default values for BBP registers */
1950 rum_eeprom_read(sc
, RT2573_EEPROM_BBP_BASE
, sc
->bbp_prom
, 2 * 16);
1952 for (i
= 0; i
< 14; i
++) {
1953 if (sc
->bbp_prom
[i
].reg
== 0 || sc
->bbp_prom
[i
].reg
== 0xff)
1955 DPRINTF("BBP R%d=%02x\n", sc
->bbp_prom
[i
].reg
,
1956 sc
->bbp_prom
[i
].val
);
1962 rum_bbp_init(struct rum_softc
*sc
)
1966 /* wait for BBP to be ready */
1967 for (ntries
= 0; ntries
< 100; ntries
++) {
1968 const uint8_t val
= rum_bbp_read(sc
, 0);
1969 if (val
!= 0 && val
!= 0xff)
1971 if (rum_pause(sc
, hz
/ 100))
1974 if (ntries
== 100) {
1975 device_printf(sc
->sc_dev
, "timeout waiting for BBP\n");
1979 /* initialize BBP registers to default values */
1980 for (i
= 0; i
< N(rum_def_bbp
); i
++)
1981 rum_bbp_write(sc
, rum_def_bbp
[i
].reg
, rum_def_bbp
[i
].val
);
1983 /* write vendor-specific BBP values (from EEPROM) */
1984 for (i
= 0; i
< 16; i
++) {
1985 if (sc
->bbp_prom
[i
].reg
== 0 || sc
->bbp_prom
[i
].reg
== 0xff)
1987 rum_bbp_write(sc
, sc
->bbp_prom
[i
].reg
, sc
->bbp_prom
[i
].val
);
1994 rum_init_locked(struct rum_softc
*sc
)
1996 struct ifnet
*ifp
= sc
->sc_ifp
;
1997 struct ieee80211com
*ic
= ifp
->if_l2com
;
2002 RUM_LOCK_ASSERT(sc
, MA_OWNED
);
2006 /* initialize MAC registers to default values */
2007 for (i
= 0; i
< N(rum_def_mac
); i
++)
2008 rum_write(sc
, rum_def_mac
[i
].reg
, rum_def_mac
[i
].val
);
2010 /* set host ready */
2011 rum_write(sc
, RT2573_MAC_CSR1
, 3);
2012 rum_write(sc
, RT2573_MAC_CSR1
, 0);
2014 /* wait for BBP/RF to wakeup */
2015 for (ntries
= 0; ntries
< 100; ntries
++) {
2016 if (rum_read(sc
, RT2573_MAC_CSR12
) & 8)
2018 rum_write(sc
, RT2573_MAC_CSR12
, 4); /* force wakeup */
2019 if (rum_pause(sc
, hz
/ 100))
2022 if (ntries
== 100) {
2023 device_printf(sc
->sc_dev
,
2024 "timeout waiting for BBP/RF to wakeup\n");
2028 if ((error
= rum_bbp_init(sc
)) != 0)
2031 /* select default channel */
2032 rum_select_band(sc
, ic
->ic_curchan
);
2033 rum_select_antenna(sc
);
2034 rum_set_chan(sc
, ic
->ic_curchan
);
2036 /* clear STA registers */
2037 rum_read_multi(sc
, RT2573_STA_CSR0
, sc
->sta
, sizeof sc
->sta
);
2039 rum_set_macaddr(sc
, IF_LLADDR(ifp
));
2041 /* initialize ASIC */
2042 rum_write(sc
, RT2573_MAC_CSR1
, 4);
2045 * Allocate Tx and Rx xfer queues.
2047 rum_setup_tx_list(sc
);
2049 /* update Rx filter */
2050 tmp
= rum_read(sc
, RT2573_TXRX_CSR0
) & 0xffff;
2052 tmp
|= RT2573_DROP_PHY_ERROR
| RT2573_DROP_CRC_ERROR
;
2053 if (ic
->ic_opmode
!= IEEE80211_M_MONITOR
) {
2054 tmp
|= RT2573_DROP_CTL
| RT2573_DROP_VER_ERROR
|
2056 if (ic
->ic_opmode
!= IEEE80211_M_HOSTAP
)
2057 tmp
|= RT2573_DROP_TODS
;
2058 if (!(ifp
->if_flags
& IFF_PROMISC
))
2059 tmp
|= RT2573_DROP_NOT_TO_ME
;
2061 rum_write(sc
, RT2573_TXRX_CSR0
, tmp
);
2063 ifq_clr_oactive(&ifp
->if_snd
);
2064 ifp
->if_flags
|= IFF_RUNNING
;
2065 usbd_xfer_set_stall(sc
->sc_xfer
[RUM_BULK_WR
]);
2066 usbd_transfer_start(sc
->sc_xfer
[RUM_BULK_RD
]);
2074 rum_init(void *priv
)
2076 struct rum_softc
*sc
= priv
;
2077 struct ifnet
*ifp
= sc
->sc_ifp
;
2078 struct ieee80211com
*ic
= ifp
->if_l2com
;
2081 rum_init_locked(sc
);
2084 if (ifp
->if_flags
& IFF_RUNNING
)
2085 ieee80211_start_all(ic
); /* start all vap's */
2089 rum_stop(struct rum_softc
*sc
)
2091 struct ifnet
*ifp
= sc
->sc_ifp
;
2094 RUM_LOCK_ASSERT(sc
, MA_OWNED
);
2096 ifp
->if_flags
&= ~IFF_RUNNING
;
2097 ifq_clr_oactive(&ifp
->if_snd
);
2102 * Drain the USB transfers, if not already drained:
2104 usbd_transfer_drain(sc
->sc_xfer
[RUM_BULK_WR
]);
2105 usbd_transfer_drain(sc
->sc_xfer
[RUM_BULK_RD
]);
2109 rum_unsetup_tx_list(sc
);
2112 tmp
= rum_read(sc
, RT2573_TXRX_CSR0
);
2113 rum_write(sc
, RT2573_TXRX_CSR0
, tmp
| RT2573_DISABLE_RX
);
2116 rum_write(sc
, RT2573_MAC_CSR1
, 3);
2117 rum_write(sc
, RT2573_MAC_CSR1
, 0);
2121 rum_load_microcode(struct rum_softc
*sc
, const uint8_t *ucode
, size_t size
)
2123 struct usb_device_request req
;
2124 uint16_t reg
= RT2573_MCU_CODE_BASE
;
2127 /* copy firmware image into NIC */
2128 for (; size
>= 4; reg
+= 4, ucode
+= 4, size
-= 4) {
2129 err
= rum_write(sc
, reg
, UGETDW(ucode
));
2131 /* firmware already loaded ? */
2132 device_printf(sc
->sc_dev
, "Firmware load "
2133 "failure! (ignored)\n");
2138 req
.bmRequestType
= UT_WRITE_VENDOR_DEVICE
;
2139 req
.bRequest
= RT2573_MCU_CNTL
;
2140 USETW(req
.wValue
, RT2573_MCU_RUN
);
2141 USETW(req
.wIndex
, 0);
2142 USETW(req
.wLength
, 0);
2144 err
= rum_do_request(sc
, &req
, NULL
);
2146 device_printf(sc
->sc_dev
, "could not run firmware: %s\n",
2150 /* give the chip some time to boot */
2151 rum_pause(sc
, hz
/ 8);
2155 rum_prepare_beacon(struct rum_softc
*sc
, struct ieee80211vap
*vap
)
2157 struct ieee80211com
*ic
= vap
->iv_ic
;
2158 const struct ieee80211_txparam
*tp
;
2159 struct rum_tx_desc desc
;
2162 if (vap
->iv_bss
->ni_chan
== IEEE80211_CHAN_ANYC
)
2164 if (ic
->ic_bsschan
== IEEE80211_CHAN_ANYC
)
2167 m0
= ieee80211_beacon_alloc(vap
->iv_bss
, &RUM_VAP(vap
)->bo
);
2171 tp
= &vap
->iv_txparms
[ieee80211_chan2mode(ic
->ic_bsschan
)];
2172 rum_setup_tx_desc(sc
, &desc
, RT2573_TX_TIMESTAMP
, RT2573_TX_HWSEQ
,
2173 m0
->m_pkthdr
.len
, tp
->mgmtrate
);
2175 /* copy the first 24 bytes of Tx descriptor into NIC memory */
2176 rum_write_multi(sc
, RT2573_HW_BEACON_BASE0
, (uint8_t *)&desc
, 24);
2178 /* copy beacon header and payload into NIC memory */
2179 rum_write_multi(sc
, RT2573_HW_BEACON_BASE0
+ 24, mtod(m0
, uint8_t *),
2186 rum_raw_xmit(struct ieee80211_node
*ni
, struct mbuf
*m
,
2187 const struct ieee80211_bpf_params
*params
)
2189 struct ifnet
*ifp
= ni
->ni_ic
->ic_ifp
;
2190 struct rum_softc
*sc
= ifp
->if_softc
;
2193 /* prevent management frames from being sent if we're not ready */
2194 if (!(ifp
->if_flags
& IFF_RUNNING
)) {
2197 ieee80211_free_node(ni
);
2200 if (sc
->tx_nfree
< RUM_TX_MINFREE
) {
2201 ifq_set_oactive(&ifp
->if_snd
);
2204 ieee80211_free_node(ni
);
2208 IFNET_STAT_INC(ifp
, opackets
, 1);
2210 if (params
== NULL
) {
2212 * Legacy path; interpret frame contents to decide
2213 * precisely how to send the frame.
2215 if (rum_tx_mgt(sc
, m
, ni
) != 0)
2219 * Caller supplied explicit parameters to use in
2220 * sending the frame.
2222 if (rum_tx_raw(sc
, m
, ni
, params
) != 0)
2229 IFNET_STAT_INC(ifp
, oerrors
, 1);
2231 ieee80211_free_node(ni
);
2236 rum_ratectl_start(struct rum_softc
*sc
, struct ieee80211_node
*ni
)
2238 struct ieee80211vap
*vap
= ni
->ni_vap
;
2239 struct rum_vap
*rvp
= RUM_VAP(vap
);
2241 /* clear statistic registers (STA_CSR0 to STA_CSR5) */
2242 rum_read_multi(sc
, RT2573_STA_CSR0
, sc
->sta
, sizeof sc
->sta
);
2244 usb_callout_reset(&rvp
->ratectl_ch
, hz
, rum_ratectl_timeout
, rvp
);
2248 rum_ratectl_timeout(void *arg
)
2250 struct rum_vap
*rvp
= arg
;
2251 struct ieee80211vap
*vap
= &rvp
->vap
;
2252 struct ieee80211com
*ic
= vap
->iv_ic
;
2254 ieee80211_runtask(ic
, &rvp
->ratectl_task
);
2258 rum_ratectl_task(void *arg
, int pending
)
2260 struct rum_vap
*rvp
= arg
;
2261 struct ieee80211vap
*vap
= &rvp
->vap
;
2262 struct ieee80211com
*ic
= vap
->iv_ic
;
2263 struct ifnet
*ifp
= ic
->ic_ifp
;
2264 struct rum_softc
*sc
= ifp
->if_softc
;
2265 struct ieee80211_node
*ni
;
2270 /* read and clear statistic registers (STA_CSR0 to STA_CSR10) */
2271 rum_read_multi(sc
, RT2573_STA_CSR0
, sc
->sta
, sizeof(sc
->sta
));
2273 ok
= (le32toh(sc
->sta
[4]) & 0xffff) + /* TX no-retry ok count */
2274 (le32toh(sc
->sta
[4]) >> 16) + /* TX one-retry ok count */
2275 (le32toh(sc
->sta
[5]) & 0xffff); /* TX more-retry ok count */
2276 fail
= (le32toh(sc
->sta
[5]) >> 16); /* TX retry-fail count */
2278 retrycnt
= (le32toh(sc
->sta
[4]) >> 16) +
2279 (le32toh(sc
->sta
[5]) & 0xffff) + fail
;
2281 ni
= ieee80211_ref_node(vap
->iv_bss
);
2282 ieee80211_ratectl_tx_update(vap
, ni
, &sum
, &ok
, &retrycnt
);
2283 (void) ieee80211_ratectl_rate(ni
, NULL
, 0);
2284 ieee80211_free_node(ni
);
2286 IFNET_STAT_INC(ifp
, oerrors
, fail
); /* count TX retry-fail as Tx errors */
2288 usb_callout_reset(&rvp
->ratectl_ch
, hz
, rum_ratectl_timeout
, rvp
);
2293 rum_scan_start(struct ieee80211com
*ic
)
2295 struct ifnet
*ifp
= ic
->ic_ifp
;
2296 struct rum_softc
*sc
= ifp
->if_softc
;
2300 /* abort TSF synchronization */
2301 tmp
= rum_read(sc
, RT2573_TXRX_CSR9
);
2302 rum_write(sc
, RT2573_TXRX_CSR9
, tmp
& ~0x00ffffff);
2303 rum_set_bssid(sc
, ifp
->if_broadcastaddr
);
2309 rum_scan_end(struct ieee80211com
*ic
)
2311 struct rum_softc
*sc
= ic
->ic_ifp
->if_softc
;
2314 rum_enable_tsf_sync(sc
);
2315 rum_set_bssid(sc
, sc
->sc_bssid
);
2321 rum_set_channel(struct ieee80211com
*ic
)
2323 struct rum_softc
*sc
= ic
->ic_ifp
->if_softc
;
2326 rum_set_chan(sc
, ic
->ic_curchan
);
2331 rum_get_rssi(struct rum_softc
*sc
, uint8_t raw
)
2333 struct ifnet
*ifp
= sc
->sc_ifp
;
2334 struct ieee80211com
*ic
= ifp
->if_l2com
;
2337 lna
= (raw
>> 5) & 0x3;
2344 * NB: Since RSSI is relative to noise floor, -1 is
2345 * adequate for caller to know error happened.
2350 rssi
= (2 * agc
) - RT2573_NOISE_FLOOR
;
2352 if (IEEE80211_IS_CHAN_2GHZ(ic
->ic_curchan
)) {
2353 rssi
+= sc
->rssi_2ghz_corr
;
2362 rssi
+= sc
->rssi_5ghz_corr
;
2364 if (!sc
->ext_5ghz_lna
&& lna
!= 1)
2378 rum_pause(struct rum_softc
*sc
, int timeout
)
2380 usb_pause_mtx(&sc
->sc_lock
, timeout
);
2384 static device_method_t rum_methods
[] = {
2385 /* Device interface */
2386 DEVMETHOD(device_probe
, rum_match
),
2387 DEVMETHOD(device_attach
, rum_attach
),
2388 DEVMETHOD(device_detach
, rum_detach
),
2392 static driver_t rum_driver
= {
2394 .methods
= rum_methods
,
2395 .size
= sizeof(struct rum_softc
),
2398 static devclass_t rum_devclass
;
2400 DRIVER_MODULE(rum
, uhub
, rum_driver
, rum_devclass
, NULL
, NULL
);
2401 MODULE_DEPEND(rum
, wlan
, 1, 1, 1);
2402 MODULE_DEPEND(rum
, usb
, 1, 1, 1);
2403 MODULE_VERSION(rum
, 1);