1 /* $OpenBSD: if_athn_usb.c,v 1.8 2011/07/03 15:47:17 matthew Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * USB front-end for Atheros AR9271 and AR7010 chipsets. 21 */ 22 23 #include "bpfilter.h" 24 25 #include <sys/param.h> 26 #include <sys/sockio.h> 27 #include <sys/mbuf.h> 28 #include <sys/kernel.h> 29 #include <sys/socket.h> 30 #include <sys/systm.h> 31 #include <sys/timeout.h> 32 #include <sys/conf.h> 33 #include <sys/device.h> 34 #include <sys/stdint.h> /* uintptr_t */ 35 36 #include <machine/bus.h> 37 #include <machine/endian.h> 38 #include <machine/intr.h> 39 40 #if NBPFILTER > 0 41 #include <net/bpf.h> 42 #endif 43 #include <net/if.h> 44 #include <net/if_arp.h> 45 #include <net/if_dl.h> 46 #include <net/if_media.h> 47 #include <net/if_types.h> 48 49 #include <netinet/in.h> 50 #include <netinet/in_systm.h> 51 #include <netinet/in_var.h> 52 #include <netinet/if_ether.h> 53 #include <netinet/ip.h> 54 55 #include <net80211/ieee80211_var.h> 56 #include <net80211/ieee80211_amrr.h> 57 #include <net80211/ieee80211_radiotap.h> 58 59 #include <dev/ic/athnreg.h> 60 #include <dev/ic/athnvar.h> 61 62 #include <dev/usb/usb.h> 63 #include <dev/usb/usbdi.h> 64 #include <dev/usb/usbdi_util.h> 65 #include <dev/usb/usbdevs.h> 66 67 #include <dev/usb/if_athn_usb.h> 68 69 static const struct athn_usb_type { 70 struct usb_devno devno; 71 u_int flags; 72 } athn_usb_devs[] = { 73 {{ USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_AR9280 }, 74 ATHN_USB_FLAG_AR7010 }, 75 {{ USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_AR9287 }, 76 ATHN_USB_FLAG_AR7010 }, 77 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_1 }}, 78 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_2 }}, 79 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9271_3 }}, 80 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9280 }, 81 ATHN_USB_FLAG_AR7010 }, 82 {{ USB_VENDOR_ATHEROS2, USB_PRODUCT_ATHEROS2_AR9287 }, 83 ATHN_USB_FLAG_AR7010 }, 84 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_1 }}, 85 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_2 }}, 86 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_3 }}, 87 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_4 }}, 88 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_5 }}, 89 {{ USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_AR9271_6 }}, 90 {{ USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_AR9271 }}, 91 {{ USB_VENDOR_LITEON, USB_PRODUCT_LITEON_AR9271 }}, 92 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1100 }}, 93 {{ USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNDA3200 }, 94 ATHN_USB_FLAG_AR7010 }, 95 {{ USB_VENDOR_VIA, USB_PRODUCT_VIA_AR9271 }} 96 }; 97 #define athn_usb_lookup(v, p) \ 98 ((const struct athn_usb_type *)usb_lookup(athn_usb_devs, v, p)) 99 100 int athn_usb_match(struct device *, void *, void *); 101 void athn_usb_attach(struct device *, struct device *, void *); 102 int athn_usb_detach(struct device *, int); 103 int athn_usb_activate(struct device *, int); 104 void athn_usb_attachhook(void *); 105 int athn_usb_open_pipes(struct athn_usb_softc *); 106 void athn_usb_close_pipes(struct athn_usb_softc *); 107 int athn_usb_alloc_rx_list(struct athn_usb_softc *); 108 void athn_usb_free_rx_list(struct athn_usb_softc *); 109 int athn_usb_alloc_tx_list(struct athn_usb_softc *); 110 void athn_usb_free_tx_list(struct athn_usb_softc *); 111 int athn_usb_alloc_tx_cmd(struct athn_usb_softc *); 112 void athn_usb_free_tx_cmd(struct athn_usb_softc *); 113 void athn_usb_task(void *); 114 void athn_usb_do_async(struct athn_usb_softc *, 115 void (*)(struct athn_usb_softc *, void *), void *, int); 116 void athn_usb_wait_async(struct athn_usb_softc *); 117 int athn_usb_load_firmware(struct athn_usb_softc *); 118 int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *, 119 int); 120 int athn_usb_htc_setup(struct athn_usb_softc *); 121 int athn_usb_htc_connect_svc(struct athn_usb_softc *, uint16_t, 122 uint8_t, uint8_t, uint8_t *); 123 void athn_usb_wmieof(usbd_xfer_handle, usbd_private_handle, 124 usbd_status); 125 int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *, 126 int, void *); 127 int athn_usb_read_rom(struct athn_softc *); 128 uint32_t athn_usb_read(struct athn_softc *, uint32_t); 129 void athn_usb_write(struct athn_softc *, uint32_t, uint32_t); 130 void athn_usb_write_barrier(struct athn_softc *); 131 int athn_usb_media_change(struct ifnet *); 132 int athn_usb_newstate(struct ieee80211com *, enum ieee80211_state, 133 int); 134 void athn_usb_newstate_cb(struct athn_usb_softc *, void *); 135 void athn_usb_newassoc(struct ieee80211com *, 136 struct ieee80211_node *, int); 137 void athn_usb_newassoc_cb(struct athn_usb_softc *, void *); 138 void athn_usb_node_leave(struct ieee80211com *, 139 struct ieee80211_node *); 140 void athn_usb_node_leave_cb(struct athn_usb_softc *, void *); 141 int athn_usb_ampdu_tx_start(struct ieee80211com *, 142 struct ieee80211_node *, uint8_t); 143 void athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *, void *); 144 void athn_usb_ampdu_tx_stop(struct ieee80211com *, 145 struct ieee80211_node *, uint8_t); 146 void athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *, void *); 147 int athn_usb_create_node(struct athn_usb_softc *, 148 struct ieee80211_node *); 149 void athn_usb_rx_enable(struct athn_softc *); 150 int athn_set_chan(struct athn_softc *, struct ieee80211_channel *, 151 struct ieee80211_channel *); 152 int athn_usb_switch_chan(struct athn_softc *, 153 struct ieee80211_channel *, struct ieee80211_channel *); 154 void athn_usb_updateedca(struct ieee80211com *); 155 void athn_usb_updateedca_cb(struct athn_usb_softc *, void *); 156 void athn_usb_updateslot(struct ieee80211com *); 157 void athn_usb_updateslot_cb(struct athn_usb_softc *, void *); 158 int athn_usb_set_key(struct ieee80211com *, 159 struct ieee80211_node *, struct ieee80211_key *); 160 void athn_usb_set_key_cb(struct athn_usb_softc *, void *); 161 void athn_usb_delete_key(struct ieee80211com *, 162 struct ieee80211_node *, struct ieee80211_key *); 163 void athn_usb_delete_key_cb(struct athn_usb_softc *, void *); 164 void athn_usb_bcneof(usbd_xfer_handle, usbd_private_handle, 165 usbd_status); 166 void athn_usb_swba(struct athn_usb_softc *); 167 void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, int); 168 void athn_usb_intr(usbd_xfer_handle, usbd_private_handle, 169 usbd_status); 170 void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *, 171 struct ar_rx_status *); 172 void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *); 173 void athn_usb_rxeof(usbd_xfer_handle, usbd_private_handle, 174 usbd_status); 175 void athn_usb_txeof(usbd_xfer_handle, usbd_private_handle, 176 usbd_status); 177 int athn_usb_tx(struct athn_softc *, struct mbuf *, 178 struct ieee80211_node *); 179 void athn_usb_start(struct ifnet *); 180 void athn_usb_watchdog(struct ifnet *); 181 int athn_usb_ioctl(struct ifnet *, u_long, caddr_t); 182 int athn_usb_init(struct ifnet *); 183 void athn_usb_stop(struct ifnet *); 184 void ar9271_load_ani(struct athn_softc *); 185 186 /* Shortcut. */ 187 #define athn_usb_wmi_cmd(sc, cmd_id) \ 188 athn_usb_wmi_xcmd(sc, cmd_id, NULL, 0, NULL) 189 190 /* Extern functions. */ 191 void athn_led_init(struct athn_softc *); 192 void athn_set_led(struct athn_softc *, int); 193 void athn_btcoex_init(struct athn_softc *); 194 void athn_set_rxfilter(struct athn_softc *, uint32_t); 195 int athn_reset(struct athn_softc *, int); 196 void athn_init_pll(struct athn_softc *, 197 const struct ieee80211_channel *); 198 int athn_set_power_awake(struct athn_softc *); 199 void athn_set_power_sleep(struct athn_softc *); 200 void athn_reset_key(struct athn_softc *, int); 201 int athn_set_key(struct ieee80211com *, struct ieee80211_node *, 202 struct ieee80211_key *); 203 void athn_delete_key(struct ieee80211com *, struct ieee80211_node *, 204 struct ieee80211_key *); 205 void athn_rx_start(struct athn_softc *); 206 void athn_set_sta_timers(struct athn_softc *); 207 void athn_set_hostap_timers(struct athn_softc *); 208 void athn_set_opmode(struct athn_softc *); 209 void athn_set_bss(struct athn_softc *, struct ieee80211_node *); 210 int athn_hw_reset(struct athn_softc *, struct ieee80211_channel *, 211 struct ieee80211_channel *, int); 212 void athn_updateedca(struct ieee80211com *); 213 void athn_updateslot(struct ieee80211com *); 214 215 const struct cfattach athn_usb_ca = { 216 sizeof(struct athn_usb_softc), 217 athn_usb_match, 218 athn_usb_attach, 219 athn_usb_detach, 220 athn_usb_activate 221 }; 222 223 int 224 athn_usb_match(struct device *parent, void *match, void *aux) 225 { 226 struct usb_attach_arg *uaa = aux; 227 228 if (uaa->iface != NULL) 229 return (UMATCH_NONE); 230 231 return ((athn_usb_lookup(uaa->vendor, uaa->product) != NULL) ? 232 UMATCH_VENDOR_PRODUCT : UMATCH_NONE); 233 } 234 235 void 236 athn_usb_attach(struct device *parent, struct device *self, void *aux) 237 { 238 struct athn_usb_softc *usc = (struct athn_usb_softc *)self; 239 struct athn_softc *sc = &usc->sc_sc; 240 struct usb_attach_arg *uaa = aux; 241 int error; 242 243 usc->sc_udev = uaa->device; 244 245 usc->flags = athn_usb_lookup(uaa->vendor, uaa->product)->flags; 246 sc->flags |= ATHN_FLAG_USB; 247 #ifdef notyet 248 /* Check if it is a combo WiFi+Bluetooth (WB193) device. */ 249 if (strncmp(product, "wb193", 5) == 0) 250 sc->flags |= ATHN_FLAG_BTCOEX3WIRE; 251 #endif 252 253 sc->ops.read = athn_usb_read; 254 sc->ops.write = athn_usb_write; 255 sc->ops.write_barrier = athn_usb_write_barrier; 256 257 usb_init_task(&usc->sc_task, athn_usb_task, sc, USB_TASK_TYPE_GENERIC); 258 259 if (usbd_set_config_no(usc->sc_udev, 1, 0) != 0) { 260 printf("%s: could not set configuration no\n", 261 sc->sc_dev.dv_xname); 262 return; 263 } 264 265 /* Get the first interface handle. */ 266 error = usbd_device2interface_handle(usc->sc_udev, 0, &usc->sc_iface); 267 if (error != 0) { 268 printf("%s: could not get interface handle\n", 269 sc->sc_dev.dv_xname); 270 return; 271 } 272 273 if (athn_usb_open_pipes(usc) != 0) 274 return; 275 276 /* Allocate xfer for firmware commands. */ 277 if (athn_usb_alloc_tx_cmd(usc) != 0) 278 return; 279 280 if (rootvp == NULL) 281 mountroothook_establish(athn_usb_attachhook, usc); 282 else 283 athn_usb_attachhook(usc); 284 } 285 286 int 287 athn_usb_detach(struct device *self, int flags) 288 { 289 struct athn_usb_softc *usc = (struct athn_usb_softc *)self; 290 struct athn_softc *sc = &usc->sc_sc; 291 292 athn_detach(sc); 293 294 /* Wait for all async commands to complete. */ 295 athn_usb_wait_async(usc); 296 297 /* Abort and close Tx/Rx pipes. */ 298 athn_usb_close_pipes(usc); 299 300 /* Free Tx/Rx buffers. */ 301 athn_usb_free_tx_cmd(usc); 302 athn_usb_free_tx_list(usc); 303 athn_usb_free_rx_list(usc); 304 305 return (0); 306 } 307 308 int 309 athn_usb_activate(struct device *self, int act) 310 { 311 struct athn_usb_softc *usc = (struct athn_usb_softc *)self; 312 313 switch (act) { 314 case DVACT_DEACTIVATE: 315 usbd_deactivate(usc->sc_udev); 316 break; 317 } 318 return (0); 319 } 320 321 void 322 athn_usb_attachhook(void *xsc) 323 { 324 struct athn_usb_softc *usc = xsc; 325 struct athn_softc *sc = &usc->sc_sc; 326 struct athn_ops *ops = &sc->ops; 327 struct ieee80211com *ic = &sc->sc_ic; 328 struct ifnet *ifp = &ic->ic_if; 329 int s, i, error; 330 331 /* Load firmware. */ 332 error = athn_usb_load_firmware(usc); 333 if (error != 0) { 334 printf("%s: could not load firmware\n", sc->sc_dev.dv_xname); 335 return; 336 } 337 338 /* Setup the host transport communication interface. */ 339 error = athn_usb_htc_setup(usc); 340 if (error != 0) 341 return; 342 343 /* We're now ready to attach the bus agnostic driver. */ 344 s = splnet(); 345 error = athn_attach(sc); 346 if (error != 0) { 347 splx(s); 348 return; 349 } 350 /* Override some operations for USB. */ 351 ifp->if_ioctl = athn_usb_ioctl; 352 ifp->if_start = athn_usb_start; 353 ifp->if_watchdog = athn_usb_watchdog; 354 ic->ic_newassoc = athn_usb_newassoc; 355 ic->ic_node_leave = athn_usb_node_leave; 356 ic->ic_updateslot = athn_usb_updateslot; 357 ic->ic_updateedca = athn_usb_updateedca; 358 #ifdef notyet 359 ic->ic_set_key = athn_usb_set_key; 360 ic->ic_delete_key = athn_usb_delete_key; 361 ic->ic_ampdu_tx_start = athn_usb_ampdu_tx_start; 362 ic->ic_ampdu_tx_stop = athn_usb_ampdu_tx_stop; 363 #endif 364 ic->ic_newstate = athn_usb_newstate; 365 ic->ic_media.ifm_change = athn_usb_media_change; 366 367 /* Firmware cannot handle more than 8 STAs. */ 368 if (ic->ic_max_nnodes > AR_USB_MAX_STA) 369 ic->ic_max_nnodes = AR_USB_MAX_STA; 370 371 ops->rx_enable = athn_usb_rx_enable; 372 splx(s); 373 374 /* Reset HW key cache entries. */ 375 for (i = 0; i < sc->kc_entries; i++) 376 athn_reset_key(sc, i); 377 378 ops->enable_antenna_diversity(sc); 379 380 #ifdef ATHN_BT_COEXISTENCE 381 /* Configure bluetooth coexistence for combo chips. */ 382 if (sc->flags & ATHN_FLAG_BTCOEX) 383 athn_btcoex_init(sc); 384 #endif 385 /* Configure LED. */ 386 athn_led_init(sc); 387 } 388 389 int 390 athn_usb_open_pipes(struct athn_usb_softc *usc) 391 { 392 usb_endpoint_descriptor_t *ed; 393 int isize, error; 394 395 error = usbd_open_pipe(usc->sc_iface, AR_PIPE_TX_DATA, 0, 396 &usc->tx_data_pipe); 397 if (error != 0) { 398 printf("%s: could not open Tx bulk pipe\n", 399 usc->usb_dev.dv_xname); 400 goto fail; 401 } 402 403 error = usbd_open_pipe(usc->sc_iface, AR_PIPE_RX_DATA, 0, 404 &usc->rx_data_pipe); 405 if (error != 0) { 406 printf("%s: could not open Rx bulk pipe\n", 407 usc->usb_dev.dv_xname); 408 goto fail; 409 } 410 411 ed = usbd_get_endpoint_descriptor(usc->sc_iface, AR_PIPE_RX_INTR); 412 if (ed == NULL) { 413 printf("%s: could not retrieve Rx intr pipe descriptor\n", 414 usc->usb_dev.dv_xname); 415 goto fail; 416 } 417 isize = UGETW(ed->wMaxPacketSize); 418 if (isize == 0) { 419 printf("%s: invalid Rx intr pipe descriptor\n", 420 usc->usb_dev.dv_xname); 421 goto fail; 422 } 423 usc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT); 424 if (usc->ibuf == NULL) { 425 printf("%s: could not allocate Rx intr buffer\n", 426 usc->usb_dev.dv_xname); 427 goto fail; 428 } 429 error = usbd_open_pipe_intr(usc->sc_iface, AR_PIPE_RX_INTR, 430 USBD_SHORT_XFER_OK, &usc->rx_intr_pipe, usc, usc->ibuf, isize, 431 athn_usb_intr, USBD_DEFAULT_INTERVAL); 432 if (error != 0) { 433 printf("%s: could not open Rx intr pipe\n", 434 usc->usb_dev.dv_xname); 435 goto fail; 436 } 437 438 error = usbd_open_pipe(usc->sc_iface, AR_PIPE_TX_INTR, 0, 439 &usc->tx_intr_pipe); 440 if (error != 0) { 441 printf("%s: could not open Tx intr pipe\n", 442 usc->usb_dev.dv_xname); 443 goto fail; 444 } 445 fail: 446 if (error != 0) 447 athn_usb_close_pipes(usc); 448 return (error); 449 } 450 451 void 452 athn_usb_close_pipes(struct athn_usb_softc *usc) 453 { 454 if (usc->tx_data_pipe != NULL) 455 usbd_close_pipe(usc->tx_data_pipe); 456 if (usc->rx_data_pipe != NULL) 457 usbd_close_pipe(usc->rx_data_pipe); 458 if (usc->tx_intr_pipe != NULL) 459 usbd_close_pipe(usc->tx_intr_pipe); 460 if (usc->rx_intr_pipe != NULL) { 461 usbd_abort_pipe(usc->rx_intr_pipe); 462 usbd_close_pipe(usc->rx_intr_pipe); 463 } 464 if (usc->ibuf != NULL) 465 free(usc->ibuf, M_USBDEV); 466 } 467 468 int 469 athn_usb_alloc_rx_list(struct athn_usb_softc *usc) 470 { 471 struct athn_usb_rx_data *data; 472 int i, error = 0; 473 474 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 475 data = &usc->rx_data[i]; 476 477 data->sc = usc; /* Backpointer for callbacks. */ 478 479 data->xfer = usbd_alloc_xfer(usc->sc_udev); 480 if (data->xfer == NULL) { 481 printf("%s: could not allocate xfer\n", 482 usc->usb_dev.dv_xname); 483 error = ENOMEM; 484 break; 485 } 486 data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_RXBUFSZ); 487 if (data->buf == NULL) { 488 printf("%s: could not allocate xfer buffer\n", 489 usc->usb_dev.dv_xname); 490 error = ENOMEM; 491 break; 492 } 493 } 494 if (error != 0) 495 athn_usb_free_rx_list(usc); 496 return (error); 497 } 498 499 void 500 athn_usb_free_rx_list(struct athn_usb_softc *usc) 501 { 502 int i; 503 504 /* NB: Caller must abort pipe first. */ 505 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 506 if (usc->rx_data[i].xfer != NULL) 507 usbd_free_xfer(usc->rx_data[i].xfer); 508 usc->rx_data[i].xfer = NULL; 509 } 510 } 511 512 int 513 athn_usb_alloc_tx_list(struct athn_usb_softc *usc) 514 { 515 struct athn_usb_tx_data *data; 516 int i, error = 0; 517 518 TAILQ_INIT(&usc->tx_free_list); 519 for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) { 520 data = &usc->tx_data[i]; 521 522 data->sc = usc; /* Backpointer for callbacks. */ 523 524 data->xfer = usbd_alloc_xfer(usc->sc_udev); 525 if (data->xfer == NULL) { 526 printf("%s: could not allocate xfer\n", 527 usc->usb_dev.dv_xname); 528 error = ENOMEM; 529 break; 530 } 531 data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXBUFSZ); 532 if (data->buf == NULL) { 533 printf("%s: could not allocate xfer buffer\n", 534 usc->usb_dev.dv_xname); 535 error = ENOMEM; 536 break; 537 } 538 /* Append this Tx buffer to our free list. */ 539 TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next); 540 } 541 if (error != 0) 542 athn_usb_free_tx_list(usc); 543 return (error); 544 } 545 546 void 547 athn_usb_free_tx_list(struct athn_usb_softc *usc) 548 { 549 int i; 550 551 /* NB: Caller must abort pipe first. */ 552 for (i = 0; i < ATHN_USB_TX_LIST_COUNT; i++) { 553 if (usc->tx_data[i].xfer != NULL) 554 usbd_free_xfer(usc->tx_data[i].xfer); 555 usc->tx_data[i].xfer = NULL; 556 } 557 } 558 559 int 560 athn_usb_alloc_tx_cmd(struct athn_usb_softc *usc) 561 { 562 struct athn_usb_tx_data *data = &usc->tx_cmd; 563 564 data->sc = usc; /* Backpointer for callbacks. */ 565 566 data->xfer = usbd_alloc_xfer(usc->sc_udev); 567 if (data->xfer == NULL) { 568 printf("%s: could not allocate xfer\n", 569 usc->usb_dev.dv_xname); 570 return (ENOMEM); 571 } 572 data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXCMDSZ); 573 if (data->buf == NULL) { 574 printf("%s: could not allocate xfer buffer\n", 575 usc->usb_dev.dv_xname); 576 return (ENOMEM); 577 } 578 return (0); 579 } 580 581 void 582 athn_usb_free_tx_cmd(struct athn_usb_softc *usc) 583 { 584 if (usc->tx_cmd.xfer != NULL) 585 usbd_free_xfer(usc->tx_cmd.xfer); 586 usc->tx_cmd.xfer = NULL; 587 } 588 589 void 590 athn_usb_task(void *arg) 591 { 592 struct athn_usb_softc *usc = arg; 593 struct athn_usb_host_cmd_ring *ring = &usc->cmdq; 594 struct athn_usb_host_cmd *cmd; 595 int s; 596 597 /* Process host commands. */ 598 s = splusb(); 599 while (ring->next != ring->cur) { 600 cmd = &ring->cmd[ring->next]; 601 splx(s); 602 /* Invoke callback. */ 603 cmd->cb(usc, cmd->data); 604 s = splusb(); 605 ring->queued--; 606 ring->next = (ring->next + 1) % ATHN_USB_HOST_CMD_RING_COUNT; 607 } 608 wakeup(ring); 609 splx(s); 610 } 611 612 void 613 athn_usb_do_async(struct athn_usb_softc *usc, 614 void (*cb)(struct athn_usb_softc *, void *), void *arg, int len) 615 { 616 struct athn_usb_host_cmd_ring *ring = &usc->cmdq; 617 struct athn_usb_host_cmd *cmd; 618 int s; 619 620 if (ring->queued) 621 return; /* XXX */ 622 s = splusb(); 623 cmd = &ring->cmd[ring->cur]; 624 cmd->cb = cb; 625 KASSERT(len <= sizeof(cmd->data)); 626 memcpy(cmd->data, arg, len); 627 ring->cur = (ring->cur + 1) % ATHN_USB_HOST_CMD_RING_COUNT; 628 629 /* If there is no pending command already, schedule a task. */ 630 if (++ring->queued == 1) 631 usb_add_task(usc->sc_udev, &usc->sc_task); 632 splx(s); 633 } 634 635 void 636 athn_usb_wait_async(struct athn_usb_softc *usc) 637 { 638 /* Wait for all queued asynchronous commands to complete. */ 639 while (usc->cmdq.queued > 0) 640 tsleep(&usc->cmdq, 0, "cmdq", 0); 641 } 642 643 int 644 athn_usb_load_firmware(struct athn_usb_softc *usc) 645 { 646 usb_device_descriptor_t *dd; 647 usb_device_request_t req; 648 const char *name; 649 u_char *fw, *ptr; 650 size_t size; 651 uint32_t addr; 652 int s, mlen, error; 653 654 /* Determine which firmware image to load. */ 655 if (usc->flags & ATHN_USB_FLAG_AR7010) { 656 dd = usbd_get_device_descriptor(usc->sc_udev); 657 if (UGETW(dd->bcdDevice) == 0x0202) 658 name = "athn-ar7010-11"; 659 else 660 name = "athn-ar7010"; 661 } else 662 name = "athn-ar9271"; 663 /* Read firmware image from the filesystem. */ 664 if ((error = loadfirmware(name, &fw, &size)) != 0) { 665 printf("%s: failed loadfirmware of file %s (error %d)\n", 666 usc->usb_dev.dv_xname, name, error); 667 return (error); 668 } 669 /* Load firmware image. */ 670 ptr = fw; 671 addr = AR9271_FIRMWARE >> 8; 672 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 673 req.bRequest = AR_FW_DOWNLOAD; 674 USETW(req.wIndex, 0); 675 while (size > 0) { 676 mlen = MIN(size, 4096); 677 678 USETW(req.wValue, addr); 679 USETW(req.wLength, mlen); 680 error = usbd_do_request(usc->sc_udev, &req, ptr); 681 if (error != 0) { 682 free(fw, M_DEVBUF); 683 return (error); 684 } 685 addr += mlen >> 8; 686 ptr += mlen; 687 size -= mlen; 688 } 689 free(fw, M_DEVBUF); 690 691 /* Start firmware. */ 692 if (usc->flags & ATHN_USB_FLAG_AR7010) 693 addr = AR7010_FIRMWARE_TEXT >> 8; 694 else 695 addr = AR9271_FIRMWARE_TEXT >> 8; 696 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 697 req.bRequest = AR_FW_DOWNLOAD_COMP; 698 USETW(req.wIndex, 0); 699 USETW(req.wValue, addr); 700 USETW(req.wLength, 0); 701 s = splusb(); 702 usc->wait_msg_id = AR_HTC_MSG_READY; 703 error = usbd_do_request(usc->sc_udev, &req, NULL); 704 /* Wait at most 1 second for firmware to boot. */ 705 if (error == 0 && usc->wait_msg_id != 0) 706 error = tsleep(&usc->wait_msg_id, 0, "athnfw", hz); 707 usc->wait_msg_id = 0; 708 splx(s); 709 return (error); 710 } 711 712 int 713 athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, 714 int len) 715 { 716 struct athn_usb_tx_data *data = &usc->tx_cmd; 717 struct ar_htc_frame_hdr *htc; 718 struct ar_htc_msg_hdr *msg; 719 720 htc = (struct ar_htc_frame_hdr *)data->buf; 721 memset(htc, 0, sizeof(*htc)); 722 htc->endpoint_id = 0; 723 htc->payload_len = htobe16(sizeof(*msg) + len); 724 725 msg = (struct ar_htc_msg_hdr *)&htc[1]; 726 msg->msg_id = htobe16(msg_id); 727 728 memcpy(&msg[1], buf, len); 729 730 usbd_setup_xfer(data->xfer, usc->tx_intr_pipe, NULL, data->buf, 731 sizeof(*htc) + sizeof(*msg) + len, 732 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT, NULL); 733 return (usbd_sync_transfer(data->xfer)); 734 } 735 736 int 737 athn_usb_htc_setup(struct athn_usb_softc *usc) 738 { 739 struct ar_htc_msg_config_pipe cfg; 740 int s, error; 741 742 /* 743 * Connect WMI services to USB pipes. 744 */ 745 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CONTROL, 746 AR_PIPE_TX_INTR, AR_PIPE_RX_INTR, &usc->ep_ctrl); 747 if (error != 0) 748 return (error); 749 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_BEACON, 750 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_bcn); 751 if (error != 0) 752 return (error); 753 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CAB, 754 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_cab); 755 if (error != 0) 756 return (error); 757 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_UAPSD, 758 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_uapsd); 759 if (error != 0) 760 return (error); 761 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_MGMT, 762 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_mgmt); 763 if (error != 0) 764 return (error); 765 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BE, 766 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_BE]); 767 if (error != 0) 768 return (error); 769 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BK, 770 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_BK]); 771 if (error != 0) 772 return (error); 773 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VI, 774 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_VI]); 775 if (error != 0) 776 return (error); 777 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VO, 778 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->ep_data[EDCA_AC_VO]); 779 if (error != 0) 780 return (error); 781 782 /* Set credits for WLAN Tx pipe. */ 783 memset(&cfg, 0, sizeof(cfg)); 784 cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA); 785 cfg.credits = (usc->flags & ATHN_USB_FLAG_AR7010) ? 45 : 33; 786 s = splusb(); 787 usc->wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP; 788 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg)); 789 if (error == 0 && usc->wait_msg_id != 0) 790 error = tsleep(&usc->wait_msg_id, 0, "athnhtc", hz); 791 usc->wait_msg_id = 0; 792 splx(s); 793 if (error != 0) { 794 printf("%s: could not configure pipe\n", 795 usc->usb_dev.dv_xname); 796 return (error); 797 } 798 799 error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0); 800 if (error != 0) { 801 printf("%s: could not complete setup\n", 802 usc->usb_dev.dv_xname); 803 return (error); 804 } 805 return (0); 806 } 807 808 int 809 athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, 810 uint8_t ul_pipe, uint8_t dl_pipe, uint8_t *endpoint_id) 811 { 812 struct ar_htc_msg_conn_svc msg; 813 struct ar_htc_msg_conn_svc_rsp rsp; 814 int s, error; 815 816 memset(&msg, 0, sizeof(msg)); 817 msg.svc_id = htobe16(svc_id); 818 msg.dl_pipeid = UE_GET_ADDR(dl_pipe); 819 msg.ul_pipeid = UE_GET_ADDR(ul_pipe); 820 s = splusb(); 821 usc->msg_conn_svc_rsp = &rsp; 822 usc->wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP; 823 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg)); 824 /* Wait at most 1 second for response. */ 825 if (error == 0 && usc->wait_msg_id != 0) 826 error = tsleep(&usc->wait_msg_id, 0, "athnhtc", hz); 827 usc->wait_msg_id = 0; 828 splx(s); 829 if (error != 0) { 830 printf("%s: error waiting for service %d connection\n", 831 usc->usb_dev.dv_xname, svc_id); 832 return (error); 833 } 834 if (rsp.status != AR_HTC_SVC_SUCCESS) { 835 printf("%s: service %d connection failed, error %d\n", 836 usc->usb_dev.dv_xname, svc_id, rsp.status); 837 return (EIO); 838 } 839 DPRINTF(("service %d successfully connected to endpoint %d\n", 840 svc_id, rsp.endpoint_id)); 841 842 /* Return endpoint id. */ 843 *endpoint_id = rsp.endpoint_id; 844 return (0); 845 } 846 847 void 848 athn_usb_wmieof(usbd_xfer_handle xfer, usbd_private_handle priv, 849 usbd_status status) 850 { 851 struct athn_usb_softc *usc = priv; 852 853 if (__predict_false(status == USBD_STALLED)) 854 usbd_clear_endpoint_stall_async(usc->tx_intr_pipe); 855 856 usc->wmi_done = 1; 857 wakeup(&usc->wmi_done); 858 } 859 860 int 861 athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, 862 int ilen, void *obuf) 863 { 864 struct athn_usb_tx_data *data = &usc->tx_cmd; 865 struct ar_htc_frame_hdr *htc; 866 struct ar_wmi_cmd_hdr *wmi; 867 int s, error; 868 869 htc = (struct ar_htc_frame_hdr *)data->buf; 870 memset(htc, 0, sizeof(*htc)); 871 htc->endpoint_id = usc->ep_ctrl; 872 htc->payload_len = htobe16(sizeof(*wmi) + ilen); 873 874 wmi = (struct ar_wmi_cmd_hdr *)&htc[1]; 875 wmi->cmd_id = htobe16(cmd_id); 876 usc->wmi_seq_no++; 877 wmi->seq_no = htobe16(usc->wmi_seq_no); 878 879 memcpy(&wmi[1], ibuf, ilen); 880 881 usbd_setup_xfer(data->xfer, usc->tx_intr_pipe, usc, data->buf, 882 sizeof(*htc) + sizeof(*wmi) + ilen, 883 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT, 884 athn_usb_wmieof); 885 s = splusb(); 886 usc->wmi_done = 0; 887 error = usbd_transfer(data->xfer); 888 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) { 889 splx(s); 890 return (error); 891 } 892 usc->obuf = obuf; 893 usc->wait_cmd_id = cmd_id; 894 /* Wait for WMI command to complete. */ 895 error = tsleep(&usc->wait_cmd_id, 0, "athnwmi", hz); 896 usc->wait_cmd_id = 0; 897 /* Most of the time this would have complete already. */ 898 while (__predict_false(!usc->wmi_done)) 899 tsleep(&usc->wmi_done, 0, "athnwmi", 0); 900 splx(s); 901 return (error); 902 } 903 904 int 905 athn_usb_read_rom(struct athn_softc *sc) 906 { 907 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 908 uint32_t addrs[8], vals[8], addr; 909 uint16_t *eep; 910 int i, j, error; 911 912 /* Read EEPROM by blocks of 16 bytes. */ 913 eep = sc->eep; 914 addr = AR_EEPROM_OFFSET(sc->eep_base); 915 for (i = 0; i < sc->eep_size / 16; i++) { 916 for (j = 0; j < 8; j++, addr += 4) 917 addrs[j] = htobe32(addr); 918 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, 919 addrs, sizeof(addrs), vals); 920 if (error != 0) 921 break; 922 for (j = 0; j < 8; j++) 923 *eep++ = betoh32(vals[j]); 924 } 925 return (error); 926 } 927 928 uint32_t 929 athn_usb_read(struct athn_softc *sc, uint32_t addr) 930 { 931 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 932 uint32_t val; 933 int error; 934 935 /* Flush pending writes for strict consistency. */ 936 athn_usb_write_barrier(sc); 937 938 addr = htobe32(addr); 939 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, 940 &addr, sizeof(addr), &val); 941 if (error != 0) 942 return (0xdeadbeef); 943 return (betoh32(val)); 944 } 945 946 void 947 athn_usb_write(struct athn_softc *sc, uint32_t addr, uint32_t val) 948 { 949 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 950 951 usc->wbuf[usc->wcount].addr = htobe32(addr); 952 usc->wbuf[usc->wcount].val = htobe32(val); 953 if (++usc->wcount == AR_MAX_WRITE_COUNT) 954 athn_usb_write_barrier(sc); 955 } 956 957 void 958 athn_usb_write_barrier(struct athn_softc *sc) 959 { 960 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 961 962 if (usc->wcount == 0) 963 return; /* Nothing to write. */ 964 965 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_WRITE, 966 usc->wbuf, usc->wcount * sizeof(usc->wbuf[0]), NULL); 967 usc->wcount = 0; /* Always flush buffer. */ 968 } 969 970 int 971 athn_usb_media_change(struct ifnet *ifp) 972 { 973 int error; 974 975 error = ieee80211_media_change(ifp); 976 if (error != ENETRESET) 977 return (error); 978 979 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 980 (IFF_UP | IFF_RUNNING)) { 981 athn_usb_stop(ifp); 982 error = athn_usb_init(ifp); 983 } 984 return (error); 985 } 986 987 int 988 athn_usb_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, 989 int arg) 990 { 991 struct athn_usb_softc *usc = ic->ic_softc; 992 struct athn_usb_cmd_newstate cmd; 993 994 /* Do it in a process context. */ 995 cmd.state = nstate; 996 cmd.arg = arg; 997 athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd)); 998 return (0); 999 } 1000 1001 void 1002 athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg) 1003 { 1004 struct athn_usb_cmd_newstate *cmd = arg; 1005 struct athn_softc *sc = &usc->sc_sc; 1006 struct ieee80211com *ic = &sc->sc_ic; 1007 enum ieee80211_state ostate; 1008 uint32_t reg, imask; 1009 uint8_t sta_index; 1010 int s, error; 1011 1012 timeout_del(&sc->calib_to); 1013 1014 s = splnet(); 1015 ostate = ic->ic_state; 1016 DPRINTF(("newstate %d -> %d\n", ostate, cmd->state)); 1017 1018 if (ostate == IEEE80211_S_RUN) { 1019 sta_index = ((struct athn_node *)ic->ic_bss)->sta_index; 1020 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, 1021 &sta_index, sizeof(sta_index), NULL); 1022 } 1023 switch (cmd->state) { 1024 case IEEE80211_S_INIT: 1025 athn_set_led(sc, 0); 1026 break; 1027 case IEEE80211_S_SCAN: 1028 /* Make the LED blink while scanning. */ 1029 athn_set_led(sc, !sc->led_state); 1030 (void)athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL); 1031 timeout_add_msec(&sc->scan_to, 200); 1032 break; 1033 case IEEE80211_S_AUTH: 1034 athn_set_led(sc, 0); 1035 error = athn_usb_switch_chan(sc, ic->ic_bss->ni_chan, NULL); 1036 break; 1037 case IEEE80211_S_ASSOC: 1038 break; 1039 case IEEE80211_S_RUN: 1040 athn_set_led(sc, 1); 1041 1042 if (ic->ic_opmode == IEEE80211_M_MONITOR) 1043 break; 1044 1045 /* Create node entry for our BSS. */ 1046 error = athn_usb_create_node(usc, ic->ic_bss); 1047 1048 athn_set_bss(sc, ic->ic_bss); 1049 athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 1050 #ifndef IEEE80211_STA_ONLY 1051 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1052 athn_set_hostap_timers(sc); 1053 /* Enable sotfware beacon alert interrupts. */ 1054 imask = htobe32(AR_IMR_SWBA); 1055 } else 1056 #endif 1057 { 1058 athn_set_sta_timers(sc); 1059 /* Enable beacon miss interrupts. */ 1060 imask = htobe32(AR_IMR_BMISS); 1061 1062 /* Stop receiving beacons from other BSS. */ 1063 reg = AR_READ(sc, AR_RX_FILTER); 1064 reg = (reg & ~AR_RX_FILTER_BEACON) | 1065 AR_RX_FILTER_MYBEACON; 1066 AR_WRITE(sc, AR_RX_FILTER, reg); 1067 AR_WRITE_BARRIER(sc); 1068 } 1069 athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR, 1070 &imask, sizeof(imask), NULL); 1071 break; 1072 } 1073 (void)sc->sc_newstate(ic, cmd->state, cmd->arg); 1074 splx(s); 1075 } 1076 1077 void 1078 athn_usb_newassoc(struct ieee80211com *ic, struct ieee80211_node *ni, 1079 int isnew) 1080 { 1081 struct athn_usb_softc *usc = ic->ic_softc; 1082 1083 if (ic->ic_opmode != IEEE80211_M_HOSTAP || !isnew) 1084 return; 1085 /* Do it in a process context. */ 1086 ieee80211_ref_node(ni); 1087 athn_usb_do_async(usc, athn_usb_newassoc_cb, &ni, sizeof(ni)); 1088 } 1089 1090 void 1091 athn_usb_newassoc_cb(struct athn_usb_softc *usc, void *arg) 1092 { 1093 struct ieee80211com *ic = &usc->sc_sc.sc_ic; 1094 struct ieee80211_node *ni = *(void **)arg; 1095 int s; 1096 1097 s = splnet(); 1098 /* NB: Node may have left before we got scheduled. */ 1099 if (ni->ni_associd != 0) 1100 (void)athn_usb_create_node(usc, ni); 1101 ieee80211_release_node(ic, ni); 1102 splx(s); 1103 } 1104 1105 void 1106 athn_usb_node_leave(struct ieee80211com *ic, struct ieee80211_node *ni) 1107 { 1108 struct athn_usb_softc *usc = ic->ic_softc; 1109 uint8_t sta_index; 1110 1111 /* Do it in a process context. */ 1112 sta_index = ((struct athn_node *)ni)->sta_index; 1113 athn_usb_do_async(usc, athn_usb_newassoc_cb, 1114 &sta_index, sizeof(sta_index)); 1115 } 1116 1117 void 1118 athn_usb_node_leave_cb(struct athn_usb_softc *usc, void *arg) 1119 { 1120 uint8_t sta_index = *(uint8_t *)arg; 1121 1122 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, 1123 &sta_index, sizeof(sta_index), NULL); 1124 } 1125 1126 int 1127 athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 1128 uint8_t tid) 1129 { 1130 struct athn_usb_softc *usc = ic->ic_softc; 1131 struct athn_node *an = (struct athn_node *)ni; 1132 struct athn_usb_aggr_cmd cmd; 1133 1134 /* Do it in a process context. */ 1135 cmd.sta_index = an->sta_index; 1136 cmd.tid = tid; 1137 athn_usb_do_async(usc, athn_usb_ampdu_tx_start_cb, &cmd, sizeof(cmd)); 1138 return (0); 1139 } 1140 1141 void 1142 athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *usc, void *arg) 1143 { 1144 struct athn_usb_aggr_cmd *cmd = arg; 1145 struct ar_htc_target_aggr aggr; 1146 1147 memset(&aggr, 0, sizeof(aggr)); 1148 aggr.sta_index = cmd->sta_index; 1149 aggr.tidno = cmd->tid; 1150 aggr.aggr_enable = 1; 1151 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, 1152 &aggr, sizeof(aggr), NULL); 1153 } 1154 1155 void 1156 athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, 1157 uint8_t tid) 1158 { 1159 struct athn_usb_softc *usc = ic->ic_softc; 1160 struct athn_node *an = (struct athn_node *)ni; 1161 struct athn_usb_aggr_cmd cmd; 1162 1163 /* Do it in a process context. */ 1164 cmd.sta_index = an->sta_index; 1165 cmd.tid = tid; 1166 athn_usb_do_async(usc, athn_usb_ampdu_tx_stop_cb, &cmd, sizeof(cmd)); 1167 } 1168 1169 void 1170 athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *usc, void *arg) 1171 { 1172 struct athn_usb_aggr_cmd *cmd = arg; 1173 struct ar_htc_target_aggr aggr; 1174 1175 memset(&aggr, 0, sizeof(aggr)); 1176 aggr.sta_index = cmd->sta_index; 1177 aggr.tidno = cmd->tid; 1178 aggr.aggr_enable = 0; 1179 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, 1180 &aggr, sizeof(aggr), NULL); 1181 } 1182 1183 int 1184 athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni) 1185 { 1186 struct athn_node *an = (struct athn_node *)ni; 1187 struct ar_htc_target_sta sta; 1188 struct ar_htc_target_rate rate; 1189 int error; 1190 1191 an->sta_index = IEEE80211_AID(ni->ni_associd); 1192 1193 /* Create node entry on target. */ 1194 memset(&sta, 0, sizeof(sta)); 1195 IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr); 1196 IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid); 1197 sta.associd = htobe16(ni->ni_associd); 1198 sta.valid = 1; 1199 sta.sta_index = an->sta_index; 1200 sta.maxampdu = 0xffff; 1201 if (ni->ni_flags & IEEE80211_NODE_HT) 1202 sta.flags |= htobe16(AR_HTC_STA_HT); 1203 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE, 1204 &sta, sizeof(sta), NULL); 1205 if (error != 0) 1206 return (error); 1207 1208 /* Setup supported rates. */ 1209 memset(&rate, 0, sizeof(rate)); 1210 rate.sta_index = sta.sta_index; 1211 rate.isnew = 1; 1212 rate.lg_rates.rs_nrates = ni->ni_rates.rs_nrates; 1213 memcpy(rate.lg_rates.rs_rates, ni->ni_rates.rs_rates, 1214 ni->ni_rates.rs_nrates); 1215 if (ni->ni_flags & IEEE80211_NODE_HT) { 1216 rate.capflags |= htobe32(AR_RC_HT_FLAG); 1217 #ifdef notyet 1218 /* XXX setup HT rates */ 1219 if (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) 1220 rate.capflags |= htobe32(AR_RC_40_FLAG); 1221 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI40) 1222 rate.capflags |= htobe32(AR_RC_SGI_FLAG); 1223 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20) 1224 rate.capflags |= htobe32(AR_RC_SGI_FLAG); 1225 #endif 1226 } 1227 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_RC_RATE_UPDATE, 1228 &rate, sizeof(rate), NULL); 1229 return (error); 1230 } 1231 1232 void 1233 athn_usb_rx_enable(struct athn_softc *sc) 1234 { 1235 AR_WRITE(sc, AR_CR, AR_CR_RXE); 1236 AR_WRITE_BARRIER(sc); 1237 } 1238 1239 int 1240 athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *c, 1241 struct ieee80211_channel *extc) 1242 { 1243 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 1244 uint16_t mode; 1245 int error; 1246 1247 /* Disable interrupts. */ 1248 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 1249 if (error != 0) 1250 goto reset; 1251 /* Stop all Tx queues. */ 1252 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); 1253 if (error != 0) 1254 goto reset; 1255 /* Stop Rx. */ 1256 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); 1257 if (error != 0) 1258 goto reset; 1259 1260 /* If band or bandwidth changes, we need to do a full reset. */ 1261 if (c->ic_flags != sc->curchan->ic_flags || 1262 ((extc != NULL) ^ (sc->curchanext != NULL))) { 1263 DPRINTFN(2, ("channel band switch\n")); 1264 goto reset; 1265 } 1266 1267 error = athn_set_chan(sc, c, extc); 1268 if (AR_SREV_9271(sc) && error == 0) 1269 ar9271_load_ani(sc); 1270 if (error != 0) { 1271 reset: /* Error found, try a full reset. */ 1272 DPRINTFN(3, ("needs a full reset\n")); 1273 error = athn_hw_reset(sc, c, extc, 0); 1274 if (error != 0) /* Hopeless case. */ 1275 return (error); 1276 } 1277 1278 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); 1279 if (error != 0) 1280 return (error); 1281 athn_rx_start(sc); 1282 1283 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ? 1284 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); 1285 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, 1286 &mode, sizeof(mode), NULL); 1287 if (error != 0) 1288 return (error); 1289 1290 /* Re-enable interrupts. */ 1291 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ENABLE_INTR); 1292 return (error); 1293 } 1294 1295 void 1296 athn_usb_updateedca(struct ieee80211com *ic) 1297 { 1298 struct athn_usb_softc *usc = ic->ic_softc; 1299 1300 /* Do it in a process context. */ 1301 athn_usb_do_async(usc, athn_usb_updateedca_cb, NULL, 0); 1302 } 1303 1304 void 1305 athn_usb_updateedca_cb(struct athn_usb_softc *usc, void *arg) 1306 { 1307 int s; 1308 1309 s = splnet(); 1310 athn_updateedca(&usc->sc_sc.sc_ic); 1311 splx(s); 1312 } 1313 1314 void 1315 athn_usb_updateslot(struct ieee80211com *ic) 1316 { 1317 struct athn_usb_softc *usc = ic->ic_softc; 1318 1319 return; /* XXX */ 1320 /* Do it in a process context. */ 1321 athn_usb_do_async(usc, athn_usb_updateslot_cb, NULL, 0); 1322 } 1323 1324 void 1325 athn_usb_updateslot_cb(struct athn_usb_softc *usc, void *arg) 1326 { 1327 int s; 1328 1329 s = splnet(); 1330 athn_updateslot(&usc->sc_sc.sc_ic); 1331 splx(s); 1332 } 1333 1334 int 1335 athn_usb_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 1336 struct ieee80211_key *k) 1337 { 1338 struct athn_usb_softc *usc = ic->ic_softc; 1339 struct athn_usb_cmd_key cmd; 1340 1341 /* Defer setting of WEP keys until interface is brought up. */ 1342 if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) != 1343 (IFF_UP | IFF_RUNNING)) 1344 return (0); 1345 1346 /* Do it in a process context. */ 1347 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; 1348 cmd.key = k; 1349 athn_usb_do_async(usc, athn_usb_set_key_cb, &cmd, sizeof(cmd)); 1350 return (0); 1351 } 1352 1353 void 1354 athn_usb_set_key_cb(struct athn_usb_softc *usc, void *arg) 1355 { 1356 struct ieee80211com *ic = &usc->sc_sc.sc_ic; 1357 struct athn_usb_cmd_key *cmd = arg; 1358 int s; 1359 1360 s = splnet(); 1361 athn_set_key(ic, cmd->ni, cmd->key); 1362 if (cmd->ni != NULL) 1363 ieee80211_release_node(ic, cmd->ni); 1364 splx(s); 1365 } 1366 1367 void 1368 athn_usb_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 1369 struct ieee80211_key *k) 1370 { 1371 struct athn_usb_softc *usc = ic->ic_softc; 1372 struct athn_usb_cmd_key cmd; 1373 1374 if (!(ic->ic_if.if_flags & IFF_RUNNING) || 1375 ic->ic_state != IEEE80211_S_RUN) 1376 return; /* Nothing to do. */ 1377 1378 /* Do it in a process context. */ 1379 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; 1380 cmd.key = k; 1381 athn_usb_do_async(usc, athn_usb_delete_key_cb, &cmd, sizeof(cmd)); 1382 } 1383 1384 void 1385 athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg) 1386 { 1387 struct ieee80211com *ic = &usc->sc_sc.sc_ic; 1388 struct athn_usb_cmd_key *cmd = arg; 1389 int s; 1390 1391 s = splnet(); 1392 athn_delete_key(ic, cmd->ni, cmd->key); 1393 if (cmd->ni != NULL) 1394 ieee80211_release_node(ic, cmd->ni); 1395 splx(s); 1396 } 1397 1398 #ifndef IEEE80211_STA_ONLY 1399 void 1400 athn_usb_bcneof(usbd_xfer_handle xfer, usbd_private_handle priv, 1401 usbd_status status) 1402 { 1403 struct athn_usb_tx_data *data = priv; 1404 struct athn_usb_softc *usc = data->sc; 1405 1406 if (__predict_false(status == USBD_STALLED)) 1407 usbd_clear_endpoint_stall_async(usc->tx_data_pipe); 1408 usc->tx_bcn = data; 1409 } 1410 1411 /* 1412 * Process Software Beacon Alert interrupts. 1413 */ 1414 void 1415 athn_usb_swba(struct athn_usb_softc *usc) 1416 { 1417 struct athn_softc *sc = &usc->sc_sc; 1418 struct ieee80211com *ic = &sc->sc_ic; 1419 struct athn_usb_tx_data *data; 1420 struct ieee80211_frame *wh; 1421 struct ar_stream_hdr *hdr; 1422 struct ar_htc_frame_hdr *htc; 1423 struct ar_tx_bcn *bcn; 1424 struct mbuf *m; 1425 int error; 1426 1427 if (ic->ic_dtim_count == 0) 1428 ic->ic_dtim_count = ic->ic_dtim_period - 1; 1429 else 1430 ic->ic_dtim_count--; 1431 1432 /* Make sure previous beacon has been sent. */ 1433 if (usc->tx_bcn == NULL) 1434 return; 1435 data = usc->tx_bcn; 1436 1437 /* Get new beacon. */ 1438 m = ieee80211_beacon_alloc(ic, ic->ic_bss); 1439 if (__predict_false(m == NULL)) 1440 return; 1441 /* Assign sequence number. */ 1442 wh = mtod(m, struct ieee80211_frame *); 1443 *(uint16_t *)&wh->i_seq[0] = 1444 htole16(ic->ic_bss->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); 1445 ic->ic_bss->ni_txseq++; 1446 1447 hdr = (struct ar_stream_hdr *)data->buf; 1448 hdr->tag = htole16(AR_USB_TX_STREAM_TAG); 1449 hdr->len = htole16(sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len); 1450 1451 htc = (struct ar_htc_frame_hdr *)&hdr[1]; 1452 memset(htc, 0, sizeof(*htc)); 1453 htc->endpoint_id = usc->ep_bcn; 1454 htc->payload_len = htobe16(sizeof(*bcn) + m->m_pkthdr.len); 1455 1456 bcn = (struct ar_tx_bcn *)&htc[1]; 1457 memset(bcn, 0, sizeof(*bcn)); 1458 bcn->vif_idx = 0; 1459 1460 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&bcn[1]); 1461 1462 usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf, 1463 sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len, 1464 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, 1465 athn_usb_bcneof); 1466 1467 m_freem(m); 1468 usc->tx_bcn = NULL; 1469 error = usbd_transfer(data->xfer); 1470 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) 1471 usc->tx_bcn = data; 1472 } 1473 #endif 1474 1475 void 1476 athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, int len) 1477 { 1478 struct ar_wmi_cmd_hdr *wmi; 1479 struct ar_wmi_evt_txrate *txrate; 1480 uint16_t cmd_id; 1481 1482 if (__predict_false(len < sizeof(*wmi))) 1483 return; 1484 wmi = (struct ar_wmi_cmd_hdr *)buf; 1485 cmd_id = betoh16(wmi->cmd_id); 1486 1487 if (!(cmd_id & AR_WMI_EVT_FLAG)) { 1488 if (usc->wait_cmd_id != cmd_id) 1489 return; /* Unexpected reply. */ 1490 if (usc->obuf != NULL) { 1491 /* Copy answer into caller supplied buffer. */ 1492 memcpy(usc->obuf, &wmi[1], len - sizeof(*wmi)); 1493 } 1494 /* Notify caller of completion. */ 1495 usc->wait_cmd_id = 0; 1496 wakeup(&usc->wait_cmd_id); 1497 return; 1498 } 1499 switch (cmd_id & 0xfff) { 1500 #ifndef IEEE80211_STA_ONLY 1501 case AR_WMI_EVT_SWBA: 1502 athn_usb_swba(usc); 1503 break; 1504 #endif 1505 case AR_WMI_EVT_TXRATE: 1506 txrate = (struct ar_wmi_evt_txrate *)&wmi[1]; 1507 DPRINTF(("txrate=%d\n", betoh32(txrate->txrate))); 1508 break; 1509 case AR_WMI_EVT_FATAL: 1510 printf("%s: fatal firmware error\n", usc->usb_dev.dv_xname); 1511 break; 1512 default: 1513 DPRINTF(("WMI event %d ignored\n", cmd_id)); 1514 break; 1515 } 1516 } 1517 1518 void 1519 athn_usb_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 1520 usbd_status status) 1521 { 1522 struct athn_usb_softc *usc = priv; 1523 struct ar_htc_frame_hdr *htc; 1524 struct ar_htc_msg_hdr *msg; 1525 uint8_t *buf = usc->ibuf; 1526 uint16_t msg_id; 1527 int len; 1528 1529 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1530 DPRINTF(("intr status=%d\n", status)); 1531 if (status == USBD_STALLED) 1532 usbd_clear_endpoint_stall_async(usc->rx_intr_pipe); 1533 return; 1534 } 1535 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1536 1537 /* Skip watchdog pattern if present. */ 1538 if (len >= 4 && *(uint32_t *)buf == htobe32(0x00c60000)) { 1539 buf += 4; 1540 len -= 4; 1541 } 1542 if (__predict_false(len < sizeof(*htc))) 1543 return; 1544 htc = (struct ar_htc_frame_hdr *)buf; 1545 /* Skip HTC header. */ 1546 buf += sizeof(*htc); 1547 len -= sizeof(*htc); 1548 1549 if (htc->endpoint_id != 0) { 1550 if (__predict_false(htc->endpoint_id != usc->ep_ctrl)) 1551 return; 1552 /* Remove trailer if present. */ 1553 if (htc->flags & AR_HTC_FLAG_TRAILER) { 1554 if (__predict_false(len < htc->control[0])) 1555 return; 1556 len -= htc->control[0]; 1557 } 1558 athn_usb_rx_wmi_ctrl(usc, buf, len); 1559 return; 1560 } 1561 /* Endpoint 0 carries HTC messages. */ 1562 if (__predict_false(len < sizeof(*msg))) 1563 return; 1564 msg = (struct ar_htc_msg_hdr *)buf; 1565 msg_id = betoh16(msg->msg_id); 1566 DPRINTF(("Rx HTC message %d\n", msg_id)); 1567 switch (msg_id) { 1568 case AR_HTC_MSG_READY: 1569 if (usc->wait_msg_id != msg_id) 1570 break; 1571 usc->wait_msg_id = 0; 1572 wakeup(&usc->wait_msg_id); 1573 break; 1574 case AR_HTC_MSG_CONN_SVC_RSP: 1575 if (usc->wait_msg_id != msg_id) 1576 break; 1577 if (usc->msg_conn_svc_rsp != NULL) { 1578 memcpy(usc->msg_conn_svc_rsp, &msg[1], 1579 sizeof(struct ar_htc_msg_conn_svc_rsp)); 1580 } 1581 usc->wait_msg_id = 0; 1582 wakeup(&usc->wait_msg_id); 1583 break; 1584 case AR_HTC_MSG_CONF_PIPE_RSP: 1585 if (usc->wait_msg_id != msg_id) 1586 break; 1587 usc->wait_msg_id = 0; 1588 wakeup(&usc->wait_msg_id); 1589 break; 1590 default: 1591 DPRINTF(("HTC message %d ignored\n", msg_id)); 1592 break; 1593 } 1594 } 1595 1596 #if NBPFILTER > 0 1597 void 1598 athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m, 1599 struct ar_rx_status *rs) 1600 { 1601 #define IEEE80211_RADIOTAP_F_SHORTGI 0x80 /* XXX from FBSD */ 1602 1603 struct athn_rx_radiotap_header *tap = &sc->sc_rxtap; 1604 struct ieee80211com *ic = &sc->sc_ic; 1605 struct mbuf mb; 1606 uint8_t rate; 1607 1608 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; 1609 tap->wr_tsft = htole64(betoh64(rs->rs_tstamp)); 1610 tap->wr_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 1611 tap->wr_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 1612 tap->wr_dbm_antsignal = rs->rs_rssi; 1613 /* XXX noise. */ 1614 tap->wr_antenna = rs->rs_antenna; 1615 tap->wr_rate = 0; /* In case it can't be found below. */ 1616 rate = rs->rs_rate; 1617 if (rate & 0x80) { /* HT. */ 1618 /* Bit 7 set means HT MCS instead of rate. */ 1619 tap->wr_rate = rate; 1620 if (!(rs->rs_flags & AR_RXS_FLAG_GI)) 1621 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; 1622 1623 } else if (rate & 0x10) { /* CCK. */ 1624 if (rate & 0x04) 1625 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1626 switch (rate & ~0x14) { 1627 case 0xb: tap->wr_rate = 2; break; 1628 case 0xa: tap->wr_rate = 4; break; 1629 case 0x9: tap->wr_rate = 11; break; 1630 case 0x8: tap->wr_rate = 22; break; 1631 } 1632 } else { /* OFDM. */ 1633 switch (rate) { 1634 case 0xb: tap->wr_rate = 12; break; 1635 case 0xf: tap->wr_rate = 18; break; 1636 case 0xa: tap->wr_rate = 24; break; 1637 case 0xe: tap->wr_rate = 36; break; 1638 case 0x9: tap->wr_rate = 48; break; 1639 case 0xd: tap->wr_rate = 72; break; 1640 case 0x8: tap->wr_rate = 96; break; 1641 case 0xc: tap->wr_rate = 108; break; 1642 } 1643 } 1644 mb.m_data = (caddr_t)tap; 1645 mb.m_len = sc->sc_rxtap_len; 1646 mb.m_next = m; 1647 mb.m_nextpkt = NULL; 1648 mb.m_type = 0; 1649 mb.m_flags = 0; 1650 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN); 1651 } 1652 #endif 1653 1654 void 1655 athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m) 1656 { 1657 struct athn_softc *sc = &usc->sc_sc; 1658 struct ieee80211com *ic = &sc->sc_ic; 1659 struct ifnet *ifp = &ic->ic_if; 1660 struct ieee80211_frame *wh; 1661 struct ieee80211_node *ni; 1662 struct ieee80211_rxinfo rxi; 1663 struct ar_htc_frame_hdr *htc; 1664 struct ar_rx_status *rs; 1665 uint16_t datalen; 1666 1667 if (__predict_false(m->m_len < sizeof(*htc))) 1668 goto skip; 1669 htc = mtod(m, struct ar_htc_frame_hdr *); 1670 if (__predict_false(htc->endpoint_id == 0)) { 1671 DPRINTF(("bad endpoint %d\n", htc->endpoint_id)); 1672 goto skip; 1673 } 1674 if (htc->flags & AR_HTC_FLAG_TRAILER) { 1675 if (m->m_len < htc->control[0]) 1676 goto skip; 1677 m_adj(m, -(int)htc->control[0]); 1678 } 1679 m_adj(m, sizeof(*htc)); /* Strip HTC header. */ 1680 1681 if (__predict_false(m->m_len < sizeof(*rs))) 1682 goto skip; 1683 rs = mtod(m, struct ar_rx_status *); 1684 1685 /* Make sure that payload fits. */ 1686 datalen = betoh16(rs->rs_datalen); 1687 if (__predict_false(m->m_len < sizeof(*rs) + datalen)) 1688 goto skip; 1689 1690 if (__predict_false(datalen < sizeof(*wh) + IEEE80211_CRC_LEN)) 1691 goto skip; 1692 1693 m_adj(m, sizeof(*rs)); /* Strip Rx status. */ 1694 m->m_pkthdr.rcvif = ifp; 1695 1696 /* Grab a reference to the source node. */ 1697 wh = mtod(m, struct ieee80211_frame *); 1698 ni = ieee80211_find_rxnode(ic, wh); 1699 1700 /* Remove any HW padding after the 802.11 header. */ 1701 if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) { 1702 u_int hdrlen = ieee80211_get_hdrlen(wh); 1703 if (hdrlen & 3) { 1704 ovbcopy(wh, (caddr_t)wh + 2, hdrlen); 1705 m_adj(m, 2); 1706 } 1707 } 1708 #if NBPFILTER > 0 1709 if (__predict_false(sc->sc_drvbpf != NULL)) 1710 athn_usb_rx_radiotap(sc, m, rs); 1711 #endif 1712 /* Trim 802.11 FCS after radiotap. */ 1713 m_adj(m, -IEEE80211_CRC_LEN); 1714 1715 /* Send the frame to the 802.11 layer. */ 1716 rxi.rxi_flags = 0; 1717 rxi.rxi_rssi = rs->rs_rssi + AR_USB_DEFAULT_NF; 1718 rxi.rxi_tstamp = betoh64(rs->rs_tstamp); 1719 ieee80211_input(ifp, m, ni, &rxi); 1720 1721 /* Node is no longer needed. */ 1722 ieee80211_release_node(ic, ni); 1723 return; 1724 skip: 1725 m_freem(m); 1726 } 1727 1728 void 1729 athn_usb_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, 1730 usbd_status status) 1731 { 1732 struct athn_usb_rx_data *data = priv; 1733 struct athn_usb_softc *usc = data->sc; 1734 struct athn_usb_rx_stream *stream = &usc->rx_stream; 1735 uint8_t *buf = data->buf; 1736 struct ar_stream_hdr *hdr; 1737 struct mbuf *m; 1738 uint16_t pktlen; 1739 int off, len; 1740 1741 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1742 DPRINTF(("RX status=%d\n", status)); 1743 if (status == USBD_STALLED) 1744 usbd_clear_endpoint_stall_async(usc->rx_data_pipe); 1745 if (status != USBD_CANCELLED) 1746 goto resubmit; 1747 return; 1748 } 1749 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1750 1751 if (stream->left > 0) { 1752 if (len >= stream->left) { 1753 /* We have all our pktlen bytes now. */ 1754 if (__predict_true(stream->m != NULL)) { 1755 memcpy(mtod(stream->m, uint8_t *) + 1756 stream->moff, buf, stream->left); 1757 athn_usb_rx_frame(usc, stream->m); 1758 stream->m = NULL; 1759 } 1760 /* Next header is 32-bit aligned. */ 1761 off = (stream->left + 3) & ~3; 1762 buf += off; 1763 len -= off; 1764 stream->left = 0; 1765 } else { 1766 /* Still need more bytes, save what we have. */ 1767 if (__predict_true(stream->m != NULL)) { 1768 memcpy(mtod(stream->m, uint8_t *) + 1769 stream->moff, buf, len); 1770 stream->moff += len; 1771 } 1772 stream->left -= len; 1773 goto resubmit; 1774 } 1775 } 1776 KASSERT(stream->left == 0); 1777 while (len >= sizeof(*hdr)) { 1778 hdr = (struct ar_stream_hdr *)buf; 1779 if (hdr->tag != htole16(AR_USB_RX_STREAM_TAG)) { 1780 DPRINTF(("invalid tag 0x%x\n", hdr->tag)); 1781 break; 1782 } 1783 pktlen = letoh16(hdr->len); 1784 buf += sizeof(*hdr); 1785 len -= sizeof(*hdr); 1786 1787 if (__predict_true(pktlen <= MCLBYTES)) { 1788 /* Allocate an mbuf to store the next pktlen bytes. */ 1789 MGETHDR(m, M_DONTWAIT, MT_DATA); 1790 if (__predict_true(m != NULL)) { 1791 m->m_pkthdr.len = m->m_len = pktlen; 1792 if (pktlen > MHLEN) { 1793 MCLGET(m, M_DONTWAIT); 1794 if (!(m->m_flags & M_EXT)) { 1795 m_free(m); 1796 m = NULL; 1797 } 1798 } 1799 } 1800 } else /* Drop frames larger than MCLBYTES. */ 1801 m = NULL; 1802 /* 1803 * NB: m can be NULL, in which case the next pktlen bytes 1804 * will be discarded from the Rx stream. 1805 */ 1806 if (pktlen > len) { 1807 /* Need more bytes, save what we have. */ 1808 stream->m = m; /* NB: m can be NULL. */ 1809 if (__predict_true(stream->m != NULL)) { 1810 memcpy(mtod(stream->m, uint8_t *), buf, len); 1811 stream->moff = len; 1812 } 1813 stream->left = pktlen - len; 1814 goto resubmit; 1815 } 1816 if (__predict_true(m != NULL)) { 1817 /* We have all the pktlen bytes in this xfer. */ 1818 memcpy(mtod(m, uint8_t *), buf, pktlen); 1819 athn_usb_rx_frame(usc, m); 1820 } 1821 1822 /* Next header is 32-bit aligned. */ 1823 off = (pktlen + 3) & ~3; 1824 buf += off; 1825 len -= off; 1826 } 1827 1828 resubmit: 1829 /* Setup a new transfer. */ 1830 usbd_setup_xfer(xfer, usc->rx_data_pipe, data, data->buf, 1831 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 1832 USBD_NO_TIMEOUT, athn_usb_rxeof); 1833 (void)usbd_transfer(xfer); 1834 } 1835 1836 void 1837 athn_usb_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 1838 usbd_status status) 1839 { 1840 struct athn_usb_tx_data *data = priv; 1841 struct athn_usb_softc *usc = data->sc; 1842 struct athn_softc *sc = &usc->sc_sc; 1843 struct ifnet *ifp = &sc->sc_ic.ic_if; 1844 int s; 1845 1846 s = splnet(); 1847 /* Put this Tx buffer back to our free list. */ 1848 TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next); 1849 1850 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1851 DPRINTF(("TX status=%d\n", status)); 1852 if (status == USBD_STALLED) 1853 usbd_clear_endpoint_stall_async(usc->tx_data_pipe); 1854 ifp->if_oerrors++; 1855 splx(s); 1856 /* XXX Why return? */ 1857 return; 1858 } 1859 sc->sc_tx_timer = 0; 1860 ifp->if_opackets++; 1861 1862 /* We just released a Tx buffer, notify Tx. */ 1863 if (ifp->if_flags & IFF_OACTIVE) { 1864 ifp->if_flags &= ~IFF_OACTIVE; 1865 ifp->if_start(ifp); 1866 } 1867 splx(s); 1868 } 1869 1870 int 1871 athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 1872 { 1873 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 1874 struct athn_node *an = (struct athn_node *)ni; 1875 struct ieee80211com *ic = &sc->sc_ic; 1876 struct ieee80211_frame *wh; 1877 struct ieee80211_key *k = NULL; 1878 struct athn_usb_tx_data *data; 1879 struct ar_stream_hdr *hdr; 1880 struct ar_htc_frame_hdr *htc; 1881 struct ar_tx_frame *txf; 1882 struct ar_tx_mgmt *txm; 1883 uint8_t *frm; 1884 uint16_t qos; 1885 uint8_t sta_index, qid, tid = 0; 1886 int hasqos, xferlen, error; 1887 1888 wh = mtod(m, struct ieee80211_frame *); 1889 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1890 k = ieee80211_get_txkey(ic, wh, ni); 1891 if ((m = ieee80211_encrypt(ic, m, k)) == NULL) 1892 return (ENOBUFS); 1893 wh = mtod(m, struct ieee80211_frame *); 1894 } 1895 if ((hasqos = ieee80211_has_qos(wh))) { 1896 qos = ieee80211_get_qos(wh); 1897 tid = qos & IEEE80211_QOS_TID; 1898 qid = ieee80211_up_to_ac(ic, tid); 1899 } else 1900 qid = EDCA_AC_BE; 1901 1902 /* Grab a Tx buffer from our free list. */ 1903 data = TAILQ_FIRST(&usc->tx_free_list); 1904 TAILQ_REMOVE(&usc->tx_free_list, data, next); 1905 1906 #if NBPFILTER > 0 1907 /* XXX Change radiotap Tx header for USB (no txrate). */ 1908 if (__predict_false(sc->sc_drvbpf != NULL)) { 1909 struct athn_tx_radiotap_header *tap = &sc->sc_txtap; 1910 struct mbuf mb; 1911 1912 tap->wt_flags = 0; 1913 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq); 1914 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags); 1915 mb.m_data = (caddr_t)tap; 1916 mb.m_len = sc->sc_txtap_len; 1917 mb.m_next = m; 1918 mb.m_nextpkt = NULL; 1919 mb.m_type = 0; 1920 mb.m_flags = 0; 1921 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT); 1922 } 1923 #endif 1924 sta_index = an->sta_index; 1925 1926 /* NB: We don't take advantage of USB Tx stream mode for now. */ 1927 hdr = (struct ar_stream_hdr *)data->buf; 1928 hdr->tag = htole16(AR_USB_TX_STREAM_TAG); 1929 1930 htc = (struct ar_htc_frame_hdr *)&hdr[1]; 1931 memset(htc, 0, sizeof(*htc)); 1932 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 1933 IEEE80211_FC0_TYPE_DATA) { 1934 htc->endpoint_id = usc->ep_data[qid]; 1935 1936 txf = (struct ar_tx_frame *)&htc[1]; 1937 memset(txf, 0, sizeof(*txf)); 1938 txf->data_type = AR_HTC_NORMAL; 1939 txf->node_idx = sta_index; 1940 txf->vif_idx = 0; 1941 txf->tid = tid; 1942 if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) 1943 txf->flags |= htobe32(AR_HTC_TX_RTSCTS); 1944 else if (ic->ic_flags & IEEE80211_F_USEPROT) { 1945 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 1946 txf->flags |= htobe32(AR_HTC_TX_CTSONLY); 1947 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 1948 txf->flags |= htobe32(AR_HTC_TX_RTSCTS); 1949 } 1950 txf->key_idx = 0xff; 1951 frm = (uint8_t *)&txf[1]; 1952 } else { 1953 htc->endpoint_id = usc->ep_mgmt; 1954 1955 txm = (struct ar_tx_mgmt *)&htc[1]; 1956 memset(txm, 0, sizeof(*txm)); 1957 txm->node_idx = sta_index; 1958 txm->vif_idx = 0; 1959 txm->key_idx = 0xff; 1960 frm = (uint8_t *)&txm[1]; 1961 } 1962 /* Copy payload. */ 1963 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)frm); 1964 frm += m->m_pkthdr.len; 1965 m_freem(m); 1966 1967 /* Finalize headers. */ 1968 htc->payload_len = htobe16(frm - (uint8_t *)&htc[1]); 1969 hdr->len = htole16(frm - (uint8_t *)&hdr[1]); 1970 xferlen = frm - data->buf; 1971 1972 usbd_setup_xfer(data->xfer, usc->tx_data_pipe, data, data->buf, 1973 xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, 1974 athn_usb_txeof); 1975 error = usbd_transfer(data->xfer); 1976 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) { 1977 /* Put this Tx buffer back to our free list. */ 1978 TAILQ_INSERT_TAIL(&usc->tx_free_list, data, next); 1979 return (error); 1980 } 1981 ieee80211_release_node(ic, ni); 1982 return (0); 1983 } 1984 1985 void 1986 athn_usb_start(struct ifnet *ifp) 1987 { 1988 struct athn_softc *sc = ifp->if_softc; 1989 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 1990 struct ieee80211com *ic = &sc->sc_ic; 1991 struct ieee80211_node *ni; 1992 struct mbuf *m; 1993 1994 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1995 return; 1996 1997 for (;;) { 1998 if (TAILQ_EMPTY(&usc->tx_free_list)) { 1999 ifp->if_flags |= IFF_OACTIVE; 2000 break; 2001 } 2002 /* Send pending management frames first. */ 2003 IF_DEQUEUE(&ic->ic_mgtq, m); 2004 if (m != NULL) { 2005 ni = (void *)m->m_pkthdr.rcvif; 2006 goto sendit; 2007 } 2008 if (ic->ic_state != IEEE80211_S_RUN) 2009 break; 2010 2011 /* Encapsulate and send data frames. */ 2012 IFQ_DEQUEUE(&ifp->if_snd, m); 2013 if (m == NULL) 2014 break; 2015 #if NBPFILTER > 0 2016 if (ifp->if_bpf != NULL) 2017 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 2018 #endif 2019 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL) 2020 continue; 2021 sendit: 2022 #if NBPFILTER > 0 2023 if (ic->ic_rawbpf != NULL) 2024 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT); 2025 #endif 2026 if (athn_usb_tx(sc, m, ni) != 0) { 2027 ieee80211_release_node(ic, ni); 2028 ifp->if_oerrors++; 2029 continue; 2030 } 2031 2032 sc->sc_tx_timer = 5; 2033 ifp->if_timer = 1; 2034 } 2035 } 2036 2037 void 2038 athn_usb_watchdog(struct ifnet *ifp) 2039 { 2040 struct athn_softc *sc = ifp->if_softc; 2041 2042 ifp->if_timer = 0; 2043 2044 if (sc->sc_tx_timer > 0) { 2045 if (--sc->sc_tx_timer == 0) { 2046 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 2047 /* athn_usb_init(ifp); XXX needs a process context! */ 2048 ifp->if_oerrors++; 2049 return; 2050 } 2051 ifp->if_timer = 1; 2052 } 2053 ieee80211_watchdog(ifp); 2054 } 2055 2056 int 2057 athn_usb_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 2058 { 2059 struct athn_softc *sc = ifp->if_softc; 2060 struct ieee80211com *ic = &sc->sc_ic; 2061 struct ifaddr *ifa; 2062 struct ifreq *ifr; 2063 int s, error = 0; 2064 2065 s = splnet(); 2066 2067 switch (cmd) { 2068 case SIOCSIFADDR: 2069 ifa = (struct ifaddr *)data; 2070 ifp->if_flags |= IFF_UP; 2071 #ifdef INET 2072 if (ifa->ifa_addr->sa_family == AF_INET) 2073 arp_ifinit(&ic->ic_ac, ifa); 2074 #endif 2075 /* FALLTHROUGH */ 2076 case SIOCSIFFLAGS: 2077 if (ifp->if_flags & IFF_UP) { 2078 if (!(ifp->if_flags & IFF_RUNNING)) 2079 error = athn_usb_init(ifp); 2080 } else { 2081 if (ifp->if_flags & IFF_RUNNING) 2082 athn_usb_stop(ifp); 2083 } 2084 break; 2085 case SIOCADDMULTI: 2086 case SIOCDELMULTI: 2087 ifr = (struct ifreq *)data; 2088 error = (cmd == SIOCADDMULTI) ? 2089 ether_addmulti(ifr, &ic->ic_ac) : 2090 ether_delmulti(ifr, &ic->ic_ac); 2091 if (error == ENETRESET) 2092 error = 0; 2093 break; 2094 case SIOCS80211CHANNEL: 2095 error = ieee80211_ioctl(ifp, cmd, data); 2096 if (error == ENETRESET && 2097 ic->ic_opmode == IEEE80211_M_MONITOR) { 2098 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 2099 (IFF_UP | IFF_RUNNING)) { 2100 athn_usb_switch_chan(sc, ic->ic_ibss_chan, 2101 NULL); 2102 } 2103 error = 0; 2104 } 2105 break; 2106 default: 2107 error = ieee80211_ioctl(ifp, cmd, data); 2108 } 2109 2110 if (error == ENETRESET) { 2111 error = 0; 2112 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 2113 (IFF_UP | IFF_RUNNING)) { 2114 athn_usb_stop(ifp); 2115 error = athn_usb_init(ifp); 2116 } 2117 } 2118 splx(s); 2119 return (error); 2120 } 2121 2122 int 2123 athn_usb_init(struct ifnet *ifp) 2124 { 2125 struct athn_softc *sc = ifp->if_softc; 2126 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 2127 struct athn_ops *ops = &sc->ops; 2128 struct ieee80211com *ic = &sc->sc_ic; 2129 struct ieee80211_channel *c, *extc; 2130 struct athn_usb_rx_data *data; 2131 struct ar_htc_target_vif hvif; 2132 struct ar_htc_target_sta sta; 2133 struct ar_htc_cap_target hic; 2134 uint16_t mode; 2135 int i, error; 2136 2137 /* Init host async commands ring. */ 2138 usc->cmdq.cur = usc->cmdq.next = usc->cmdq.queued = 0; 2139 2140 /* Allocate Tx/Rx buffers. */ 2141 error = athn_usb_alloc_rx_list(usc); 2142 if (error != 0) 2143 goto fail; 2144 error = athn_usb_alloc_tx_list(usc); 2145 if (error != 0) 2146 goto fail; 2147 /* Steal one buffer for beacons. */ 2148 usc->tx_bcn = TAILQ_FIRST(&usc->tx_free_list); 2149 TAILQ_REMOVE(&usc->tx_free_list, usc->tx_bcn, next); 2150 2151 c = ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2152 extc = NULL; 2153 2154 /* In case a new MAC address has been configured. */ 2155 IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl)); 2156 2157 error = athn_set_power_awake(sc); 2158 if (error != 0) 2159 goto fail; 2160 2161 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_FLUSH_RECV); 2162 if (error != 0) 2163 goto fail; 2164 2165 error = athn_hw_reset(sc, c, extc, 1); 2166 if (error != 0) 2167 goto fail; 2168 2169 ops->set_txpower(sc, c, extc); 2170 2171 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(c) ? 2172 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); 2173 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, 2174 &mode, sizeof(mode), NULL); 2175 if (error != 0) 2176 goto fail; 2177 2178 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ATH_INIT); 2179 if (error != 0) 2180 goto fail; 2181 2182 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); 2183 if (error != 0) 2184 goto fail; 2185 2186 athn_rx_start(sc); 2187 2188 /* Create main interface on target. */ 2189 memset(&hvif, 0, sizeof(hvif)); 2190 hvif.index = 0; 2191 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); 2192 switch (ic->ic_opmode) { 2193 case IEEE80211_M_STA: 2194 hvif.opmode = htobe32(AR_HTC_M_STA); 2195 break; 2196 case IEEE80211_M_MONITOR: 2197 hvif.opmode = htobe32(AR_HTC_M_MONITOR); 2198 break; 2199 #ifndef IEEE80211_STA_ONLY 2200 case IEEE80211_M_IBSS: 2201 hvif.opmode = htobe32(AR_HTC_M_IBSS); 2202 break; 2203 case IEEE80211_M_AHDEMO: 2204 hvif.opmode = htobe32(AR_HTC_M_AHDEMO); 2205 break; 2206 case IEEE80211_M_HOSTAP: 2207 hvif.opmode = htobe32(AR_HTC_M_HOSTAP); 2208 break; 2209 #endif 2210 } 2211 hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold); 2212 DPRINTF(("creating VAP\n")); 2213 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE, 2214 &hvif, sizeof(hvif), NULL); 2215 if (error != 0) 2216 goto fail; 2217 2218 /* Create a fake node to send management frames before assoc. */ 2219 memset(&sta, 0, sizeof(sta)); 2220 IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_myaddr); 2221 sta.sta_index = 0; 2222 sta.is_vif_sta = 1; 2223 sta.vif_index = hvif.index; 2224 sta.maxampdu = 0xffff; 2225 DPRINTF(("creating default node\n")); 2226 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE, 2227 &sta, sizeof(sta), NULL); 2228 if (error != 0) 2229 goto fail; 2230 2231 /* Update target capabilities. */ 2232 memset(&hic, 0, sizeof(hic)); 2233 hic.flags = htobe32(0x400c2400); 2234 hic.flags_ext = htobe32(0x00106080); 2235 hic.ampdu_limit = htobe32(0x0000ffff); 2236 hic.ampdu_subframes = 20; 2237 hic.protmode = 1; /* XXX */ 2238 hic.lg_txchainmask = sc->txchainmask; 2239 hic.ht_txchainmask = sc->txchainmask; 2240 DPRINTF(("updating target configuration\n")); 2241 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE, 2242 &hic, sizeof(hic), NULL); 2243 if (error != 0) 2244 goto fail; 2245 2246 /* Queue Rx xfers. */ 2247 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 2248 data = &usc->rx_data[i]; 2249 2250 usbd_setup_xfer(data->xfer, usc->rx_data_pipe, data, data->buf, 2251 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 2252 USBD_NO_TIMEOUT, athn_usb_rxeof); 2253 error = usbd_transfer(data->xfer); 2254 if (error != 0 && error != USBD_IN_PROGRESS) 2255 goto fail; 2256 } 2257 /* We're ready to go. */ 2258 ifp->if_flags &= ~IFF_OACTIVE; 2259 ifp->if_flags |= IFF_RUNNING; 2260 2261 #ifdef notyet 2262 if (ic->ic_flags & IEEE80211_F_WEPON) { 2263 /* Install WEP keys. */ 2264 for (i = 0; i < IEEE80211_WEP_NKID; i++) 2265 athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]); 2266 } 2267 #endif 2268 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2269 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2270 else 2271 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2272 athn_usb_wait_async(usc); 2273 return (0); 2274 fail: 2275 athn_usb_stop(ifp); 2276 return (error); 2277 } 2278 2279 void 2280 athn_usb_stop(struct ifnet *ifp) 2281 { 2282 struct athn_softc *sc = ifp->if_softc; 2283 struct athn_usb_softc *usc = (struct athn_usb_softc *)sc; 2284 struct ieee80211com *ic = &sc->sc_ic; 2285 struct ar_htc_target_vif hvif; 2286 uint8_t sta_index; 2287 int s; 2288 2289 sc->sc_tx_timer = 0; 2290 ifp->if_timer = 0; 2291 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2292 2293 s = splusb(); 2294 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2295 2296 /* Wait for all async commands to complete. */ 2297 athn_usb_wait_async(usc); 2298 2299 timeout_del(&sc->scan_to); 2300 timeout_del(&sc->calib_to); 2301 2302 /* Remove main interface. */ 2303 memset(&hvif, 0, sizeof(hvif)); 2304 hvif.index = 0; 2305 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); 2306 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE, 2307 &hvif, sizeof(hvif), NULL); 2308 /* Remove default node. */ 2309 sta_index = 0; 2310 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, 2311 &sta_index, sizeof(sta_index), NULL); 2312 2313 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 2314 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); 2315 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); 2316 2317 athn_reset(sc, 0); 2318 athn_init_pll(sc, NULL); 2319 athn_set_power_awake(sc); 2320 athn_reset(sc, 1); 2321 athn_init_pll(sc, NULL); 2322 athn_set_power_sleep(sc); 2323 2324 /* Abort Tx/Rx. */ 2325 usbd_abort_pipe(usc->tx_data_pipe); 2326 usbd_abort_pipe(usc->rx_data_pipe); 2327 2328 /* Free Tx/Rx buffers. */ 2329 athn_usb_free_tx_list(usc); 2330 athn_usb_free_rx_list(usc); 2331 splx(s); 2332 2333 /* Flush Rx stream. */ 2334 if (usc->rx_stream.m != NULL) 2335 m_freem(usc->rx_stream.m); 2336 usc->rx_stream.m = NULL; 2337 usc->rx_stream.left = 0; 2338 } 2339