1 /* $NetBSD: if_athn_usb.c,v 1.38 2020/03/14 02:35:33 christos Exp $ */ 2 /* $OpenBSD: if_athn_usb.c,v 1.12 2013/01/14 09:50:31 jsing Exp $ */ 3 4 /*- 5 * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr> 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 * USB front-end for Atheros AR9271 and AR7010 chipsets. 22 */ 23 24 #include <sys/cdefs.h> 25 __KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.38 2020/03/14 02:35:33 christos Exp $"); 26 27 #ifdef _KERNEL_OPT 28 #include "opt_inet.h" 29 #endif 30 31 #include <sys/param.h> 32 #include <sys/callout.h> 33 #include <sys/conf.h> 34 #include <sys/device.h> 35 #include <sys/kernel.h> 36 #include <sys/mbuf.h> 37 #include <sys/module.h> 38 #include <sys/proc.h> 39 #include <sys/socket.h> 40 #include <sys/sockio.h> 41 #include <sys/systm.h> 42 #include <sys/kmem.h> 43 44 #include <sys/bus.h> 45 #include <sys/endian.h> 46 #include <sys/intr.h> 47 48 #include <net/bpf.h> 49 #include <net/if.h> 50 #include <net/if_arp.h> 51 #include <net/if_dl.h> 52 #include <net/if_ether.h> 53 #include <net/if_media.h> 54 #include <net/if_types.h> 55 56 #include <netinet/if_inarp.h> 57 #include <netinet/in.h> 58 #include <netinet/in_systm.h> 59 #include <netinet/in_var.h> 60 #include <netinet/ip.h> 61 62 #include <net80211/ieee80211_var.h> 63 #include <net80211/ieee80211_amrr.h> 64 #include <net80211/ieee80211_radiotap.h> 65 66 #include <dev/firmload.h> 67 68 #include <dev/usb/usb.h> 69 #include <dev/usb/usbdevs.h> 70 #include <dev/usb/usbdi.h> 71 #include <dev/usb/usbdi_util.h> 72 73 #include <dev/ic/athnreg.h> 74 #include <dev/ic/athnvar.h> 75 #include <dev/ic/arn9285.h> 76 #include <dev/usb/if_athn_usb.h> 77 78 #define ATHN_USB_SOFTC(sc) ((struct athn_usb_softc *)(sc)) 79 #define ATHN_USB_NODE(ni) ((struct athn_usb_node *)(ni)) 80 81 #define IS_UP_AND_RUNNING(ifp) \ 82 (((ifp)->if_flags & IFF_UP) && ((ifp)->if_flags & IFF_RUNNING)) 83 84 #define athn_usb_wmi_cmd(sc, cmd_id) \ 85 athn_usb_wmi_xcmd(sc, cmd_id, NULL, 0, NULL) 86 87 Static int athn_usb_activate(device_t, enum devact); 88 Static int athn_usb_detach(device_t, int); 89 Static int athn_usb_match(device_t, cfdata_t, void *); 90 Static void athn_usb_attach(device_t, device_t, void *); 91 92 CFATTACH_DECL_NEW(athn_usb, sizeof(struct athn_usb_softc), athn_usb_match, 93 athn_usb_attach, athn_usb_detach, athn_usb_activate); 94 95 Static int athn_usb_alloc_rx_list(struct athn_usb_softc *); 96 Static int athn_usb_alloc_tx_cmd(struct athn_usb_softc *); 97 Static int athn_usb_alloc_tx_msg(struct athn_usb_softc *); 98 Static int athn_usb_alloc_tx_list(struct athn_usb_softc *); 99 Static void athn_usb_attachhook(device_t); 100 Static void athn_usb_bcneof(struct usbd_xfer *, void *, 101 usbd_status); 102 Static void athn_usb_abort_pipes(struct athn_usb_softc *); 103 Static void athn_usb_close_pipes(struct athn_usb_softc *); 104 Static int athn_usb_create_hw_node(struct athn_usb_softc *, 105 struct ar_htc_target_sta *); 106 Static int athn_usb_create_node(struct athn_usb_softc *, 107 struct ieee80211_node *); 108 Static void athn_usb_do_async(struct athn_usb_softc *, 109 void (*)(struct athn_usb_softc *, void *), void *, int); 110 Static void athn_usb_free_rx_list(struct athn_usb_softc *); 111 Static void athn_usb_free_tx_cmd(struct athn_usb_softc *); 112 Static void athn_usb_free_tx_msg(struct athn_usb_softc *); 113 Static void athn_usb_free_tx_list(struct athn_usb_softc *); 114 Static int athn_usb_htc_connect_svc(struct athn_usb_softc *, uint16_t, 115 uint8_t, uint8_t, uint8_t *); 116 Static int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *, 117 int); 118 Static int athn_usb_htc_setup(struct athn_usb_softc *); 119 Static int athn_usb_init(struct ifnet *); 120 Static int athn_usb_init_locked(struct ifnet *); 121 Static void athn_usb_intr(struct usbd_xfer *, void *, 122 usbd_status); 123 Static int athn_usb_ioctl(struct ifnet *, u_long, void *); 124 Static int athn_usb_load_firmware(struct athn_usb_softc *); 125 Static const struct athn_usb_type * 126 athn_usb_lookup(int, int); 127 Static int athn_usb_media_change(struct ifnet *); 128 Static void athn_usb_newassoc(struct ieee80211_node *, int); 129 Static void athn_usb_newassoc_cb(struct athn_usb_softc *, void *); 130 Static int athn_usb_newstate(struct ieee80211com *, enum ieee80211_state, 131 int); 132 Static void athn_usb_newstate_cb(struct athn_usb_softc *, void *); 133 Static void athn_usb_node_cleanup(struct ieee80211_node *); 134 Static void athn_usb_node_cleanup_cb(struct athn_usb_softc *, void *); 135 Static int athn_usb_open_pipes(struct athn_usb_softc *); 136 Static uint32_t athn_usb_read(struct athn_softc *, uint32_t); 137 Static int athn_usb_remove_hw_node(struct athn_usb_softc *, uint8_t *); 138 Static void athn_usb_rx_enable(struct athn_softc *); 139 Static void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *); 140 Static void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *, 141 struct ar_rx_status *); 142 Static void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, size_t); 143 Static void athn_usb_rxeof(struct usbd_xfer *, void *, 144 usbd_status); 145 Static void athn_usb_start(struct ifnet *); 146 //Static void athn_usb_start_locked(struct ifnet *); 147 Static void athn_usb_stop(struct ifnet *, int disable); 148 Static void athn_usb_stop_locked(struct ifnet *); 149 Static void athn_usb_swba(struct athn_usb_softc *); 150 Static int athn_usb_switch_chan(struct athn_softc *, 151 struct ieee80211_channel *, struct ieee80211_channel *); 152 Static void athn_usb_task(void *); 153 Static int athn_usb_tx(struct athn_softc *, struct mbuf *, 154 struct ieee80211_node *, struct athn_usb_tx_data *); 155 Static void athn_usb_txeof(struct usbd_xfer *, void *, 156 usbd_status); 157 Static void athn_usb_updateslot(struct ifnet *); 158 Static void athn_usb_updateslot_cb(struct athn_usb_softc *, void *); 159 Static void athn_usb_wait_async(struct athn_usb_softc *); 160 Static int athn_usb_wait_msg(struct athn_usb_softc *); 161 Static void athn_usb_watchdog(struct ifnet *); 162 Static int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *, 163 int, void *); 164 Static void athn_usb_wmieof(struct usbd_xfer *, void *, 165 usbd_status); 166 Static void athn_usb_write(struct athn_softc *, uint32_t, uint32_t); 167 Static void athn_usb_write_barrier(struct athn_softc *); 168 169 /************************************************************************ 170 * unused/notyet declarations 171 */ 172 #ifdef unused 173 Static int athn_usb_read_rom(struct athn_softc *); 174 #endif /* unused */ 175 176 #ifdef notyet_edca 177 Static void athn_usb_updateedca(struct ieee80211com *); 178 Static void athn_usb_updateedca_cb(struct athn_usb_softc *, void *); 179 #endif /* notyet_edca */ 180 181 #ifdef notyet 182 Static int athn_usb_ampdu_tx_start(struct ieee80211com *, 183 struct ieee80211_node *, uint8_t); 184 Static void athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *, void *); 185 Static void athn_usb_ampdu_tx_stop(struct ieee80211com *, 186 struct ieee80211_node *, uint8_t); 187 Static void athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *, void *); 188 Static void athn_usb_delete_key(struct ieee80211com *, 189 struct ieee80211_node *, struct ieee80211_key *); 190 Static void athn_usb_delete_key_cb(struct athn_usb_softc *, void *); 191 Static int athn_usb_set_key(struct ieee80211com *, 192 struct ieee80211_node *, struct ieee80211_key *); 193 Static void athn_usb_set_key_cb(struct athn_usb_softc *, void *); 194 #endif /* notyet */ 195 /************************************************************************/ 196 197 struct athn_usb_type { 198 struct usb_devno devno; 199 u_int flags; 200 }; 201 202 Static const struct athn_usb_type * 203 athn_usb_lookup(int vendor, int product) 204 { 205 static const struct athn_usb_type athn_usb_devs[] = { 206 #define _D(v,p,f) \ 207 {{ USB_VENDOR_##v, USB_PRODUCT_##p }, ATHN_USB_FLAG_##f } 208 209 _D( ACCTON, ACCTON_AR9280, AR7010 ), 210 _D( ACTIONTEC, ACTIONTEC_AR9287, AR7010 ), 211 _D( ATHEROS2, ATHEROS2_AR9271_1, NONE ), 212 _D( ATHEROS2, ATHEROS2_AR9271_2, NONE ), 213 _D( ATHEROS2, ATHEROS2_AR9271_3, NONE ), 214 _D( ATHEROS2, ATHEROS2_AR9280, AR7010 ), 215 _D( ATHEROS2, ATHEROS2_AR9287, AR7010 ), 216 _D( AZUREWAVE, AZUREWAVE_AR9271_1, NONE ), 217 _D( AZUREWAVE, AZUREWAVE_AR9271_2, NONE ), 218 _D( AZUREWAVE, AZUREWAVE_AR9271_3, NONE ), 219 _D( AZUREWAVE, AZUREWAVE_AR9271_4, NONE ), 220 _D( AZUREWAVE, AZUREWAVE_AR9271_5, NONE ), 221 _D( AZUREWAVE, AZUREWAVE_AR9271_6, NONE ), 222 _D( DLINK2, DLINK2_AR9271, NONE ), 223 _D( LITEON, LITEON_AR9271, NONE ), 224 _D( NETGEAR, NETGEAR_WNA1100, NONE ), 225 _D( NETGEAR, NETGEAR_WNDA3200, AR7010 ), 226 _D( VIA, VIA_AR9271, NONE ), 227 _D( MELCO, MELCO_CEWL_1, AR7010 ), 228 _D( PANASONIC, PANASONIC_N5HBZ0000055, AR7010 ), 229 #undef _D 230 }; 231 232 return (const void *)usb_lookup(athn_usb_devs, vendor, product); 233 } 234 235 Static int 236 athn_usb_match(device_t parent, cfdata_t match, void *aux) 237 { 238 struct usb_attach_arg *uaa = aux; 239 240 return athn_usb_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? 241 UMATCH_VENDOR_PRODUCT : UMATCH_NONE; 242 } 243 244 Static void 245 athn_usb_attach(device_t parent, device_t self, void *aux) 246 { 247 struct athn_usb_softc *usc; 248 struct athn_softc *sc; 249 struct usb_attach_arg *uaa; 250 int error; 251 252 usc = device_private(self); 253 sc = &usc->usc_sc; 254 uaa = aux; 255 sc->sc_dev = self; 256 usc->usc_udev = uaa->uaa_device; 257 258 aprint_naive("\n"); 259 aprint_normal("\n"); 260 261 DPRINTFN(DBG_FN, sc, "\n"); 262 263 usc->usc_init_state = ATHN_INIT_NONE; 264 usc->usc_athn_attached = 0; 265 usc->usc_flags = athn_usb_lookup(uaa->uaa_vendor, uaa->uaa_product)->flags; 266 sc->sc_flags |= ATHN_FLAG_USB; 267 #ifdef notyet 268 /* Check if it is a combo WiFi+Bluetooth (WB193) device. */ 269 if (strncmp(product, "wb193", 5) == 0) 270 sc->sc_flags |= ATHN_FLAG_BTCOEX3WIRE; 271 #endif 272 273 sc->sc_ops.read = athn_usb_read; 274 sc->sc_ops.write = athn_usb_write; 275 sc->sc_ops.write_barrier = athn_usb_write_barrier; 276 277 mutex_init(&usc->usc_lock, MUTEX_DEFAULT, IPL_NONE); 278 279 cv_init(&usc->usc_wmi_cv, "athnwmi"); 280 cv_init(&usc->usc_htc_cv, "athnhtc"); 281 282 cv_init(&usc->usc_cmd_cv, "athncmd"); 283 mutex_init(&usc->usc_cmd_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); 284 cv_init(&usc->usc_msg_cv, "athnmsg"); 285 mutex_init(&usc->usc_msg_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); 286 287 cv_init(&usc->usc_task_cv, "athntsk"); 288 mutex_init(&usc->usc_task_mtx, MUTEX_DEFAULT, IPL_NET); 289 mutex_init(&usc->usc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); 290 291 usb_init_task(&usc->usc_task, athn_usb_task, usc, 0); 292 293 if (usbd_set_config_no(usc->usc_udev, 1, 0) != 0) { 294 aprint_error_dev(sc->sc_dev, 295 "could not set configuration no\n"); 296 goto fail; 297 } 298 299 /* Get the first interface handle. */ 300 error = usbd_device2interface_handle(usc->usc_udev, 0, &usc->usc_iface); 301 if (error != 0) { 302 aprint_error_dev(sc->sc_dev, 303 "could not get interface handle\n"); 304 goto fail; 305 } 306 307 if (athn_usb_open_pipes(usc) != 0) 308 goto fail; 309 310 /* Allocate xfer for firmware commands. */ 311 if (athn_usb_alloc_tx_cmd(usc) != 0) 312 goto fail; 313 314 /* Allocate xfer for firmware commands. */ 315 if (athn_usb_alloc_tx_msg(usc) != 0) 316 goto fail; 317 318 /* Allocate Tx/Rx buffers. */ 319 error = athn_usb_alloc_rx_list(usc); 320 if (error != 0) 321 goto fail; 322 error = athn_usb_alloc_tx_list(usc); 323 if (error != 0) 324 goto fail; 325 326 config_mountroot(self, athn_usb_attachhook); 327 328 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, usc->usc_udev, sc->sc_dev); 329 if (!pmf_device_register(self, NULL, NULL)) 330 aprint_error_dev(self, "couldn't establish power handler\n"); 331 332 usc->usc_init_state = ATHN_INIT_INITED; 333 334 return; 335 336 fail: 337 338 /* Free Tx/Rx buffers. */ 339 athn_usb_abort_pipes(usc); 340 athn_usb_free_tx_list(usc); 341 athn_usb_free_rx_list(usc); 342 athn_usb_free_tx_cmd(usc); 343 athn_usb_free_tx_msg(usc); 344 athn_usb_close_pipes(usc); 345 usb_rem_task_wait(usc->usc_udev, &usc->usc_task, USB_TASKQ_DRIVER, 346 NULL); 347 348 cv_destroy(&usc->usc_cmd_cv); 349 cv_destroy(&usc->usc_msg_cv); 350 351 cv_destroy(&usc->usc_wmi_cv); 352 cv_destroy(&usc->usc_htc_cv); 353 mutex_destroy(&usc->usc_lock); 354 355 mutex_destroy(&usc->usc_cmd_mtx); 356 mutex_destroy(&usc->usc_msg_mtx); 357 mutex_destroy(&usc->usc_tx_mtx); 358 mutex_destroy(&usc->usc_task_mtx); 359 } 360 361 Static void 362 athn_usb_node_cleanup_cb(struct athn_usb_softc *usc, void *arg) 363 { 364 uint8_t sta_index = *(uint8_t *)arg; 365 366 DPRINTFN(DBG_FN, usc, "\n"); 367 DPRINTFN(DBG_NODES, usc, "removing node %u\n", sta_index); 368 athn_usb_remove_hw_node(usc, &sta_index); 369 } 370 371 Static void 372 athn_usb_node_cleanup(struct ieee80211_node *ni) 373 { 374 struct athn_usb_softc *usc; 375 struct ieee80211com *ic; 376 uint8_t sta_index; 377 378 usc = ATHN_USB_SOFTC(ni->ni_ic->ic_ifp->if_softc); 379 ic = &ATHN_SOFTC(usc)->sc_ic; 380 381 DPRINTFN(DBG_FN, usc, "\n"); 382 383 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 384 sta_index = ATHN_NODE(ni)->sta_index; 385 if (sta_index != 0) 386 athn_usb_do_async(usc, athn_usb_node_cleanup_cb, 387 &sta_index, sizeof(sta_index)); 388 } 389 usc->usc_node_cleanup(ni); 390 } 391 392 Static void 393 athn_usb_attachhook(device_t arg) 394 { 395 struct athn_usb_softc *usc = device_private(arg); 396 struct athn_softc *sc = &usc->usc_sc; 397 struct athn_ops *ops = &sc->sc_ops; 398 struct ieee80211com *ic = &sc->sc_ic; 399 struct ifnet *ifp = &sc->sc_if; 400 size_t i; 401 int error; 402 403 if (usc->usc_dying) 404 return; 405 406 DPRINTFN(DBG_FN, usc, "\n"); 407 408 /* Load firmware. */ 409 error = athn_usb_load_firmware(usc); 410 if (error != 0) { 411 aprint_error_dev(sc->sc_dev, 412 "could not load firmware (%d)\n", error); 413 return; 414 } 415 416 /* Setup the host transport communication interface. */ 417 error = athn_usb_htc_setup(usc); 418 if (error != 0) 419 return; 420 421 /* We're now ready to attach the bus agnostic driver. */ 422 ic->ic_ifp = ifp; 423 ic->ic_updateslot = athn_usb_updateslot; 424 sc->sc_max_aid = AR_USB_MAX_STA; /* Firmware is limited to 8 STA */ 425 sc->sc_media_change = athn_usb_media_change; 426 427 /* Override some operations for USB. */ 428 ifp->if_init = athn_usb_init; 429 ifp->if_stop = athn_usb_stop; 430 ifp->if_ioctl = athn_usb_ioctl; 431 ifp->if_start = athn_usb_start; 432 ifp->if_watchdog = athn_usb_watchdog; 433 434 error = athn_attach(sc); 435 if (error != 0) { 436 return; 437 } 438 usc->usc_athn_attached = 1; 439 440 /* hooks for HostAP association and disassociation */ 441 ic->ic_newassoc = athn_usb_newassoc; 442 usc->usc_node_cleanup = ic->ic_node_cleanup; 443 ic->ic_node_cleanup = athn_usb_node_cleanup; 444 445 #ifdef notyet_edca 446 ic->ic_updateedca = athn_usb_updateedca; 447 #endif 448 #ifdef notyet 449 ic->ic_set_key = athn_usb_set_key; 450 ic->ic_delete_key = athn_usb_delete_key; 451 ic->ic_ampdu_tx_start = athn_usb_ampdu_tx_start; 452 ic->ic_ampdu_tx_stop = athn_usb_ampdu_tx_stop; 453 #endif 454 ic->ic_newstate = athn_usb_newstate; 455 456 ops->rx_enable = athn_usb_rx_enable; 457 458 /* Reset HW key cache entries. */ 459 for (i = 0; i < sc->sc_kc_entries; i++) 460 athn_reset_key(sc, i); 461 462 ops->enable_antenna_diversity(sc); 463 464 #ifdef ATHN_BT_COEXISTENCE 465 /* Configure bluetooth coexistence for combo chips. */ 466 if (sc->sc_flags & ATHN_FLAG_BTCOEX) 467 athn_btcoex_init(sc); 468 #endif 469 /* Configure LED. */ 470 athn_led_init(sc); 471 472 ieee80211_announce(ic); 473 } 474 475 Static int 476 athn_usb_detach(device_t self, int flags) 477 { 478 struct athn_usb_softc *usc = device_private(self); 479 struct athn_softc *sc = &usc->usc_sc; 480 int error; 481 482 DPRINTFN(DBG_FN, usc, "\n"); 483 484 if (usc->usc_init_state < ATHN_INIT_INITED) 485 return 0; 486 487 pmf_device_deregister(self); 488 489 mutex_enter(&usc->usc_lock); 490 usc->usc_dying = 1; 491 mutex_exit(&usc->usc_lock); 492 493 mutex_enter(&usc->usc_cmd_mtx); 494 while (usc->usc_wmiactive) { 495 error = cv_timedwait(&usc->usc_wmi_cv, &usc->usc_cmd_mtx, hz); 496 497 if (error) { 498 mutex_exit(&usc->usc_cmd_mtx); 499 return error; 500 } 501 } 502 mutex_exit(&usc->usc_cmd_mtx); 503 504 mutex_enter(&usc->usc_msg_mtx); 505 while (usc->usc_htcactive) { 506 error = cv_timedwait(&usc->usc_htc_cv, &usc->usc_msg_mtx, hz); 507 508 if (error) { 509 mutex_exit(&usc->usc_msg_mtx); 510 return error; 511 } 512 } 513 mutex_exit(&usc->usc_msg_mtx); 514 515 athn_usb_wait_async(usc); 516 517 athn_usb_stop(&sc->sc_if, 0); 518 usb_rem_task_wait(usc->usc_udev, &usc->usc_task, USB_TASKQ_DRIVER, 519 NULL); 520 521 /* Abort Tx/Rx pipes. */ 522 athn_usb_abort_pipes(usc); 523 524 if (usc->usc_athn_attached) { 525 usc->usc_athn_attached = 0; 526 athn_detach(sc); 527 } 528 529 /* Free Tx/Rx buffers. */ 530 athn_usb_free_rx_list(usc); 531 athn_usb_free_tx_list(usc); 532 athn_usb_free_tx_cmd(usc); 533 athn_usb_free_tx_msg(usc); 534 535 /* Close Tx/Rx pipes. */ 536 athn_usb_close_pipes(usc); 537 538 mutex_destroy(&usc->usc_tx_mtx); 539 cv_destroy(&usc->usc_task_cv); 540 mutex_destroy(&usc->usc_task_mtx); 541 542 mutex_destroy(&usc->usc_cmd_mtx); 543 cv_destroy(&usc->usc_cmd_cv); 544 mutex_destroy(&usc->usc_msg_mtx); 545 cv_destroy(&usc->usc_msg_cv); 546 547 cv_destroy(&usc->usc_wmi_cv); 548 mutex_destroy(&usc->usc_lock); 549 550 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, usc->usc_udev, sc->sc_dev); 551 return 0; 552 } 553 554 Static int 555 athn_usb_activate(device_t self, enum devact act) 556 { 557 struct athn_usb_softc *usc = device_private(self); 558 struct athn_softc *sc = &usc->usc_sc; 559 560 DPRINTFN(DBG_FN, usc, "\n"); 561 562 switch (act) { 563 case DVACT_DEACTIVATE: 564 if_deactivate(sc->sc_ic.ic_ifp); 565 usc->usc_dying = 1; 566 return 0; 567 default: 568 return EOPNOTSUPP; 569 } 570 } 571 572 Static int 573 athn_usb_open_pipes(struct athn_usb_softc *usc) 574 { 575 usb_endpoint_descriptor_t *ed; 576 int error; 577 578 DPRINTFN(DBG_FN, usc, "\n"); 579 580 error = usbd_open_pipe(usc->usc_iface, AR_PIPE_TX_DATA, 0, 581 &usc->usc_tx_data_pipe); 582 if (error != 0) { 583 aprint_error_dev(usc->usc_dev, 584 "could not open Tx bulk pipe\n"); 585 goto fail; 586 } 587 588 error = usbd_open_pipe(usc->usc_iface, AR_PIPE_RX_DATA, 0, 589 &usc->usc_rx_data_pipe); 590 if (error != 0) { 591 aprint_error_dev(usc->usc_dev, 592 "could not open Rx bulk pipe\n"); 593 goto fail; 594 } 595 596 ed = usbd_get_endpoint_descriptor(usc->usc_iface, AR_PIPE_RX_INTR); 597 if (ed == NULL) { 598 aprint_error_dev(usc->usc_dev, 599 "could not retrieve Rx intr pipe descriptor\n"); 600 goto fail; 601 } 602 usc->usc_ibufsize = UGETW(ed->wMaxPacketSize); 603 if (usc->usc_ibufsize == 0) { 604 aprint_error_dev(usc->usc_dev, 605 "invalid Rx intr pipe descriptor\n"); 606 goto fail; 607 } 608 usc->usc_ibuf = kmem_alloc(usc->usc_ibufsize, KM_SLEEP); 609 610 error = usbd_open_pipe_intr(usc->usc_iface, AR_PIPE_RX_INTR, 611 USBD_SHORT_XFER_OK, &usc->usc_rx_intr_pipe, usc, usc->usc_ibuf, 612 usc->usc_ibufsize, athn_usb_intr, USBD_DEFAULT_INTERVAL); 613 if (error != 0) { 614 aprint_error_dev(usc->usc_dev, 615 "could not open Rx intr pipe\n"); 616 goto fail; 617 } 618 error = usbd_open_pipe(usc->usc_iface, AR_PIPE_TX_INTR, 0, 619 &usc->usc_tx_intr_pipe); 620 if (error != 0) { 621 aprint_error_dev(usc->usc_dev, 622 "could not open Tx intr pipe\n"); 623 goto fail; 624 } 625 return 0; 626 fail: 627 athn_usb_abort_pipes(usc); 628 athn_usb_close_pipes(usc); 629 return error; 630 } 631 632 static inline void 633 athn_usb_kill_pipe(struct usbd_pipe **pipeptr) 634 { 635 struct usbd_pipe *pipe; 636 637 CTASSERT(sizeof(pipe) == sizeof(void *)); 638 pipe = atomic_swap_ptr(pipeptr, NULL); 639 if (pipe != NULL) { 640 usbd_close_pipe(pipe); 641 } 642 } 643 644 Static void 645 athn_usb_abort_pipes(struct athn_usb_softc *usc) 646 { 647 DPRINTFN(DBG_FN, usc, "\n"); 648 649 if (usc->usc_tx_data_pipe != NULL) 650 usbd_abort_pipe(usc->usc_tx_data_pipe); 651 if (usc->usc_rx_data_pipe != NULL) 652 usbd_abort_pipe(usc->usc_rx_data_pipe); 653 if (usc->usc_tx_intr_pipe != NULL) 654 usbd_abort_pipe(usc->usc_tx_intr_pipe); 655 if (usc->usc_rx_intr_pipe != NULL) 656 usbd_abort_pipe(usc->usc_rx_intr_pipe); 657 } 658 659 Static void 660 athn_usb_close_pipes(struct athn_usb_softc *usc) 661 { 662 uint8_t *ibuf; 663 664 DPRINTFN(DBG_FN, usc, "\n"); 665 666 athn_usb_kill_pipe(&usc->usc_tx_data_pipe); 667 athn_usb_kill_pipe(&usc->usc_rx_data_pipe); 668 athn_usb_kill_pipe(&usc->usc_tx_intr_pipe); 669 athn_usb_kill_pipe(&usc->usc_rx_intr_pipe); 670 ibuf = atomic_swap_ptr(&usc->usc_ibuf, NULL); 671 if (ibuf != NULL) 672 kmem_free(ibuf, usc->usc_ibufsize); 673 } 674 675 Static int 676 athn_usb_alloc_rx_list(struct athn_usb_softc *usc) 677 { 678 struct athn_usb_rx_data *data; 679 size_t i; 680 int error = 0; 681 682 DPRINTFN(DBG_FN, usc, "\n"); 683 684 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 685 data = &usc->usc_rx_data[i]; 686 687 data->sc = usc; /* Backpointer for callbacks. */ 688 689 error = usbd_create_xfer(usc->usc_rx_data_pipe, 690 ATHN_USB_RXBUFSZ, 0, 0, &data->xfer); 691 if (error) { 692 aprint_error_dev(usc->usc_dev, 693 "could not allocate xfer\n"); 694 break; 695 } 696 data->buf = usbd_get_buffer(data->xfer); 697 } 698 if (error != 0) 699 athn_usb_free_rx_list(usc); 700 return error; 701 } 702 703 Static void 704 athn_usb_free_rx_list(struct athn_usb_softc *usc) 705 { 706 struct usbd_xfer *xfer; 707 size_t i; 708 709 DPRINTFN(DBG_FN, usc, "\n"); 710 711 /* NB: Caller must abort pipe first. */ 712 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 713 CTASSERT(sizeof(xfer) == sizeof(void *)); 714 xfer = atomic_swap_ptr(&usc->usc_rx_data[i].xfer, NULL); 715 if (xfer != NULL) 716 usbd_destroy_xfer(xfer); 717 } 718 } 719 720 Static int 721 athn_usb_alloc_tx_list(struct athn_usb_softc *usc) 722 { 723 struct athn_usb_tx_data *data; 724 size_t i; 725 int error = 0; 726 727 DPRINTFN(DBG_FN, usc, "\n"); 728 729 mutex_enter(&usc->usc_tx_mtx); 730 TAILQ_INIT(&usc->usc_tx_free_list); 731 for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) { 732 data = &usc->usc_tx_data[i]; 733 734 data->sc = usc; /* Backpointer for callbacks. */ 735 736 error = usbd_create_xfer(usc->usc_tx_data_pipe, 737 ATHN_USB_TXBUFSZ, USBD_FORCE_SHORT_XFER, 0, &data->xfer); 738 if (error) { 739 aprint_error_dev(usc->usc_dev, 740 "could not create xfer on TX pipe\n"); 741 break; 742 } 743 data->buf = usbd_get_buffer(data->xfer); 744 745 /* Append this Tx buffer to our free list. */ 746 TAILQ_INSERT_TAIL(&usc->usc_tx_free_list, data, next); 747 } 748 if (error == 0) { 749 /* Steal one buffer for beacons. */ 750 usc->usc_tx_bcn = TAILQ_FIRST(&usc->usc_tx_free_list); 751 TAILQ_REMOVE(&usc->usc_tx_free_list, usc->usc_tx_bcn, next); 752 } else { 753 athn_usb_free_tx_list(usc); 754 } 755 mutex_exit(&usc->usc_tx_mtx); 756 757 return error; 758 } 759 760 Static void 761 athn_usb_free_tx_list(struct athn_usb_softc *usc) 762 { 763 struct usbd_xfer *xfer; 764 size_t i; 765 766 DPRINTFN(DBG_FN, usc, "\n"); 767 768 /* NB: Caller must abort pipe first. */ 769 for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) { 770 CTASSERT(sizeof(xfer) == sizeof(void *)); 771 xfer = atomic_swap_ptr(&usc->usc_tx_data[i].xfer, NULL); 772 if (xfer != NULL) 773 usbd_destroy_xfer(xfer); 774 } 775 } 776 777 Static int 778 athn_usb_alloc_tx_cmd(struct athn_usb_softc *usc) 779 { 780 struct athn_usb_tx_data *data = &usc->usc_tx_cmd; 781 782 DPRINTFN(DBG_FN, usc, "\n"); 783 784 data->sc = usc; /* Backpointer for callbacks. */ 785 786 int err = usbd_create_xfer(usc->usc_tx_intr_pipe, ATHN_USB_TXCMDSZ, 787 0, 0, &data->xfer); 788 if (err) { 789 aprint_error_dev(usc->usc_dev, 790 "could not allocate command xfer\n"); 791 return err; 792 } 793 data->buf = usbd_get_buffer(data->xfer); 794 795 return 0; 796 } 797 798 Static void 799 athn_usb_free_tx_cmd(struct athn_usb_softc *usc) 800 { 801 struct usbd_xfer *xfer; 802 803 DPRINTFN(DBG_FN, usc, "\n"); 804 805 CTASSERT(sizeof(xfer) == sizeof(void *)); 806 xfer = atomic_swap_ptr(&usc->usc_tx_cmd.xfer, NULL); 807 if (xfer != NULL) 808 usbd_destroy_xfer(xfer); 809 } 810 811 Static int 812 athn_usb_alloc_tx_msg(struct athn_usb_softc *usc) 813 { 814 struct athn_usb_tx_data *data = &usc->usc_tx_msg; 815 816 DPRINTFN(DBG_FN, usc, "\n"); 817 818 data->sc = usc; /* Backpointer for callbacks. */ 819 820 int err = usbd_create_xfer(usc->usc_tx_intr_pipe, ATHN_USB_TXCMDSZ, 821 0, 0, &data->xfer); 822 if (err) { 823 aprint_error_dev(usc->usc_dev, 824 "could not allocate command xfer\n"); 825 return err; 826 } 827 data->buf = usbd_get_buffer(data->xfer); 828 829 return 0; 830 } 831 832 Static void 833 athn_usb_free_tx_msg(struct athn_usb_softc *usc) 834 { 835 struct usbd_xfer *xfer; 836 837 DPRINTFN(DBG_FN, usc, "\n"); 838 839 CTASSERT(sizeof(xfer) == sizeof(void *)); 840 xfer = atomic_swap_ptr(&usc->usc_tx_msg.xfer, NULL); 841 if (xfer != NULL) 842 usbd_destroy_xfer(xfer); 843 } 844 845 Static void 846 athn_usb_task(void *arg) 847 { 848 struct athn_usb_softc *usc = arg; 849 struct athn_usb_host_cmd_ring *ring = &usc->usc_cmdq; 850 struct athn_usb_host_cmd *cmd; 851 852 DPRINTFN(DBG_FN, usc, "\n"); 853 854 /* Process host commands. */ 855 mutex_spin_enter(&usc->usc_task_mtx); 856 while (ring->next != ring->cur) { 857 cmd = &ring->cmd[ring->next]; 858 mutex_spin_exit(&usc->usc_task_mtx); 859 860 /* Invoke callback. */ 861 if (!usc->usc_dying) 862 cmd->cb(usc, cmd->data); 863 864 mutex_spin_enter(&usc->usc_task_mtx); 865 ring->queued--; 866 ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT; 867 } 868 cv_broadcast(&usc->usc_task_cv); 869 mutex_spin_exit(&usc->usc_task_mtx); 870 } 871 872 Static void 873 athn_usb_do_async(struct athn_usb_softc *usc, 874 void (*cb)(struct athn_usb_softc *, void *), void *arg, int len) 875 { 876 struct athn_usb_host_cmd_ring *ring = &usc->usc_cmdq; 877 struct athn_usb_host_cmd *cmd; 878 879 if (usc->usc_dying) 880 return; 881 882 DPRINTFN(DBG_FN, usc, "\n"); 883 884 mutex_spin_enter(&usc->usc_task_mtx); 885 cmd = &ring->cmd[ring->cur]; 886 cmd->cb = cb; 887 KASSERT(len <= sizeof(cmd->data)); 888 memcpy(cmd->data, arg, len); 889 ring->cur = (ring->cur + 1) % ATHN_USB_HOST_CMD_RING_COUNT; 890 891 /* If there is no pending command already, schedule a task. */ 892 if (++ring->queued == 1) { 893 usb_add_task(usc->usc_udev, &usc->usc_task, USB_TASKQ_DRIVER); 894 } 895 mutex_spin_exit(&usc->usc_task_mtx); 896 } 897 898 Static void 899 athn_usb_wait_async(struct athn_usb_softc *usc) 900 { 901 902 DPRINTFN(DBG_FN, usc, "\n"); 903 904 /* Wait for all queued asynchronous commands to complete. */ 905 mutex_spin_enter(&usc->usc_task_mtx); 906 while (usc->usc_cmdq.queued > 0) 907 cv_wait(&usc->usc_task_cv, &usc->usc_task_mtx); 908 mutex_spin_exit(&usc->usc_task_mtx); 909 } 910 911 Static int 912 athn_usb_load_firmware(struct athn_usb_softc *usc) 913 { 914 struct athn_softc *sc = &usc->usc_sc; 915 firmware_handle_t fwh; 916 usb_device_descriptor_t *dd; 917 usb_device_request_t req; 918 const char *name; 919 u_char *fw, *ptr; 920 size_t size, remain; 921 uint32_t addr; 922 int mlen, error; 923 924 DPRINTFN(DBG_FN, sc, "\n"); 925 926 /* Determine which firmware image to load. */ 927 if (usc->usc_flags & ATHN_USB_FLAG_AR7010) { 928 dd = usbd_get_device_descriptor(usc->usc_udev); 929 if (UGETW(dd->bcdDevice) == 0x0202) 930 name = "athn-ar7010-11"; 931 else 932 name = "athn-ar7010"; 933 } else 934 name = "athn-ar9271"; 935 936 /* Read firmware image from the filesystem. */ 937 if ((error = firmware_open("if_athn", name, &fwh)) != 0) { 938 aprint_error_dev(sc->sc_dev, 939 "failed to open firmware file %s (%d)\n", name, error); 940 return error; 941 } 942 size = firmware_get_size(fwh); 943 fw = firmware_malloc(size); 944 if (fw == NULL) { 945 aprint_error_dev(usc->usc_dev, 946 "failed to allocate firmware memory\n"); 947 firmware_close(fwh); 948 return ENOMEM; 949 } 950 error = firmware_read(fwh, 0, fw, size); 951 firmware_close(fwh); 952 if (error != 0) { 953 aprint_error_dev(usc->usc_dev, 954 "failed to read firmware (error %d)\n", error); 955 firmware_free(fw, size); 956 return error; 957 } 958 959 /* Load firmware image. */ 960 ptr = fw; 961 addr = AR9271_FIRMWARE >> 8; 962 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 963 req.bRequest = AR_FW_DOWNLOAD; 964 USETW(req.wIndex, 0); 965 remain = size; 966 while (remain > 0) { 967 mlen = MIN(remain, 4096); 968 969 USETW(req.wValue, addr); 970 USETW(req.wLength, mlen); 971 error = usbd_do_request(usc->usc_udev, &req, ptr); 972 if (error != 0) { 973 firmware_free(fw, size); 974 return error; 975 } 976 addr += mlen >> 8; 977 ptr += mlen; 978 remain -= mlen; 979 } 980 firmware_free(fw, size); 981 982 /* Start firmware. */ 983 if (usc->usc_flags & ATHN_USB_FLAG_AR7010) 984 addr = AR7010_FIRMWARE_TEXT >> 8; 985 else 986 addr = AR9271_FIRMWARE_TEXT >> 8; 987 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 988 req.bRequest = AR_FW_DOWNLOAD_COMP; 989 USETW(req.wIndex, 0); 990 USETW(req.wValue, addr); 991 USETW(req.wLength, 0); 992 993 mutex_enter(&usc->usc_msg_mtx); 994 while (usc->usc_htcactive) { 995 error = cv_timedwait(&usc->usc_htc_cv, &usc->usc_msg_mtx, hz); 996 997 if (error) { 998 mutex_exit(&usc->usc_msg_mtx); 999 return error; 1000 } 1001 } 1002 1003 usc->usc_htcactive = true; 1004 1005 KASSERT(usc->usc_wait_msg_id == 0); 1006 usc->usc_wait_msg_id = AR_HTC_MSG_READY; 1007 mutex_exit(&usc->usc_msg_mtx); 1008 1009 error = usbd_do_request(usc->usc_udev, &req, NULL); 1010 1011 mutex_enter(&usc->usc_msg_mtx); 1012 /* Wait at most 1 second for firmware to boot. */ 1013 if (error == 0) 1014 error = athn_usb_wait_msg(usc); 1015 1016 usc->usc_htcactive = false; 1017 cv_broadcast(&usc->usc_htc_cv); 1018 mutex_exit(&usc->usc_msg_mtx); 1019 1020 DPRINTFN(DBG_FN, sc, "return %d\n", error); 1021 1022 return error; 1023 } 1024 1025 Static int 1026 athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, 1027 int len) 1028 { 1029 struct athn_usb_tx_data *data = &usc->usc_tx_msg; 1030 struct ar_htc_frame_hdr *htc; 1031 struct ar_htc_msg_hdr *msg; 1032 1033 if (usc->usc_dying) 1034 return USBD_CANCELLED; 1035 1036 DPRINTFN(DBG_FN, usc, "\n"); 1037 1038 htc = (struct ar_htc_frame_hdr *)data->buf; 1039 memset(htc, 0, sizeof(*htc)); 1040 htc->endpoint_id = 0; 1041 htc->payload_len = htobe16(sizeof(*msg) + len); 1042 1043 msg = (struct ar_htc_msg_hdr *)&htc[1]; 1044 msg->msg_id = htobe16(msg_id); 1045 1046 memcpy(&msg[1], buf, len); 1047 1048 usbd_setup_xfer(data->xfer, NULL, data->buf, 1049 sizeof(*htc) + sizeof(*msg) + len, 1050 USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, NULL); 1051 return usbd_sync_transfer(data->xfer); 1052 1053 1054 } 1055 1056 Static int 1057 athn_usb_htc_setup(struct athn_usb_softc *usc) 1058 { 1059 struct ar_htc_msg_config_pipe cfg; 1060 int error; 1061 1062 mutex_enter(&usc->usc_msg_mtx); 1063 while (usc->usc_htcactive) { 1064 error = cv_timedwait(&usc->usc_htc_cv, &usc->usc_msg_mtx, hz); 1065 1066 if (error) { 1067 mutex_exit(&usc->usc_msg_mtx); 1068 return error; 1069 } 1070 } 1071 usc->usc_htcactive = true; 1072 mutex_exit(&usc->usc_msg_mtx); 1073 1074 /* 1075 * Connect WMI services to USB pipes. 1076 */ 1077 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CONTROL, 1078 AR_PIPE_TX_INTR, AR_PIPE_RX_INTR, &usc->usc_ep_ctrl); 1079 if (error != 0) 1080 return error; 1081 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_BEACON, 1082 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_bcn); 1083 if (error != 0) 1084 return error; 1085 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CAB, 1086 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_cab); 1087 if (error != 0) 1088 return error; 1089 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_UAPSD, 1090 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_uapsd); 1091 if (error != 0) 1092 return error; 1093 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_MGMT, 1094 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_mgmt); 1095 if (error != 0) 1096 return error; 1097 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BE, 1098 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_BE]); 1099 if (error != 0) 1100 return error; 1101 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BK, 1102 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_BK]); 1103 if (error != 0) 1104 return error; 1105 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VI, 1106 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_VI]); 1107 if (error != 0) 1108 return error; 1109 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VO, 1110 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_VO]); 1111 if (error != 0) 1112 return error; 1113 1114 /* Set credits for WLAN Tx pipe. */ 1115 memset(&cfg, 0, sizeof(cfg)); 1116 cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA); 1117 cfg.credits = (usc->usc_flags & ATHN_USB_FLAG_AR7010) ? 45 : 33; 1118 1119 mutex_enter(&usc->usc_msg_mtx); 1120 1121 KASSERT(usc->usc_wait_msg_id == 0); 1122 usc->usc_wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP; 1123 mutex_exit(&usc->usc_msg_mtx); 1124 1125 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg)); 1126 1127 if (error != 0) { 1128 aprint_error_dev(usc->usc_dev, "could not request pipe configurations\n"); 1129 return error; 1130 } 1131 1132 mutex_enter(&usc->usc_msg_mtx); 1133 error = athn_usb_wait_msg(usc); 1134 if (error) { 1135 mutex_exit(&usc->usc_msg_mtx); 1136 return error; 1137 } 1138 1139 mutex_exit(&usc->usc_msg_mtx); 1140 error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0); 1141 if (error != 0) { 1142 aprint_error_dev(usc->usc_dev, "could not request complete setup\n"); 1143 return error; 1144 } 1145 mutex_enter(&usc->usc_msg_mtx); 1146 error = athn_usb_wait_msg(usc); 1147 if (error) { 1148 mutex_exit(&usc->usc_msg_mtx); 1149 return error; 1150 } 1151 1152 usc->usc_htcactive = false; 1153 cv_broadcast(&usc->usc_htc_cv); 1154 mutex_exit(&usc->usc_msg_mtx); 1155 1156 return 0; 1157 } 1158 1159 Static int 1160 athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, 1161 uint8_t ul_pipe, uint8_t dl_pipe, uint8_t *endpoint_id) 1162 { 1163 struct ar_htc_msg_conn_svc msg; 1164 struct ar_htc_msg_conn_svc_rsp rsp; 1165 int error; 1166 1167 DPRINTFN(DBG_FN, usc, "\n"); 1168 1169 memset(&msg, 0, sizeof(msg)); 1170 msg.svc_id = htobe16(svc_id); 1171 msg.dl_pipeid = UE_GET_ADDR(dl_pipe); 1172 msg.ul_pipeid = UE_GET_ADDR(ul_pipe); 1173 1174 mutex_enter(&usc->usc_msg_mtx); 1175 KASSERT(usc->usc_wait_msg_id == 0); 1176 usc->usc_msg_conn_svc_rsp = &rsp; 1177 usc->usc_wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP; 1178 mutex_exit(&usc->usc_msg_mtx); 1179 1180 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg)); 1181 1182 mutex_enter(&usc->usc_msg_mtx); 1183 if (error == 0) 1184 error = athn_usb_wait_msg(usc); 1185 1186 mutex_exit(&usc->usc_msg_mtx); 1187 1188 if (error != 0) { 1189 aprint_error_dev(usc->usc_dev, 1190 "error waiting for service %d connection\n", svc_id); 1191 return error; 1192 } 1193 if (rsp.status != AR_HTC_SVC_SUCCESS) { 1194 aprint_error_dev(usc->usc_dev, 1195 "service %d connection failed, error %d\n", 1196 svc_id, rsp.status); 1197 return EIO; 1198 } 1199 DPRINTFN(DBG_INIT, usc, 1200 "service %d successfully connected to endpoint %d\n", 1201 svc_id, rsp.endpoint_id); 1202 1203 /* Return endpoint id. */ 1204 *endpoint_id = rsp.endpoint_id; 1205 return 0; 1206 } 1207 1208 Static int 1209 athn_usb_wait_msg(struct athn_usb_softc *usc) 1210 { 1211 DPRINTFN(DBG_FN, usc, "\n"); 1212 1213 KASSERT(mutex_owned(&usc->usc_msg_mtx)); 1214 1215 int error = 0; 1216 while (usc->usc_wait_msg_id) 1217 error = cv_timedwait(&usc->usc_msg_cv, &usc->usc_msg_mtx, hz); 1218 1219 return error; 1220 } 1221 1222 Static void 1223 athn_usb_wmieof(struct usbd_xfer *xfer, void * priv, 1224 usbd_status status) 1225 { 1226 struct athn_usb_softc *usc = priv; 1227 1228 DPRINTFN(DBG_FN, usc, "\n"); 1229 1230 if (__predict_false(status == USBD_STALLED)) 1231 usbd_clear_endpoint_stall_async(usc->usc_tx_intr_pipe); 1232 } 1233 1234 Static int 1235 athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, 1236 int ilen, void *obuf) 1237 { 1238 struct athn_usb_tx_data *data = &usc->usc_tx_cmd; 1239 struct ar_htc_frame_hdr *htc; 1240 struct ar_wmi_cmd_hdr *wmi; 1241 int error = 0; 1242 1243 if (usc->usc_dying) 1244 return EIO; 1245 1246 DPRINTFN(DBG_FN, usc, "cmd_id %#x\n", cmd_id); 1247 1248 htc = (struct ar_htc_frame_hdr *)data->buf; 1249 memset(htc, 0, sizeof(*htc)); 1250 htc->endpoint_id = usc->usc_ep_ctrl; 1251 htc->payload_len = htobe16(sizeof(*wmi) + ilen); 1252 1253 wmi = (struct ar_wmi_cmd_hdr *)&htc[1]; 1254 wmi->cmd_id = htobe16(cmd_id); 1255 usc->usc_wmi_seq_no++; 1256 wmi->seq_no = htobe16(usc->usc_wmi_seq_no); 1257 1258 memcpy(&wmi[1], ibuf, ilen); 1259 1260 usbd_setup_xfer(data->xfer, usc, data->buf, 1261 sizeof(*htc) + sizeof(*wmi) + ilen, 1262 USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, 1263 athn_usb_wmieof); 1264 1265 mutex_enter(&usc->usc_cmd_mtx); 1266 while (usc->usc_wmiactive) { 1267 error = cv_timedwait(&usc->usc_wmi_cv, &usc->usc_cmd_mtx, hz); 1268 1269 if (error) { 1270 mutex_exit(&usc->usc_cmd_mtx); 1271 return error; 1272 } 1273 } 1274 usc->usc_wmiactive = true; 1275 1276 KASSERT(usc->usc_wait_cmd_id == 0); 1277 usc->usc_wait_cmd_id = cmd_id; 1278 usc->usc_obuf = obuf; 1279 mutex_exit(&usc->usc_cmd_mtx); 1280 1281 error = usbd_sync_transfer(data->xfer); 1282 if (error) { 1283 DPRINTFN(DBG_FN, usc, "transfer error %d\n", error); 1284 1285 return error; 1286 } 1287 1288 mutex_enter(&usc->usc_cmd_mtx); 1289 while (usc->usc_wait_cmd_id) 1290 error = cv_timedwait(&usc->usc_cmd_cv, &usc->usc_cmd_mtx, hz); 1291 1292 usc->usc_wmiactive = false; 1293 cv_broadcast(&usc->usc_wmi_cv); 1294 mutex_exit(&usc->usc_cmd_mtx); 1295 1296 return 0; 1297 } 1298 1299 #ifdef unused 1300 Static int 1301 athn_usb_read_rom(struct athn_softc *sc) 1302 { 1303 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1304 uint32_t addrs[8], vals[8], addr; 1305 uint16_t *eep; 1306 size_t i, j; 1307 int error = 0; 1308 1309 DPRINTFN(DBG_FN, sc, "\n"); 1310 1311 /* Read EEPROM by blocks of 16 bytes. */ 1312 eep = sc->sc_eep; 1313 addr = AR_EEPROM_OFFSET(sc->sc_eep_base); 1314 for (i = 0; i < sc->sc_eep_size / 16; i++) { 1315 for (j = 0; j < 8; j++, addr += 4) 1316 addrs[j] = htobe32(addr); 1317 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, 1318 addrs, sizeof(addrs), vals); 1319 if (error != 0) 1320 break; 1321 for (j = 0; j < 8; j++) 1322 *eep++ = be32toh(vals[j]); 1323 } 1324 return error; 1325 } 1326 #endif /* unused */ 1327 1328 Static uint32_t 1329 athn_usb_read(struct athn_softc *sc, uint32_t addr) 1330 { 1331 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1332 uint32_t val; 1333 int error; 1334 1335 if (usc->usc_dying) 1336 return 0; 1337 1338 DPRINTFN(DBG_FN, sc, "addr %#x\n", htobe32(addr)); 1339 1340 /* Flush pending writes for strict consistency. */ 1341 athn_usb_write_barrier(sc); 1342 1343 addr = htobe32(addr); 1344 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, 1345 &addr, sizeof(addr), &val); 1346 if (error != 0) { 1347 DPRINTFN(DBG_FN, sc, "error %d\n", addr); 1348 return 0xdeadbeef; 1349 } 1350 DPRINTFN(DBG_FN, sc, "addr %#x return %#x\n", addr, be32toh(val)); 1351 1352 return be32toh(val); 1353 } 1354 1355 Static void 1356 athn_usb_write(struct athn_softc *sc, uint32_t addr, uint32_t val) 1357 { 1358 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1359 1360 if (usc->usc_dying) 1361 return; 1362 1363 DPRINTFN(DBG_FN, sc, "addr %#x val %#x\n", addr, val); 1364 1365 usc->usc_wbuf[usc->usc_wcount].addr = htobe32(addr); 1366 usc->usc_wbuf[usc->usc_wcount].val = htobe32(val); 1367 if (++usc->usc_wcount == AR_MAX_WRITE_COUNT) 1368 athn_usb_write_barrier(sc); 1369 } 1370 1371 Static void 1372 athn_usb_write_barrier(struct athn_softc *sc) 1373 { 1374 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1375 1376 if (usc->usc_dying) 1377 goto done; 1378 1379 DPRINTFN(DBG_FN, sc, "usc_wcount %d\n", usc->usc_wcount); 1380 1381 if (usc->usc_wcount == 0) 1382 return; 1383 1384 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_WRITE, 1385 usc->usc_wbuf, usc->usc_wcount * sizeof(usc->usc_wbuf[0]), NULL); 1386 done: 1387 usc->usc_wcount = 0; /* Always flush buffer. */ 1388 } 1389 1390 Static int 1391 athn_usb_media_change(struct ifnet *ifp) 1392 { 1393 struct athn_softc *sc = ifp->if_softc; 1394 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1395 int error; 1396 1397 if (usc->usc_dying) 1398 return EIO; 1399 1400 DPRINTFN(DBG_FN, sc, "\n"); 1401 1402 error = ieee80211_media_change(ifp); 1403 if (error == ENETRESET && IS_UP_AND_RUNNING(ifp)) { 1404 athn_usb_stop(ifp, 0); 1405 error = athn_usb_init(ifp); 1406 } 1407 return error; 1408 } 1409 1410 Static int 1411 athn_usb_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, 1412 int arg) 1413 { 1414 struct athn_softc *sc = ic->ic_ifp->if_softc; 1415 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1416 struct athn_usb_cmd_newstate cmd; 1417 1418 DPRINTFN(DBG_FN, sc, "\n"); 1419 1420 /* Do it in a process context. */ 1421 cmd.state = nstate; 1422 cmd.arg = arg; 1423 athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd)); 1424 return 0; 1425 } 1426 1427 Static void 1428 athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg) 1429 { 1430 struct athn_usb_cmd_newstate *cmd = arg; 1431 struct athn_softc *sc = &usc->usc_sc; 1432 struct ieee80211com *ic = &sc->sc_ic; 1433 enum ieee80211_state ostate, nstate; 1434 uint32_t reg, intr_mask; 1435 int s; 1436 1437 DPRINTFN(DBG_FN, sc, "\n"); 1438 1439 callout_stop(&sc->sc_calib_to); 1440 1441 s = splnet(); 1442 1443 ostate = ic->ic_state; 1444 nstate = cmd->state; 1445 DPRINTFN(DBG_STM, usc, "newstate %s(%d) -> %s(%d)\n", 1446 ieee80211_state_name[ostate], ostate, 1447 ieee80211_state_name[nstate], nstate); 1448 1449 if (ostate == IEEE80211_S_RUN) { 1450 uint8_t sta_index; 1451 1452 sta_index = ATHN_NODE(ic->ic_bss)->sta_index; 1453 DPRINTFN(DBG_NODES, usc, "removing node %u\n", sta_index); 1454 athn_usb_remove_hw_node(usc, &sta_index); 1455 } 1456 1457 switch (nstate) { 1458 case IEEE80211_S_INIT: 1459 athn_set_led(sc, 0); 1460 break; 1461 case IEEE80211_S_SCAN: 1462 /* Make the LED blink while scanning. */ 1463 athn_set_led(sc, !sc->sc_led_state); 1464 (void)athn_usb_switch_chan(sc, ic->ic_curchan, NULL); 1465 if (!usc->usc_dying) 1466 callout_schedule(&sc->sc_scan_to, hz / 5); 1467 break; 1468 case IEEE80211_S_AUTH: 1469 athn_set_led(sc, 0); 1470 athn_usb_switch_chan(sc, ic->ic_curchan, NULL); 1471 break; 1472 case IEEE80211_S_ASSOC: 1473 break; 1474 case IEEE80211_S_RUN: 1475 athn_set_led(sc, 1); 1476 1477 if (ic->ic_opmode == IEEE80211_M_MONITOR) 1478 break; 1479 1480 /* Create node entry for our BSS. */ 1481 DPRINTFN(DBG_NODES, sc, "create node for AID=%#x\n", 1482 ic->ic_bss->ni_associd); 1483 athn_usb_create_node(usc, ic->ic_bss); /* XXX: handle error? */ 1484 1485 athn_set_bss(sc, ic->ic_bss); 1486 athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 1487 #ifndef IEEE80211_STA_ONLY 1488 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1489 athn_set_hostap_timers(sc); 1490 /* Enable software beacon alert interrupts. */ 1491 intr_mask = htobe32(AR_IMR_SWBA); 1492 } else 1493 #endif 1494 { 1495 athn_set_sta_timers(sc); 1496 /* Enable beacon miss interrupts. */ 1497 intr_mask = htobe32(AR_IMR_BMISS); 1498 1499 /* Stop receiving beacons from other BSS. */ 1500 reg = AR_READ(sc, AR_RX_FILTER); 1501 reg = (reg & ~AR_RX_FILTER_BEACON) | 1502 AR_RX_FILTER_MYBEACON; 1503 AR_WRITE(sc, AR_RX_FILTER, reg); 1504 AR_WRITE_BARRIER(sc); 1505 } 1506 athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR, 1507 &intr_mask, sizeof(intr_mask), NULL); 1508 break; 1509 } 1510 if (!usc->usc_dying) 1511 (void)sc->sc_newstate(ic, nstate, cmd->arg); 1512 splx(s); 1513 } 1514 1515 Static void 1516 athn_usb_newassoc(struct ieee80211_node *ni, int isnew) 1517 { 1518 struct ieee80211com *ic = ni->ni_ic; 1519 struct athn_softc *sc = ic->ic_ifp->if_softc; 1520 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1521 1522 DPRINTFN(DBG_FN, sc, "\n"); 1523 1524 if (ic->ic_opmode != IEEE80211_M_HOSTAP || !isnew) 1525 return; 1526 1527 /* Do it in a process context. */ 1528 ieee80211_ref_node(ni); 1529 athn_usb_do_async(usc, athn_usb_newassoc_cb, &ni, sizeof(ni)); 1530 } 1531 1532 Static void 1533 athn_usb_newassoc_cb(struct athn_usb_softc *usc, void *arg) 1534 { 1535 struct ieee80211_node *ni = *(void **)arg; 1536 int s; 1537 1538 DPRINTFN(DBG_FN, usc, "\n"); 1539 1540 s = splnet(); 1541 /* NB: Node may have left before we got scheduled. */ 1542 if (ni->ni_associd != 0) { 1543 DPRINTFN(DBG_NODES, usc, "creating node for AID=%#x\n", 1544 ni->ni_associd); 1545 (void)athn_usb_create_node(usc, ni); /* XXX: handle error? */ 1546 } 1547 ieee80211_free_node(ni); 1548 splx(s); 1549 } 1550 1551 #ifdef notyet 1552 Static int 1553 athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 1554 uint8_t tid) 1555 { 1556 struct athn_softc *sc = ic->ic_ifp->if_softc; 1557 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1558 struct athn_node *an = ATHN_NODE(ni); 1559 struct athn_usb_aggr_cmd cmd; 1560 1561 DPRINTFN(DBG_FN, sc, "\n"); 1562 1563 /* Do it in a process context. */ 1564 cmd.sta_index = an->sta_index; 1565 cmd.tid = tid; 1566 athn_usb_do_async(usc, athn_usb_ampdu_tx_start_cb, &cmd, sizeof(cmd)); 1567 return 0; 1568 } 1569 1570 Static void 1571 athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *usc, void *arg) 1572 { 1573 struct athn_usb_aggr_cmd *cmd = arg; 1574 struct ar_htc_target_aggr aggr; 1575 1576 DPRINTFN(DBG_FN, usc, "\n"); 1577 1578 memset(&aggr, 0, sizeof(aggr)); 1579 aggr.sta_index = cmd->sta_index; 1580 aggr.tidno = cmd->tid; 1581 aggr.aggr_enable = 1; 1582 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, 1583 &aggr, sizeof(aggr), NULL); 1584 } 1585 1586 Static void 1587 athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, 1588 uint8_t tid) 1589 { 1590 struct athn_softc *sc = ic->ic_ifp->if_softc; 1591 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1592 struct athn_node *an = ATHN_NODE(ni); 1593 struct athn_usb_aggr_cmd cmd; 1594 1595 DPRINTFN(DBG_FN, sc, "\n"); 1596 1597 /* Do it in a process context. */ 1598 cmd.sta_index = an->sta_index; 1599 cmd.tid = tid; 1600 athn_usb_do_async(usc, athn_usb_ampdu_tx_stop_cb, &cmd, sizeof(cmd)); 1601 } 1602 1603 Static void 1604 athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *usc, void *arg) 1605 { 1606 struct athn_usb_aggr_cmd *cmd = arg; 1607 struct ar_htc_target_aggr aggr; 1608 1609 DPRINTFN(DBG_FN, usc, "\n"); 1610 1611 memset(&aggr, 0, sizeof(aggr)); 1612 aggr.sta_index = cmd->sta_index; 1613 aggr.tidno = cmd->tid; 1614 aggr.aggr_enable = 0; 1615 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, 1616 &aggr, sizeof(aggr), NULL); 1617 } 1618 #endif /* notyet */ 1619 1620 Static int 1621 athn_usb_remove_hw_node(struct athn_usb_softc *usc, uint8_t *sta_idx) 1622 { 1623 int error; 1624 1625 DPRINTFN(DBG_FN, usc, "\n"); 1626 1627 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, 1628 sta_idx, sizeof(*sta_idx), NULL); 1629 1630 DPRINTFN(DBG_NODES, usc, "node=%u error=%d\n", 1631 *sta_idx, error); 1632 return error; 1633 } 1634 1635 Static int 1636 athn_usb_create_hw_node(struct athn_usb_softc *usc, 1637 struct ar_htc_target_sta *sta) 1638 { 1639 int error; 1640 1641 DPRINTFN(DBG_FN, usc, "\n"); 1642 1643 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE, 1644 sta, sizeof(*sta), NULL); 1645 1646 DPRINTFN(DBG_NODES, usc, "node=%u error=%d\n", 1647 sta->sta_index, error); 1648 1649 return error; 1650 } 1651 1652 Static int 1653 athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni) 1654 { 1655 struct athn_node *an = ATHN_NODE(ni); 1656 struct ar_htc_target_sta sta; 1657 struct ar_htc_target_rate rate; 1658 int error; 1659 1660 DPRINTFN(DBG_FN | DBG_NODES, usc, "AID=%#x\n", ni->ni_associd); 1661 1662 /* 1663 * NB: this is called by ic_newstate and (in HOSTAP mode by) 1664 * ic_newassoc. 1665 * 1666 * The firmware has a limit of 8 nodes. In HOSTAP mode, we 1667 * limit the AID to < 8 and use that value to index the 1668 * firmware node table. Node zero is used for the BSS. 1669 * 1670 * In STA mode, we simply use node 1 for the BSS. 1671 */ 1672 if (ATHN_SOFTC(usc)->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) 1673 an->sta_index = IEEE80211_NODE_AID(ni); 1674 else 1675 an->sta_index = 1; 1676 1677 /* Create node entry on target. */ 1678 memset(&sta, 0, sizeof(sta)); 1679 IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr); 1680 IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid); 1681 1682 sta.associd = htobe16(ni->ni_associd); 1683 sta.valid = 1; 1684 sta.sta_index = an->sta_index; 1685 1686 sta.maxampdu = 0xffff; 1687 #ifndef IEEE80211_NO_HT 1688 if (ni->ni_flags & IEEE80211_NODE_HT) 1689 sta.flags |= htobe16(AR_HTC_STA_HT); 1690 #endif 1691 error = athn_usb_create_hw_node(usc, &sta); 1692 if (error) 1693 return error; 1694 1695 /* Setup supported rates. */ 1696 memset(&rate, 0, sizeof(rate)); 1697 rate.sta_index = sta.sta_index; 1698 rate.isnew = 1; 1699 rate.lg_rates.rs_nrates = ni->ni_rates.rs_nrates; 1700 memcpy(rate.lg_rates.rs_rates, ni->ni_rates.rs_rates, 1701 ni->ni_rates.rs_nrates); 1702 1703 #ifndef IEEE80211_NO_HT 1704 if (ni->ni_flags & IEEE80211_NODE_HT) { 1705 rate.capflags |= htobe32(AR_RC_HT_FLAG); 1706 #ifdef notyet 1707 /* XXX setup HT rates */ 1708 if (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) 1709 rate.capflags |= htobe32(AR_RC_40_FLAG); 1710 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI40) 1711 rate.capflags |= htobe32(AR_RC_SGI_FLAG); 1712 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20) 1713 rate.capflags |= htobe32(AR_RC_SGI_FLAG); 1714 #endif 1715 } 1716 #endif 1717 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_RC_RATE_UPDATE, 1718 &rate, sizeof(rate), NULL); 1719 return error; 1720 } 1721 1722 Static void 1723 athn_usb_rx_enable(struct athn_softc *sc) 1724 { 1725 1726 DPRINTFN(DBG_FN, sc, "\n"); 1727 1728 AR_WRITE(sc, AR_CR, AR_CR_RXE); 1729 AR_WRITE_BARRIER(sc); 1730 } 1731 1732 Static int 1733 athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *curchan, 1734 struct ieee80211_channel *extchan) 1735 { 1736 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1737 uint16_t mode; 1738 int error; 1739 1740 DPRINTFN(DBG_FN, sc, "\n"); 1741 1742 /* Disable interrupts. */ 1743 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 1744 if (error != 0) 1745 goto reset; 1746 /* Stop all Tx queues. */ 1747 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); 1748 if (error != 0) 1749 goto reset; 1750 /* Stop Rx. */ 1751 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); 1752 if (error != 0) 1753 goto reset; 1754 1755 /* If band or bandwidth changes, we need to do a full reset. */ 1756 if (curchan->ic_flags != sc->sc_curchan->ic_flags || 1757 ((extchan != NULL) ^ (sc->sc_curchanext != NULL))) { 1758 DPRINTFN(DBG_RF, sc, "channel band switch\n"); 1759 goto reset; 1760 } 1761 1762 error = athn_set_chan(sc, curchan, extchan); 1763 if (AR_SREV_9271(sc) && error == 0) 1764 ar9271_load_ani(sc); 1765 if (error != 0) { 1766 reset: /* Error found, try a full reset. */ 1767 DPRINTFN(DBG_RF, sc, "needs a full reset\n"); 1768 error = athn_hw_reset(sc, curchan, extchan, 0); 1769 if (error != 0) /* Hopeless case. */ 1770 return error; 1771 } 1772 1773 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); 1774 if (error != 0) 1775 return error; 1776 athn_rx_start(sc); 1777 1778 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(curchan) ? 1779 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); 1780 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, 1781 &mode, sizeof(mode), NULL); 1782 if (error != 0) 1783 return error; 1784 1785 /* Re-enable interrupts. */ 1786 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ENABLE_INTR); 1787 return error; 1788 } 1789 1790 #ifdef notyet_edca 1791 Static void 1792 athn_usb_updateedca(struct ieee80211com *ic) 1793 { 1794 struct athn_softc *sc = ic->ic_ifp->if_softc; 1795 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1796 1797 DPRINTFN(DBG_FN, sc, "\n"); 1798 1799 /* Do it in a process context. */ 1800 athn_usb_do_async(usc, athn_usb_updateedca_cb, NULL, 0); 1801 } 1802 1803 Static void 1804 athn_usb_updateedca_cb(struct athn_usb_softc *usc, void *arg) 1805 { 1806 int s; 1807 1808 DPRINTFN(DBG_FN, usc, "\n"); 1809 1810 s = splnet(); 1811 athn_updateedca(&usc->usc_sc.sc_ic); 1812 splx(s); 1813 } 1814 #endif /* notyet_edca */ 1815 1816 Static void 1817 athn_usb_updateslot(struct ifnet *ifp) 1818 { 1819 struct athn_softc *sc = ifp->if_softc; 1820 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1821 1822 DPRINTFN(DBG_FN, sc, "\n"); 1823 1824 /* 1825 * NB: athn_updateslog() needs to be done in a process context 1826 * to avoid being called by ieee80211_reset_erp() inside a 1827 * spinlock held by ieee80211_free_allnodes(). 1828 * 1829 * XXX: calling this during the athn_attach() causes 1830 * usb_insert_transfer() to produce a bunch of "not busy" 1831 * messages. Why? 1832 */ 1833 if (usc->usc_athn_attached) 1834 athn_usb_do_async(usc, athn_usb_updateslot_cb, NULL, 0); 1835 } 1836 1837 Static void 1838 athn_usb_updateslot_cb(struct athn_usb_softc *usc, void *arg) 1839 { 1840 int s; 1841 1842 DPRINTFN(DBG_FN, usc, "\n"); 1843 1844 s = splnet(); 1845 athn_updateslot(&usc->usc_sc.sc_if); 1846 splx(s); 1847 } 1848 1849 #ifdef notyet 1850 Static int 1851 athn_usb_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 1852 struct ieee80211_key *k) 1853 { 1854 struct athn_softc *sc = ic->ic_ifp->if_softc; 1855 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1856 struct ifnet *ifp = &usc->usc_sc.sc_if; 1857 struct athn_usb_cmd_key cmd; 1858 1859 DPRINTFN(DBG_FN, sc, "\n"); 1860 1861 /* Defer setting of WEP keys until interface is brought up. */ 1862 if (!IS_UP_AND_RUNNING(ifp)) 1863 return 0; 1864 1865 /* Do it in a process context. */ 1866 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; 1867 cmd.key = k; 1868 athn_usb_do_async(usc, athn_usb_set_key_cb, &cmd, sizeof(cmd)); 1869 return 0; 1870 } 1871 1872 Static void 1873 athn_usb_set_key_cb(struct athn_usb_softc *usc, void *arg) 1874 { 1875 struct ieee80211com *ic = &usc->usc_sc.sc_ic; 1876 struct athn_usb_cmd_key *cmd = arg; 1877 int s; 1878 1879 DPRINTFN(DBG_FN, usc, "\n"); 1880 1881 s = splnet(); 1882 athn_set_key(ic, cmd->ni, cmd->key); 1883 if (cmd->ni != NULL) 1884 ieee80211_free_node(cmd->ni); 1885 splx(s); 1886 } 1887 1888 Static void 1889 athn_usb_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 1890 struct ieee80211_key *k) 1891 { 1892 struct athn_softc *sc = ic->ic_ifp->if_softc; 1893 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1894 struct ifnet *ifp = &usc->usc_sc.sc_if; 1895 struct athn_usb_cmd_key cmd; 1896 1897 DPRINTFN(DBG_FN, sc, "\n"); 1898 1899 if (!(ifp->if_flags & IFF_RUNNING) || 1900 ic->ic_state != IEEE80211_S_RUN) 1901 return; /* Nothing to do. */ 1902 1903 /* Do it in a process context. */ 1904 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; 1905 cmd.key = k; 1906 athn_usb_do_async(usc, athn_usb_delete_key_cb, &cmd, sizeof(cmd)); 1907 } 1908 1909 Static void 1910 athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg) 1911 { 1912 struct ieee80211com *ic = &usc->usc_sc.sc_ic; 1913 struct athn_usb_cmd_key *cmd = arg; 1914 int s; 1915 1916 DPRINTFN(DBG_FN, usc, "\n"); 1917 1918 s = splnet(); 1919 athn_delete_key(ic, cmd->ni, cmd->key); 1920 if (cmd->ni != NULL) 1921 ieee80211_free_node(cmd->ni); 1922 splx(s); 1923 } 1924 #endif /* notyet */ 1925 1926 #ifndef IEEE80211_STA_ONLY 1927 Static void 1928 athn_usb_bcneof(struct usbd_xfer *xfer, void * priv, 1929 usbd_status status) 1930 { 1931 struct athn_usb_tx_data *data = priv; 1932 struct athn_usb_softc *usc = data->sc; 1933 1934 DPRINTFN(DBG_FN, usc, "\n"); 1935 1936 if (__predict_false(status == USBD_STALLED)) 1937 usbd_clear_endpoint_stall_async(usc->usc_tx_data_pipe); 1938 usc->usc_tx_bcn = data; 1939 } 1940 1941 /* 1942 * Process Software Beacon Alert interrupts. 1943 */ 1944 Static void 1945 athn_usb_swba(struct athn_usb_softc *usc) 1946 { 1947 struct athn_softc *sc = &usc->usc_sc; 1948 struct ieee80211com *ic = &sc->sc_ic; 1949 struct athn_usb_tx_data *data; 1950 struct ieee80211_frame *wh; 1951 struct ieee80211_beacon_offsets bo; 1952 struct ar_stream_hdr *hdr; 1953 struct ar_htc_frame_hdr *htc; 1954 struct ar_tx_bcn *bcn; 1955 struct mbuf *m; 1956 int error; 1957 1958 if (usc->usc_dying) 1959 return; 1960 1961 DPRINTFN(DBG_FN, sc, "\n"); 1962 1963 if (ic->ic_dtim_count == 0) 1964 ic->ic_dtim_count = ic->ic_dtim_period - 1; 1965 else 1966 ic->ic_dtim_count--; 1967 1968 /* Make sure previous beacon has been sent. */ 1969 if (usc->usc_tx_bcn == NULL) 1970 return; 1971 data = usc->usc_tx_bcn; 1972 1973 /* Get new beacon. */ 1974 #ifdef ATHN_DEBUG 1975 memset(&bo, 0, sizeof(bo)); 1976 #endif 1977 m = ieee80211_beacon_alloc(ic, ic->ic_bss, &bo); 1978 if (__predict_false(m == NULL)) 1979 return; 1980 /* Assign sequence number. */ 1981 /* XXX: use non-QoS tid? */ 1982 wh = mtod(m, struct ieee80211_frame *); 1983 *(uint16_t *)&wh->i_seq[0] = 1984 htole16(ic->ic_bss->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT); 1985 ic->ic_bss->ni_txseqs[0]++; 1986 1987 hdr = (struct ar_stream_hdr *)data->buf; 1988 hdr->tag = htole16(AR_USB_TX_STREAM_TAG); 1989 hdr->len = htole16(sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len); 1990 1991 htc = (struct ar_htc_frame_hdr *)&hdr[1]; 1992 memset(htc, 0, sizeof(*htc)); 1993 htc->endpoint_id = usc->usc_ep_bcn; 1994 htc->payload_len = htobe16(sizeof(*bcn) + m->m_pkthdr.len); 1995 1996 bcn = (struct ar_tx_bcn *)&htc[1]; 1997 memset(bcn, 0, sizeof(*bcn)); 1998 bcn->vif_idx = 0; 1999 2000 m_copydata(m, 0, m->m_pkthdr.len, (void *)&bcn[1]); 2001 2002 usbd_setup_xfer(data->xfer, data, data->buf, 2003 sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len, 2004 USBD_SHORT_XFER_OK, ATHN_USB_TX_TIMEOUT, 2005 athn_usb_bcneof); 2006 2007 m_freem(m); 2008 usc->usc_tx_bcn = NULL; 2009 error = usbd_transfer(data->xfer); 2010 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) 2011 usc->usc_tx_bcn = data; 2012 } 2013 #endif 2014 2015 Static void 2016 athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, size_t len) 2017 { 2018 #ifdef ATHN_DEBUG 2019 struct ar_wmi_evt_txrate *txrate; 2020 #endif 2021 struct ar_wmi_cmd_hdr *wmi; 2022 uint16_t cmd_id; 2023 2024 if (usc->usc_dying) 2025 return; 2026 2027 DPRINTFN(DBG_FN, usc, "\n"); 2028 2029 if (__predict_false(len < sizeof(*wmi))) 2030 return; 2031 wmi = (struct ar_wmi_cmd_hdr *)buf; 2032 cmd_id = be16toh(wmi->cmd_id); 2033 2034 if (!(cmd_id & AR_WMI_EVT_FLAG)) { 2035 mutex_enter(&usc->usc_cmd_mtx); 2036 if (usc->usc_wait_cmd_id == cmd_id) { 2037 2038 if (usc->usc_obuf != NULL) { 2039 /* Copy answer into caller supplied buffer. */ 2040 memcpy(usc->usc_obuf, &wmi[1], len - sizeof(*wmi)); 2041 } 2042 /* Notify caller of completion. */ 2043 usc->usc_wait_cmd_id = 0; 2044 cv_broadcast(&usc->usc_cmd_cv); 2045 } 2046 mutex_exit(&usc->usc_cmd_mtx); 2047 return; 2048 } 2049 /* 2050 * XXX: the Linux 2.6 and 3.7.4 kernels differ on the event numbers! 2051 * See the alternate defines in if_athn_usb.h. 2052 */ 2053 switch (cmd_id & 0xfff) { 2054 #ifndef IEEE80211_STA_ONLY 2055 case AR_WMI_EVT_SWBA: 2056 athn_usb_swba(usc); 2057 break; 2058 #endif 2059 case AR_WMI_EVT_FATAL: 2060 aprint_error_dev(usc->usc_dev, "fatal firmware error\n"); 2061 break; 2062 case AR_WMI_EVT_TXRATE: 2063 #ifdef ATHN_DEBUG 2064 txrate = (struct ar_wmi_evt_txrate *)&wmi[1]; 2065 DPRINTFN(DBG_TX, usc, "txrate=%d\n", be32toh(txrate->txrate)); 2066 #endif 2067 break; 2068 default: 2069 DPRINTFN(DBG_TX, usc, "WMI event %#x (%d) ignored\n", cmd_id, cmd_id); 2070 break; 2071 } 2072 } 2073 2074 Static void 2075 athn_usb_intr(struct usbd_xfer *xfer, void * priv, 2076 usbd_status status) 2077 { 2078 struct athn_usb_softc *usc = priv; 2079 struct ar_htc_frame_hdr *htc; 2080 struct ar_htc_msg_hdr *msg; 2081 uint8_t *buf = usc->usc_ibuf; 2082 uint16_t msg_id; 2083 int len; 2084 2085 if (usc->usc_dying) 2086 return; 2087 2088 DPRINTFN(DBG_FN, usc, "\n"); 2089 2090 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2091 DPRINTFN(DBG_INTR, usc, "intr status=%d\n", status); 2092 if (status == USBD_STALLED) 2093 usbd_clear_endpoint_stall_async(usc->usc_rx_intr_pipe); 2094 return; 2095 } 2096 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 2097 2098 /* Skip watchdog pattern if present. */ 2099 if (len >= 4 && *(uint32_t *)buf == htobe32(0x00c60000)) { 2100 buf += 4; 2101 len -= 4; 2102 } 2103 if (__predict_false(len < (int)sizeof(*htc))) 2104 return; 2105 htc = (struct ar_htc_frame_hdr *)buf; 2106 /* Skip HTC header. */ 2107 buf += sizeof(*htc); 2108 len -= sizeof(*htc); 2109 2110 if (htc->endpoint_id != 0) { 2111 if (__predict_false(htc->endpoint_id != usc->usc_ep_ctrl)) { 2112 DPRINTFN(DBG_RX, usc, "Rx %d != %d\n", 2113 htc->endpoint_id, usc->usc_ep_ctrl); 2114 return; 2115 } 2116 /* Remove trailer if present. */ 2117 if (htc->flags & AR_HTC_FLAG_TRAILER) { 2118 if (__predict_false(len < htc->control[0])) { 2119 DPRINTFN(DBG_RX, usc, "Rx trailer %d < %d\n", 2120 len, htc->control[0]); 2121 return; 2122 } 2123 len -= htc->control[0]; 2124 } 2125 athn_usb_rx_wmi_ctrl(usc, buf, len); 2126 return; 2127 } 2128 2129 /* 2130 * Endpoint 0 carries HTC messages. 2131 */ 2132 if (__predict_false(len < (int)sizeof(*msg))) 2133 return; 2134 msg = (struct ar_htc_msg_hdr *)buf; 2135 msg_id = be16toh(msg->msg_id); 2136 DPRINTFN(DBG_RX, usc, "Rx HTC message %d\n", msg_id); 2137 switch (msg_id) { 2138 case AR_HTC_MSG_READY: 2139 case AR_HTC_MSG_CONF_PIPE_RSP: 2140 mutex_enter(&usc->usc_msg_mtx); 2141 DPRINTFN(DBG_RX, usc, "AR_HTC_MSG_READY: %d vs %d\n", 2142 usc->usc_wait_msg_id, msg_id); 2143 if (usc->usc_wait_msg_id == msg_id) { 2144 usc->usc_wait_msg_id = 0; 2145 cv_broadcast(&usc->usc_msg_cv); 2146 } 2147 mutex_exit(&usc->usc_msg_mtx); 2148 break; 2149 case AR_HTC_MSG_CONN_SVC_RSP: 2150 mutex_enter(&usc->usc_msg_mtx); 2151 DPRINTFN(DBG_RX, usc, "AR_HTC_MSG_CONN_SVC_RSP: %d vs %d\n", 2152 usc->usc_wait_msg_id, msg_id); 2153 if (usc->usc_wait_msg_id == msg_id) { 2154 if (usc->usc_msg_conn_svc_rsp != NULL) { 2155 memcpy(usc->usc_msg_conn_svc_rsp, &msg[1], 2156 sizeof(*usc->usc_msg_conn_svc_rsp)); 2157 } 2158 usc->usc_wait_msg_id = 0; 2159 cv_broadcast(&usc->usc_msg_cv); 2160 } 2161 mutex_exit(&usc->usc_msg_mtx); 2162 break; 2163 default: 2164 DPRINTFN(DBG_RX, usc, "HTC message %d ignored\n", msg_id); 2165 break; 2166 } 2167 } 2168 2169 Static void 2170 athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m, 2171 struct ar_rx_status *rs) 2172 { 2173 struct athn_rx_radiotap_header *tap = &sc->sc_rxtap; 2174 struct ieee80211com *ic = &sc->sc_ic; 2175 uint8_t rate; 2176 2177 DPRINTFN(DBG_FN, sc, "\n"); 2178 2179 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; 2180 tap->wr_tsft = htole64(be64toh(rs->rs_tstamp)); 2181 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 2182 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 2183 tap->wr_dbm_antsignal = rs->rs_rssi; 2184 /* XXX noise. */ 2185 tap->wr_antenna = rs->rs_antenna; 2186 rate = rs->rs_rate; 2187 if (rate & 0x80) { /* HT. */ 2188 /* Bit 7 set means HT MCS instead of rate. */ 2189 tap->wr_rate = rate; 2190 if (!(rs->rs_flags & AR_RXS_FLAG_GI)) 2191 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; 2192 } else if (rate & 0x10) { /* CCK. */ 2193 if (rate & 0x04) 2194 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 2195 switch (rate & ~0x14) { 2196 case 0xb: tap->wr_rate = 2; break; 2197 case 0xa: tap->wr_rate = 4; break; 2198 case 0x9: tap->wr_rate = 11; break; 2199 case 0x8: tap->wr_rate = 22; break; 2200 default: tap->wr_rate = 0; break; 2201 } 2202 } else { /* OFDM. */ 2203 switch (rate) { 2204 case 0xb: tap->wr_rate = 12; break; 2205 case 0xf: tap->wr_rate = 18; break; 2206 case 0xa: tap->wr_rate = 24; break; 2207 case 0xe: tap->wr_rate = 36; break; 2208 case 0x9: tap->wr_rate = 48; break; 2209 case 0xd: tap->wr_rate = 72; break; 2210 case 0x8: tap->wr_rate = 96; break; 2211 case 0xc: tap->wr_rate = 108; break; 2212 default: tap->wr_rate = 0; break; 2213 } 2214 } 2215 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m, BPF_D_IN); 2216 } 2217 2218 Static void 2219 athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m) 2220 { 2221 struct athn_softc *sc = &usc->usc_sc; 2222 struct ieee80211com *ic = &sc->sc_ic; 2223 struct ifnet *ifp = &sc->sc_if; 2224 struct ieee80211_frame *wh; 2225 struct ieee80211_node *ni; 2226 struct ar_htc_frame_hdr *htc; 2227 struct ar_rx_status *rs; 2228 uint16_t datalen; 2229 int s; 2230 2231 DPRINTFN(DBG_FN, sc, "\n"); 2232 2233 if (__predict_false(m->m_len < (int)sizeof(*htc))) 2234 goto skip; 2235 htc = mtod(m, struct ar_htc_frame_hdr *); 2236 if (__predict_false(htc->endpoint_id == 0)) { 2237 DPRINTFN(DBG_RX, sc, "bad endpoint %d\n", htc->endpoint_id); 2238 goto skip; 2239 } 2240 if (htc->flags & AR_HTC_FLAG_TRAILER) { 2241 if (m->m_len < htc->control[0]) 2242 goto skip; 2243 m_adj(m, -(int)htc->control[0]); 2244 } 2245 m_adj(m, sizeof(*htc)); /* Strip HTC header. */ 2246 2247 if (__predict_false(m->m_len < (int)sizeof(*rs))) 2248 goto skip; 2249 rs = mtod(m, struct ar_rx_status *); 2250 2251 /* Make sure that payload fits. */ 2252 datalen = be16toh(rs->rs_datalen); 2253 if (__predict_false(m->m_len < (int)sizeof(*rs) + datalen)) 2254 goto skip; 2255 2256 /* Ignore runt frames. Let ACKs be seen by bpf */ 2257 if (__predict_false(datalen < 2258 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN)) 2259 goto skip; 2260 2261 m_adj(m, sizeof(*rs)); /* Strip Rx status. */ 2262 m_set_rcvif(m, ifp); 2263 2264 s = splnet(); 2265 2266 /* Grab a reference to the source node. */ 2267 wh = mtod(m, struct ieee80211_frame *); 2268 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 2269 2270 /* Remove any HW padding after the 802.11 header. */ 2271 if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) { 2272 u_int hdrlen = ieee80211_anyhdrsize(wh); 2273 if (hdrlen & 3) { 2274 memmove((uint8_t *)wh + 2, wh, hdrlen); 2275 m_adj(m, 2); 2276 } 2277 } 2278 if (__predict_false(sc->sc_drvbpf != NULL)) 2279 athn_usb_rx_radiotap(sc, m, rs); 2280 2281 /* Trim 802.11 FCS after radiotap. */ 2282 m_adj(m, -IEEE80211_CRC_LEN); 2283 2284 /* Send the frame to the 802.11 layer. */ 2285 ieee80211_input(ic, m, ni, rs->rs_rssi + AR_USB_DEFAULT_NF, 0); 2286 2287 /* Node is no longer needed. */ 2288 ieee80211_free_node(ni); 2289 splx(s); 2290 return; 2291 skip: 2292 m_freem(m); 2293 } 2294 2295 Static void 2296 athn_usb_rxeof(struct usbd_xfer *xfer, void * priv, 2297 usbd_status status) 2298 { 2299 struct athn_usb_rx_data *data = priv; 2300 struct athn_usb_softc *usc = data->sc; 2301 struct athn_usb_rx_stream *stream = &usc->usc_rx_stream; 2302 uint8_t *buf = data->buf; 2303 struct ar_stream_hdr *hdr; 2304 struct mbuf *m; 2305 uint16_t pktlen; 2306 int off, len; 2307 2308 if (usc->usc_dying) 2309 return; 2310 2311 DPRINTFN(DBG_FN, usc, "\n"); 2312 2313 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2314 DPRINTFN(DBG_RX, usc, "RX status=%d\n", status); 2315 if (status == USBD_STALLED) 2316 usbd_clear_endpoint_stall_async(usc->usc_rx_data_pipe); 2317 if (status != USBD_CANCELLED) 2318 goto resubmit; 2319 return; 2320 } 2321 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 2322 2323 if (stream->left > 0) { 2324 if (len >= stream->left) { 2325 /* We have all our pktlen bytes now. */ 2326 if (__predict_true(stream->m != NULL)) { 2327 memcpy(mtod(stream->m, uint8_t *) + 2328 stream->moff, buf, stream->left); 2329 athn_usb_rx_frame(usc, stream->m); 2330 stream->m = NULL; 2331 } 2332 /* Next header is 32-bit aligned. */ 2333 off = (stream->left + 3) & ~3; 2334 buf += off; 2335 len -= off; 2336 stream->left = 0; 2337 } else { 2338 /* Still need more bytes, save what we have. */ 2339 if (__predict_true(stream->m != NULL)) { 2340 memcpy(mtod(stream->m, uint8_t *) + 2341 stream->moff, buf, len); 2342 stream->moff += len; 2343 } 2344 stream->left -= len; 2345 goto resubmit; 2346 } 2347 } 2348 KASSERT(stream->left == 0); 2349 while (len >= (int)sizeof(*hdr)) { 2350 hdr = (struct ar_stream_hdr *)buf; 2351 if (hdr->tag != htole16(AR_USB_RX_STREAM_TAG)) { 2352 DPRINTFN(DBG_RX, usc, "invalid tag %#x\n", hdr->tag); 2353 break; 2354 } 2355 pktlen = le16toh(hdr->len); 2356 buf += sizeof(*hdr); 2357 len -= sizeof(*hdr); 2358 2359 if (__predict_true(pktlen <= MCLBYTES)) { 2360 /* Allocate an mbuf to store the next pktlen bytes. */ 2361 MGETHDR(m, M_DONTWAIT, MT_DATA); 2362 if (__predict_true(m != NULL)) { 2363 m->m_pkthdr.len = m->m_len = pktlen; 2364 if (pktlen > MHLEN) { 2365 MCLGET(m, M_DONTWAIT); 2366 if (!(m->m_flags & M_EXT)) { 2367 m_free(m); 2368 m = NULL; 2369 } 2370 } 2371 } 2372 } else /* Drop frames larger than MCLBYTES. */ 2373 m = NULL; 2374 /* 2375 * NB: m can be NULL, in which case the next pktlen bytes 2376 * will be discarded from the Rx stream. 2377 */ 2378 if (pktlen > len) { 2379 /* Need more bytes, save what we have. */ 2380 stream->m = m; /* NB: m can be NULL. */ 2381 if (__predict_true(stream->m != NULL)) { 2382 memcpy(mtod(stream->m, uint8_t *), buf, len); 2383 stream->moff = len; 2384 } 2385 stream->left = pktlen - len; 2386 goto resubmit; 2387 } 2388 if (__predict_true(m != NULL)) { 2389 /* We have all the pktlen bytes in this xfer. */ 2390 memcpy(mtod(m, uint8_t *), buf, pktlen); 2391 athn_usb_rx_frame(usc, m); 2392 } 2393 2394 /* Next header is 32-bit aligned. */ 2395 off = (pktlen + 3) & ~3; 2396 buf += off; 2397 len -= off; 2398 } 2399 2400 resubmit: 2401 /* Setup a new transfer. */ 2402 usbd_setup_xfer(xfer, data, data->buf, ATHN_USB_RXBUFSZ, 2403 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, athn_usb_rxeof); 2404 (void)usbd_transfer(xfer); 2405 } 2406 2407 Static void 2408 athn_usb_txeof(struct usbd_xfer *xfer, void * priv, 2409 usbd_status status) 2410 { 2411 struct athn_usb_tx_data *data = priv; 2412 struct athn_usb_softc *usc = data->sc; 2413 struct athn_softc *sc = &usc->usc_sc; 2414 struct ifnet *ifp = &sc->sc_if; 2415 int s; 2416 2417 if (usc->usc_dying) 2418 return; 2419 2420 DPRINTFN(DBG_FN, usc, "\n"); 2421 2422 s = splnet(); 2423 /* Put this Tx buffer back to our free list. */ 2424 mutex_enter(&usc->usc_tx_mtx); 2425 TAILQ_INSERT_TAIL(&usc->usc_tx_free_list, data, next); 2426 mutex_exit(&usc->usc_tx_mtx); 2427 2428 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2429 DPRINTFN(DBG_TX, sc, "TX status=%d\n", status); 2430 if (status == USBD_STALLED) 2431 usbd_clear_endpoint_stall_async(usc->usc_tx_data_pipe); 2432 if_statinc(ifp, if_oerrors); 2433 splx(s); 2434 /* XXX Why return? */ 2435 return; 2436 } 2437 sc->sc_tx_timer = 0; 2438 if_statinc(ifp, if_opackets); 2439 2440 /* We just released a Tx buffer, notify Tx. */ 2441 if (ifp->if_flags & IFF_OACTIVE) { 2442 ifp->if_flags &= ~IFF_OACTIVE; 2443 ifp->if_start(ifp); 2444 } 2445 splx(s); 2446 } 2447 2448 Static int 2449 athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2450 struct athn_usb_tx_data *data) 2451 { 2452 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2453 struct athn_node *an = ATHN_NODE(ni); 2454 struct ieee80211com *ic = &sc->sc_ic; 2455 struct ieee80211_frame *wh; 2456 struct ieee80211_key *k = NULL; 2457 struct ar_stream_hdr *hdr; 2458 struct ar_htc_frame_hdr *htc; 2459 struct ar_tx_frame *txf; 2460 struct ar_tx_mgmt *txm; 2461 uint8_t *frm; 2462 uint8_t sta_index, qid, tid; 2463 int error, s, xferlen; 2464 2465 DPRINTFN(DBG_FN, sc, "\n"); 2466 2467 wh = mtod(m, struct ieee80211_frame *); 2468 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2469 k = ieee80211_crypto_encap(ic, ni, m); 2470 if (k == NULL) 2471 return ENOBUFS; 2472 2473 /* packet header may have moved, reset our local pointer */ 2474 wh = mtod(m, struct ieee80211_frame *); 2475 } 2476 #ifdef notyet_edca 2477 if (ieee80211_has_qos(wh)) { 2478 uint16_t qos; 2479 2480 qos = ieee80211_get_qos(wh); 2481 tid = qos & IEEE80211_QOS_TID; 2482 qid = ieee80211_up_to_ac(ic, tid); 2483 } else 2484 #endif /* notyet_edca */ 2485 { 2486 tid = 0; 2487 qid = WME_AC_BE; 2488 } 2489 2490 /* XXX Change radiotap Tx header for USB (no txrate). */ 2491 if (__predict_false(sc->sc_drvbpf != NULL)) { 2492 struct athn_tx_radiotap_header *tap = &sc->sc_txtap; 2493 2494 tap->wt_flags = 0; 2495 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2496 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2497 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 2498 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 2499 2500 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m, BPF_D_OUT); 2501 } 2502 sta_index = an->sta_index; 2503 2504 /* NB: We don't take advantage of USB Tx stream mode for now. */ 2505 hdr = (struct ar_stream_hdr *)data->buf; 2506 hdr->tag = htole16(AR_USB_TX_STREAM_TAG); 2507 2508 htc = (struct ar_htc_frame_hdr *)&hdr[1]; 2509 memset(htc, 0, sizeof(*htc)); 2510 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2511 IEEE80211_FC0_TYPE_DATA) { 2512 htc->endpoint_id = usc->usc_ep_data[qid]; 2513 2514 txf = (struct ar_tx_frame *)&htc[1]; 2515 memset(txf, 0, sizeof(*txf)); 2516 txf->data_type = AR_HTC_NORMAL; 2517 txf->node_idx = sta_index; 2518 txf->vif_idx = 0; 2519 txf->tid = tid; 2520 if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) 2521 txf->flags |= htobe32(AR_HTC_TX_RTSCTS); 2522 else if (ic->ic_flags & IEEE80211_F_USEPROT) { 2523 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 2524 txf->flags |= htobe32(AR_HTC_TX_CTSONLY); 2525 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 2526 txf->flags |= htobe32(AR_HTC_TX_RTSCTS); 2527 } 2528 txf->key_idx = 0xff; 2529 frm = (uint8_t *)&txf[1]; 2530 } else { 2531 htc->endpoint_id = usc->usc_ep_mgmt; 2532 2533 txm = (struct ar_tx_mgmt *)&htc[1]; 2534 memset(txm, 0, sizeof(*txm)); 2535 txm->node_idx = sta_index; 2536 txm->vif_idx = 0; 2537 txm->key_idx = 0xff; 2538 frm = (uint8_t *)&txm[1]; 2539 } 2540 /* Copy payload. */ 2541 m_copydata(m, 0, m->m_pkthdr.len, (void *)frm); 2542 frm += m->m_pkthdr.len; 2543 2544 /* Finalize headers. */ 2545 htc->payload_len = htobe16(frm - (uint8_t *)&htc[1]); 2546 hdr->len = htole16(frm - (uint8_t *)&hdr[1]); 2547 xferlen = frm - data->buf; 2548 2549 s = splnet(); 2550 usbd_setup_xfer(data->xfer, data, data->buf, xferlen, 2551 USBD_FORCE_SHORT_XFER, ATHN_USB_TX_TIMEOUT, athn_usb_txeof); 2552 error = usbd_transfer(data->xfer); 2553 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) { 2554 splx(s); 2555 return error; 2556 } 2557 splx(s); 2558 return 0; 2559 } 2560 2561 Static void 2562 athn_usb_start(struct ifnet *ifp) 2563 { 2564 struct athn_softc *sc = ifp->if_softc; 2565 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2566 struct ieee80211com *ic = &sc->sc_ic; 2567 struct athn_usb_tx_data *data; 2568 struct ether_header *eh; 2569 struct ieee80211_node *ni; 2570 struct mbuf *m; 2571 2572 if (usc->usc_dying) 2573 return; 2574 2575 DPRINTFN(DBG_FN, sc, "\n"); 2576 2577 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 2578 return; 2579 2580 data = NULL; 2581 for (;;) { 2582 mutex_enter(&usc->usc_tx_mtx); 2583 if (data == NULL && !TAILQ_EMPTY(&usc->usc_tx_free_list)) { 2584 data = TAILQ_FIRST(&usc->usc_tx_free_list); 2585 TAILQ_REMOVE(&usc->usc_tx_free_list, data, next); 2586 } 2587 mutex_exit(&usc->usc_tx_mtx); 2588 2589 if (data == NULL) { 2590 ifp->if_flags |= IFF_OACTIVE; 2591 return; 2592 } 2593 2594 /* Send pending management frames first. */ 2595 IF_DEQUEUE(&ic->ic_mgtq, m); 2596 if (m != NULL) { 2597 ni = M_GETCTX(m, struct ieee80211_node *); 2598 M_CLEARCTX(m); 2599 goto sendit; 2600 } 2601 if (ic->ic_state != IEEE80211_S_RUN) 2602 break; 2603 2604 /* Encapsulate and send data frames. */ 2605 IFQ_DEQUEUE(&ifp->if_snd, m); 2606 if (m == NULL) 2607 break; 2608 2609 if (m->m_len < (int)sizeof(*eh) && 2610 (m = m_pullup(m, sizeof(*eh))) == NULL) { 2611 if_statinc(ifp, if_oerrors); 2612 continue; 2613 } 2614 eh = mtod(m, struct ether_header *); 2615 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 2616 if (ni == NULL) { 2617 m_freem(m); 2618 if_statinc(ifp, if_oerrors); 2619 continue; 2620 } 2621 2622 bpf_mtap(ifp, m, BPF_D_OUT); 2623 2624 if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 2625 ieee80211_free_node(ni); 2626 if_statinc(ifp, if_oerrors); 2627 continue; 2628 } 2629 sendit: 2630 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 2631 2632 if (athn_usb_tx(sc, m, ni, data) != 0) { 2633 m_freem(m); 2634 ieee80211_free_node(ni); 2635 if_statinc(ifp, if_oerrors); 2636 continue; 2637 } 2638 data = NULL; 2639 m_freem(m); 2640 ieee80211_free_node(ni); 2641 sc->sc_tx_timer = 5; 2642 ifp->if_timer = 1; 2643 } 2644 2645 /* Return the Tx buffer to the free list */ 2646 mutex_enter(&usc->usc_tx_mtx); 2647 TAILQ_INSERT_TAIL(&usc->usc_tx_free_list, data, next); 2648 mutex_exit(&usc->usc_tx_mtx); 2649 } 2650 2651 Static void 2652 athn_usb_watchdog(struct ifnet *ifp) 2653 { 2654 struct athn_softc *sc = ifp->if_softc; 2655 2656 DPRINTFN(DBG_FN, sc, "\n"); 2657 2658 ifp->if_timer = 0; 2659 2660 if (sc->sc_tx_timer > 0) { 2661 if (--sc->sc_tx_timer == 0) { 2662 aprint_error_dev(sc->sc_dev, "device timeout\n"); 2663 /* athn_usb_init(ifp); XXX needs a process context! */ 2664 if_statinc(ifp, if_oerrors); 2665 return; 2666 } 2667 ifp->if_timer = 1; 2668 } 2669 ieee80211_watchdog(&sc->sc_ic); 2670 } 2671 2672 Static int 2673 athn_usb_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2674 { 2675 struct athn_softc *sc = ifp->if_softc; 2676 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2677 struct ieee80211com *ic = &sc->sc_ic; 2678 int s, error = 0; 2679 2680 if (usc->usc_dying) 2681 return EIO; 2682 2683 DPRINTFN(DBG_FN, sc, "cmd=0x%08lx\n", cmd); 2684 2685 s = splnet(); 2686 2687 switch (cmd) { 2688 case SIOCSIFFLAGS: 2689 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 2690 break; 2691 2692 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 2693 case IFF_UP | IFF_RUNNING: 2694 break; 2695 case IFF_UP: 2696 error = athn_usb_init(ifp); 2697 break; 2698 case IFF_RUNNING: 2699 athn_usb_stop(ifp, 0); 2700 break; 2701 case 0: 2702 default: 2703 break; 2704 } 2705 break; 2706 2707 case SIOCADDMULTI: 2708 case SIOCDELMULTI: 2709 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 2710 /* setup multicast filter, etc */ 2711 error = 0; 2712 } 2713 break; 2714 2715 case SIOCS80211CHANNEL: 2716 error = ieee80211_ioctl(ic, cmd, data); 2717 if (error == ENETRESET && 2718 ic->ic_opmode == IEEE80211_M_MONITOR) { 2719 if (IS_UP_AND_RUNNING(ifp)) 2720 athn_usb_switch_chan(sc, ic->ic_curchan, NULL); 2721 error = 0; 2722 } 2723 break; 2724 2725 default: 2726 error = ieee80211_ioctl(ic, cmd, data); 2727 break; 2728 } 2729 if (error == ENETRESET) { 2730 error = 0; 2731 if (IS_UP_AND_RUNNING(ifp) && 2732 ic->ic_roaming != IEEE80211_ROAMING_MANUAL) { 2733 mutex_enter(&usc->usc_lock); 2734 athn_usb_stop_locked(ifp); 2735 error = athn_usb_init_locked(ifp); 2736 mutex_exit(&usc->usc_lock); 2737 } 2738 } 2739 splx(s); 2740 return error; 2741 } 2742 2743 Static int 2744 athn_usb_init(struct ifnet *ifp) 2745 { 2746 struct athn_softc *sc = ifp->if_softc; 2747 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2748 2749 mutex_enter(&usc->usc_lock); 2750 int ret = athn_usb_init_locked(ifp); 2751 mutex_exit(&usc->usc_lock); 2752 2753 return ret; 2754 } 2755 2756 Static int 2757 athn_usb_init_locked(struct ifnet *ifp) 2758 { 2759 struct athn_softc *sc = ifp->if_softc; 2760 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2761 struct athn_ops *ops = &sc->sc_ops; 2762 struct ieee80211com *ic = &sc->sc_ic; 2763 struct ieee80211_channel *curchan, *extchan; 2764 struct athn_usb_rx_data *data; 2765 struct ar_htc_target_vif hvif; 2766 struct ar_htc_target_sta sta; 2767 struct ar_htc_cap_target hic; 2768 uint16_t mode; 2769 size_t i; 2770 int error; 2771 2772 if (usc->usc_dying) 2773 return USBD_CANCELLED; 2774 2775 DPRINTFN(DBG_FN, sc, "\n"); 2776 2777 /* Init host async commands ring. */ 2778 mutex_spin_enter(&usc->usc_task_mtx); 2779 usc->usc_cmdq.cur = usc->usc_cmdq.next = usc->usc_cmdq.queued = 0; 2780 mutex_spin_exit(&usc->usc_task_mtx); 2781 2782 curchan = ic->ic_curchan; 2783 extchan = NULL; 2784 2785 /* In case a new MAC address has been configured. */ 2786 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 2787 2788 error = athn_set_power_awake(sc); 2789 if (error != 0) 2790 goto fail; 2791 2792 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_FLUSH_RECV); 2793 if (error != 0) 2794 goto fail; 2795 2796 error = athn_hw_reset(sc, curchan, extchan, 1); 2797 if (error != 0) 2798 goto fail; 2799 2800 ops->set_txpower(sc, curchan, extchan); 2801 2802 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(curchan) ? 2803 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); 2804 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, 2805 &mode, sizeof(mode), NULL); 2806 if (error != 0) 2807 goto fail; 2808 2809 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ATH_INIT); 2810 if (error != 0) 2811 goto fail; 2812 2813 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); 2814 if (error != 0) 2815 goto fail; 2816 2817 athn_rx_start(sc); 2818 2819 /* Create main interface on target. */ 2820 memset(&hvif, 0, sizeof(hvif)); 2821 hvif.index = 0; 2822 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); 2823 switch (ic->ic_opmode) { 2824 case IEEE80211_M_STA: 2825 hvif.opmode = htobe32(AR_HTC_M_STA); 2826 break; 2827 case IEEE80211_M_MONITOR: 2828 hvif.opmode = htobe32(AR_HTC_M_MONITOR); 2829 break; 2830 #ifndef IEEE80211_STA_ONLY 2831 case IEEE80211_M_IBSS: 2832 hvif.opmode = htobe32(AR_HTC_M_IBSS); 2833 break; 2834 case IEEE80211_M_AHDEMO: 2835 hvif.opmode = htobe32(AR_HTC_M_AHDEMO); 2836 break; 2837 case IEEE80211_M_HOSTAP: 2838 hvif.opmode = htobe32(AR_HTC_M_HOSTAP); 2839 break; 2840 #endif 2841 } 2842 hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold); 2843 DPRINTFN(DBG_INIT, sc, "creating VAP\n"); 2844 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE, 2845 &hvif, sizeof(hvif), NULL); 2846 if (error != 0) 2847 goto fail; 2848 2849 /* Create a fake node to send management frames before assoc. */ 2850 memset(&sta, 0, sizeof(sta)); 2851 IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_myaddr); 2852 sta.sta_index = 0; 2853 sta.is_vif_sta = 1; 2854 sta.vif_index = hvif.index; 2855 sta.maxampdu = 0xffff; 2856 2857 DPRINTFN(DBG_INIT | DBG_NODES, sc, "creating default node %u\n", 2858 sta.sta_index); 2859 error = athn_usb_create_hw_node(usc, &sta); 2860 if (error != 0) 2861 goto fail; 2862 2863 /* Update target capabilities. */ 2864 memset(&hic, 0, sizeof(hic)); 2865 hic.flags = htobe32(0x400c2400); 2866 hic.flags_ext = htobe32(0x00106080); 2867 hic.ampdu_limit = htobe32(0x0000ffff); 2868 hic.ampdu_subframes = 20; 2869 hic.protmode = 1; /* XXX */ 2870 hic.lg_txchainmask = sc->sc_txchainmask; 2871 hic.ht_txchainmask = sc->sc_txchainmask; 2872 DPRINTFN(DBG_INIT, sc, "updating target configuration\n"); 2873 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE, 2874 &hic, sizeof(hic), NULL); 2875 if (error != 0) 2876 goto fail; 2877 2878 2879 /* Queue Rx xfers. */ 2880 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 2881 data = &usc->usc_rx_data[i]; 2882 2883 usbd_setup_xfer(data->xfer, data, data->buf, 2884 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK, 2885 USBD_NO_TIMEOUT, athn_usb_rxeof); 2886 error = usbd_transfer(data->xfer); 2887 if (error != 0 && error != USBD_IN_PROGRESS) 2888 goto fail; 2889 } 2890 /* We're ready to go. */ 2891 ifp->if_flags &= ~IFF_OACTIVE; 2892 ifp->if_flags |= IFF_RUNNING; 2893 2894 #ifdef notyet 2895 if (ic->ic_flags & IEEE80211_F_WEPON) { 2896 /* Install WEP keys. */ 2897 for (i = 0; i < IEEE80211_WEP_NKID; i++) 2898 athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]); 2899 } 2900 #endif 2901 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 2902 ic->ic_max_aid = AR_USB_MAX_STA; /* Firmware is limited to 8 STA */ 2903 else 2904 ic->ic_max_aid = sc->sc_max_aid; 2905 2906 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2907 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2908 else 2909 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2910 athn_usb_wait_async(usc); 2911 return 0; 2912 fail: 2913 athn_usb_stop(ifp, 0); 2914 return error; 2915 } 2916 2917 Static void 2918 athn_usb_stop(struct ifnet *ifp, int disable) 2919 { 2920 struct athn_softc *sc = ifp->if_softc; 2921 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2922 2923 mutex_enter(&usc->usc_lock); 2924 athn_usb_stop_locked(ifp); 2925 mutex_exit(&usc->usc_lock); 2926 } 2927 2928 Static void 2929 athn_usb_stop_locked(struct ifnet *ifp) 2930 { 2931 struct athn_softc *sc = ifp->if_softc; 2932 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2933 struct ieee80211com *ic = &sc->sc_ic; 2934 struct ar_htc_target_vif hvif; 2935 struct mbuf *m; 2936 uint8_t sta_index; 2937 int s; 2938 2939 DPRINTFN(DBG_FN, sc, "\n"); 2940 2941 s = splusb(); 2942 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2943 athn_usb_wait_async(usc); 2944 splx(s); 2945 2946 sc->sc_tx_timer = 0; 2947 ifp->if_timer = 0; 2948 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2949 2950 callout_stop(&sc->sc_scan_to); 2951 callout_stop(&sc->sc_calib_to); 2952 2953 /* Abort Tx/Rx. */ 2954 usbd_abort_pipe(usc->usc_tx_data_pipe); 2955 usbd_abort_pipe(usc->usc_rx_data_pipe); 2956 2957 /* Flush Rx stream. */ 2958 CTASSERT(sizeof(m) == sizeof(void *)); 2959 m = atomic_swap_ptr(&usc->usc_rx_stream.m, NULL); 2960 m_freem(m); 2961 usc->usc_rx_stream.left = 0; 2962 2963 /* Remove main interface. */ 2964 memset(&hvif, 0, sizeof(hvif)); 2965 hvif.index = 0; 2966 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); 2967 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE, 2968 &hvif, sizeof(hvif), NULL); 2969 2970 /* Remove default node. */ 2971 sta_index = 0; 2972 DPRINTFN(DBG_NODES, usc, "removing node %u\n", sta_index); 2973 (void)athn_usb_remove_hw_node(usc, &sta_index); 2974 2975 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 2976 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); 2977 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); 2978 2979 athn_reset(sc, 0); 2980 athn_init_pll(sc, NULL); 2981 athn_set_power_awake(sc); 2982 athn_reset(sc, 1); 2983 athn_init_pll(sc, NULL); 2984 athn_set_power_sleep(sc); 2985 } 2986 2987 MODULE(MODULE_CLASS_DRIVER, if_athn_usb, NULL); 2988 2989 #ifdef _MODULE 2990 #include "ioconf.c" 2991 #endif 2992 2993 static int 2994 if_athn_usb_modcmd(modcmd_t cmd, void *aux) 2995 { 2996 int error = 0; 2997 2998 switch (cmd) { 2999 case MODULE_CMD_INIT: 3000 #ifdef _MODULE 3001 error = config_init_component(cfdriver_ioconf_if_athn_usb, 3002 cfattach_ioconf_if_athn_usb, cfdata_ioconf_if_athn_usb); 3003 #endif 3004 return error; 3005 case MODULE_CMD_FINI: 3006 #ifdef _MODULE 3007 error = config_fini_component(cfdriver_ioconf_if_athn_usb, 3008 cfattach_ioconf_if_athn_usb, cfdata_ioconf_if_athn_usb); 3009 #endif 3010 return error; 3011 default: 3012 return ENOTTY; 3013 } 3014 } 3015