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