if_otus.c revision 289165
1/* $OpenBSD: if_otus.c,v 1.46 2015/03/14 03:38:49 jsg Exp $ */ 2 3/*- 4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2015 Adrian Chadd <adrian@FreeBSD.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20/* 21 * Driver for Atheros AR9001U chipset. 22 */ 23 24#include <sys/cdefs.h> 25__FBSDID("$FreeBSD: head/sys/dev/otus/if_otus.c 289165 2015-10-12 04:55:20Z adrian $"); 26 27#include "opt_wlan.h" 28 29#include <sys/param.h> 30#include <sys/endian.h> 31#include <sys/sockio.h> 32#include <sys/mbuf.h> 33#include <sys/kernel.h> 34#include <sys/socket.h> 35#include <sys/systm.h> 36#include <sys/conf.h> 37#include <sys/bus.h> 38#include <sys/rman.h> 39#include <sys/firmware.h> 40#include <sys/module.h> 41#include <sys/taskqueue.h> 42 43#include <machine/bus.h> 44#include <machine/resource.h> 45 46#include <net/bpf.h> 47#include <net/if.h> 48#include <net/if_var.h> 49#include <net/if_arp.h> 50#include <net/if_dl.h> 51#include <net/if_media.h> 52#include <net/if_types.h> 53 54#include <netinet/in.h> 55#include <netinet/in_systm.h> 56#include <netinet/in_var.h> 57#include <netinet/if_ether.h> 58#include <netinet/ip.h> 59 60#include <net80211/ieee80211_var.h> 61#include <net80211/ieee80211_regdomain.h> 62#include <net80211/ieee80211_radiotap.h> 63#include <net80211/ieee80211_ratectl.h> 64#include <net80211/ieee80211_input.h> 65#ifdef IEEE80211_SUPPORT_SUPERG 66#include <net80211/ieee80211_superg.h> 67#endif 68 69#include <dev/usb/usb.h> 70#include <dev/usb/usbdi.h> 71#include "usbdevs.h" 72 73#define USB_DEBUG_VAR otus_debug 74#include <dev/usb/usb_debug.h> 75 76#include "if_otusreg.h" 77 78static int otus_debug = 0; 79static SYSCTL_NODE(_hw_usb, OID_AUTO, otus, CTLFLAG_RW, 0, "USB otus"); 80SYSCTL_INT(_hw_usb_otus, OID_AUTO, debug, CTLFLAG_RWTUN, &otus_debug, 0, 81 "Debug level"); 82#define OTUS_DEBUG_XMIT 0x00000001 83#define OTUS_DEBUG_RECV 0x00000002 84#define OTUS_DEBUG_TXDONE 0x00000004 85#define OTUS_DEBUG_RXDONE 0x00000008 86#define OTUS_DEBUG_CMD 0x00000010 87#define OTUS_DEBUG_CMDDONE 0x00000020 88#define OTUS_DEBUG_RESET 0x00000040 89#define OTUS_DEBUG_STATE 0x00000080 90#define OTUS_DEBUG_CMDNOTIFY 0x00000100 91#define OTUS_DEBUG_REGIO 0x00000200 92#define OTUS_DEBUG_IRQ 0x00000400 93#define OTUS_DEBUG_TXCOMP 0x00000800 94#define OTUS_DEBUG_ANY 0xffffffff 95 96#define OTUS_DPRINTF(sc, dm, ...) \ 97 do { \ 98 if ((dm == OTUS_DEBUG_ANY) || (dm & otus_debug)) \ 99 device_printf(sc->sc_dev, __VA_ARGS__); \ 100 } while (0) 101 102#define OTUS_DEV(v, p) { USB_VPI(v, p, 0) } 103static const STRUCT_USB_HOST_ID otus_devs[] = { 104 OTUS_DEV(USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_WN7512), 105 OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_3CRUSBN275), 106 OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_TG121N), 107 OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9170), 108 OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN612), 109 OTUS_DEV(USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_WN821NV2), 110 OTUS_DEV(USB_VENDOR_AVM, USB_PRODUCT_AVM_FRITZWLAN), 111 OTUS_DEV(USB_VENDOR_CACE, USB_PRODUCT_CACE_AIRPCAPNX), 112 OTUS_DEV(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA130D1), 113 OTUS_DEV(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A1), 114 OTUS_DEV(USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA160A2), 115 OTUS_DEV(USB_VENDOR_IODATA, USB_PRODUCT_IODATA_WNGDNUS2), 116 OTUS_DEV(USB_VENDOR_NEC, USB_PRODUCT_NEC_WL300NUG), 117 OTUS_DEV(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WN111V2), 118 OTUS_DEV(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000), 119 OTUS_DEV(USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3100), 120 OTUS_DEV(USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US300), 121 OTUS_DEV(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_O8494), 122 OTUS_DEV(USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_WNC0600), 123 OTUS_DEV(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB81), 124 OTUS_DEV(USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_UB82), 125 OTUS_DEV(USB_VENDOR_ZYDAS, USB_PRODUCT_ZYDAS_ZD1221), 126 OTUS_DEV(USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_NWD271N), 127}; 128 129static device_probe_t otus_match; 130static device_attach_t otus_attach; 131static device_detach_t otus_detach; 132 133static int otus_attachhook(struct otus_softc *); 134void otus_get_chanlist(struct otus_softc *); 135int otus_load_firmware(struct otus_softc *, const char *, 136 uint32_t); 137int otus_open_pipes(struct otus_softc *); 138void otus_close_pipes(struct otus_softc *); 139 140static int otus_alloc_tx_cmd_list(struct otus_softc *); 141static void otus_free_tx_cmd_list(struct otus_softc *); 142 143static int otus_alloc_rx_list(struct otus_softc *); 144static void otus_free_rx_list(struct otus_softc *); 145static int otus_alloc_tx_list(struct otus_softc *); 146static void otus_free_tx_list(struct otus_softc *); 147static void otus_free_list(struct otus_softc *, struct otus_data [], int); 148static struct otus_data *_otus_getbuf(struct otus_softc *); 149static struct otus_data *otus_getbuf(struct otus_softc *); 150static void otus_freebuf(struct otus_softc *, struct otus_data *); 151 152static struct otus_tx_cmd *_otus_get_txcmd(struct otus_softc *); 153static struct otus_tx_cmd *otus_get_txcmd(struct otus_softc *); 154static void otus_free_txcmd(struct otus_softc *, struct otus_tx_cmd *); 155 156void otus_next_scan(void *, int); 157static void otus_tx_task(void *, int pending); 158static void otus_wme_update_task(void *, int pending); 159void otus_do_async(struct otus_softc *, 160 void (*)(struct otus_softc *, void *), void *, int); 161int otus_newstate(struct ieee80211vap *, enum ieee80211_state, 162 int); 163int otus_cmd(struct otus_softc *, uint8_t, const void *, int, 164 void *, int); 165void otus_write(struct otus_softc *, uint32_t, uint32_t); 166int otus_write_barrier(struct otus_softc *); 167struct ieee80211_node *otus_node_alloc(struct ieee80211com *); 168int otus_media_change(struct ifnet *); 169int otus_read_eeprom(struct otus_softc *); 170void otus_newassoc(struct ieee80211_node *, int); 171void otus_cmd_rxeof(struct otus_softc *, uint8_t *, int); 172void otus_sub_rxeof(struct otus_softc *, uint8_t *, int, 173 struct mbufq *); 174static int otus_tx(struct otus_softc *, struct ieee80211_node *, 175 struct mbuf *, struct otus_data *); 176int otus_ioctl(struct ifnet *, u_long, caddr_t); 177int otus_set_multi(struct otus_softc *); 178static void otus_updateedca(struct otus_softc *sc); 179static void otus_updateslot(struct otus_softc *sc); 180int otus_init_mac(struct otus_softc *); 181uint32_t otus_phy_get_def(struct otus_softc *, uint32_t); 182int otus_set_board_values(struct otus_softc *, 183 struct ieee80211_channel *); 184int otus_program_phy(struct otus_softc *, 185 struct ieee80211_channel *); 186int otus_set_rf_bank4(struct otus_softc *, 187 struct ieee80211_channel *); 188void otus_get_delta_slope(uint32_t, uint32_t *, uint32_t *); 189static int otus_set_chan(struct otus_softc *, struct ieee80211_channel *, 190 int); 191int otus_set_key(struct ieee80211com *, struct ieee80211_node *, 192 struct ieee80211_key *); 193void otus_set_key_cb(struct otus_softc *, void *); 194void otus_delete_key(struct ieee80211com *, struct ieee80211_node *, 195 struct ieee80211_key *); 196void otus_delete_key_cb(struct otus_softc *, void *); 197void otus_calibrate_to(void *, int); 198int otus_set_bssid(struct otus_softc *, const uint8_t *); 199int otus_set_macaddr(struct otus_softc *, const uint8_t *); 200void otus_led_newstate_type1(struct otus_softc *); 201void otus_led_newstate_type2(struct otus_softc *); 202void otus_led_newstate_type3(struct otus_softc *); 203int otus_init(struct otus_softc *sc); 204void otus_stop(struct otus_softc *sc); 205 206static device_method_t otus_methods[] = { 207 DEVMETHOD(device_probe, otus_match), 208 DEVMETHOD(device_attach, otus_attach), 209 DEVMETHOD(device_detach, otus_detach), 210 211 DEVMETHOD_END 212}; 213 214static driver_t otus_driver = { 215 .name = "otus", 216 .methods = otus_methods, 217 .size = sizeof(struct otus_softc) 218}; 219 220static devclass_t otus_devclass; 221 222DRIVER_MODULE(otus, uhub, otus_driver, otus_devclass, NULL, 0); 223MODULE_DEPEND(otus, wlan, 1, 1, 1); 224MODULE_DEPEND(otus, usb, 1, 1, 1); 225MODULE_DEPEND(otus, firmware, 1, 1, 1); 226MODULE_VERSION(otus, 1); 227 228static usb_callback_t otus_bulk_tx_callback; 229static usb_callback_t otus_bulk_rx_callback; 230static usb_callback_t otus_bulk_irq_callback; 231static usb_callback_t otus_bulk_cmd_callback; 232 233static const struct usb_config otus_config[OTUS_N_XFER] = { 234 [OTUS_BULK_TX] = { 235 .type = UE_BULK, 236 .endpoint = UE_ADDR_ANY, 237 .direction = UE_DIR_OUT, 238 .bufsize = 0x200, 239 .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 240 .callback = otus_bulk_tx_callback, 241 .timeout = 5000, /* ms */ 242 }, 243 [OTUS_BULK_RX] = { 244 .type = UE_BULK, 245 .endpoint = UE_ADDR_ANY, 246 .direction = UE_DIR_IN, 247 .bufsize = OTUS_RXBUFSZ, 248 .flags = { .ext_buffer = 1, .pipe_bof = 1,.short_xfer_ok = 1,}, 249 .callback = otus_bulk_rx_callback, 250 }, 251 [OTUS_BULK_IRQ] = { 252 .type = UE_INTERRUPT, 253 .endpoint = UE_ADDR_ANY, 254 .direction = UE_DIR_IN, 255 .bufsize = OTUS_MAX_CTRLSZ, 256 .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, 257 .callback = otus_bulk_irq_callback, 258 }, 259 [OTUS_BULK_CMD] = { 260 .type = UE_INTERRUPT, 261 .endpoint = UE_ADDR_ANY, 262 .direction = UE_DIR_OUT, 263 .bufsize = OTUS_MAX_CTRLSZ, 264 .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, 265 .callback = otus_bulk_cmd_callback, 266 .timeout = 5000, /* ms */ 267 }, 268}; 269 270static int 271otus_match(device_t self) 272{ 273 struct usb_attach_arg *uaa = device_get_ivars(self); 274 275 if (uaa->usb_mode != USB_MODE_HOST || 276 uaa->info.bIfaceIndex != 0 || 277 uaa->info.bConfigIndex != 0) 278 return (ENXIO); 279 280 return (usbd_lookup_id_by_uaa(otus_devs, sizeof(otus_devs), uaa)); 281} 282 283static int 284otus_attach(device_t self) 285{ 286 struct usb_attach_arg *uaa = device_get_ivars(self); 287 struct otus_softc *sc = device_get_softc(self); 288 int error; 289 uint8_t iface_index; 290 291 device_set_usb_desc(self); 292 sc->sc_udev = uaa->device; 293 sc->sc_dev = self; 294 295 mtx_init(&sc->sc_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK, 296 MTX_DEF); 297 298 TIMEOUT_TASK_INIT(taskqueue_thread, &sc->scan_to, 0, otus_next_scan, sc); 299 TIMEOUT_TASK_INIT(taskqueue_thread, &sc->calib_to, 0, otus_calibrate_to, sc); 300 TASK_INIT(&sc->tx_task, 0, otus_tx_task, sc); 301 TASK_INIT(&sc->wme_update_task, 0, otus_wme_update_task, sc); 302 mbufq_init(&sc->sc_snd, ifqmaxlen); 303 304 iface_index = 0; 305 error = usbd_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, 306 otus_config, OTUS_N_XFER, sc, &sc->sc_mtx); 307 if (error) { 308 device_printf(sc->sc_dev, 309 "could not allocate USB transfers, err=%s\n", 310 usbd_errstr(error)); 311 goto fail_usb; 312 } 313 314 if ((error = otus_open_pipes(sc)) != 0) { 315 device_printf(sc->sc_dev, "%s: could not open pipes\n", 316 __func__); 317 goto fail; 318 } 319 320 /* XXX check return status; fail out if appropriate */ 321 if (otus_attachhook(sc) != 0) 322 goto fail; 323 324 return (0); 325 326fail: 327 otus_close_pipes(sc); 328fail_usb: 329 mtx_destroy(&sc->sc_mtx); 330 return (ENXIO); 331} 332 333static int 334otus_detach(device_t self) 335{ 336 struct otus_softc *sc = device_get_softc(self); 337 struct ieee80211com *ic = &sc->sc_ic; 338 339 otus_stop(sc); 340 341 usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER); 342 343 taskqueue_drain_timeout(taskqueue_thread, &sc->scan_to); 344 taskqueue_drain_timeout(taskqueue_thread, &sc->calib_to); 345 taskqueue_drain(taskqueue_thread, &sc->tx_task); 346 taskqueue_drain(taskqueue_thread, &sc->wme_update_task); 347 348 otus_close_pipes(sc); 349#if 0 350 /* Wait for all queued asynchronous commands to complete. */ 351 usb_rem_wait_task(sc->sc_udev, &sc->sc_task); 352 353 usbd_ref_wait(sc->sc_udev); 354#endif 355 356 ieee80211_ifdetach(ic); 357 mtx_destroy(&sc->sc_mtx); 358 return 0; 359} 360 361static void 362otus_delay_ms(struct otus_softc *sc, int ms) 363{ 364 365 DELAY(1000 * ms); 366} 367 368static struct ieee80211vap * 369otus_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 370 enum ieee80211_opmode opmode, int flags, 371 const uint8_t bssid[IEEE80211_ADDR_LEN], 372 const uint8_t mac[IEEE80211_ADDR_LEN]) 373{ 374 struct otus_vap *uvp; 375 struct ieee80211vap *vap; 376 377 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ 378 return (NULL); 379 380 uvp = malloc(sizeof(struct otus_vap), M_80211_VAP, M_WAITOK | M_ZERO); 381 vap = &uvp->vap; 382 383 if (ieee80211_vap_setup(ic, vap, name, unit, opmode, 384 flags, bssid) != 0) { 385 /* out of memory */ 386 free(uvp, M_80211_VAP); 387 return (NULL); 388 } 389 390 /* override state transition machine */ 391 uvp->newstate = vap->iv_newstate; 392 vap->iv_newstate = otus_newstate; 393 394 /* XXX TODO: double-check */ 395 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_16; 396 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_32K; 397 398 ieee80211_ratectl_init(vap); 399 400 /* complete setup */ 401 ieee80211_vap_attach(vap, ieee80211_media_change, 402 ieee80211_media_status, mac); 403 ic->ic_opmode = opmode; 404 405 return (vap); 406} 407 408static void 409otus_vap_delete(struct ieee80211vap *vap) 410{ 411 struct otus_vap *uvp = OTUS_VAP(vap); 412 413 ieee80211_ratectl_deinit(vap); 414 ieee80211_vap_detach(vap); 415 free(uvp, M_80211_VAP); 416} 417 418static void 419otus_parent(struct ieee80211com *ic) 420{ 421 struct otus_softc *sc = ic->ic_softc; 422 int startall = 0; 423 424 if (ic->ic_nrunning > 0) { 425 if (!sc->sc_running) { 426 otus_init(sc); 427 startall = 1; 428 } else { 429 (void) otus_set_multi(sc); 430 } 431 } else if (sc->sc_running) 432 otus_stop(sc); 433 434 if (startall) 435 ieee80211_start_all(ic); 436} 437 438static void 439otus_drain_mbufq(struct otus_softc *sc) 440{ 441 struct mbuf *m; 442 struct ieee80211_node *ni; 443 444 OTUS_LOCK_ASSERT(sc); 445 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 446 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 447 m->m_pkthdr.rcvif = NULL; 448 ieee80211_free_node(ni); 449 m_freem(m); 450 } 451} 452 453static void 454otus_tx_start(struct otus_softc *sc) 455{ 456 457 taskqueue_enqueue(taskqueue_thread, &sc->tx_task); 458} 459 460static int 461otus_transmit(struct ieee80211com *ic, struct mbuf *m) 462{ 463 struct otus_softc *sc = ic->ic_softc; 464 int error; 465 466 OTUS_LOCK(sc); 467 if (! sc->sc_running) { 468 OTUS_UNLOCK(sc); 469 return (ENXIO); 470 } 471 472 /* XXX TODO: handle fragments */ 473 error = mbufq_enqueue(&sc->sc_snd, m); 474 if (error) { 475 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, 476 "%s: mbufq_enqueue failed: %d\n", 477 __func__, 478 error); 479 OTUS_UNLOCK(sc); 480 return (error); 481 } 482 OTUS_UNLOCK(sc); 483 484 /* Kick TX */ 485 otus_tx_start(sc); 486 487 return (0); 488} 489 490static void 491_otus_start(struct otus_softc *sc) 492{ 493 struct ieee80211_node *ni; 494 struct otus_data *bf; 495 struct mbuf *m; 496 497 OTUS_LOCK_ASSERT(sc); 498 499 while ((m = mbufq_dequeue(&sc->sc_snd)) != NULL) { 500 bf = otus_getbuf(sc); 501 if (bf == NULL) { 502 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, 503 "%s: failed to get buffer\n", __func__); 504 mbufq_prepend(&sc->sc_snd, m); 505 break; 506 } 507 508 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; 509 m->m_pkthdr.rcvif = NULL; 510 511 if (otus_tx(sc, ni, m, bf) != 0) { 512 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, 513 "%s: failed to transmit\n", __func__); 514 if_inc_counter(ni->ni_vap->iv_ifp, 515 IFCOUNTER_OERRORS, 1); 516 otus_freebuf(sc, bf); 517 ieee80211_free_node(ni); 518 m_freem(m); 519 break; 520 } 521 } 522} 523 524static void 525otus_tx_task(void *arg, int pending) 526{ 527 struct otus_softc *sc = arg; 528 529 OTUS_LOCK(sc); 530 _otus_start(sc); 531 OTUS_UNLOCK(sc); 532} 533 534static int 535otus_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 536 const struct ieee80211_bpf_params *params) 537{ 538 struct ieee80211com *ic= ni->ni_ic; 539 struct otus_softc *sc = ic->ic_softc; 540 struct otus_data *bf = NULL; 541 int error = 0; 542 543 /* Don't transmit if we're not running */ 544 OTUS_LOCK(sc); 545 if (! sc->sc_running) { 546 error = ENETDOWN; 547 goto error; 548 } 549 550 bf = otus_getbuf(sc); 551 if (bf == NULL) { 552 error = ENOBUFS; 553 goto error; 554 } 555 556 /* 557 * XXX TODO: support TX bpf params 558 */ 559 if (otus_tx(sc, ni, m, bf) != 0) { 560 error = EIO; 561 goto error; 562 } 563 564 OTUS_UNLOCK(sc); 565 return (0); 566error: 567 if (bf) 568 otus_freebuf(sc, bf); 569 OTUS_UNLOCK(sc); 570 m_freem(m); 571 return (ENXIO); 572} 573 574static void 575otus_update_chw(struct ieee80211com *ic) 576{ 577 578 printf("%s: TODO\n", __func__); 579} 580 581static void 582otus_set_channel(struct ieee80211com *ic) 583{ 584 struct otus_softc *sc = ic->ic_softc; 585 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "%s: set channel: %d\n", 586 __func__, 587 ic->ic_curchan->ic_freq); 588 589 OTUS_LOCK(sc); 590 (void) otus_set_chan(sc, ic->ic_curchan, 0); 591 OTUS_UNLOCK(sc); 592} 593 594static void 595otus_wme_update_task(void *arg, int pending) 596{ 597 struct otus_softc *sc = arg; 598 599 OTUS_LOCK(sc); 600 /* 601 * XXX TODO: take temporary copy of EDCA information 602 * when scheduling this so we have a more time-correct view 603 * of things. 604 */ 605 otus_updateedca(sc); 606 OTUS_UNLOCK(sc); 607} 608 609static void 610otus_wme_schedule_update(struct otus_softc *sc) 611{ 612 613 taskqueue_enqueue(taskqueue_thread, &sc->wme_update_task); 614} 615 616/* 617 * This is called by net80211 in RX packet context, so we 618 * can't sleep here. 619 * 620 * TODO: have net80211 schedule an update itself for its 621 * own internal taskqueue. 622 */ 623static int 624otus_wme_update(struct ieee80211com *ic) 625{ 626 struct otus_softc *sc = ic->ic_softc; 627 628 otus_wme_schedule_update(sc); 629 return (0); 630} 631 632static int 633otus_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) 634{ 635 636 /* For now, no A-MPDU TX support in the driver */ 637 return (0); 638} 639 640static void 641otus_scan_start(struct ieee80211com *ic) 642{ 643 644// printf("%s: TODO\n", __func__); 645} 646 647static void 648otus_scan_end(struct ieee80211com *ic) 649{ 650 651// printf("%s: TODO\n", __func__); 652} 653 654static void 655otus_update_mcast(struct ieee80211com *ic) 656{ 657 struct otus_softc *sc = ic->ic_softc; 658 659 (void) otus_set_multi(sc); 660} 661 662static int 663otus_attachhook(struct otus_softc *sc) 664{ 665 struct ieee80211com *ic = &sc->sc_ic; 666 usb_device_request_t req; 667 uint32_t in, out; 668 int error; 669 uint8_t bands; 670 671 /* Not locked */ 672 error = otus_load_firmware(sc, "otusfw_init", AR_FW_INIT_ADDR); 673 if (error != 0) { 674 device_printf(sc->sc_dev, "%s: could not load %s firmware\n", 675 __func__, "init"); 676 return (ENXIO); 677 } 678 679 /* XXX not locked? */ 680 otus_delay_ms(sc, 1000); 681 682 /* Not locked */ 683 error = otus_load_firmware(sc, "otusfw_main", AR_FW_MAIN_ADDR); 684 if (error != 0) { 685 device_printf(sc->sc_dev, "%s: could not load %s firmware\n", 686 __func__, "main"); 687 return (ENXIO); 688 } 689 690 OTUS_LOCK(sc); 691 692 /* Tell device that firmware transfer is complete. */ 693 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 694 req.bRequest = AR_FW_DOWNLOAD_COMPLETE; 695 USETW(req.wValue, 0); 696 USETW(req.wIndex, 0); 697 USETW(req.wLength, 0); 698 if (usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, &req, NULL, 699 0, NULL, 250) != 0) { 700 OTUS_UNLOCK(sc); 701 device_printf(sc->sc_dev, 702 "%s: firmware initialization failed\n", 703 __func__); 704 return (ENXIO); 705 } 706 707 /* Send an ECHO command to check that everything is settled. */ 708 in = 0xbadc0ffe; 709 if (otus_cmd(sc, AR_CMD_ECHO, &in, sizeof in, &out, sizeof(out)) != 0) { 710 OTUS_UNLOCK(sc); 711 device_printf(sc->sc_dev, 712 "%s: echo command failed\n", __func__); 713 return (ENXIO); 714 } 715 if (in != out) { 716 OTUS_UNLOCK(sc); 717 device_printf(sc->sc_dev, 718 "%s: echo reply mismatch: 0x%08x!=0x%08x\n", 719 __func__, in, out); 720 return (ENXIO); 721 } 722 723 /* Read entire EEPROM. */ 724 if (otus_read_eeprom(sc) != 0) { 725 OTUS_UNLOCK(sc); 726 device_printf(sc->sc_dev, 727 "%s: could not read EEPROM\n", 728 __func__); 729 return (ENXIO); 730 } 731 732 OTUS_UNLOCK(sc); 733 734 sc->txmask = sc->eeprom.baseEepHeader.txMask; 735 sc->rxmask = sc->eeprom.baseEepHeader.rxMask; 736 sc->capflags = sc->eeprom.baseEepHeader.opCapFlags; 737 IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->eeprom.baseEepHeader.macAddr); 738 sc->sc_led_newstate = otus_led_newstate_type3; /* XXX */ 739 740 device_printf(sc->sc_dev, 741 "MAC/BBP AR9170, RF AR%X, MIMO %dT%dR, address %s\n", 742 (sc->capflags & AR5416_OPFLAGS_11A) ? 743 0x9104 : ((sc->txmask == 0x5) ? 0x9102 : 0x9101), 744 (sc->txmask == 0x5) ? 2 : 1, (sc->rxmask == 0x5) ? 2 : 1, 745 ether_sprintf(ic->ic_macaddr)); 746 747 ic->ic_softc = sc; 748 ic->ic_name = device_get_nameunit(sc->sc_dev); 749 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ 750 ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ 751 752 /* Set device capabilities. */ 753 ic->ic_caps = 754 IEEE80211_C_STA | /* station mode */ 755#if 0 756 IEEE80211_C_BGSCAN | /* Background scan. */ 757#endif 758 IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ 759 IEEE80211_C_WME | /* WME/QoS */ 760 IEEE80211_C_SHSLOT | /* Short slot time supported. */ 761 IEEE80211_C_FF | /* Atheros fast-frames supported. */ 762 IEEE80211_C_WPA; /* WPA/RSN. */ 763 764 /* XXX TODO: 11n */ 765 766#if 0 767 if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 768 /* Set supported .11b and .11g rates. */ 769 ic->ic_sup_rates[IEEE80211_MODE_11B] = 770 ieee80211_std_rateset_11b; 771 ic->ic_sup_rates[IEEE80211_MODE_11G] = 772 ieee80211_std_rateset_11g; 773 } 774 if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 775 /* Set supported .11a rates. */ 776 ic->ic_sup_rates[IEEE80211_MODE_11A] = 777 ieee80211_std_rateset_11a; 778 } 779#endif 780 781#if 0 782 /* Build the list of supported channels. */ 783 otus_get_chanlist(sc); 784#else 785 /* Set supported .11b and .11g rates. */ 786 bands = 0; 787 if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 788 setbit(&bands, IEEE80211_MODE_11B); 789 setbit(&bands, IEEE80211_MODE_11G); 790 } 791 if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 792 setbit(&bands, IEEE80211_MODE_11A); 793 } 794#if 0 795 if (sc->sc_ht) 796 setbit(&bands, IEEE80211_MODE_11NG); 797#endif 798 ieee80211_init_channels(ic, NULL, &bands); 799#endif 800 801 ieee80211_ifattach(ic); 802 ic->ic_raw_xmit = otus_raw_xmit; 803 ic->ic_scan_start = otus_scan_start; 804 ic->ic_scan_end = otus_scan_end; 805 ic->ic_set_channel = otus_set_channel; 806 ic->ic_vap_create = otus_vap_create; 807 ic->ic_vap_delete = otus_vap_delete; 808 ic->ic_update_mcast = otus_update_mcast; 809 ic->ic_update_promisc = otus_update_mcast; 810 ic->ic_parent = otus_parent; 811 ic->ic_transmit = otus_transmit; 812 ic->ic_update_chw = otus_update_chw; 813 ic->ic_ampdu_enable = otus_ampdu_enable; 814 ic->ic_wme.wme_update = otus_wme_update; 815 ic->ic_newassoc = otus_newassoc; 816 817#ifdef notyet 818 ic->ic_set_key = otus_set_key; 819 ic->ic_delete_key = otus_delete_key; 820#endif 821 822 ieee80211_radiotap_attach(ic, &sc->sc_txtap.wt_ihdr, 823 sizeof(sc->sc_txtap), OTUS_TX_RADIOTAP_PRESENT, 824 &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), 825 OTUS_RX_RADIOTAP_PRESENT); 826 827 return (0); 828} 829 830void 831otus_get_chanlist(struct otus_softc *sc) 832{ 833 struct ieee80211com *ic = &sc->sc_ic; 834 uint16_t domain; 835 uint8_t chan; 836 int i; 837 838 /* XXX regulatory domain. */ 839 domain = le16toh(sc->eeprom.baseEepHeader.regDmn[0]); 840 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "regdomain=0x%04x\n", domain); 841 842 if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11G) { 843 for (i = 0; i < 14; i++) { 844 chan = ar_chans[i]; 845 ic->ic_channels[chan].ic_freq = 846 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_2GHZ); 847 ic->ic_channels[chan].ic_flags = 848 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 849 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 850 } 851 } 852 if (sc->eeprom.baseEepHeader.opCapFlags & AR5416_OPFLAGS_11A) { 853 for (i = 14; i < nitems(ar_chans); i++) { 854 chan = ar_chans[i]; 855 ic->ic_channels[chan].ic_freq = 856 ieee80211_ieee2mhz(chan, IEEE80211_CHAN_5GHZ); 857 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_A; 858 } 859 } 860} 861 862int 863otus_load_firmware(struct otus_softc *sc, const char *name, uint32_t addr) 864{ 865 usb_device_request_t req; 866 char *ptr; 867 const struct firmware *fw; 868 int mlen, error, size; 869 870 error = 0; 871 872 /* Read firmware image from the filesystem. */ 873 if ((fw = firmware_get(name)) == NULL) { 874 device_printf(sc->sc_dev, 875 "%s: failed loadfirmware of file %s\n", __func__, name); 876 return (ENXIO); 877 } 878 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 879 req.bRequest = AR_FW_DOWNLOAD; 880 USETW(req.wIndex, 0); 881 882 OTUS_LOCK(sc); 883 884 /* XXX const */ 885 ptr = __DECONST(char *, fw->data); 886 size = fw->datasize; 887 addr >>= 8; 888 while (size > 0) { 889 mlen = MIN(size, 4096); 890 891 USETW(req.wValue, addr); 892 USETW(req.wLength, mlen); 893 if (usbd_do_request_flags(sc->sc_udev, &sc->sc_mtx, 894 &req, ptr, 0, NULL, 250) != 0) { 895 error = EIO; 896 break; 897 } 898 addr += mlen >> 8; 899 ptr += mlen; 900 size -= mlen; 901 } 902 903 OTUS_UNLOCK(sc); 904 905 firmware_put(fw, FIRMWARE_UNLOAD); 906 if (error != 0) 907 device_printf(sc->sc_dev, 908 "%s: %s: error=%d\n", __func__, name, error); 909 return error; 910} 911 912int 913otus_open_pipes(struct otus_softc *sc) 914{ 915#if 0 916 int isize, error; 917 int i; 918#endif 919 int error; 920 921 OTUS_UNLOCK_ASSERT(sc); 922 923 if ((error = otus_alloc_tx_cmd_list(sc)) != 0) { 924 device_printf(sc->sc_dev, 925 "%s: could not allocate command xfer\n", 926 __func__); 927 goto fail; 928 } 929 930 if ((error = otus_alloc_tx_list(sc)) != 0) { 931 device_printf(sc->sc_dev, "%s: could not allocate Tx xfers\n", 932 __func__); 933 goto fail; 934 } 935 936 if ((error = otus_alloc_rx_list(sc)) != 0) { 937 device_printf(sc->sc_dev, "%s: could not allocate Rx xfers\n", 938 __func__); 939 goto fail; 940 } 941 942 /* Enable RX transfers; needed for initial firmware messages */ 943 OTUS_LOCK(sc); 944 usbd_transfer_start(sc->sc_xfer[OTUS_BULK_RX]); 945 usbd_transfer_start(sc->sc_xfer[OTUS_BULK_IRQ]); 946 OTUS_UNLOCK(sc); 947 return 0; 948 949fail: otus_close_pipes(sc); 950 return error; 951} 952 953void 954otus_close_pipes(struct otus_softc *sc) 955{ 956 957 OTUS_LOCK(sc); 958 otus_free_tx_cmd_list(sc); 959 otus_free_tx_list(sc); 960 otus_free_rx_list(sc); 961 OTUS_UNLOCK(sc); 962 963 usbd_transfer_unsetup(sc->sc_xfer, OTUS_N_XFER); 964} 965 966static void 967otus_free_cmd_list(struct otus_softc *sc, struct otus_tx_cmd cmd[], int ndata) 968{ 969 int i; 970 971 /* XXX TODO: someone has to have waken up waiters! */ 972 for (i = 0; i < ndata; i++) { 973 struct otus_tx_cmd *dp = &cmd[i]; 974 975 if (dp->buf != NULL) { 976 free(dp->buf, M_USBDEV); 977 dp->buf = NULL; 978 } 979 } 980} 981 982static int 983otus_alloc_cmd_list(struct otus_softc *sc, struct otus_tx_cmd cmd[], 984 int ndata, int maxsz) 985{ 986 int i, error; 987 988 for (i = 0; i < ndata; i++) { 989 struct otus_tx_cmd *dp = &cmd[i]; 990 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); 991 dp->odata = NULL; 992 if (dp->buf == NULL) { 993 device_printf(sc->sc_dev, 994 "could not allocate buffer\n"); 995 error = ENOMEM; 996 goto fail; 997 } 998 } 999 1000 return (0); 1001fail: 1002 otus_free_cmd_list(sc, cmd, ndata); 1003 return (error); 1004} 1005 1006static int 1007otus_alloc_tx_cmd_list(struct otus_softc *sc) 1008{ 1009 int error, i; 1010 1011 error = otus_alloc_cmd_list(sc, sc->sc_cmd, OTUS_CMD_LIST_COUNT, 1012 OTUS_MAX_TXCMDSZ); 1013 if (error != 0) 1014 return (error); 1015 1016 STAILQ_INIT(&sc->sc_cmd_active); 1017 STAILQ_INIT(&sc->sc_cmd_inactive); 1018 STAILQ_INIT(&sc->sc_cmd_pending); 1019 STAILQ_INIT(&sc->sc_cmd_waiting); 1020 1021 for (i = 0; i < OTUS_CMD_LIST_COUNT; i++) 1022 STAILQ_INSERT_HEAD(&sc->sc_cmd_inactive, &sc->sc_cmd[i], 1023 next_cmd); 1024 1025 return (0); 1026} 1027 1028static void 1029otus_free_tx_cmd_list(struct otus_softc *sc) 1030{ 1031 1032 /* 1033 * XXX TODO: something needs to wake up any pending/sleeping 1034 * waiters! 1035 */ 1036 STAILQ_INIT(&sc->sc_cmd_active); 1037 STAILQ_INIT(&sc->sc_cmd_inactive); 1038 STAILQ_INIT(&sc->sc_cmd_pending); 1039 STAILQ_INIT(&sc->sc_cmd_waiting); 1040 1041 otus_free_cmd_list(sc, sc->sc_cmd, OTUS_CMD_LIST_COUNT); 1042} 1043 1044static int 1045otus_alloc_list(struct otus_softc *sc, struct otus_data data[], 1046 int ndata, int maxsz) 1047{ 1048 int i, error; 1049 1050 for (i = 0; i < ndata; i++) { 1051 struct otus_data *dp = &data[i]; 1052 dp->sc = sc; 1053 dp->m = NULL; 1054 dp->buf = malloc(maxsz, M_USBDEV, M_NOWAIT); 1055 if (dp->buf == NULL) { 1056 device_printf(sc->sc_dev, 1057 "could not allocate buffer\n"); 1058 error = ENOMEM; 1059 goto fail; 1060 } 1061 dp->ni = NULL; 1062 } 1063 1064 return (0); 1065fail: 1066 otus_free_list(sc, data, ndata); 1067 return (error); 1068} 1069 1070static int 1071otus_alloc_rx_list(struct otus_softc *sc) 1072{ 1073 int error, i; 1074 1075 error = otus_alloc_list(sc, sc->sc_rx, OTUS_RX_LIST_COUNT, 1076 OTUS_RXBUFSZ); 1077 if (error != 0) 1078 return (error); 1079 1080 STAILQ_INIT(&sc->sc_rx_active); 1081 STAILQ_INIT(&sc->sc_rx_inactive); 1082 1083 for (i = 0; i < OTUS_RX_LIST_COUNT; i++) 1084 STAILQ_INSERT_HEAD(&sc->sc_rx_inactive, &sc->sc_rx[i], next); 1085 1086 return (0); 1087} 1088 1089static int 1090otus_alloc_tx_list(struct otus_softc *sc) 1091{ 1092 int error, i; 1093 1094 error = otus_alloc_list(sc, sc->sc_tx, OTUS_TX_LIST_COUNT, 1095 OTUS_TXBUFSZ); 1096 if (error != 0) 1097 return (error); 1098 1099 STAILQ_INIT(&sc->sc_tx_inactive); 1100 1101 for (i = 0; i != OTUS_N_XFER; i++) { 1102 STAILQ_INIT(&sc->sc_tx_active[i]); 1103 STAILQ_INIT(&sc->sc_tx_pending[i]); 1104 } 1105 1106 for (i = 0; i < OTUS_TX_LIST_COUNT; i++) { 1107 STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, &sc->sc_tx[i], next); 1108 } 1109 1110 return (0); 1111} 1112 1113static void 1114otus_free_tx_list(struct otus_softc *sc) 1115{ 1116 int i; 1117 1118 /* prevent further allocations from TX list(s) */ 1119 STAILQ_INIT(&sc->sc_tx_inactive); 1120 1121 for (i = 0; i != OTUS_N_XFER; i++) { 1122 STAILQ_INIT(&sc->sc_tx_active[i]); 1123 STAILQ_INIT(&sc->sc_tx_pending[i]); 1124 } 1125 1126 otus_free_list(sc, sc->sc_tx, OTUS_TX_LIST_COUNT); 1127} 1128 1129static void 1130otus_free_rx_list(struct otus_softc *sc) 1131{ 1132 /* prevent further allocations from RX list(s) */ 1133 STAILQ_INIT(&sc->sc_rx_inactive); 1134 STAILQ_INIT(&sc->sc_rx_active); 1135 1136 otus_free_list(sc, sc->sc_rx, OTUS_RX_LIST_COUNT); 1137} 1138 1139static void 1140otus_free_list(struct otus_softc *sc, struct otus_data data[], int ndata) 1141{ 1142 int i; 1143 1144 for (i = 0; i < ndata; i++) { 1145 struct otus_data *dp = &data[i]; 1146 1147 if (dp->buf != NULL) { 1148 free(dp->buf, M_USBDEV); 1149 dp->buf = NULL; 1150 } 1151 if (dp->ni != NULL) { 1152 ieee80211_free_node(dp->ni); 1153 dp->ni = NULL; 1154 } 1155 } 1156} 1157 1158static struct otus_data * 1159_otus_getbuf(struct otus_softc *sc) 1160{ 1161 struct otus_data *bf; 1162 1163 bf = STAILQ_FIRST(&sc->sc_tx_inactive); 1164 if (bf != NULL) 1165 STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next); 1166 else 1167 bf = NULL; 1168 return (bf); 1169} 1170 1171static struct otus_data * 1172otus_getbuf(struct otus_softc *sc) 1173{ 1174 struct otus_data *bf; 1175 1176 OTUS_LOCK_ASSERT(sc); 1177 1178 bf = _otus_getbuf(sc); 1179 return (bf); 1180} 1181 1182static void 1183otus_freebuf(struct otus_softc *sc, struct otus_data *bf) 1184{ 1185 1186 OTUS_LOCK_ASSERT(sc); 1187 STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, bf, next); 1188} 1189 1190static struct otus_tx_cmd * 1191_otus_get_txcmd(struct otus_softc *sc) 1192{ 1193 struct otus_tx_cmd *bf; 1194 1195 bf = STAILQ_FIRST(&sc->sc_cmd_inactive); 1196 if (bf != NULL) 1197 STAILQ_REMOVE_HEAD(&sc->sc_cmd_inactive, next_cmd); 1198 else 1199 bf = NULL; 1200 return (bf); 1201} 1202 1203static struct otus_tx_cmd * 1204otus_get_txcmd(struct otus_softc *sc) 1205{ 1206 struct otus_tx_cmd *bf; 1207 1208 OTUS_LOCK_ASSERT(sc); 1209 1210 bf = _otus_get_txcmd(sc); 1211 if (bf == NULL) { 1212 device_printf(sc->sc_dev, "%s: no tx cmd buffers\n", 1213 __func__); 1214 } 1215 return (bf); 1216} 1217 1218static void 1219otus_free_txcmd(struct otus_softc *sc, struct otus_tx_cmd *bf) 1220{ 1221 1222 OTUS_LOCK_ASSERT(sc); 1223 STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, bf, next_cmd); 1224} 1225 1226void 1227otus_next_scan(void *arg, int pending) 1228{ 1229#if 0 1230 struct otus_softc *sc = arg; 1231 1232 if (usbd_is_dying(sc->sc_udev)) 1233 return; 1234 1235 usbd_ref_incr(sc->sc_udev); 1236 1237 if (sc->sc_ic.ic_state == IEEE80211_S_SCAN) 1238 ieee80211_next_scan(&sc->sc_ic.ic_if); 1239 1240 usbd_ref_decr(sc->sc_udev); 1241#endif 1242} 1243 1244int 1245otus_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1246{ 1247 struct otus_vap *uvp = OTUS_VAP(vap); 1248 struct ieee80211com *ic = vap->iv_ic; 1249 struct otus_softc *sc = ic->ic_softc; 1250 struct ieee80211_node *ni; 1251 enum ieee80211_state ostate; 1252 1253 ostate = vap->iv_state; 1254 OTUS_DPRINTF(sc, OTUS_DEBUG_STATE, "%s: %s -> %s\n", __func__, 1255 ieee80211_state_name[ostate], 1256 ieee80211_state_name[nstate]); 1257 1258 IEEE80211_UNLOCK(ic); 1259 1260 OTUS_LOCK(sc); 1261 1262 /* XXX TODO: more fleshing out! */ 1263 1264 switch (nstate) { 1265 case IEEE80211_S_RUN: 1266 ni = ieee80211_ref_node(vap->iv_bss); 1267 1268 if (ic->ic_opmode == IEEE80211_M_STA) { 1269 otus_updateslot(sc); 1270 otus_set_bssid(sc, ni->ni_bssid); 1271 1272 /* Start calibration timer. */ 1273 taskqueue_enqueue_timeout(taskqueue_thread, 1274 &sc->calib_to, hz); 1275 } 1276 break; 1277 default: 1278 break; 1279 } 1280 1281 /* XXX TODO: calibration? */ 1282 1283 sc->sc_led_newstate(sc); 1284 1285 OTUS_UNLOCK(sc); 1286 IEEE80211_LOCK(ic); 1287 return (uvp->newstate(vap, nstate, arg)); 1288} 1289 1290int 1291otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen, 1292 void *odata, int odatalen) 1293{ 1294 struct otus_tx_cmd *cmd; 1295 struct ar_cmd_hdr *hdr; 1296 int xferlen, error; 1297 1298 OTUS_LOCK_ASSERT(sc); 1299 1300 /* Always bulk-out a multiple of 4 bytes. */ 1301 xferlen = (sizeof (*hdr) + ilen + 3) & ~3; 1302 if (xferlen > OTUS_MAX_TXCMDSZ) { 1303 device_printf(sc->sc_dev, "%s: command (0x%02x) size (%d) > %d\n", 1304 __func__, 1305 code, 1306 xferlen, 1307 OTUS_MAX_TXCMDSZ); 1308 return (EIO); 1309 } 1310 1311 cmd = otus_get_txcmd(sc); 1312 if (cmd == NULL) { 1313 device_printf(sc->sc_dev, "%s: failed to get buf\n", 1314 __func__); 1315 return (EIO); 1316 } 1317 1318 hdr = (struct ar_cmd_hdr *)cmd->buf; 1319 hdr->code = code; 1320 hdr->len = ilen; 1321 hdr->token = ++sc->token; /* Don't care about endianness. */ 1322 cmd->token = hdr->token; 1323 /* XXX TODO: check max cmd length? */ 1324 memcpy((uint8_t *)&hdr[1], idata, ilen); 1325 1326 OTUS_DPRINTF(sc, OTUS_DEBUG_CMD, 1327 "%s: sending command code=0x%02x len=%d token=%d\n", 1328 __func__, code, ilen, hdr->token); 1329 1330 cmd->odata = odata; 1331 cmd->odatalen = odatalen; 1332 cmd->buflen = xferlen; 1333 1334 /* Queue the command to the endpoint */ 1335 STAILQ_INSERT_TAIL(&sc->sc_cmd_pending, cmd, next_cmd); 1336 usbd_transfer_start(sc->sc_xfer[OTUS_BULK_CMD]); 1337 1338 /* Sleep on the command; wait for it to complete */ 1339 error = msleep(cmd, &sc->sc_mtx, PCATCH, "otuscmd", hz); 1340 1341 /* 1342 * At this point we don't own cmd any longer; it'll be 1343 * freed by the cmd bulk path or the RX notification 1344 * path. If the data is made available then it'll be copied 1345 * to the caller. All that is left to do is communicate 1346 * status back to the caller. 1347 */ 1348 if (error != 0) { 1349 device_printf(sc->sc_dev, 1350 "%s: timeout waiting for command 0x%02x reply\n", 1351 __func__, code); 1352 } 1353 return error; 1354} 1355 1356void 1357otus_write(struct otus_softc *sc, uint32_t reg, uint32_t val) 1358{ 1359 1360 OTUS_LOCK_ASSERT(sc); 1361 1362 sc->write_buf[sc->write_idx].reg = htole32(reg); 1363 sc->write_buf[sc->write_idx].val = htole32(val); 1364 1365 if (++sc->write_idx > (AR_MAX_WRITE_IDX-1)) 1366 (void)otus_write_barrier(sc); 1367} 1368 1369int 1370otus_write_barrier(struct otus_softc *sc) 1371{ 1372 int error; 1373 1374 OTUS_LOCK_ASSERT(sc); 1375 1376 if (sc->write_idx == 0) 1377 return 0; /* Nothing to flush. */ 1378 1379 OTUS_DPRINTF(sc, OTUS_DEBUG_REGIO, "%s: called; %d updates\n", 1380 __func__, 1381 sc->write_idx); 1382 1383 error = otus_cmd(sc, AR_CMD_WREG, sc->write_buf, 1384 sizeof (sc->write_buf[0]) * sc->write_idx, NULL, 0); 1385 sc->write_idx = 0; 1386 return error; 1387} 1388 1389struct ieee80211_node * 1390otus_node_alloc(struct ieee80211com *ic) 1391{ 1392 return malloc(sizeof (struct otus_node), M_DEVBUF, M_NOWAIT | M_ZERO); 1393} 1394 1395#if 0 1396int 1397otus_media_change(struct ifnet *ifp) 1398{ 1399 struct otus_softc *sc = ifp->if_softc; 1400 struct ieee80211com *ic = &sc->sc_ic; 1401 uint8_t rate, ridx; 1402 int error; 1403 1404 error = ieee80211_media_change(ifp); 1405 if (error != ENETRESET) 1406 return error; 1407 1408 if (ic->ic_fixed_rate != -1) { 1409 rate = ic->ic_sup_rates[ic->ic_curmode]. 1410 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 1411 for (ridx = 0; ridx <= OTUS_RIDX_MAX; ridx++) 1412 if (otus_rates[ridx].rate == rate) 1413 break; 1414 sc->fixed_ridx = ridx; 1415 } 1416 1417 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) 1418 error = otus_init(sc); 1419 1420 return error; 1421} 1422#endif 1423 1424int 1425otus_read_eeprom(struct otus_softc *sc) 1426{ 1427 uint32_t regs[8], reg; 1428 uint8_t *eep; 1429 int i, j, error; 1430 1431 OTUS_LOCK_ASSERT(sc); 1432 1433 /* Read EEPROM by blocks of 32 bytes. */ 1434 eep = (uint8_t *)&sc->eeprom; 1435 reg = AR_EEPROM_OFFSET; 1436 for (i = 0; i < sizeof (sc->eeprom) / 32; i++) { 1437 for (j = 0; j < 8; j++, reg += 4) 1438 regs[j] = htole32(reg); 1439 error = otus_cmd(sc, AR_CMD_RREG, regs, sizeof regs, eep, 32); 1440 if (error != 0) 1441 break; 1442 eep += 32; 1443 } 1444 return error; 1445} 1446 1447void 1448otus_newassoc(struct ieee80211_node *ni, int isnew) 1449{ 1450 struct ieee80211com *ic = ni->ni_ic; 1451 struct otus_softc *sc = ic->ic_softc; 1452 struct otus_node *on = OTUS_NODE(ni); 1453 1454 OTUS_DPRINTF(sc, OTUS_DEBUG_STATE, "new assoc isnew=%d addr=%s\n", 1455 isnew, ether_sprintf(ni->ni_macaddr)); 1456 1457 on->tx_done = 0; 1458 on->tx_err = 0; 1459 on->tx_retries = 0; 1460} 1461 1462static void 1463otus_cmd_handle_response(struct otus_softc *sc, struct ar_cmd_hdr *hdr) 1464{ 1465 struct otus_tx_cmd *cmd; 1466 1467 OTUS_LOCK_ASSERT(sc); 1468 1469 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, 1470 "%s: received reply code=0x%02x len=%d token=%d\n", 1471 __func__, 1472 hdr->code, hdr->len, hdr->token); 1473 1474 /* 1475 * Walk the list, freeing items that aren't ours, 1476 * stopping when we hit our token. 1477 */ 1478 while ((cmd = STAILQ_FIRST(&sc->sc_cmd_waiting)) != NULL) { 1479 STAILQ_REMOVE_HEAD(&sc->sc_cmd_waiting, next_cmd); 1480 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, 1481 "%s: cmd=%p; hdr.token=%d, cmd.token=%d\n", 1482 __func__, 1483 cmd, 1484 (int) hdr->token, 1485 (int) cmd->token); 1486 if (hdr->token == cmd->token) { 1487 /* Copy answer into caller's supplied buffer. */ 1488 if (cmd->odata != NULL) { 1489 if (hdr->len != cmd->odatalen) { 1490 device_printf(sc->sc_dev, 1491 "%s: code 0x%02x, len=%d, olen=%d\n", 1492 __func__, 1493 (int) hdr->code, 1494 (int) hdr->len, 1495 (int) cmd->odatalen); 1496 } 1497 memcpy(cmd->odata, &hdr[1], 1498 MIN(cmd->odatalen, hdr->len)); 1499 } 1500 wakeup(cmd); 1501 } 1502 1503 STAILQ_INSERT_TAIL(&sc->sc_cmd_inactive, cmd, next_cmd); 1504 } 1505} 1506 1507void 1508otus_cmd_rxeof(struct otus_softc *sc, uint8_t *buf, int len) 1509{ 1510 struct ieee80211com *ic = &sc->sc_ic; 1511 struct ar_cmd_hdr *hdr; 1512 1513 OTUS_LOCK_ASSERT(sc); 1514 1515 if (__predict_false(len < sizeof (*hdr))) { 1516 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, 1517 "cmd too small %d\n", len); 1518 return; 1519 } 1520 hdr = (struct ar_cmd_hdr *)buf; 1521 if (__predict_false(sizeof (*hdr) + hdr->len > len || 1522 sizeof (*hdr) + hdr->len > 64)) { 1523 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, 1524 "cmd too large %d\n", hdr->len); 1525 return; 1526 } 1527 1528 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, 1529 "%s: code=%.02x\n", 1530 __func__, 1531 hdr->code); 1532 1533 /* 1534 * This has to reach into the cmd queue "waiting for 1535 * an RX response" list, grab the head entry and check 1536 * if we need to wake anyone up. 1537 */ 1538 if ((hdr->code & 0xc0) != 0xc0) { 1539 otus_cmd_handle_response(sc, hdr); 1540 return; 1541 } 1542 1543 /* Received unsolicited notification. */ 1544 switch (hdr->code & 0x3f) { 1545 case AR_EVT_BEACON: 1546 break; 1547 case AR_EVT_TX_COMP: 1548 { 1549 struct ar_evt_tx_comp *tx = (struct ar_evt_tx_comp *)&hdr[1]; 1550 struct ieee80211_node *ni; 1551 1552 ni = ieee80211_find_node(&ic->ic_sta, tx->macaddr); 1553 if (ni == NULL) { 1554 device_printf(sc->sc_dev, 1555 "%s: txcomp on unknown node (%s)\n", 1556 __func__, 1557 ether_sprintf(tx->macaddr)); 1558 break; 1559 } 1560 1561 OTUS_DPRINTF(sc, OTUS_DEBUG_TXCOMP, 1562 "tx completed %s status=%d phy=0x%x\n", 1563 ether_sprintf(tx->macaddr), le16toh(tx->status), 1564 le32toh(tx->phy)); 1565 1566 switch (le16toh(tx->status)) { 1567 case AR_TX_STATUS_COMP: 1568#if 0 1569 ackfailcnt = 0; 1570 ieee80211_ratectl_tx_complete(ni->ni_vap, ni, 1571 IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); 1572#endif 1573 /* 1574 * We don't get the above; only error notifications. 1575 * Sigh. So, don't worry about this. 1576 */ 1577 break; 1578 case AR_TX_STATUS_RETRY_COMP: 1579 OTUS_NODE(ni)->tx_retries++; 1580 break; 1581 case AR_TX_STATUS_FAILED: 1582 OTUS_NODE(ni)->tx_err++; 1583 break; 1584 } 1585 ieee80211_free_node(ni); 1586 break; 1587 } 1588 case AR_EVT_TBTT: 1589 break; 1590 case AR_EVT_DO_BB_RESET: 1591 /* 1592 * This is "tell driver to reset baseband" from ar9170-fw. 1593 * 1594 * I'm not sure what we should do here, so I'm going to 1595 * fall through; it gets generated when RTSRetryCnt internally 1596 * reaches '5' - I guess the firmware authors thought that 1597 * meant that the BB may have gone deaf or something. 1598 */ 1599 default: 1600 device_printf(sc->sc_dev, 1601 "%s: received notification code=0x%02x len=%d\n", 1602 __func__, 1603 hdr->code, hdr->len); 1604 } 1605} 1606 1607void 1608otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len, struct mbufq *rxq) 1609{ 1610 struct ieee80211com *ic = &sc->sc_ic; 1611 struct ieee80211_rx_stats rxs; 1612#if 0 1613 struct ieee80211_node *ni; 1614#endif 1615 struct ar_rx_tail *tail; 1616 struct ieee80211_frame *wh; 1617 struct mbuf *m; 1618 uint8_t *plcp; 1619// int s; 1620 int mlen; 1621 1622 if (__predict_false(len < AR_PLCP_HDR_LEN)) { 1623 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, 1624 "sub-xfer too short %d\n", len); 1625 return; 1626 } 1627 plcp = buf; 1628 1629 /* All bits in the PLCP header are set to 1 for non-MPDU. */ 1630 if (memcmp(plcp, AR_PLCP_HDR_INTR, AR_PLCP_HDR_LEN) == 0) { 1631 otus_cmd_rxeof(sc, plcp + AR_PLCP_HDR_LEN, 1632 len - AR_PLCP_HDR_LEN); 1633 return; 1634 } 1635 1636 /* Received MPDU. */ 1637 if (__predict_false(len < AR_PLCP_HDR_LEN + sizeof (*tail))) { 1638 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "MPDU too short %d\n", len); 1639 counter_u64_add(ic->ic_ierrors, 1); 1640 return; 1641 } 1642 tail = (struct ar_rx_tail *)(plcp + len - sizeof (*tail)); 1643 1644 /* Discard error frames. */ 1645 if (__predict_false(tail->error != 0)) { 1646 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "error frame 0x%02x\n", tail->error); 1647 if (tail->error & AR_RX_ERROR_FCS) { 1648 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, "bad FCS\n"); 1649 } else if (tail->error & AR_RX_ERROR_MMIC) { 1650 /* Report Michael MIC failures to net80211. */ 1651#if 0 1652 ieee80211_notify_michael_failure(ni->ni_vap, wh, keyidx); 1653#endif 1654 device_printf(sc->sc_dev, "%s: MIC failure\n", __func__); 1655 } 1656 counter_u64_add(ic->ic_ierrors, 1); 1657 return; 1658 } 1659 /* Compute MPDU's length. */ 1660 mlen = len - AR_PLCP_HDR_LEN - sizeof (*tail); 1661 /* Make sure there's room for an 802.11 header + FCS. */ 1662 if (__predict_false(mlen < IEEE80211_MIN_LEN)) { 1663 counter_u64_add(ic->ic_ierrors, 1); 1664 return; 1665 } 1666 mlen -= IEEE80211_CRC_LEN; /* strip 802.11 FCS */ 1667 1668 wh = (struct ieee80211_frame *)(plcp + AR_PLCP_HDR_LEN); 1669 1670 m = m_get2(mlen, M_NOWAIT, MT_DATA, M_PKTHDR); 1671 if (m == NULL) { 1672 device_printf(sc->sc_dev, "%s: failed m_get2()\n", __func__); 1673 counter_u64_add(ic->ic_ierrors, 1); 1674 } 1675 1676 /* Finalize mbuf. */ 1677 memcpy(mtod(m, uint8_t *), wh, mlen); 1678 m->m_pkthdr.len = m->m_len = mlen; 1679 1680#if 0 1681 if (__predict_false(sc->sc_drvbpf != NULL)) { 1682 struct otus_rx_radiotap_header *tap = &sc->sc_rxtap; 1683 struct mbuf mb; 1684 1685 tap->wr_flags = 0; 1686 tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq); 1687 tap->wr_chan_flags = htole16(ic->ic_ibss_chan->ic_flags); 1688 tap->wr_antsignal = tail->rssi; 1689 tap->wr_rate = 2; /* In case it can't be found below. */ 1690 switch (tail->status & AR_RX_STATUS_MT_MASK) { 1691 case AR_RX_STATUS_MT_CCK: 1692 switch (plcp[0]) { 1693 case 10: tap->wr_rate = 2; break; 1694 case 20: tap->wr_rate = 4; break; 1695 case 55: tap->wr_rate = 11; break; 1696 case 110: tap->wr_rate = 22; break; 1697 } 1698 if (tail->status & AR_RX_STATUS_SHPREAMBLE) 1699 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1700 break; 1701 case AR_RX_STATUS_MT_OFDM: 1702 switch (plcp[0] & 0xf) { 1703 case 0xb: tap->wr_rate = 12; break; 1704 case 0xf: tap->wr_rate = 18; break; 1705 case 0xa: tap->wr_rate = 24; break; 1706 case 0xe: tap->wr_rate = 36; break; 1707 case 0x9: tap->wr_rate = 48; break; 1708 case 0xd: tap->wr_rate = 72; break; 1709 case 0x8: tap->wr_rate = 96; break; 1710 case 0xc: tap->wr_rate = 108; break; 1711 } 1712 break; 1713 } 1714 mb.m_data = (caddr_t)tap; 1715 mb.m_len = sc->sc_rxtap_len; 1716 mb.m_next = m; 1717 mb.m_nextpkt = NULL; 1718 mb.m_type = 0; 1719 mb.m_flags = 0; 1720 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); 1721 } 1722#endif 1723 1724 /* Add RSSI/NF to this mbuf */ 1725 bzero(&rxs, sizeof(rxs)); 1726 rxs.r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI; 1727 rxs.nf = sc->sc_nf[0]; /* XXX chain 0 != combined rssi/nf */ 1728 rxs.rssi = tail->rssi; 1729 /* XXX TODO: add MIMO RSSI/NF as well */ 1730 ieee80211_add_rx_params(m, &rxs); 1731 1732 /* XXX make a method */ 1733 STAILQ_INSERT_TAIL(&rxq->mq_head, m, m_stailqpkt); 1734 1735#if 0 1736 OTUS_UNLOCK(sc); 1737 ni = ieee80211_find_rxnode(ic, wh); 1738 rxi.rxi_flags = 0; 1739 rxi.rxi_rssi = tail->rssi; 1740 rxi.rxi_tstamp = 0; /* unused */ 1741 ieee80211_input(ifp, m, ni, &rxi); 1742 1743 /* Node is no longer needed. */ 1744 ieee80211_release_node(ic, ni); 1745 OTUS_LOCK(sc); 1746#endif 1747} 1748 1749static void 1750otus_rxeof(struct usb_xfer *xfer, struct otus_data *data, struct mbufq *rxq) 1751{ 1752 struct otus_softc *sc = usbd_xfer_softc(xfer); 1753 caddr_t buf = data->buf; 1754 struct ar_rx_head *head; 1755 uint16_t hlen; 1756 int len; 1757 1758 usbd_xfer_status(xfer, &len, NULL, NULL, NULL); 1759 1760 while (len >= sizeof (*head)) { 1761 head = (struct ar_rx_head *)buf; 1762 if (__predict_false(head->tag != htole16(AR_RX_HEAD_TAG))) { 1763 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, 1764 "tag not valid 0x%x\n", le16toh(head->tag)); 1765 break; 1766 } 1767 hlen = le16toh(head->len); 1768 if (__predict_false(sizeof (*head) + hlen > len)) { 1769 OTUS_DPRINTF(sc, OTUS_DEBUG_RXDONE, 1770 "xfer too short %d/%d\n", len, hlen); 1771 break; 1772 } 1773 /* Process sub-xfer. */ 1774 otus_sub_rxeof(sc, (uint8_t *)&head[1], hlen, rxq); 1775 1776 /* Next sub-xfer is aligned on a 32-bit boundary. */ 1777 hlen = (sizeof (*head) + hlen + 3) & ~3; 1778 buf += hlen; 1779 len -= hlen; 1780 } 1781} 1782 1783static void 1784otus_bulk_rx_callback(struct usb_xfer *xfer, usb_error_t error) 1785{ 1786 struct otus_softc *sc = usbd_xfer_softc(xfer); 1787 struct ieee80211com *ic = &sc->sc_ic; 1788 struct ieee80211_frame *wh; 1789 struct ieee80211_node *ni; 1790 struct mbuf *m; 1791 struct mbufq scrx; 1792 struct otus_data *data; 1793 1794 OTUS_LOCK_ASSERT(sc); 1795 1796 mbufq_init(&scrx, 1024); 1797 1798#if 0 1799 device_printf(sc->sc_dev, "%s: called; state=%d; error=%d\n", 1800 __func__, 1801 USB_GET_STATE(xfer), 1802 error); 1803#endif 1804 1805 switch (USB_GET_STATE(xfer)) { 1806 case USB_ST_TRANSFERRED: 1807 data = STAILQ_FIRST(&sc->sc_rx_active); 1808 if (data == NULL) 1809 goto tr_setup; 1810 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 1811 otus_rxeof(xfer, data, &scrx); 1812 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 1813 /* FALLTHROUGH */ 1814 case USB_ST_SETUP: 1815tr_setup: 1816 /* 1817 * XXX TODO: what if sc_rx isn't empty, but data 1818 * is empty? Then we leak mbufs. 1819 */ 1820 data = STAILQ_FIRST(&sc->sc_rx_inactive); 1821 if (data == NULL) { 1822 //KASSERT(m == NULL, ("mbuf isn't NULL")); 1823 return; 1824 } 1825 STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); 1826 STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); 1827 usbd_xfer_set_frame_data(xfer, 0, data->buf, 1828 usbd_xfer_max_len(xfer)); 1829 usbd_transfer_submit(xfer); 1830 /* 1831 * To avoid LOR we should unlock our private mutex here to call 1832 * ieee80211_input() because here is at the end of a USB 1833 * callback and safe to unlock. 1834 */ 1835 OTUS_UNLOCK(sc); 1836 while ((m = mbufq_dequeue(&scrx)) != NULL) { 1837 wh = mtod(m, struct ieee80211_frame *); 1838 ni = ieee80211_find_rxnode(ic, 1839 (struct ieee80211_frame_min *)wh); 1840 if (ni != NULL) { 1841 if (ni->ni_flags & IEEE80211_NODE_HT) 1842 m->m_flags |= M_AMPDU; 1843 (void)ieee80211_input_mimo(ni, m, NULL); 1844 ieee80211_free_node(ni); 1845 } else 1846 (void)ieee80211_input_mimo_all(ic, m, NULL); 1847 } 1848#ifdef IEEE80211_SUPPORT_SUPERG 1849 ieee80211_ff_age_all(ic, 100); 1850#endif 1851 OTUS_LOCK(sc); 1852 break; 1853 default: 1854 /* needs it to the inactive queue due to a error. */ 1855 data = STAILQ_FIRST(&sc->sc_rx_active); 1856 if (data != NULL) { 1857 STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); 1858 STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); 1859 } 1860 if (error != USB_ERR_CANCELLED) { 1861 usbd_xfer_set_stall(xfer); 1862 counter_u64_add(ic->ic_ierrors, 1); 1863 goto tr_setup; 1864 } 1865 break; 1866 } 1867} 1868 1869static void 1870otus_txeof(struct usb_xfer *xfer, struct otus_data *data) 1871{ 1872 struct otus_softc *sc = usbd_xfer_softc(xfer); 1873 1874 OTUS_DPRINTF(sc, OTUS_DEBUG_TXDONE, 1875 "%s: called; data=%p\n", __func__, data); 1876 1877 OTUS_LOCK_ASSERT(sc); 1878 1879 if (sc->sc_tx_n_active == 0) { 1880 device_printf(sc->sc_dev, 1881 "%s: completed but tx_active=0\n", 1882 __func__); 1883 } else { 1884 sc->sc_tx_n_active--; 1885 } 1886 1887 if (data->m) { 1888 /* XXX status? */ 1889 /* XXX we get TX status via the RX path.. */ 1890 ieee80211_tx_complete(data->ni, data->m, 0); 1891 data->m = NULL; 1892 data->ni = NULL; 1893 } 1894} 1895 1896static void 1897otus_txcmdeof(struct usb_xfer *xfer, struct otus_tx_cmd *cmd) 1898{ 1899 struct otus_softc *sc = usbd_xfer_softc(xfer); 1900 1901 OTUS_LOCK_ASSERT(sc); 1902 1903 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, 1904 "%s: called; data=%p; odata=%p\n", 1905 __func__, cmd, cmd->odata); 1906 1907 /* 1908 * Non-response commands still need wakeup so the caller 1909 * knows it was submitted and completed OK; response commands should 1910 * wait until they're ACKed by the firmware with a response. 1911 */ 1912 if (cmd->odata) { 1913 STAILQ_INSERT_TAIL(&sc->sc_cmd_waiting, cmd, next_cmd); 1914 } else { 1915 wakeup(cmd); 1916 otus_free_txcmd(sc, cmd); 1917 } 1918} 1919 1920static void 1921otus_bulk_tx_callback(struct usb_xfer *xfer, usb_error_t error) 1922{ 1923 uint8_t which = OTUS_BULK_TX; 1924 struct otus_softc *sc = usbd_xfer_softc(xfer); 1925 struct ieee80211com *ic = &sc->sc_ic; 1926 struct otus_data *data; 1927 1928 OTUS_LOCK_ASSERT(sc); 1929 1930 switch (USB_GET_STATE(xfer)) { 1931 case USB_ST_TRANSFERRED: 1932 data = STAILQ_FIRST(&sc->sc_tx_active[which]); 1933 if (data == NULL) 1934 goto tr_setup; 1935 OTUS_DPRINTF(sc, OTUS_DEBUG_TXDONE, 1936 "%s: transfer done %p\n", __func__, data); 1937 STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); 1938 otus_txeof(xfer, data); 1939 otus_freebuf(sc, data); 1940 /* FALLTHROUGH */ 1941 case USB_ST_SETUP: 1942tr_setup: 1943 data = STAILQ_FIRST(&sc->sc_tx_pending[which]); 1944 if (data == NULL) { 1945 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, 1946 "%s: empty pending queue sc %p\n", __func__, sc); 1947 sc->sc_tx_n_active = 0; 1948 goto finish; 1949 } 1950 STAILQ_REMOVE_HEAD(&sc->sc_tx_pending[which], next); 1951 STAILQ_INSERT_TAIL(&sc->sc_tx_active[which], data, next); 1952 usbd_xfer_set_frame_data(xfer, 0, data->buf, data->buflen); 1953 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, 1954 "%s: submitting transfer %p\n", __func__, data); 1955 usbd_transfer_submit(xfer); 1956 sc->sc_tx_n_active++; 1957 break; 1958 default: 1959 data = STAILQ_FIRST(&sc->sc_tx_active[which]); 1960 if (data != NULL) { 1961 STAILQ_REMOVE_HEAD(&sc->sc_tx_active[which], next); 1962 otus_txeof(xfer, data); 1963 otus_freebuf(sc, data); 1964 } 1965 counter_u64_add(ic->ic_oerrors, 1); 1966 1967 if (error != USB_ERR_CANCELLED) { 1968 usbd_xfer_set_stall(xfer); 1969 goto tr_setup; 1970 } 1971 break; 1972 } 1973 1974finish: 1975#ifdef IEEE80211_SUPPORT_SUPERG 1976 /* 1977 * If the TX active queue drops below a certain 1978 * threshold, ensure we age fast-frames out so they're 1979 * transmitted. 1980 */ 1981 if (sc->sc_tx_n_active < 2) { 1982 /* XXX ew - net80211 should defer this for us! */ 1983 OTUS_UNLOCK(sc); 1984 ieee80211_ff_flush(ic, WME_AC_VO); 1985 ieee80211_ff_flush(ic, WME_AC_VI); 1986 ieee80211_ff_flush(ic, WME_AC_BE); 1987 ieee80211_ff_flush(ic, WME_AC_BK); 1988 OTUS_LOCK(sc); 1989 } 1990#endif 1991 /* Kick TX */ 1992 otus_tx_start(sc); 1993} 1994 1995static void 1996otus_bulk_cmd_callback(struct usb_xfer *xfer, usb_error_t error) 1997{ 1998 struct otus_softc *sc = usbd_xfer_softc(xfer); 1999#if 0 2000 struct ieee80211com *ic = &sc->sc_ic; 2001#endif 2002 struct otus_tx_cmd *cmd; 2003 2004 OTUS_LOCK_ASSERT(sc); 2005 2006 switch (USB_GET_STATE(xfer)) { 2007 case USB_ST_TRANSFERRED: 2008 cmd = STAILQ_FIRST(&sc->sc_cmd_active); 2009 if (cmd == NULL) 2010 goto tr_setup; 2011 OTUS_DPRINTF(sc, OTUS_DEBUG_CMDDONE, 2012 "%s: transfer done %p\n", __func__, cmd); 2013 STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next_cmd); 2014 otus_txcmdeof(xfer, cmd); 2015 /* FALLTHROUGH */ 2016 case USB_ST_SETUP: 2017tr_setup: 2018 cmd = STAILQ_FIRST(&sc->sc_cmd_pending); 2019 if (cmd == NULL) { 2020 OTUS_DPRINTF(sc, OTUS_DEBUG_CMD, 2021 "%s: empty pending queue sc %p\n", __func__, sc); 2022 return; 2023 } 2024 STAILQ_REMOVE_HEAD(&sc->sc_cmd_pending, next_cmd); 2025 STAILQ_INSERT_TAIL(&sc->sc_cmd_active, cmd, next_cmd); 2026 usbd_xfer_set_frame_data(xfer, 0, cmd->buf, cmd->buflen); 2027 OTUS_DPRINTF(sc, OTUS_DEBUG_CMD, 2028 "%s: submitting transfer %p; buf=%p, buflen=%d\n", __func__, cmd, cmd->buf, cmd->buflen); 2029 usbd_transfer_submit(xfer); 2030 break; 2031 default: 2032 cmd = STAILQ_FIRST(&sc->sc_cmd_active); 2033 if (cmd != NULL) { 2034 STAILQ_REMOVE_HEAD(&sc->sc_cmd_active, next_cmd); 2035 otus_txcmdeof(xfer, cmd); 2036 } 2037 2038 if (error != USB_ERR_CANCELLED) { 2039 usbd_xfer_set_stall(xfer); 2040 goto tr_setup; 2041 } 2042 break; 2043 } 2044} 2045 2046/* 2047 * This isn't used by carl9170; it however may be used by the 2048 * initial bootloader. 2049 */ 2050static void 2051otus_bulk_irq_callback(struct usb_xfer *xfer, usb_error_t error) 2052{ 2053 struct otus_softc *sc = usbd_xfer_softc(xfer); 2054 int actlen; 2055 int sumlen; 2056 2057 usbd_xfer_status(xfer, &actlen, &sumlen, NULL, NULL); 2058 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, 2059 "%s: called; state=%d\n", __func__, USB_GET_STATE(xfer)); 2060 2061 switch (USB_GET_STATE(xfer)) { 2062 case USB_ST_TRANSFERRED: 2063 /* 2064 * Read usb frame data, if any. 2065 * "actlen" has the total length for all frames 2066 * transferred. 2067 */ 2068 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, 2069 "%s: comp; %d bytes\n", 2070 __func__, 2071 actlen); 2072#if 0 2073 pc = usbd_xfer_get_frame(xfer, 0); 2074 otus_dump_usb_rx_page(sc, pc, actlen); 2075#endif 2076 /* XXX fallthrough */ 2077 case USB_ST_SETUP: 2078 /* 2079 * Setup xfer frame lengths/count and data 2080 */ 2081 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, "%s: setup\n", __func__); 2082 usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer)); 2083 usbd_transfer_submit(xfer); 2084 break; 2085 2086 default: /* Error */ 2087 /* 2088 * Print error message and clear stall 2089 * for example. 2090 */ 2091 OTUS_DPRINTF(sc, OTUS_DEBUG_IRQ, "%s: ERROR?\n", __func__); 2092 break; 2093 } 2094} 2095 2096/* 2097 * Map net80211 rate to hw rate for otus MAC/PHY. 2098 */ 2099static uint8_t 2100otus_rate_to_hw_rate(struct otus_softc *sc, uint8_t rate) 2101{ 2102 int is_2ghz; 2103 2104 is_2ghz = !! (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_curchan)); 2105 2106 switch (rate) { 2107 /* CCK */ 2108 case 2: 2109 return (0x0); 2110 case 4: 2111 return (0x1); 2112 case 11: 2113 return (0x2); 2114 case 22: 2115 return (0x3); 2116 /* OFDM */ 2117 case 12: 2118 return (0xb); 2119 case 18: 2120 return (0xf); 2121 case 24: 2122 return (0xa); 2123 case 36: 2124 return (0xe); 2125 case 48: 2126 return (0x9); 2127 case 72: 2128 return (0xd); 2129 case 96: 2130 return (0x8); 2131 case 108: 2132 return (0xc); 2133 default: 2134 device_printf(sc->sc_dev, "%s: unknown rate '%d'\n", 2135 __func__, (int) rate); 2136 case 0: 2137 if (is_2ghz) 2138 return (0x0); /* 1MB CCK */ 2139 else 2140 return (0xb); /* 6MB OFDM */ 2141 2142 /* XXX TODO: HT */ 2143 } 2144} 2145 2146static int 2147otus_hw_rate_is_ofdm(struct otus_softc *sc, uint8_t hw_rate) 2148{ 2149 2150 switch (hw_rate) { 2151 case 0x0: 2152 case 0x1: 2153 case 0x2: 2154 case 0x3: 2155 return (0); 2156 default: 2157 return (1); 2158 } 2159} 2160 2161 2162static void 2163otus_tx_update_ratectl(struct otus_softc *sc, struct ieee80211_node *ni) 2164{ 2165 int tx, tx_success, tx_retry; 2166 2167 tx = OTUS_NODE(ni)->tx_done; 2168 tx_success = OTUS_NODE(ni)->tx_done - OTUS_NODE(ni)->tx_err; 2169 tx_retry = OTUS_NODE(ni)->tx_retries; 2170 2171 ieee80211_ratectl_tx_update(ni->ni_vap, ni, &tx, &tx_success, 2172 &tx_retry); 2173} 2174 2175/* 2176 * XXX TODO: support tx bpf parameters for configuration! 2177 */ 2178static int 2179otus_tx(struct otus_softc *sc, struct ieee80211_node *ni, struct mbuf *m, 2180 struct otus_data *data) 2181{ 2182 struct ieee80211com *ic = &sc->sc_ic; 2183 struct ieee80211vap *vap = ni->ni_vap; 2184 struct ieee80211_frame *wh; 2185 struct ieee80211_key *k; 2186 struct ar_tx_head *head; 2187 uint32_t phyctl; 2188 uint16_t macctl, qos; 2189 uint8_t qid, rate; 2190 int hasqos, xferlen; 2191 2192 wh = mtod(m, struct ieee80211_frame *); 2193 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2194 k = ieee80211_crypto_encap(ni, m); 2195 if (k == NULL) { 2196 device_printf(sc->sc_dev, 2197 "%s: m=%p: ieee80211_crypto_encap returns NULL\n", 2198 __func__, 2199 m); 2200 return (ENOBUFS); 2201 } 2202 wh = mtod(m, struct ieee80211_frame *); 2203 } 2204 2205 /* Calculate transfer length; ensure data buffer is large enough */ 2206 xferlen = sizeof (*head) + m->m_pkthdr.len; 2207 if (xferlen > OTUS_TXBUFSZ) { 2208 device_printf(sc->sc_dev, 2209 "%s: 802.11 TX frame is %d bytes, max %d bytes\n", 2210 __func__, 2211 xferlen, 2212 OTUS_TXBUFSZ); 2213 return (ENOBUFS); 2214 } 2215 2216 hasqos = !! IEEE80211_QOS_HAS_SEQ(wh); 2217 2218 if (hasqos) { 2219 uint8_t tid; 2220 qos = ((const struct ieee80211_qosframe *)wh)->i_qos[0]; 2221 tid = qos & IEEE80211_QOS_TID; 2222 qid = TID_TO_WME_AC(tid); 2223 } else { 2224 qos = 0; 2225 qid = WME_AC_BE; 2226 } 2227 2228 /* Pickup a rate index. */ 2229 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 2230 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_DATA) { 2231 /* Get lowest rate */ 2232 rate = otus_rate_to_hw_rate(sc, 0); 2233 } else { 2234 (void) ieee80211_ratectl_rate(ni, NULL, 0); 2235 rate = otus_rate_to_hw_rate(sc, ni->ni_txrate); 2236 } 2237 2238 phyctl = 0; 2239 macctl = AR_TX_MAC_BACKOFF | AR_TX_MAC_HW_DUR | AR_TX_MAC_QID(qid); 2240 2241 if (IEEE80211_IS_MULTICAST(wh->i_addr1) || 2242 (hasqos && ((qos & IEEE80211_QOS_ACKPOLICY) == 2243 IEEE80211_QOS_ACKPOLICY_NOACK))) 2244 macctl |= AR_TX_MAC_NOACK; 2245 2246 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 2247 if (m->m_pkthdr.len + IEEE80211_CRC_LEN >= vap->iv_rtsthreshold) 2248 macctl |= AR_TX_MAC_RTS; 2249 else if (ic->ic_flags & IEEE80211_F_USEPROT) { 2250 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 2251 macctl |= AR_TX_MAC_CTS; 2252 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 2253 macctl |= AR_TX_MAC_RTS; 2254 } 2255 } 2256 2257 phyctl |= AR_TX_PHY_MCS(rate); 2258 if (otus_hw_rate_is_ofdm(sc, rate)) { 2259 phyctl |= AR_TX_PHY_MT_OFDM; 2260 /* Always use all tx antennas for now, just to be safe */ 2261 phyctl |= AR_TX_PHY_ANTMSK(sc->txmask); 2262 } else { /* CCK */ 2263 phyctl |= AR_TX_PHY_MT_CCK; 2264 phyctl |= AR_TX_PHY_ANTMSK(sc->txmask); 2265 } 2266 2267 /* Update net80211 with the current counters */ 2268 otus_tx_update_ratectl(sc, ni); 2269 2270 /* Update rate control stats for frames that are ACK'ed. */ 2271 if (!(macctl & AR_TX_MAC_NOACK)) 2272 OTUS_NODE(ni)->tx_done++; 2273 2274 2275 /* Fill Tx descriptor. */ 2276 head = (struct ar_tx_head *)data->buf; 2277 head->len = htole16(m->m_pkthdr.len + IEEE80211_CRC_LEN); 2278 head->macctl = htole16(macctl); 2279 head->phyctl = htole32(phyctl); 2280 2281 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&head[1]); 2282 2283 data->buflen = xferlen; 2284 data->ni = ni; 2285 data->m = m; 2286 2287 OTUS_DPRINTF(sc, OTUS_DEBUG_XMIT, 2288 "%s: tx: m=%p; data=%p; len=%d mac=0x%04x phy=0x%08x rate=0x%02x, ni_txrate=%d\n", 2289 __func__, m, data, head->len, head->macctl, head->phyctl, 2290 (int) rate, (int) ni->ni_txrate); 2291 2292 /* Submit transfer */ 2293 STAILQ_INSERT_TAIL(&sc->sc_tx_pending[OTUS_BULK_TX], data, next); 2294 usbd_transfer_start(sc->sc_xfer[OTUS_BULK_TX]); 2295 2296 return 0; 2297} 2298 2299int 2300otus_set_multi(struct otus_softc *sc) 2301{ 2302 uint32_t lo, hi; 2303 struct ieee80211com *ic = &sc->sc_ic; 2304 int r; 2305 2306 if (ic->ic_allmulti > 0 || ic->ic_promisc > 0 || 2307 ic->ic_opmode == IEEE80211_M_MONITOR) { 2308 lo = 0xffffffff; 2309 hi = 0xffffffff; 2310 } else { 2311 struct ieee80211vap *vap; 2312 struct ifnet *ifp; 2313 struct ifmultiaddr *ifma; 2314 2315 lo = hi = 0; 2316 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 2317 ifp = vap->iv_ifp; 2318 if_maddr_rlock(ifp); 2319 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2320 caddr_t dl; 2321 uint32_t val; 2322 2323 dl = LLADDR((struct sockaddr_dl *) ifma->ifma_addr); 2324 val = LE_READ_4(dl + 4); 2325 /* Get address byte 5 */ 2326 val = val & 0x0000ff00; 2327 val = val >> 8; 2328 2329 /* As per below, shift it >> 2 to get only 6 bits */ 2330 val = val >> 2; 2331 if (val < 32) 2332 lo |= 1 << val; 2333 else 2334 hi |= 1 << (val - 32); 2335 } 2336 if_maddr_runlock(ifp); 2337 } 2338 } 2339#if 0 2340 /* XXX openbsd code */ 2341 while (enm != NULL) { 2342 bit = enm->enm_addrlo[5] >> 2; 2343 if (bit < 32) 2344 lo |= 1 << bit; 2345 else 2346 hi |= 1 << (bit - 32); 2347 ETHER_NEXT_MULTI(step, enm); 2348 } 2349#endif 2350 2351 hi |= 1U << 31; /* Make sure the broadcast bit is set. */ 2352 2353 OTUS_LOCK(sc); 2354 otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_L, lo); 2355 otus_write(sc, AR_MAC_REG_GROUP_HASH_TBL_H, hi); 2356 r = otus_write_barrier(sc); 2357 OTUS_UNLOCK(sc); 2358 return (r); 2359} 2360 2361static void 2362otus_updateedca(struct otus_softc *sc) 2363{ 2364#define EXP2(val) ((1 << (val)) - 1) 2365#define AIFS(val) ((val) * 9 + 10) 2366 struct ieee80211com *ic = &sc->sc_ic; 2367 const struct wmeParams *edca; 2368 2369 OTUS_LOCK_ASSERT(sc); 2370 2371 edca = ic->ic_wme.wme_chanParams.cap_wmeParams; 2372 2373 /* Set CWmin/CWmax values. */ 2374 otus_write(sc, AR_MAC_REG_AC0_CW, 2375 EXP2(edca[WME_AC_BE].wmep_logcwmax) << 16 | 2376 EXP2(edca[WME_AC_BE].wmep_logcwmin)); 2377 otus_write(sc, AR_MAC_REG_AC1_CW, 2378 EXP2(edca[WME_AC_BK].wmep_logcwmax) << 16 | 2379 EXP2(edca[WME_AC_BK].wmep_logcwmin)); 2380 otus_write(sc, AR_MAC_REG_AC2_CW, 2381 EXP2(edca[WME_AC_VI].wmep_logcwmax) << 16 | 2382 EXP2(edca[WME_AC_VI].wmep_logcwmin)); 2383 otus_write(sc, AR_MAC_REG_AC3_CW, 2384 EXP2(edca[WME_AC_VO].wmep_logcwmax) << 16 | 2385 EXP2(edca[WME_AC_VO].wmep_logcwmin)); 2386 otus_write(sc, AR_MAC_REG_AC4_CW, /* Special TXQ. */ 2387 EXP2(edca[WME_AC_VO].wmep_logcwmax) << 16 | 2388 EXP2(edca[WME_AC_VO].wmep_logcwmin)); 2389 2390 /* Set AIFSN values. */ 2391 otus_write(sc, AR_MAC_REG_AC1_AC0_AIFS, 2392 AIFS(edca[WME_AC_VI].wmep_aifsn) << 24 | 2393 AIFS(edca[WME_AC_BK].wmep_aifsn) << 12 | 2394 AIFS(edca[WME_AC_BE].wmep_aifsn)); 2395 otus_write(sc, AR_MAC_REG_AC3_AC2_AIFS, 2396 AIFS(edca[WME_AC_VO].wmep_aifsn) << 16 | /* Special TXQ. */ 2397 AIFS(edca[WME_AC_VO].wmep_aifsn) << 4 | 2398 AIFS(edca[WME_AC_VI].wmep_aifsn) >> 8); 2399 2400 /* Set TXOP limit. */ 2401 otus_write(sc, AR_MAC_REG_AC1_AC0_TXOP, 2402 edca[WME_AC_BK].wmep_txopLimit << 16 | 2403 edca[WME_AC_BE].wmep_txopLimit); 2404 otus_write(sc, AR_MAC_REG_AC3_AC2_TXOP, 2405 edca[WME_AC_VO].wmep_txopLimit << 16 | 2406 edca[WME_AC_VI].wmep_txopLimit); 2407 2408 /* XXX ACK policy? */ 2409 2410 (void)otus_write_barrier(sc); 2411 2412#undef AIFS 2413#undef EXP2 2414} 2415 2416static void 2417otus_updateslot(struct otus_softc *sc) 2418{ 2419 struct ieee80211com *ic = &sc->sc_ic; 2420 uint32_t slottime; 2421 2422 OTUS_LOCK_ASSERT(sc); 2423 2424 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; 2425 otus_write(sc, AR_MAC_REG_SLOT_TIME, slottime << 10); 2426 (void)otus_write_barrier(sc); 2427} 2428 2429int 2430otus_init_mac(struct otus_softc *sc) 2431{ 2432 int error; 2433 2434 OTUS_LOCK_ASSERT(sc); 2435 2436 otus_write(sc, AR_MAC_REG_ACK_EXTENSION, 0x40); 2437 otus_write(sc, AR_MAC_REG_RETRY_MAX, 0); 2438 otus_write(sc, AR_MAC_REG_SNIFFER, 0x2000000); 2439 otus_write(sc, AR_MAC_REG_RX_THRESHOLD, 0xc1f80); 2440 otus_write(sc, AR_MAC_REG_RX_PE_DELAY, 0x70); 2441 otus_write(sc, AR_MAC_REG_EIFS_AND_SIFS, 0xa144000); 2442 otus_write(sc, AR_MAC_REG_SLOT_TIME, 9 << 10); 2443 otus_write(sc, 0x1c3b2c, 0x19000000); 2444 /* NAV protects ACK only (in TXOP). */ 2445 otus_write(sc, 0x1c3b38, 0x201); 2446 /* Set beacon Tx power to 0x7. */ 2447 otus_write(sc, AR_MAC_REG_BCN_HT1, 0x8000170); 2448 otus_write(sc, AR_MAC_REG_BACKOFF_PROTECT, 0x105); 2449 otus_write(sc, 0x1c3b9c, 0x10000a); 2450 /* Filter any control frames, BAR is bit 24. */ 2451 otus_write(sc, 0x1c368c, 0x0500ffff); 2452 otus_write(sc, 0x1c3c40, 0x1); 2453 otus_write(sc, AR_MAC_REG_BASIC_RATE, 0x150f); 2454 otus_write(sc, AR_MAC_REG_MANDATORY_RATE, 0x150f); 2455 otus_write(sc, AR_MAC_REG_RTS_CTS_RATE, 0x10b01bb); 2456 otus_write(sc, 0x1c3694, 0x4003c1e); 2457 /* Enable LED0 and LED1. */ 2458 otus_write(sc, 0x1d0100, 0x3); 2459 otus_write(sc, 0x1d0104, 0x3); 2460 /* Switch MAC to OTUS interface. */ 2461 otus_write(sc, 0x1c3600, 0x3); 2462 otus_write(sc, 0x1c3c50, 0xffff); 2463 otus_write(sc, 0x1c3680, 0xf00008); 2464 /* Disable Rx timeout (workaround). */ 2465 otus_write(sc, 0x1c362c, 0); 2466 2467 /* Set USB Rx stream mode maximum frame number to 2. */ 2468 otus_write(sc, 0x1e1110, 0x4); 2469 /* Set USB Rx stream mode timeout to 10us. */ 2470 otus_write(sc, 0x1e1114, 0x80); 2471 2472 /* Set clock frequency to 88/80MHz. */ 2473 otus_write(sc, 0x1d4008, 0x73); 2474 /* Set WLAN DMA interrupt mode: generate intr per packet. */ 2475 otus_write(sc, 0x1c3d7c, 0x110011); 2476 otus_write(sc, 0x1c3bb0, 0x4); 2477 otus_write(sc, AR_MAC_REG_TXOP_NOT_ENOUGH_INDICATION, 0x141e0f48); 2478 2479 /* Disable HW decryption for now. */ 2480 otus_write(sc, 0x1c3678, 0x78); 2481 2482 if ((error = otus_write_barrier(sc)) != 0) 2483 return error; 2484 2485 /* Set default EDCA parameters. */ 2486 otus_updateedca(sc); 2487 2488 return 0; 2489} 2490 2491/* 2492 * Return default value for PHY register based on current operating mode. 2493 */ 2494uint32_t 2495otus_phy_get_def(struct otus_softc *sc, uint32_t reg) 2496{ 2497 int i; 2498 2499 for (i = 0; i < nitems(ar5416_phy_regs); i++) 2500 if (AR_PHY(ar5416_phy_regs[i]) == reg) 2501 return sc->phy_vals[i]; 2502 return 0; /* Register not found. */ 2503} 2504 2505/* 2506 * Update PHY's programming based on vendor-specific data stored in EEPROM. 2507 * This is for FEM-type devices only. 2508 */ 2509int 2510otus_set_board_values(struct otus_softc *sc, struct ieee80211_channel *c) 2511{ 2512 const struct ModalEepHeader *eep; 2513 uint32_t tmp, offset; 2514 2515 if (IEEE80211_IS_CHAN_5GHZ(c)) 2516 eep = &sc->eeprom.modalHeader[0]; 2517 else 2518 eep = &sc->eeprom.modalHeader[1]; 2519 2520 /* Offset of chain 2. */ 2521 offset = 2 * 0x1000; 2522 2523 tmp = le32toh(eep->antCtrlCommon); 2524 otus_write(sc, AR_PHY_SWITCH_COM, tmp); 2525 2526 tmp = le32toh(eep->antCtrlChain[0]); 2527 otus_write(sc, AR_PHY_SWITCH_CHAIN_0, tmp); 2528 2529 tmp = le32toh(eep->antCtrlChain[1]); 2530 otus_write(sc, AR_PHY_SWITCH_CHAIN_0 + offset, tmp); 2531 2532 if (1 /* sc->sc_sco == AR_SCO_SCN */) { 2533 tmp = otus_phy_get_def(sc, AR_PHY_SETTLING); 2534 tmp &= ~(0x7f << 7); 2535 tmp |= (eep->switchSettling & 0x7f) << 7; 2536 otus_write(sc, AR_PHY_SETTLING, tmp); 2537 } 2538 2539 tmp = otus_phy_get_def(sc, AR_PHY_DESIRED_SZ); 2540 tmp &= ~0xffff; 2541 tmp |= eep->pgaDesiredSize << 8 | eep->adcDesiredSize; 2542 otus_write(sc, AR_PHY_DESIRED_SZ, tmp); 2543 2544 tmp = eep->txEndToXpaOff << 24 | eep->txEndToXpaOff << 16 | 2545 eep->txFrameToXpaOn << 8 | eep->txFrameToXpaOn; 2546 otus_write(sc, AR_PHY_RF_CTL4, tmp); 2547 2548 tmp = otus_phy_get_def(sc, AR_PHY_RF_CTL3); 2549 tmp &= ~(0xff << 16); 2550 tmp |= eep->txEndToRxOn << 16; 2551 otus_write(sc, AR_PHY_RF_CTL3, tmp); 2552 2553 tmp = otus_phy_get_def(sc, AR_PHY_CCA); 2554 tmp &= ~(0x7f << 12); 2555 tmp |= (eep->thresh62 & 0x7f) << 12; 2556 otus_write(sc, AR_PHY_CCA, tmp); 2557 2558 tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN); 2559 tmp &= ~(0x3f << 12); 2560 tmp |= (eep->txRxAttenCh[0] & 0x3f) << 12; 2561 otus_write(sc, AR_PHY_RXGAIN, tmp); 2562 2563 tmp = otus_phy_get_def(sc, AR_PHY_RXGAIN + offset); 2564 tmp &= ~(0x3f << 12); 2565 tmp |= (eep->txRxAttenCh[1] & 0x3f) << 12; 2566 otus_write(sc, AR_PHY_RXGAIN + offset, tmp); 2567 2568 tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ); 2569 tmp &= ~(0x3f << 18); 2570 tmp |= (eep->rxTxMarginCh[0] & 0x3f) << 18; 2571 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2572 tmp &= ~(0xf << 10); 2573 tmp |= (eep->bswMargin[0] & 0xf) << 10; 2574 } 2575 otus_write(sc, AR_PHY_GAIN_2GHZ, tmp); 2576 2577 tmp = otus_phy_get_def(sc, AR_PHY_GAIN_2GHZ + offset); 2578 tmp &= ~(0x3f << 18); 2579 tmp |= (eep->rxTxMarginCh[1] & 0x3f) << 18; 2580 otus_write(sc, AR_PHY_GAIN_2GHZ + offset, tmp); 2581 2582 tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4); 2583 tmp &= ~(0x3f << 5 | 0x1f); 2584 tmp |= (eep->iqCalICh[0] & 0x3f) << 5 | (eep->iqCalQCh[0] & 0x1f); 2585 otus_write(sc, AR_PHY_TIMING_CTRL4, tmp); 2586 2587 tmp = otus_phy_get_def(sc, AR_PHY_TIMING_CTRL4 + offset); 2588 tmp &= ~(0x3f << 5 | 0x1f); 2589 tmp |= (eep->iqCalICh[1] & 0x3f) << 5 | (eep->iqCalQCh[1] & 0x1f); 2590 otus_write(sc, AR_PHY_TIMING_CTRL4 + offset, tmp); 2591 2592 tmp = otus_phy_get_def(sc, AR_PHY_TPCRG1); 2593 tmp &= ~(0xf << 16); 2594 tmp |= (eep->xpd & 0xf) << 16; 2595 otus_write(sc, AR_PHY_TPCRG1, tmp); 2596 2597 return otus_write_barrier(sc); 2598} 2599 2600int 2601otus_program_phy(struct otus_softc *sc, struct ieee80211_channel *c) 2602{ 2603 const uint32_t *vals; 2604 int error, i; 2605 2606 /* Select PHY programming based on band and bandwidth. */ 2607 if (IEEE80211_IS_CHAN_2GHZ(c)) 2608 vals = ar5416_phy_vals_2ghz_20mhz; 2609 else 2610 vals = ar5416_phy_vals_5ghz_20mhz; 2611 for (i = 0; i < nitems(ar5416_phy_regs); i++) 2612 otus_write(sc, AR_PHY(ar5416_phy_regs[i]), vals[i]); 2613 sc->phy_vals = vals; 2614 2615 if (sc->eeprom.baseEepHeader.deviceType == 0x80) /* FEM */ 2616 if ((error = otus_set_board_values(sc, c)) != 0) 2617 return error; 2618 2619 /* Initial Tx power settings. */ 2620 otus_write(sc, AR_PHY_POWER_TX_RATE_MAX, 0x7f); 2621 otus_write(sc, AR_PHY_POWER_TX_RATE1, 0x3f3f3f3f); 2622 otus_write(sc, AR_PHY_POWER_TX_RATE2, 0x3f3f3f3f); 2623 otus_write(sc, AR_PHY_POWER_TX_RATE3, 0x3f3f3f3f); 2624 otus_write(sc, AR_PHY_POWER_TX_RATE4, 0x3f3f3f3f); 2625 otus_write(sc, AR_PHY_POWER_TX_RATE5, 0x3f3f3f3f); 2626 otus_write(sc, AR_PHY_POWER_TX_RATE6, 0x3f3f3f3f); 2627 otus_write(sc, AR_PHY_POWER_TX_RATE7, 0x3f3f3f3f); 2628 otus_write(sc, AR_PHY_POWER_TX_RATE8, 0x3f3f3f3f); 2629 otus_write(sc, AR_PHY_POWER_TX_RATE9, 0x3f3f3f3f); 2630 2631 if (IEEE80211_IS_CHAN_2GHZ(c)) 2632 otus_write(sc, 0x1d4014, 0x5163); 2633 else 2634 otus_write(sc, 0x1d4014, 0x5143); 2635 2636 return otus_write_barrier(sc); 2637} 2638 2639static __inline uint8_t 2640otus_reverse_bits(uint8_t v) 2641{ 2642 v = ((v >> 1) & 0x55) | ((v & 0x55) << 1); 2643 v = ((v >> 2) & 0x33) | ((v & 0x33) << 2); 2644 v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4); 2645 return v; 2646} 2647 2648int 2649otus_set_rf_bank4(struct otus_softc *sc, struct ieee80211_channel *c) 2650{ 2651 uint8_t chansel, d0, d1; 2652 uint16_t data; 2653 int error; 2654 2655 OTUS_LOCK_ASSERT(sc); 2656 2657 d0 = 0; 2658 if (IEEE80211_IS_CHAN_5GHZ(c)) { 2659 chansel = (c->ic_freq - 4800) / 5; 2660 if (chansel & 1) 2661 d0 |= AR_BANK4_AMODE_REFSEL(2); 2662 else 2663 d0 |= AR_BANK4_AMODE_REFSEL(1); 2664 } else { 2665 d0 |= AR_BANK4_AMODE_REFSEL(2); 2666 if (c->ic_freq == 2484) { /* CH 14 */ 2667 d0 |= AR_BANK4_BMODE_LF_SYNTH_FREQ; 2668 chansel = 10 + (c->ic_freq - 2274) / 5; 2669 } else 2670 chansel = 16 + (c->ic_freq - 2272) / 5; 2671 chansel <<= 2; 2672 } 2673 d0 |= AR_BANK4_ADDR(1) | AR_BANK4_CHUP; 2674 d1 = otus_reverse_bits(chansel); 2675 2676 /* Write bits 0-4 of d0 and d1. */ 2677 data = (d1 & 0x1f) << 5 | (d0 & 0x1f); 2678 otus_write(sc, AR_PHY(44), data); 2679 /* Write bits 5-7 of d0 and d1. */ 2680 data = (d1 >> 5) << 5 | (d0 >> 5); 2681 otus_write(sc, AR_PHY(58), data); 2682 2683 if ((error = otus_write_barrier(sc)) == 0) 2684 otus_delay_ms(sc, 10); 2685 return error; 2686} 2687 2688void 2689otus_get_delta_slope(uint32_t coeff, uint32_t *exponent, uint32_t *mantissa) 2690{ 2691#define COEFF_SCALE_SHIFT 24 2692 uint32_t exp, man; 2693 2694 /* exponent = 14 - floor(log2(coeff)) */ 2695 for (exp = 31; exp > 0; exp--) 2696 if (coeff & (1 << exp)) 2697 break; 2698 KASSERT(exp != 0, ("exp")); 2699 exp = 14 - (exp - COEFF_SCALE_SHIFT); 2700 2701 /* mantissa = floor(coeff * 2^exponent + 0.5) */ 2702 man = coeff + (1 << (COEFF_SCALE_SHIFT - exp - 1)); 2703 2704 *mantissa = man >> (COEFF_SCALE_SHIFT - exp); 2705 *exponent = exp - 16; 2706#undef COEFF_SCALE_SHIFT 2707} 2708 2709static int 2710otus_set_chan(struct otus_softc *sc, struct ieee80211_channel *c, int assoc) 2711{ 2712 struct ieee80211com *ic = &sc->sc_ic; 2713 struct ar_cmd_frequency cmd; 2714 struct ar_rsp_frequency rsp; 2715 const uint32_t *vals; 2716 uint32_t coeff, exp, man, tmp; 2717 uint8_t code; 2718 int error, chan, i; 2719 2720 error = 0; 2721 chan = ieee80211_chan2ieee(ic, c); 2722 2723 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, 2724 "setting channel %d (%dMHz)\n", chan, c->ic_freq); 2725 2726 tmp = IEEE80211_IS_CHAN_2GHZ(c) ? 0x105 : 0x104; 2727 otus_write(sc, AR_MAC_REG_DYNAMIC_SIFS_ACK, tmp); 2728 if ((error = otus_write_barrier(sc)) != 0) 2729 goto finish; 2730 2731 /* Disable BB Heavy Clip. */ 2732 otus_write(sc, AR_PHY_HEAVY_CLIP_ENABLE, 0x200); 2733 if ((error = otus_write_barrier(sc)) != 0) 2734 goto finish; 2735 2736 /* XXX Is that FREQ_START ? */ 2737 error = otus_cmd(sc, AR_CMD_FREQ_STRAT, NULL, 0, NULL, 0); 2738 if (error != 0) 2739 goto finish; 2740 2741 /* Reprogram PHY and RF on channel band or bandwidth changes. */ 2742 if (sc->bb_reset || c->ic_flags != sc->sc_curchan->ic_flags) { 2743 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, "band switch\n"); 2744 2745 /* Cold/Warm reset BB/ADDA. */ 2746 otus_write(sc, 0x1d4004, sc->bb_reset ? 0x800 : 0x400); 2747 if ((error = otus_write_barrier(sc)) != 0) 2748 goto finish; 2749 otus_write(sc, 0x1d4004, 0); 2750 if ((error = otus_write_barrier(sc)) != 0) 2751 goto finish; 2752 sc->bb_reset = 0; 2753 2754 if ((error = otus_program_phy(sc, c)) != 0) { 2755 device_printf(sc->sc_dev, 2756 "%s: could not program PHY\n", 2757 __func__); 2758 goto finish; 2759 } 2760 2761 /* Select RF programming based on band. */ 2762 if (IEEE80211_IS_CHAN_5GHZ(c)) 2763 vals = ar5416_banks_vals_5ghz; 2764 else 2765 vals = ar5416_banks_vals_2ghz; 2766 for (i = 0; i < nitems(ar5416_banks_regs); i++) 2767 otus_write(sc, AR_PHY(ar5416_banks_regs[i]), vals[i]); 2768 if ((error = otus_write_barrier(sc)) != 0) { 2769 device_printf(sc->sc_dev, 2770 "%s: could not program RF\n", 2771 __func__); 2772 goto finish; 2773 } 2774 code = AR_CMD_RF_INIT; 2775 } else { 2776 code = AR_CMD_FREQUENCY; 2777 } 2778 2779 if ((error = otus_set_rf_bank4(sc, c)) != 0) 2780 goto finish; 2781 2782 tmp = (sc->txmask == 0x5) ? 0x340 : 0x240; 2783 otus_write(sc, AR_PHY_TURBO, tmp); 2784 if ((error = otus_write_barrier(sc)) != 0) 2785 goto finish; 2786 2787 /* Send firmware command to set channel. */ 2788 cmd.freq = htole32((uint32_t)c->ic_freq * 1000); 2789 cmd.dynht2040 = htole32(0); 2790 cmd.htena = htole32(1); 2791 /* Set Delta Slope (exponent and mantissa). */ 2792 coeff = (100 << 24) / c->ic_freq; 2793 otus_get_delta_slope(coeff, &exp, &man); 2794 cmd.dsc_exp = htole32(exp); 2795 cmd.dsc_man = htole32(man); 2796 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, 2797 "ds coeff=%u exp=%u man=%u\n", coeff, exp, man); 2798 /* For Short GI, coeff is 9/10 that of normal coeff. */ 2799 coeff = (9 * coeff) / 10; 2800 otus_get_delta_slope(coeff, &exp, &man); 2801 cmd.dsc_shgi_exp = htole32(exp); 2802 cmd.dsc_shgi_man = htole32(man); 2803 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, 2804 "ds shgi coeff=%u exp=%u man=%u\n", coeff, exp, man); 2805 /* Set wait time for AGC and noise calibration (100 or 200ms). */ 2806 cmd.check_loop_count = assoc ? htole32(2000) : htole32(1000); 2807 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, 2808 "%s\n", (code == AR_CMD_RF_INIT) ? "RF_INIT" : "FREQUENCY"); 2809 error = otus_cmd(sc, code, &cmd, sizeof cmd, &rsp, sizeof(rsp)); 2810 if (error != 0) 2811 goto finish; 2812 if ((rsp.status & htole32(AR_CAL_ERR_AGC | AR_CAL_ERR_NF_VAL)) != 0) { 2813 OTUS_DPRINTF(sc, OTUS_DEBUG_RESET, 2814 "status=0x%x\n", le32toh(rsp.status)); 2815 /* Force cold reset on next channel. */ 2816 sc->bb_reset = 1; 2817 } 2818#ifdef USB_DEBUG 2819 if (otus_debug & OTUS_DEBUG_RESET) { 2820 device_printf(sc->sc_dev, "calibration status=0x%x\n", 2821 le32toh(rsp.status)); 2822 for (i = 0; i < 2; i++) { /* 2 Rx chains */ 2823 /* Sign-extend 9-bit NF values. */ 2824 device_printf(sc->sc_dev, 2825 "noisefloor chain %d=%d\n", i, 2826 (((int32_t)le32toh(rsp.nf[i])) << 4) >> 23); 2827 device_printf(sc->sc_dev, 2828 "noisefloor ext chain %d=%d\n", i, 2829 ((int32_t)le32toh(rsp.nf_ext[i])) >> 23); 2830 } 2831 } 2832#endif 2833 for (i = 0; i < OTUS_NUM_CHAINS; i++) { 2834 sc->sc_nf[i] = ((((int32_t)le32toh(rsp.nf[i])) << 4) >> 23); 2835 } 2836 sc->sc_curchan = c; 2837finish: 2838 return (error); 2839} 2840 2841#ifdef notyet 2842int 2843otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 2844 struct ieee80211_key *k) 2845{ 2846 struct otus_softc *sc = ic->ic_softc; 2847 struct otus_cmd_key cmd; 2848 2849 /* Defer setting of WEP keys until interface is brought up. */ 2850 if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) != 2851 (IFF_UP | IFF_RUNNING)) 2852 return 0; 2853 2854 /* Do it in a process context. */ 2855 cmd.key = *k; 2856 cmd.associd = (ni != NULL) ? ni->ni_associd : 0; 2857 otus_do_async(sc, otus_set_key_cb, &cmd, sizeof cmd); 2858 return 0; 2859} 2860 2861void 2862otus_set_key_cb(struct otus_softc *sc, void *arg) 2863{ 2864 struct otus_cmd_key *cmd = arg; 2865 struct ieee80211_key *k = &cmd->key; 2866 struct ar_cmd_ekey key; 2867 uint16_t cipher; 2868 int error; 2869 2870 memset(&key, 0, sizeof key); 2871 if (k->k_flags & IEEE80211_KEY_GROUP) { 2872 key.uid = htole16(k->k_id); 2873 IEEE80211_ADDR_COPY(key.macaddr, sc->sc_ic.ic_myaddr); 2874 key.macaddr[0] |= 0x80; 2875 } else { 2876 key.uid = htole16(OTUS_UID(cmd->associd)); 2877 IEEE80211_ADDR_COPY(key.macaddr, ni->ni_macaddr); 2878 } 2879 key.kix = htole16(0); 2880 /* Map net80211 cipher to hardware. */ 2881 switch (k->k_cipher) { 2882 case IEEE80211_CIPHER_WEP40: 2883 cipher = AR_CIPHER_WEP64; 2884 break; 2885 case IEEE80211_CIPHER_WEP104: 2886 cipher = AR_CIPHER_WEP128; 2887 break; 2888 case IEEE80211_CIPHER_TKIP: 2889 cipher = AR_CIPHER_TKIP; 2890 break; 2891 case IEEE80211_CIPHER_CCMP: 2892 cipher = AR_CIPHER_AES; 2893 break; 2894 default: 2895 return; 2896 } 2897 key.cipher = htole16(cipher); 2898 memcpy(key.key, k->k_key, MIN(k->k_len, 16)); 2899 error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0); 2900 if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP) 2901 return; 2902 2903 /* TKIP: set Tx/Rx MIC Key. */ 2904 key.kix = htole16(1); 2905 memcpy(key.key, k->k_key + 16, 16); 2906 (void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL, 0); 2907} 2908 2909void 2910otus_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 2911 struct ieee80211_key *k) 2912{ 2913 struct otus_softc *sc = ic->ic_softc; 2914 struct otus_cmd_key cmd; 2915 2916 if (!(ic->ic_if.if_flags & IFF_RUNNING) || 2917 ic->ic_state != IEEE80211_S_RUN) 2918 return; /* Nothing to do. */ 2919 2920 /* Do it in a process context. */ 2921 cmd.key = *k; 2922 cmd.associd = (ni != NULL) ? ni->ni_associd : 0; 2923 otus_do_async(sc, otus_delete_key_cb, &cmd, sizeof cmd); 2924} 2925 2926void 2927otus_delete_key_cb(struct otus_softc *sc, void *arg) 2928{ 2929 struct otus_cmd_key *cmd = arg; 2930 struct ieee80211_key *k = &cmd->key; 2931 uint32_t uid; 2932 2933 if (k->k_flags & IEEE80211_KEY_GROUP) 2934 uid = htole32(k->k_id); 2935 else 2936 uid = htole32(OTUS_UID(cmd->associd)); 2937 (void)otus_cmd(sc, AR_CMD_DKEY, &uid, sizeof uid, NULL, 0); 2938} 2939#endif 2940 2941/* 2942 * XXX TODO: check if we have to be doing any calibration in the host 2943 * or whether it's purely a firmware thing. 2944 */ 2945void 2946otus_calibrate_to(void *arg, int pending) 2947{ 2948#if 0 2949 struct otus_softc *sc = arg; 2950 2951 device_printf(sc->sc_dev, "%s: called\n", __func__); 2952 struct ieee80211com *ic = &sc->sc_ic; 2953 struct ieee80211_node *ni; 2954 int s; 2955 2956 if (usbd_is_dying(sc->sc_udev)) 2957 return; 2958 2959 usbd_ref_incr(sc->sc_udev); 2960 2961 s = splnet(); 2962 ni = ic->ic_bss; 2963 ieee80211_amrr_choose(&sc->amrr, ni, &((struct otus_node *)ni)->amn); 2964 splx(s); 2965 2966 if (!usbd_is_dying(sc->sc_udev)) 2967 timeout_add_sec(&sc->calib_to, 1); 2968 2969 usbd_ref_decr(sc->sc_udev); 2970#endif 2971} 2972 2973int 2974otus_set_bssid(struct otus_softc *sc, const uint8_t *bssid) 2975{ 2976 2977 OTUS_LOCK_ASSERT(sc); 2978 2979 otus_write(sc, AR_MAC_REG_BSSID_L, 2980 bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24); 2981 otus_write(sc, AR_MAC_REG_BSSID_H, 2982 bssid[4] | bssid[5] << 8); 2983 return otus_write_barrier(sc); 2984} 2985 2986int 2987otus_set_macaddr(struct otus_softc *sc, const uint8_t *addr) 2988{ 2989 OTUS_LOCK_ASSERT(sc); 2990 2991 otus_write(sc, AR_MAC_REG_MAC_ADDR_L, 2992 addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24); 2993 otus_write(sc, AR_MAC_REG_MAC_ADDR_H, 2994 addr[4] | addr[5] << 8); 2995 return otus_write_barrier(sc); 2996} 2997 2998/* Default single-LED. */ 2999void 3000otus_led_newstate_type1(struct otus_softc *sc) 3001{ 3002 /* TBD */ 3003 device_printf(sc->sc_dev, "%s: TODO\n", __func__); 3004} 3005 3006/* NETGEAR, dual-LED. */ 3007void 3008otus_led_newstate_type2(struct otus_softc *sc) 3009{ 3010 /* TBD */ 3011 device_printf(sc->sc_dev, "%s: TODO\n", __func__); 3012} 3013 3014/* NETGEAR, single-LED/3 colors (blue, red, purple.) */ 3015void 3016otus_led_newstate_type3(struct otus_softc *sc) 3017{ 3018#if 0 3019 struct ieee80211com *ic = &sc->sc_ic; 3020 struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); 3021 3022 uint32_t state = sc->led_state; 3023 3024 OTUS_LOCK_ASSERT(sc); 3025 3026 if (!vap) { 3027 state = 0; /* led off */ 3028 } else if (vap->iv_state == IEEE80211_S_INIT) { 3029 state = 0; /* LED off. */ 3030 } else if (vap->iv_state == IEEE80211_S_RUN) { 3031 /* Associated, LED always on. */ 3032 if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) 3033 state = AR_LED0_ON; /* 2GHz=>Red. */ 3034 else 3035 state = AR_LED1_ON; /* 5GHz=>Blue. */ 3036 } else { 3037 /* Scanning, blink LED. */ 3038 state ^= AR_LED0_ON | AR_LED1_ON; 3039 if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) 3040 state &= ~AR_LED1_ON; 3041 else 3042 state &= ~AR_LED0_ON; 3043 } 3044 if (state != sc->led_state) { 3045 otus_write(sc, 0x1d0104, state); 3046 if (otus_write_barrier(sc) == 0) 3047 sc->led_state = state; 3048 } 3049#endif 3050} 3051 3052int 3053otus_init(struct otus_softc *sc) 3054{ 3055 struct ieee80211com *ic = &sc->sc_ic; 3056 int error; 3057 3058 OTUS_UNLOCK_ASSERT(sc); 3059 3060 OTUS_LOCK(sc); 3061 3062 /* Drain any pending TX frames */ 3063 otus_drain_mbufq(sc); 3064 3065 /* Init MAC */ 3066 if ((error = otus_init_mac(sc)) != 0) { 3067 OTUS_UNLOCK(sc); 3068 device_printf(sc->sc_dev, 3069 "%s: could not initialize MAC\n", __func__); 3070 return error; 3071 } 3072 3073 (void) otus_set_macaddr(sc, ic->ic_macaddr); 3074 3075#if 0 3076 switch (ic->ic_opmode) { 3077#ifdef notyet 3078#ifndef IEEE80211_STA_ONLY 3079 case IEEE80211_M_HOSTAP: 3080 otus_write(sc, 0x1c3700, 0x0f0000a1); 3081 otus_write(sc, 0x1c3c40, 0x1); 3082 break; 3083 case IEEE80211_M_IBSS: 3084 otus_write(sc, 0x1c3700, 0x0f000000); 3085 otus_write(sc, 0x1c3c40, 0x1); 3086 break; 3087#endif 3088#endif 3089 case IEEE80211_M_STA: 3090 otus_write(sc, 0x1c3700, 0x0f000002); 3091 otus_write(sc, 0x1c3c40, 0x1); 3092 break; 3093 default: 3094 break; 3095 } 3096#endif 3097 3098 /* Expect STA operation */ 3099 otus_write(sc, 0x1c3700, 0x0f000002); 3100 otus_write(sc, 0x1c3c40, 0x1); 3101 3102 /* XXX ic_opmode? */ 3103 otus_write(sc, AR_MAC_REG_SNIFFER, 3104 (ic->ic_opmode == IEEE80211_M_MONITOR) ? 0x2000001 : 0x2000000); 3105 (void)otus_write_barrier(sc); 3106 3107 sc->bb_reset = 1; /* Force cold reset. */ 3108 3109 if ((error = otus_set_chan(sc, ic->ic_curchan, 0)) != 0) { 3110 OTUS_UNLOCK(sc); 3111 device_printf(sc->sc_dev, 3112 "%s: could not set channel\n", __func__); 3113 return error; 3114 } 3115 3116 /* Start Rx. */ 3117 otus_write(sc, 0x1c3d30, 0x100); 3118 (void)otus_write_barrier(sc); 3119 3120 sc->sc_running = 1; 3121 3122 OTUS_UNLOCK(sc); 3123 return 0; 3124} 3125 3126void 3127otus_stop(struct otus_softc *sc) 3128{ 3129#if 0 3130 int s; 3131#endif 3132 3133 OTUS_UNLOCK_ASSERT(sc); 3134 3135 OTUS_LOCK(sc); 3136 sc->sc_running = 0; 3137 sc->sc_tx_timer = 0; 3138 OTUS_UNLOCK(sc); 3139 3140 taskqueue_drain_timeout(taskqueue_thread, &sc->scan_to); 3141 taskqueue_drain_timeout(taskqueue_thread, &sc->calib_to); 3142 taskqueue_drain(taskqueue_thread, &sc->tx_task); 3143 taskqueue_drain(taskqueue_thread, &sc->wme_update_task); 3144 3145 OTUS_LOCK(sc); 3146 sc->sc_running = 0; 3147 /* Stop Rx. */ 3148 otus_write(sc, 0x1c3d30, 0); 3149 (void)otus_write_barrier(sc); 3150 3151 /* Drain any pending TX frames */ 3152 otus_drain_mbufq(sc); 3153 3154 OTUS_UNLOCK(sc); 3155} 3156