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