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