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