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