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