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