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