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