1 /* $NetBSD: if_athn_usb.c,v 1.6 2013/10/16 18:23:39 christos 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.6 2013/10/16 18:23:39 christos 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; 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, 0); 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 while (size > 0) { 845 mlen = MIN(size, 4096); 846 847 USETW(req.wValue, addr); 848 USETW(req.wLength, mlen); 849 error = usbd_do_request(usc->usc_udev, &req, ptr); 850 if (error != 0) { 851 free(fw, M_DEVBUF); 852 return error; 853 } 854 addr += mlen >> 8; 855 ptr += mlen; 856 size -= mlen; 857 } 858 free(fw, M_DEVBUF); 859 860 /* Start firmware. */ 861 if (usc->usc_flags & ATHN_USB_FLAG_AR7010) 862 addr = AR7010_FIRMWARE_TEXT >> 8; 863 else 864 addr = AR9271_FIRMWARE_TEXT >> 8; 865 req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 866 req.bRequest = AR_FW_DOWNLOAD_COMP; 867 USETW(req.wIndex, 0); 868 USETW(req.wValue, addr); 869 USETW(req.wLength, 0); 870 871 s = splusb(); 872 usc->usc_wait_msg_id = AR_HTC_MSG_READY; 873 error = usbd_do_request(usc->usc_udev, &req, NULL); 874 /* Wait at most 1 second for firmware to boot. */ 875 if (error == 0 && usc->usc_wait_msg_id != 0) 876 error = tsleep(&usc->usc_wait_msg_id, 0, "athnfw", hz); 877 usc->usc_wait_msg_id = 0; 878 splx(s); 879 return error; 880 } 881 882 Static int 883 athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, 884 int len) 885 { 886 struct athn_usb_tx_data *data = &usc->usc_tx_cmd; 887 struct ar_htc_frame_hdr *htc; 888 struct ar_htc_msg_hdr *msg; 889 890 if (usc->usc_dying) 891 return USBD_CANCELLED; 892 893 DPRINTFN(DBG_FN, usc, "\n"); 894 895 htc = (struct ar_htc_frame_hdr *)data->buf; 896 memset(htc, 0, sizeof(*htc)); 897 htc->endpoint_id = 0; 898 htc->payload_len = htobe16(sizeof(*msg) + len); 899 900 msg = (struct ar_htc_msg_hdr *)&htc[1]; 901 msg->msg_id = htobe16(msg_id); 902 903 memcpy(&msg[1], buf, len); 904 905 usbd_setup_xfer(data->xfer, usc->usc_tx_intr_pipe, NULL, data->buf, 906 sizeof(*htc) + sizeof(*msg) + len, 907 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT, NULL); 908 return usbd_sync_transfer(data->xfer); 909 } 910 911 Static int 912 athn_usb_htc_setup(struct athn_usb_softc *usc) 913 { 914 struct ar_htc_msg_config_pipe cfg; 915 int s, error; 916 917 /* 918 * Connect WMI services to USB pipes. 919 */ 920 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CONTROL, 921 AR_PIPE_TX_INTR, AR_PIPE_RX_INTR, &usc->usc_ep_ctrl); 922 if (error != 0) 923 return error; 924 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_BEACON, 925 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_bcn); 926 if (error != 0) 927 return error; 928 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_CAB, 929 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_cab); 930 if (error != 0) 931 return error; 932 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_UAPSD, 933 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_uapsd); 934 if (error != 0) 935 return error; 936 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_MGMT, 937 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_mgmt); 938 if (error != 0) 939 return error; 940 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BE, 941 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_BE]); 942 if (error != 0) 943 return error; 944 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_BK, 945 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_BK]); 946 if (error != 0) 947 return error; 948 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VI, 949 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_VI]); 950 if (error != 0) 951 return error; 952 error = athn_usb_htc_connect_svc(usc, AR_SVC_WMI_DATA_VO, 953 AR_PIPE_TX_DATA, AR_PIPE_RX_DATA, &usc->usc_ep_data[WME_AC_VO]); 954 if (error != 0) 955 return error; 956 957 /* Set credits for WLAN Tx pipe. */ 958 memset(&cfg, 0, sizeof(cfg)); 959 cfg.pipe_id = UE_GET_ADDR(AR_PIPE_TX_DATA); 960 cfg.credits = (usc->usc_flags & ATHN_USB_FLAG_AR7010) ? 45 : 33; 961 962 s = splusb(); 963 964 usc->usc_wait_msg_id = AR_HTC_MSG_CONF_PIPE_RSP; 965 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONF_PIPE, &cfg, sizeof(cfg)); 966 if (error == 0 && usc->usc_wait_msg_id != 0) 967 error = tsleep(&usc->usc_wait_msg_id, 0, "athnhtc", hz); 968 usc->usc_wait_msg_id = 0; 969 970 splx(s); 971 972 if (error != 0) { 973 aprint_error_dev(usc->usc_dev, "could not configure pipe\n"); 974 return error; 975 } 976 977 error = athn_usb_htc_msg(usc, AR_HTC_MSG_SETUP_COMPLETE, NULL, 0); 978 if (error != 0) { 979 aprint_error_dev(usc->usc_dev, "could not complete setup\n"); 980 return error; 981 } 982 return 0; 983 } 984 985 Static int 986 athn_usb_htc_connect_svc(struct athn_usb_softc *usc, uint16_t svc_id, 987 uint8_t ul_pipe, uint8_t dl_pipe, uint8_t *endpoint_id) 988 { 989 struct ar_htc_msg_conn_svc msg; 990 struct ar_htc_msg_conn_svc_rsp rsp; 991 int s, error; 992 993 DPRINTFN(DBG_FN, usc, "\n"); 994 995 memset(&msg, 0, sizeof(msg)); 996 msg.svc_id = htobe16(svc_id); 997 msg.dl_pipeid = UE_GET_ADDR(dl_pipe); 998 msg.ul_pipeid = UE_GET_ADDR(ul_pipe); 999 s = splusb(); 1000 1001 usc->usc_msg_conn_svc_rsp = &rsp; 1002 1003 usc->usc_wait_msg_id = AR_HTC_MSG_CONN_SVC_RSP; 1004 error = athn_usb_htc_msg(usc, AR_HTC_MSG_CONN_SVC, &msg, sizeof(msg)); 1005 if (error == 0 && usc->usc_wait_msg_id != 0) 1006 error = tsleep(&usc->usc_wait_msg_id, 0, "athnhtc", hz); 1007 usc->usc_wait_msg_id = 0; 1008 1009 splx(s); 1010 if (error != 0) { 1011 aprint_error_dev(usc->usc_dev, 1012 "error waiting for service %d connection\n", svc_id); 1013 return error; 1014 } 1015 if (rsp.status != AR_HTC_SVC_SUCCESS) { 1016 aprint_error_dev(usc->usc_dev, 1017 "service %d connection failed, error %d\n", 1018 svc_id, rsp.status); 1019 return EIO; 1020 } 1021 DPRINTFN(DBG_INIT, usc, 1022 "service %d successfully connected to endpoint %d\n", 1023 svc_id, rsp.endpoint_id); 1024 1025 /* Return endpoint id. */ 1026 *endpoint_id = rsp.endpoint_id; 1027 return 0; 1028 } 1029 1030 Static void 1031 athn_usb_wait_msg(struct athn_usb_softc *usc) 1032 { 1033 1034 DPRINTFN(DBG_FN, usc, "\n"); 1035 1036 while (__predict_false(usc->usc_wait_msg_id)) 1037 tsleep(&usc->usc_wait_msg_id, 0, "athnmsg", hz); 1038 } 1039 1040 Static void 1041 athn_usb_wait_cmd(struct athn_usb_softc *usc) 1042 { 1043 1044 DPRINTFN(DBG_FN, usc, "\n"); 1045 1046 while (__predict_false(usc->usc_wait_cmd_id)) 1047 tsleep(&usc->usc_wait_cmd_id, 0, "athncmd", hz); 1048 } 1049 1050 Static void 1051 athn_usb_wmieof(usbd_xfer_handle xfer, usbd_private_handle priv, 1052 usbd_status status) 1053 { 1054 struct athn_usb_softc *usc = priv; 1055 1056 DPRINTFN(DBG_FN, usc, "\n"); 1057 1058 if (__predict_false(status == USBD_STALLED)) 1059 usbd_clear_endpoint_stall_async(usc->usc_tx_intr_pipe); 1060 1061 usc->usc_wmi_done = 1; 1062 wakeup(&usc->usc_wmi_done); 1063 } 1064 1065 Static int 1066 athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, 1067 int ilen, void *obuf) 1068 { 1069 struct athn_usb_tx_data *data = &usc->usc_tx_cmd; 1070 struct ar_htc_frame_hdr *htc; 1071 struct ar_wmi_cmd_hdr *wmi; 1072 int s, error; 1073 1074 if (usc->usc_dying) 1075 return EIO; 1076 1077 DPRINTFN(DBG_FN, usc, "\n"); 1078 1079 htc = (struct ar_htc_frame_hdr *)data->buf; 1080 memset(htc, 0, sizeof(*htc)); 1081 htc->endpoint_id = usc->usc_ep_ctrl; 1082 htc->payload_len = htobe16(sizeof(*wmi) + ilen); 1083 1084 wmi = (struct ar_wmi_cmd_hdr *)&htc[1]; 1085 wmi->cmd_id = htobe16(cmd_id); 1086 usc->usc_wmi_seq_no++; 1087 wmi->seq_no = htobe16(usc->usc_wmi_seq_no); 1088 1089 memcpy(&wmi[1], ibuf, ilen); 1090 1091 usbd_setup_xfer(data->xfer, usc->usc_tx_intr_pipe, usc, data->buf, 1092 sizeof(*htc) + sizeof(*wmi) + ilen, 1093 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT, 1094 athn_usb_wmieof); 1095 1096 s = splusb(); 1097 usc->usc_wmi_done = 0; 1098 usc->usc_wait_cmd_id = cmd_id; 1099 error = usbd_transfer(data->xfer); 1100 if (__predict_true(error == 0 || error == USBD_IN_PROGRESS)) { 1101 usc->usc_obuf = obuf; 1102 1103 /* Wait for WMI command to complete. */ 1104 error = tsleep(&usc->usc_wait_cmd_id, 0, "athnwmi", hz); 1105 usc->usc_wait_cmd_id = 0; 1106 athn_usb_wait_wmi(usc); 1107 } 1108 splx(s); 1109 return error; 1110 } 1111 1112 Static void 1113 athn_usb_wait_wmi(struct athn_usb_softc *usc) 1114 { 1115 1116 DPRINTFN(DBG_FN, usc, "\n"); 1117 1118 while (__predict_false(!usc->usc_wmi_done)) 1119 tsleep(&usc->usc_wmi_done, 0, "athnwmi", 0); 1120 } 1121 1122 #ifdef unused 1123 Static int 1124 athn_usb_read_rom(struct athn_softc *sc) 1125 { 1126 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1127 uint32_t addrs[8], vals[8], addr; 1128 uint16_t *eep; 1129 size_t i, j; 1130 int error = 0; 1131 1132 DPRINTFN(DBG_FN, sc, "\n"); 1133 1134 /* Read EEPROM by blocks of 16 bytes. */ 1135 eep = sc->sc_eep; 1136 addr = AR_EEPROM_OFFSET(sc->sc_eep_base); 1137 for (i = 0; i < sc->sc_eep_size / 16; i++) { 1138 for (j = 0; j < 8; j++, addr += 4) 1139 addrs[j] = htobe32(addr); 1140 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, 1141 addrs, sizeof(addrs), vals); 1142 if (error != 0) 1143 break; 1144 for (j = 0; j < 8; j++) 1145 *eep++ = be32toh(vals[j]); 1146 } 1147 return error; 1148 } 1149 #endif /* unused */ 1150 1151 Static uint32_t 1152 athn_usb_read(struct athn_softc *sc, uint32_t addr) 1153 { 1154 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1155 uint32_t val; 1156 int error; 1157 1158 if (usc->usc_dying) 1159 return 0; 1160 1161 DPRINTFN(DBG_FN, sc, "\n"); 1162 1163 /* Flush pending writes for strict consistency. */ 1164 athn_usb_write_barrier(sc); 1165 1166 addr = htobe32(addr); 1167 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_READ, 1168 &addr, sizeof(addr), &val); 1169 if (error != 0) 1170 return 0xdeadbeef; 1171 return be32toh(val); 1172 } 1173 1174 Static void 1175 athn_usb_write(struct athn_softc *sc, uint32_t addr, uint32_t val) 1176 { 1177 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1178 1179 if (usc->usc_dying) 1180 return; 1181 1182 DPRINTFN(DBG_FN, sc, "\n"); 1183 1184 usc->usc_wbuf[usc->usc_wcount].addr = htobe32(addr); 1185 usc->usc_wbuf[usc->usc_wcount].val = htobe32(val); 1186 if (++usc->usc_wcount == AR_MAX_WRITE_COUNT) 1187 athn_usb_write_barrier(sc); 1188 } 1189 1190 Static void 1191 athn_usb_write_barrier(struct athn_softc *sc) 1192 { 1193 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1194 1195 if (usc->usc_dying) 1196 goto done; 1197 1198 DPRINTFN(DBG_FN, sc, "\n"); 1199 1200 if (usc->usc_wcount == 0) 1201 return; 1202 1203 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_REG_WRITE, 1204 usc->usc_wbuf, usc->usc_wcount * sizeof(usc->usc_wbuf[0]), NULL); 1205 done: 1206 usc->usc_wcount = 0; /* Always flush buffer. */ 1207 } 1208 1209 Static int 1210 athn_usb_media_change(struct ifnet *ifp) 1211 { 1212 struct athn_softc *sc = ifp->if_softc; 1213 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1214 int error; 1215 1216 if (usc->usc_dying) 1217 return EIO; 1218 1219 DPRINTFN(DBG_FN, sc, "\n"); 1220 1221 error = ieee80211_media_change(ifp); 1222 if (error == ENETRESET && IS_UP_AND_RUNNING(ifp)) { 1223 athn_usb_stop(ifp); 1224 error = athn_usb_init(ifp); 1225 } 1226 return error; 1227 } 1228 1229 Static int 1230 athn_usb_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, 1231 int arg) 1232 { 1233 struct athn_softc *sc = ic->ic_ifp->if_softc; 1234 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1235 struct athn_usb_cmd_newstate cmd; 1236 1237 DPRINTFN(DBG_FN, sc, "\n"); 1238 1239 /* Do it in a process context. */ 1240 cmd.state = nstate; 1241 cmd.arg = arg; 1242 athn_usb_do_async(usc, athn_usb_newstate_cb, &cmd, sizeof(cmd)); 1243 return 0; 1244 } 1245 1246 Static void 1247 athn_usb_newstate_cb(struct athn_usb_softc *usc, void *arg) 1248 { 1249 struct athn_usb_cmd_newstate *cmd = arg; 1250 struct athn_softc *sc = &usc->usc_sc; 1251 struct ieee80211com *ic = &sc->sc_ic; 1252 enum ieee80211_state ostate, nstate; 1253 uint32_t reg, imask; 1254 int s; 1255 1256 DPRINTFN(DBG_FN, sc, "\n"); 1257 1258 callout_stop(&sc->sc_calib_to); 1259 1260 s = splnet(); 1261 1262 ostate = ic->ic_state; 1263 nstate = cmd->state; 1264 DPRINTFN(DBG_STM, usc, "newstate %s(%d) -> %s(%d)\n", 1265 ieee80211_state_name[ostate], ostate, 1266 ieee80211_state_name[nstate], nstate); 1267 1268 if (ostate == IEEE80211_S_RUN) { 1269 uint8_t sta_index; 1270 1271 sta_index = ATHN_NODE(ic->ic_bss)->sta_index; 1272 DPRINTFN(DBG_NODES, usc, "removing node %u\n", sta_index); 1273 athn_usb_remove_hw_node(usc, &sta_index); 1274 } 1275 1276 switch (nstate) { 1277 case IEEE80211_S_INIT: 1278 athn_set_led(sc, 0); 1279 break; 1280 case IEEE80211_S_SCAN: 1281 /* Make the LED blink while scanning. */ 1282 athn_set_led(sc, !sc->sc_led_state); 1283 (void)athn_usb_switch_chan(sc, ic->ic_curchan, NULL); 1284 if (!usc->usc_dying) 1285 callout_schedule(&sc->sc_scan_to, hz / 5); 1286 break; 1287 case IEEE80211_S_AUTH: 1288 athn_set_led(sc, 0); 1289 athn_usb_switch_chan(sc, ic->ic_curchan, NULL); 1290 break; 1291 case IEEE80211_S_ASSOC: 1292 break; 1293 case IEEE80211_S_RUN: 1294 athn_set_led(sc, 1); 1295 1296 if (ic->ic_opmode == IEEE80211_M_MONITOR) 1297 break; 1298 1299 /* Create node entry for our BSS. */ 1300 DPRINTFN(DBG_NODES, sc, "create node for AID=0x%x\n", 1301 ic->ic_bss->ni_associd); 1302 athn_usb_create_node(usc, ic->ic_bss); /* XXX: handle error? */ 1303 1304 athn_set_bss(sc, ic->ic_bss); 1305 athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 1306 #ifndef IEEE80211_STA_ONLY 1307 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 1308 athn_set_hostap_timers(sc); 1309 /* Enable software beacon alert interrupts. */ 1310 imask = htobe32(AR_IMR_SWBA); 1311 } 1312 else 1313 #endif 1314 { 1315 athn_set_sta_timers(sc); 1316 /* Enable beacon miss interrupts. */ 1317 imask = htobe32(AR_IMR_BMISS); 1318 1319 /* Stop receiving beacons from other BSS. */ 1320 reg = AR_READ(sc, AR_RX_FILTER); 1321 reg = (reg & ~AR_RX_FILTER_BEACON) | 1322 AR_RX_FILTER_MYBEACON; 1323 AR_WRITE(sc, AR_RX_FILTER, reg); 1324 AR_WRITE_BARRIER(sc); 1325 } 1326 athn_usb_wmi_xcmd(usc, AR_WMI_CMD_ENABLE_INTR, 1327 &imask, sizeof(imask), NULL); 1328 break; 1329 } 1330 if (!usc->usc_dying) 1331 (void)sc->sc_newstate(ic, nstate, cmd->arg); 1332 splx(s); 1333 } 1334 1335 Static void 1336 athn_usb_newassoc(struct ieee80211_node *ni, int isnew) 1337 { 1338 struct ieee80211com *ic = ni->ni_ic; 1339 struct athn_softc *sc = ic->ic_ifp->if_softc; 1340 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1341 1342 DPRINTFN(DBG_FN, sc, "\n"); 1343 1344 if (ic->ic_opmode != IEEE80211_M_HOSTAP || !isnew) 1345 return; 1346 1347 /* Do it in a process context. */ 1348 ieee80211_ref_node(ni); 1349 athn_usb_do_async(usc, athn_usb_newassoc_cb, &ni, sizeof(ni)); 1350 } 1351 1352 Static void 1353 athn_usb_newassoc_cb(struct athn_usb_softc *usc, void *arg) 1354 { 1355 struct ieee80211_node *ni = *(void **)arg; 1356 int s; 1357 1358 DPRINTFN(DBG_FN, usc, "\n"); 1359 1360 s = splnet(); 1361 /* NB: Node may have left before we got scheduled. */ 1362 if (ni->ni_associd != 0) { 1363 DPRINTFN(DBG_NODES, usc, "creating node for AID=0x%x\n", 1364 ni->ni_associd); 1365 (void)athn_usb_create_node(usc, ni); /* XXX: handle error? */ 1366 } 1367 ieee80211_free_node(ni); 1368 splx(s); 1369 } 1370 1371 #ifdef notyet 1372 Static int 1373 athn_usb_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, 1374 uint8_t tid) 1375 { 1376 struct athn_softc *sc = ic->ic_ifp->if_softc; 1377 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1378 struct athn_node *an = ATHN_NODE(ni); 1379 struct athn_usb_aggr_cmd cmd; 1380 1381 DPRINTFN(DBG_FN, sc, "\n"); 1382 1383 /* Do it in a process context. */ 1384 cmd.sta_index = an->sta_index; 1385 cmd.tid = tid; 1386 athn_usb_do_async(usc, athn_usb_ampdu_tx_start_cb, &cmd, sizeof(cmd)); 1387 return 0; 1388 } 1389 1390 Static void 1391 athn_usb_ampdu_tx_start_cb(struct athn_usb_softc *usc, void *arg) 1392 { 1393 struct athn_usb_aggr_cmd *cmd = arg; 1394 struct ar_htc_target_aggr aggr; 1395 1396 DPRINTFN(DBG_FN, usc, "\n"); 1397 1398 memset(&aggr, 0, sizeof(aggr)); 1399 aggr.sta_index = cmd->sta_index; 1400 aggr.tidno = cmd->tid; 1401 aggr.aggr_enable = 1; 1402 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, 1403 &aggr, sizeof(aggr), NULL); 1404 } 1405 1406 Static void 1407 athn_usb_ampdu_tx_stop(struct ieee80211com *ic, struct ieee80211_node *ni, 1408 uint8_t tid) 1409 { 1410 struct athn_softc *sc = ic->ic_ifp->if_softc; 1411 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1412 struct athn_node *an = ATHN_NODE(ni); 1413 struct athn_usb_aggr_cmd cmd; 1414 1415 DPRINTFN(DBG_FN, sc, "\n"); 1416 1417 /* Do it in a process context. */ 1418 cmd.sta_index = an->sta_index; 1419 cmd.tid = tid; 1420 athn_usb_do_async(usc, athn_usb_ampdu_tx_stop_cb, &cmd, sizeof(cmd)); 1421 } 1422 1423 Static void 1424 athn_usb_ampdu_tx_stop_cb(struct athn_usb_softc *usc, void *arg) 1425 { 1426 struct athn_usb_aggr_cmd *cmd = arg; 1427 struct ar_htc_target_aggr aggr; 1428 1429 DPRINTFN(DBG_FN, usc, "\n"); 1430 1431 memset(&aggr, 0, sizeof(aggr)); 1432 aggr.sta_index = cmd->sta_index; 1433 aggr.tidno = cmd->tid; 1434 aggr.aggr_enable = 0; 1435 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TX_AGGR_ENABLE, 1436 &aggr, sizeof(aggr), NULL); 1437 } 1438 #endif /* notyet */ 1439 1440 Static int 1441 athn_usb_remove_hw_node(struct athn_usb_softc *usc, uint8_t *sta_idx) 1442 { 1443 int error; 1444 1445 DPRINTFN(DBG_FN, usc, "\n"); 1446 1447 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_REMOVE, 1448 sta_idx, sizeof(*sta_idx), NULL); 1449 1450 DPRINTFN(DBG_NODES, usc, "node=%u error=%d\n", 1451 *sta_idx, error); 1452 return error; 1453 } 1454 1455 Static int 1456 athn_usb_create_hw_node(struct athn_usb_softc *usc, 1457 struct ar_htc_target_sta *sta) 1458 { 1459 int error; 1460 1461 DPRINTFN(DBG_FN, usc, "\n"); 1462 1463 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_NODE_CREATE, 1464 sta, sizeof(*sta), NULL); 1465 1466 DPRINTFN(DBG_NODES, usc, "node=%u error=%d\n", 1467 sta->sta_index, error); 1468 1469 return error; 1470 } 1471 1472 Static int 1473 athn_usb_create_node(struct athn_usb_softc *usc, struct ieee80211_node *ni) 1474 { 1475 struct athn_node *an = ATHN_NODE(ni); 1476 struct ar_htc_target_sta sta; 1477 struct ar_htc_target_rate rate; 1478 int error; 1479 1480 DPRINTFN(DBG_FN | DBG_NODES, usc, "AID=0x%x\n", ni->ni_associd); 1481 1482 /* 1483 * NB: this is called by ic_newstate and (in HOSTAP mode by) 1484 * ic_newassoc. 1485 * 1486 * The firmware has a limit of 8 nodes. In HOSTAP mode, we 1487 * limit the AID to < 8 and use that value to index the 1488 * firmware node table. Node zero is used for the BSS. 1489 * 1490 * In STA mode, we simply use node 1 for the BSS. 1491 */ 1492 if (ATHN_SOFTC(usc)->sc_ic.ic_opmode == IEEE80211_M_HOSTAP) 1493 an->sta_index = IEEE80211_NODE_AID(ni); 1494 else 1495 an->sta_index = 1; 1496 1497 /* Create node entry on target. */ 1498 memset(&sta, 0, sizeof(sta)); 1499 IEEE80211_ADDR_COPY(sta.macaddr, ni->ni_macaddr); 1500 IEEE80211_ADDR_COPY(sta.bssid, ni->ni_bssid); 1501 1502 sta.associd = htobe16(ni->ni_associd); 1503 sta.valid = 1; 1504 sta.sta_index = an->sta_index; 1505 1506 sta.maxampdu = 0xffff; 1507 #ifndef IEEE80211_NO_HT 1508 if (ni->ni_flags & IEEE80211_NODE_HT) 1509 sta.flags |= htobe16(AR_HTC_STA_HT); 1510 #endif 1511 error = athn_usb_create_hw_node(usc, &sta); 1512 if (error) 1513 return error; 1514 1515 /* Setup supported rates. */ 1516 memset(&rate, 0, sizeof(rate)); 1517 rate.sta_index = sta.sta_index; 1518 rate.isnew = 1; 1519 rate.lg_rates.rs_nrates = ni->ni_rates.rs_nrates; 1520 memcpy(rate.lg_rates.rs_rates, ni->ni_rates.rs_rates, 1521 ni->ni_rates.rs_nrates); 1522 1523 #ifndef IEEE80211_NO_HT 1524 if (ni->ni_flags & IEEE80211_NODE_HT) { 1525 rate.capflags |= htobe32(AR_RC_HT_FLAG); 1526 #ifdef notyet 1527 /* XXX setup HT rates */ 1528 if (ni->ni_htcaps & IEEE80211_HTCAP_CBW20_40) 1529 rate.capflags |= htobe32(AR_RC_40_FLAG); 1530 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI40) 1531 rate.capflags |= htobe32(AR_RC_SGI_FLAG); 1532 if (ni->ni_htcaps & IEEE80211_HTCAP_SGI20) 1533 rate.capflags |= htobe32(AR_RC_SGI_FLAG); 1534 #endif 1535 } 1536 #endif 1537 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_RC_RATE_UPDATE, 1538 &rate, sizeof(rate), NULL); 1539 return error; 1540 } 1541 1542 Static void 1543 athn_usb_rx_enable(struct athn_softc *sc) 1544 { 1545 1546 DPRINTFN(DBG_FN, sc, "\n"); 1547 1548 AR_WRITE(sc, AR_CR, AR_CR_RXE); 1549 AR_WRITE_BARRIER(sc); 1550 } 1551 1552 Static int 1553 athn_usb_switch_chan(struct athn_softc *sc, struct ieee80211_channel *curchan, 1554 struct ieee80211_channel *extchan) 1555 { 1556 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1557 uint16_t mode; 1558 int error; 1559 1560 DPRINTFN(DBG_FN, sc, "\n"); 1561 1562 /* Disable interrupts. */ 1563 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 1564 if (error != 0) 1565 goto reset; 1566 /* Stop all Tx queues. */ 1567 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); 1568 if (error != 0) 1569 goto reset; 1570 /* Stop Rx. */ 1571 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); 1572 if (error != 0) 1573 goto reset; 1574 1575 /* If band or bandwidth changes, we need to do a full reset. */ 1576 if (curchan->ic_flags != sc->sc_curchan->ic_flags || 1577 ((extchan != NULL) ^ (sc->sc_curchanext != NULL))) { 1578 DPRINTFN(DBG_RF, sc, "channel band switch\n"); 1579 goto reset; 1580 } 1581 1582 error = athn_set_chan(sc, curchan, extchan); 1583 if (AR_SREV_9271(sc) && error == 0) 1584 ar9271_load_ani(sc); 1585 if (error != 0) { 1586 reset: /* Error found, try a full reset. */ 1587 DPRINTFN(DBG_RF, sc, "needs a full reset\n"); 1588 error = athn_hw_reset(sc, curchan, extchan, 0); 1589 if (error != 0) /* Hopeless case. */ 1590 return error; 1591 } 1592 1593 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); 1594 if (error != 0) 1595 return error; 1596 athn_rx_start(sc); 1597 1598 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(curchan) ? 1599 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); 1600 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, 1601 &mode, sizeof(mode), NULL); 1602 if (error != 0) 1603 return error; 1604 1605 /* Re-enable interrupts. */ 1606 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ENABLE_INTR); 1607 return error; 1608 } 1609 1610 #ifdef notyet_edca 1611 Static void 1612 athn_usb_updateedca(struct ieee80211com *ic) 1613 { 1614 struct athn_softc *sc = ic->ic_ifp->if_softc; 1615 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1616 1617 DPRINTFN(DBG_FN, sc, "\n"); 1618 1619 /* Do it in a process context. */ 1620 athn_usb_do_async(usc, athn_usb_updateedca_cb, NULL, 0); 1621 } 1622 1623 Static void 1624 athn_usb_updateedca_cb(struct athn_usb_softc *usc, void *arg) 1625 { 1626 int s; 1627 1628 DPRINTFN(DBG_FN, usc, "\n"); 1629 1630 s = splnet(); 1631 athn_updateedca(&usc->usc_sc.sc_ic); 1632 splx(s); 1633 } 1634 #endif /* notyet_edca */ 1635 1636 Static void 1637 athn_usb_updateslot(struct ifnet *ifp) 1638 { 1639 struct athn_softc *sc = ifp->if_softc; 1640 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1641 1642 DPRINTFN(DBG_FN, sc, "\n"); 1643 1644 /* 1645 * NB: athn_updateslog() needs to be done in a process context 1646 * to avoid being called by ieee80211_reset_erp() inside a 1647 * spinlock held by ieee80211_free_allnodes(). 1648 * 1649 * XXX: calling this during the athn_attach() causes 1650 * usb_insert_transfer() to produce a bunch of "not busy" 1651 * messages. Why? 1652 */ 1653 if (usc->usc_athn_attached) 1654 athn_usb_do_async(usc, athn_usb_updateslot_cb, NULL, 0); 1655 } 1656 1657 Static void 1658 athn_usb_updateslot_cb(struct athn_usb_softc *usc, void *arg) 1659 { 1660 int s; 1661 1662 DPRINTFN(DBG_FN, usc, "\n"); 1663 1664 s = splnet(); 1665 athn_updateslot(&usc->usc_sc.sc_if); 1666 splx(s); 1667 } 1668 1669 #ifdef notyet 1670 Static int 1671 athn_usb_set_key(struct ieee80211com *ic, struct ieee80211_node *ni, 1672 struct ieee80211_key *k) 1673 { 1674 struct athn_softc *sc = ic->ic_ifp->if_softc; 1675 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1676 struct ifnet *ifp = &usc->usc_sc.sc_if; 1677 struct athn_usb_cmd_key cmd; 1678 1679 DPRINTFN(DBG_FN, sc, "\n"); 1680 1681 /* Defer setting of WEP keys until interface is brought up. */ 1682 if (!IS_UP_AND_RUNNING(ifp)) 1683 return 0; 1684 1685 /* Do it in a process context. */ 1686 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; 1687 cmd.key = k; 1688 athn_usb_do_async(usc, athn_usb_set_key_cb, &cmd, sizeof(cmd)); 1689 return 0; 1690 } 1691 1692 Static void 1693 athn_usb_set_key_cb(struct athn_usb_softc *usc, void *arg) 1694 { 1695 struct ieee80211com *ic = &usc->usc_sc.sc_ic; 1696 struct athn_usb_cmd_key *cmd = arg; 1697 int s; 1698 1699 DPRINTFN(DBG_FN, usc, "\n"); 1700 1701 s = splnet(); 1702 athn_set_key(ic, cmd->ni, cmd->key); 1703 if (cmd->ni != NULL) 1704 ieee80211_free_node(cmd->ni); 1705 splx(s); 1706 } 1707 1708 Static void 1709 athn_usb_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni, 1710 struct ieee80211_key *k) 1711 { 1712 struct athn_softc *sc = ic->ic_ifp->if_softc; 1713 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 1714 struct ifnet *ifp = &usc->usc_sc.sc_if; 1715 struct athn_usb_cmd_key cmd; 1716 1717 DPRINTFN(DBG_FN, sc, "\n"); 1718 1719 if (!(ifp->if_flags & IFF_RUNNING) || 1720 ic->ic_state != IEEE80211_S_RUN) 1721 return; /* Nothing to do. */ 1722 1723 /* Do it in a process context. */ 1724 cmd.ni = (ni != NULL) ? ieee80211_ref_node(ni) : NULL; 1725 cmd.key = k; 1726 athn_usb_do_async(usc, athn_usb_delete_key_cb, &cmd, sizeof(cmd)); 1727 } 1728 1729 Static void 1730 athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg) 1731 { 1732 struct ieee80211com *ic = &usc->usc_sc.sc_ic; 1733 struct athn_usb_cmd_key *cmd = arg; 1734 int s; 1735 1736 DPRINTFN(DBG_FN, usc, "\n"); 1737 1738 s = splnet(); 1739 athn_delete_key(ic, cmd->ni, cmd->key); 1740 if (cmd->ni != NULL) 1741 ieee80211_free_node(cmd->ni); 1742 splx(s); 1743 } 1744 #endif /* notyet */ 1745 1746 #ifndef IEEE80211_STA_ONLY 1747 Static void 1748 athn_usb_bcneof(usbd_xfer_handle xfer, usbd_private_handle priv, 1749 usbd_status status) 1750 { 1751 struct athn_usb_tx_data *data = priv; 1752 struct athn_usb_softc *usc = data->sc; 1753 1754 DPRINTFN(DBG_FN, usc, "\n"); 1755 1756 if (__predict_false(status == USBD_STALLED)) 1757 usbd_clear_endpoint_stall_async(usc->usc_tx_data_pipe); 1758 usc->usc_tx_bcn = data; 1759 } 1760 1761 /* 1762 * Process Software Beacon Alert interrupts. 1763 */ 1764 Static void 1765 athn_usb_swba(struct athn_usb_softc *usc) 1766 { 1767 struct athn_softc *sc = &usc->usc_sc; 1768 struct ieee80211com *ic = &sc->sc_ic; 1769 struct athn_usb_tx_data *data; 1770 struct ieee80211_frame *wh; 1771 struct ieee80211_beacon_offsets bo; 1772 struct ar_stream_hdr *hdr; 1773 struct ar_htc_frame_hdr *htc; 1774 struct ar_tx_bcn *bcn; 1775 struct mbuf *m; 1776 int error; 1777 1778 if (usc->usc_dying) 1779 return; 1780 1781 DPRINTFN(DBG_FN, sc, "\n"); 1782 1783 if (ic->ic_dtim_count == 0) 1784 ic->ic_dtim_count = ic->ic_dtim_period - 1; 1785 else 1786 ic->ic_dtim_count--; 1787 1788 /* Make sure previous beacon has been sent. */ 1789 if (usc->usc_tx_bcn == NULL) 1790 return; 1791 data = usc->usc_tx_bcn; 1792 1793 /* Get new beacon. */ 1794 #ifdef ATHN_DEBUG 1795 memset(&bo, 0, sizeof(bo)); 1796 #endif 1797 m = ieee80211_beacon_alloc(ic, ic->ic_bss, &bo); 1798 if (__predict_false(m == NULL)) 1799 return; 1800 /* Assign sequence number. */ 1801 /* XXX: use non-QoS tid? */ 1802 wh = mtod(m, struct ieee80211_frame *); 1803 *(uint16_t *)&wh->i_seq[0] = 1804 htole16(ic->ic_bss->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT); 1805 ic->ic_bss->ni_txseqs[0]++; 1806 1807 hdr = (struct ar_stream_hdr *)data->buf; 1808 hdr->tag = htole16(AR_USB_TX_STREAM_TAG); 1809 hdr->len = htole16(sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len); 1810 1811 htc = (struct ar_htc_frame_hdr *)&hdr[1]; 1812 memset(htc, 0, sizeof(*htc)); 1813 htc->endpoint_id = usc->usc_ep_bcn; 1814 htc->payload_len = htobe16(sizeof(*bcn) + m->m_pkthdr.len); 1815 1816 bcn = (struct ar_tx_bcn *)&htc[1]; 1817 memset(bcn, 0, sizeof(*bcn)); 1818 bcn->vif_idx = 0; 1819 1820 m_copydata(m, 0, m->m_pkthdr.len, (void *)&bcn[1]); 1821 1822 usbd_setup_xfer(data->xfer, usc->usc_tx_data_pipe, data, data->buf, 1823 sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len, 1824 USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, 1825 athn_usb_bcneof); 1826 1827 m_freem(m); 1828 usc->usc_tx_bcn = NULL; 1829 error = usbd_transfer(data->xfer); 1830 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) 1831 usc->usc_tx_bcn = data; 1832 } 1833 #endif 1834 1835 Static void 1836 athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, size_t len) 1837 { 1838 #ifdef ATHN_DEBUG 1839 struct ar_wmi_evt_txrate *txrate; 1840 #endif 1841 struct ar_wmi_cmd_hdr *wmi; 1842 uint16_t cmd_id; 1843 1844 if (usc->usc_dying) 1845 return; 1846 1847 DPRINTFN(DBG_FN, usc, "\n"); 1848 1849 if (__predict_false(len < sizeof(*wmi))) 1850 return; 1851 wmi = (struct ar_wmi_cmd_hdr *)buf; 1852 cmd_id = be16toh(wmi->cmd_id); 1853 1854 if (!(cmd_id & AR_WMI_EVT_FLAG)) { 1855 if (usc->usc_wait_cmd_id != cmd_id) 1856 return; /* Unexpected reply. */ 1857 if (usc->usc_obuf != NULL) { 1858 /* Copy answer into caller supplied buffer. */ 1859 memcpy(usc->usc_obuf, &wmi[1], len - sizeof(*wmi)); 1860 } 1861 /* Notify caller of completion. */ 1862 usc->usc_wait_cmd_id = 0; 1863 wakeup(&usc->usc_wait_cmd_id); 1864 return; 1865 } 1866 /* 1867 * XXX: the Linux 2.6 and 3.7.4 kernels differ on the event numbers! 1868 * See the alternate defines in if_athn_usb.h. 1869 */ 1870 switch (cmd_id & 0xfff) { 1871 #ifndef IEEE80211_STA_ONLY 1872 case AR_WMI_EVT_SWBA: 1873 athn_usb_swba(usc); 1874 break; 1875 #endif 1876 case AR_WMI_EVT_FATAL: 1877 aprint_error_dev(usc->usc_dev, "fatal firmware error\n"); 1878 break; 1879 case AR_WMI_EVT_TXRATE: 1880 #ifdef ATHN_DEBUG 1881 txrate = (struct ar_wmi_evt_txrate *)&wmi[1]; 1882 DPRINTFN(DBG_TX, usc, "txrate=%d\n", be32toh(txrate->txrate)); 1883 #endif 1884 break; 1885 default: 1886 DPRINTFN(DBG_TX, usc, "WMI event 0x%x (%d) ignored\n", cmd_id, cmd_id); 1887 break; 1888 } 1889 } 1890 1891 Static void 1892 athn_usb_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 1893 usbd_status status) 1894 { 1895 struct athn_usb_softc *usc = priv; 1896 struct ar_htc_frame_hdr *htc; 1897 struct ar_htc_msg_hdr *msg; 1898 uint8_t *buf = usc->usc_ibuf; 1899 uint16_t msg_id; 1900 int len; 1901 1902 if (usc->usc_dying) 1903 return; 1904 1905 DPRINTFN(DBG_FN, usc, "\n"); 1906 1907 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1908 DPRINTFN(DBG_INTR, usc, "intr status=%d\n", status); 1909 if (status == USBD_STALLED) 1910 usbd_clear_endpoint_stall_async(usc->usc_rx_intr_pipe); 1911 return; 1912 } 1913 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1914 1915 /* Skip watchdog pattern if present. */ 1916 if (len >= 4 && *(uint32_t *)buf == htobe32(0x00c60000)) { 1917 buf += 4; 1918 len -= 4; 1919 } 1920 if (__predict_false(len < (int)sizeof(*htc))) 1921 return; 1922 htc = (struct ar_htc_frame_hdr *)buf; 1923 /* Skip HTC header. */ 1924 buf += sizeof(*htc); 1925 len -= sizeof(*htc); 1926 1927 if (htc->endpoint_id != 0) { 1928 if (__predict_false(htc->endpoint_id != usc->usc_ep_ctrl)) 1929 return; 1930 /* Remove trailer if present. */ 1931 if (htc->flags & AR_HTC_FLAG_TRAILER) { 1932 if (__predict_false(len < htc->control[0])) 1933 return; 1934 len -= htc->control[0]; 1935 } 1936 athn_usb_rx_wmi_ctrl(usc, buf, len); 1937 return; 1938 } 1939 1940 /* 1941 * Endpoint 0 carries HTC messages. 1942 */ 1943 if (__predict_false(len < (int)sizeof(*msg))) 1944 return; 1945 msg = (struct ar_htc_msg_hdr *)buf; 1946 msg_id = be16toh(msg->msg_id); 1947 DPRINTFN(DBG_RX, usc, "Rx HTC message %d\n", msg_id); 1948 switch (msg_id) { 1949 case AR_HTC_MSG_READY: 1950 case AR_HTC_MSG_CONF_PIPE_RSP: 1951 if (usc->usc_wait_msg_id != msg_id) 1952 break; 1953 usc->usc_wait_msg_id = 0; 1954 wakeup(&usc->usc_wait_msg_id); 1955 break; 1956 case AR_HTC_MSG_CONN_SVC_RSP: 1957 if (usc->usc_wait_msg_id != msg_id) 1958 break; 1959 if (usc->usc_msg_conn_svc_rsp != NULL) { 1960 memcpy(usc->usc_msg_conn_svc_rsp, &msg[1], 1961 sizeof(*usc->usc_msg_conn_svc_rsp)); 1962 } 1963 usc->usc_wait_msg_id = 0; 1964 wakeup(&usc->usc_wait_msg_id); 1965 break; 1966 default: 1967 DPRINTFN(DBG_RX, usc, "HTC message %d ignored\n", msg_id); 1968 break; 1969 } 1970 } 1971 1972 Static void 1973 athn_usb_rx_radiotap(struct athn_softc *sc, struct mbuf *m, 1974 struct ar_rx_status *rs) 1975 { 1976 struct athn_rx_radiotap_header *tap = &sc->sc_rxtap; 1977 struct ieee80211com *ic = &sc->sc_ic; 1978 uint8_t rate; 1979 1980 DPRINTFN(DBG_FN, sc, "\n"); 1981 1982 tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; 1983 tap->wr_tsft = htole64(be64toh(rs->rs_tstamp)); 1984 tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); 1985 tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); 1986 tap->wr_dbm_antsignal = rs->rs_rssi; 1987 /* XXX noise. */ 1988 tap->wr_antenna = rs->rs_antenna; 1989 rate = rs->rs_rate; 1990 if (rate & 0x80) { /* HT. */ 1991 /* Bit 7 set means HT MCS instead of rate. */ 1992 tap->wr_rate = rate; 1993 if (!(rs->rs_flags & AR_RXS_FLAG_GI)) 1994 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI; 1995 } 1996 else if (rate & 0x10) { /* CCK. */ 1997 if (rate & 0x04) 1998 tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; 1999 switch (rate & ~0x14) { 2000 case 0xb: tap->wr_rate = 2; break; 2001 case 0xa: tap->wr_rate = 4; break; 2002 case 0x9: tap->wr_rate = 11; break; 2003 case 0x8: tap->wr_rate = 22; break; 2004 default: tap->wr_rate = 0; break; 2005 } 2006 } 2007 else { /* OFDM. */ 2008 switch (rate) { 2009 case 0xb: tap->wr_rate = 12; break; 2010 case 0xf: tap->wr_rate = 18; break; 2011 case 0xa: tap->wr_rate = 24; break; 2012 case 0xe: tap->wr_rate = 36; break; 2013 case 0x9: tap->wr_rate = 48; break; 2014 case 0xd: tap->wr_rate = 72; break; 2015 case 0x8: tap->wr_rate = 96; break; 2016 case 0xc: tap->wr_rate = 108; break; 2017 default: tap->wr_rate = 0; break; 2018 } 2019 } 2020 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); 2021 } 2022 2023 Static void 2024 athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m) 2025 { 2026 struct athn_softc *sc = &usc->usc_sc; 2027 struct ieee80211com *ic = &sc->sc_ic; 2028 struct ifnet *ifp = &sc->sc_if; 2029 struct ieee80211_frame *wh; 2030 struct ieee80211_node *ni; 2031 struct ar_htc_frame_hdr *htc; 2032 struct ar_rx_status *rs; 2033 uint16_t datalen; 2034 int s; 2035 2036 DPRINTFN(DBG_FN, sc, "\n"); 2037 2038 if (__predict_false(m->m_len < (int)sizeof(*htc))) 2039 goto skip; 2040 htc = mtod(m, struct ar_htc_frame_hdr *); 2041 if (__predict_false(htc->endpoint_id == 0)) { 2042 DPRINTFN(DBG_RX, sc, "bad endpoint %d\n", htc->endpoint_id); 2043 goto skip; 2044 } 2045 if (htc->flags & AR_HTC_FLAG_TRAILER) { 2046 if (m->m_len < htc->control[0]) 2047 goto skip; 2048 m_adj(m, -(int)htc->control[0]); 2049 } 2050 m_adj(m, sizeof(*htc)); /* Strip HTC header. */ 2051 2052 if (__predict_false(m->m_len < (int)sizeof(*rs))) 2053 goto skip; 2054 rs = mtod(m, struct ar_rx_status *); 2055 2056 /* Make sure that payload fits. */ 2057 datalen = be16toh(rs->rs_datalen); 2058 if (__predict_false(m->m_len < (int)sizeof(*rs) + datalen)) 2059 goto skip; 2060 2061 /* Ignore runt frames. Let ACKs be seen by bpf */ 2062 if (__predict_false(datalen < 2063 sizeof(struct ieee80211_frame_ack) + IEEE80211_CRC_LEN)) 2064 goto skip; 2065 2066 m_adj(m, sizeof(*rs)); /* Strip Rx status. */ 2067 m->m_pkthdr.rcvif = ifp; 2068 2069 s = splnet(); 2070 2071 /* Grab a reference to the source node. */ 2072 wh = mtod(m, struct ieee80211_frame *); 2073 ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 2074 2075 /* Remove any HW padding after the 802.11 header. */ 2076 if (!(wh->i_fc[0] & IEEE80211_FC0_TYPE_CTL)) { 2077 u_int hdrlen = ieee80211_anyhdrsize(wh); 2078 if (hdrlen & 3) { 2079 ovbcopy(wh, (uint8_t *)wh + 2, hdrlen); 2080 m_adj(m, 2); 2081 } 2082 } 2083 if (__predict_false(sc->sc_drvbpf != NULL)) 2084 athn_usb_rx_radiotap(sc, m, rs); 2085 2086 /* Trim 802.11 FCS after radiotap. */ 2087 m_adj(m, -IEEE80211_CRC_LEN); 2088 2089 /* Send the frame to the 802.11 layer. */ 2090 ieee80211_input(ic, m, ni, rs->rs_rssi + AR_USB_DEFAULT_NF, 0); 2091 2092 /* Node is no longer needed. */ 2093 ieee80211_free_node(ni); 2094 splx(s); 2095 return; 2096 skip: 2097 m_freem(m); 2098 } 2099 2100 Static void 2101 athn_usb_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, 2102 usbd_status status) 2103 { 2104 struct athn_usb_rx_data *data = priv; 2105 struct athn_usb_softc *usc = data->sc; 2106 struct athn_usb_rx_stream *stream = &usc->usc_rx_stream; 2107 uint8_t *buf = data->buf; 2108 struct ar_stream_hdr *hdr; 2109 struct mbuf *m; 2110 uint16_t pktlen; 2111 int off, len; 2112 2113 if (usc->usc_dying) 2114 return; 2115 2116 DPRINTFN(DBG_FN, usc, "\n"); 2117 2118 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2119 DPRINTFN(DBG_RX, usc, "RX status=%d\n", status); 2120 if (status == USBD_STALLED) 2121 usbd_clear_endpoint_stall_async(usc->usc_rx_data_pipe); 2122 if (status != USBD_CANCELLED) 2123 goto resubmit; 2124 return; 2125 } 2126 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 2127 2128 if (stream->left > 0) { 2129 if (len >= stream->left) { 2130 /* We have all our pktlen bytes now. */ 2131 if (__predict_true(stream->m != NULL)) { 2132 memcpy(mtod(stream->m, uint8_t *) + 2133 stream->moff, buf, stream->left); 2134 athn_usb_rx_frame(usc, stream->m); 2135 stream->m = NULL; 2136 } 2137 /* Next header is 32-bit aligned. */ 2138 off = (stream->left + 3) & ~3; 2139 buf += off; 2140 len -= off; 2141 stream->left = 0; 2142 } 2143 else { 2144 /* Still need more bytes, save what we have. */ 2145 if (__predict_true(stream->m != NULL)) { 2146 memcpy(mtod(stream->m, uint8_t *) + 2147 stream->moff, buf, len); 2148 stream->moff += len; 2149 } 2150 stream->left -= len; 2151 goto resubmit; 2152 } 2153 } 2154 KASSERT(stream->left == 0); 2155 while (len >= (int)sizeof(*hdr)) { 2156 hdr = (struct ar_stream_hdr *)buf; 2157 if (hdr->tag != htole16(AR_USB_RX_STREAM_TAG)) { 2158 DPRINTFN(DBG_RX, usc, "invalid tag 0x%x\n", hdr->tag); 2159 break; 2160 } 2161 pktlen = le16toh(hdr->len); 2162 buf += sizeof(*hdr); 2163 len -= sizeof(*hdr); 2164 2165 if (__predict_true(pktlen <= MCLBYTES)) { 2166 /* Allocate an mbuf to store the next pktlen bytes. */ 2167 MGETHDR(m, M_DONTWAIT, MT_DATA); 2168 if (__predict_true(m != NULL)) { 2169 m->m_pkthdr.len = m->m_len = pktlen; 2170 if (pktlen > MHLEN) { 2171 MCLGET(m, M_DONTWAIT); 2172 if (!(m->m_flags & M_EXT)) { 2173 m_free(m); 2174 m = NULL; 2175 } 2176 } 2177 } 2178 } 2179 else /* Drop frames larger than MCLBYTES. */ 2180 m = NULL; 2181 /* 2182 * NB: m can be NULL, in which case the next pktlen bytes 2183 * will be discarded from the Rx stream. 2184 */ 2185 if (pktlen > len) { 2186 /* Need more bytes, save what we have. */ 2187 stream->m = m; /* NB: m can be NULL. */ 2188 if (__predict_true(stream->m != NULL)) { 2189 memcpy(mtod(stream->m, uint8_t *), buf, len); 2190 stream->moff = len; 2191 } 2192 stream->left = pktlen - len; 2193 goto resubmit; 2194 } 2195 if (__predict_true(m != NULL)) { 2196 /* We have all the pktlen bytes in this xfer. */ 2197 memcpy(mtod(m, uint8_t *), buf, pktlen); 2198 athn_usb_rx_frame(usc, m); 2199 } 2200 2201 /* Next header is 32-bit aligned. */ 2202 off = (pktlen + 3) & ~3; 2203 buf += off; 2204 len -= off; 2205 } 2206 2207 resubmit: 2208 /* Setup a new transfer. */ 2209 usbd_setup_xfer(xfer, usc->usc_rx_data_pipe, data, data->buf, 2210 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 2211 USBD_NO_TIMEOUT, athn_usb_rxeof); 2212 (void)usbd_transfer(xfer); 2213 } 2214 2215 Static void 2216 athn_usb_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, 2217 usbd_status status) 2218 { 2219 struct athn_usb_tx_data *data = priv; 2220 struct athn_usb_softc *usc = data->sc; 2221 struct athn_softc *sc = &usc->usc_sc; 2222 struct ifnet *ifp = &sc->sc_if; 2223 int s; 2224 2225 if (usc->usc_dying) 2226 return; 2227 2228 DPRINTFN(DBG_FN, usc, "\n"); 2229 2230 s = splnet(); 2231 /* Put this Tx buffer back to our free list. */ 2232 mutex_enter(&usc->usc_tx_mtx); 2233 TAILQ_INSERT_TAIL(&usc->usc_tx_free_list, data, next); 2234 mutex_exit(&usc->usc_tx_mtx); 2235 2236 if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 2237 DPRINTFN(DBG_TX, sc, "TX status=%d\n", status); 2238 if (status == USBD_STALLED) 2239 usbd_clear_endpoint_stall_async(usc->usc_tx_data_pipe); 2240 ifp->if_oerrors++; 2241 splx(s); 2242 /* XXX Why return? */ 2243 return; 2244 } 2245 sc->sc_tx_timer = 0; 2246 ifp->if_opackets++; 2247 2248 /* We just released a Tx buffer, notify Tx. */ 2249 if (ifp->if_flags & IFF_OACTIVE) { 2250 ifp->if_flags &= ~IFF_OACTIVE; 2251 ifp->if_start(ifp); 2252 } 2253 splx(s); 2254 } 2255 2256 Static int 2257 athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, 2258 struct athn_usb_tx_data *data) 2259 { 2260 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2261 struct athn_node *an = ATHN_NODE(ni); 2262 struct ieee80211com *ic = &sc->sc_ic; 2263 struct ieee80211_frame *wh; 2264 struct ieee80211_key *k = NULL; 2265 struct ar_stream_hdr *hdr; 2266 struct ar_htc_frame_hdr *htc; 2267 struct ar_tx_frame *txf; 2268 struct ar_tx_mgmt *txm; 2269 uint8_t *frm; 2270 uint8_t sta_index, qid, tid; 2271 int error, s, xferlen; 2272 2273 DPRINTFN(DBG_FN, sc, "\n"); 2274 2275 wh = mtod(m, struct ieee80211_frame *); 2276 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 2277 k = ieee80211_crypto_encap(ic, ni, m); 2278 if (k == NULL) 2279 return ENOBUFS; 2280 2281 /* packet header may have moved, reset our local pointer */ 2282 wh = mtod(m, struct ieee80211_frame *); 2283 } 2284 #ifdef notyet_edca 2285 if (ieee80211_has_qos(wh)) { 2286 uint16_t qos; 2287 2288 qos = ieee80211_get_qos(wh); 2289 tid = qos & IEEE80211_QOS_TID; 2290 qid = ieee80211_up_to_ac(ic, tid); 2291 } 2292 else 2293 #endif /* notyet_edca */ 2294 { 2295 tid = 0; 2296 qid = WME_AC_BE; 2297 } 2298 2299 /* XXX Change radiotap Tx header for USB (no txrate). */ 2300 if (__predict_false(sc->sc_drvbpf != NULL)) { 2301 struct athn_tx_radiotap_header *tap = &sc->sc_txtap; 2302 2303 tap->wt_flags = 0; 2304 tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); 2305 tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); 2306 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) 2307 tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; 2308 2309 bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m); 2310 } 2311 sta_index = an->sta_index; 2312 2313 /* NB: We don't take advantage of USB Tx stream mode for now. */ 2314 hdr = (struct ar_stream_hdr *)data->buf; 2315 hdr->tag = htole16(AR_USB_TX_STREAM_TAG); 2316 2317 htc = (struct ar_htc_frame_hdr *)&hdr[1]; 2318 memset(htc, 0, sizeof(*htc)); 2319 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 2320 IEEE80211_FC0_TYPE_DATA) { 2321 htc->endpoint_id = usc->usc_ep_data[qid]; 2322 2323 txf = (struct ar_tx_frame *)&htc[1]; 2324 memset(txf, 0, sizeof(*txf)); 2325 txf->data_type = AR_HTC_NORMAL; 2326 txf->node_idx = sta_index; 2327 txf->vif_idx = 0; 2328 txf->tid = tid; 2329 if (m->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) 2330 txf->flags |= htobe32(AR_HTC_TX_RTSCTS); 2331 else if (ic->ic_flags & IEEE80211_F_USEPROT) { 2332 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) 2333 txf->flags |= htobe32(AR_HTC_TX_CTSONLY); 2334 else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) 2335 txf->flags |= htobe32(AR_HTC_TX_RTSCTS); 2336 } 2337 txf->key_idx = 0xff; 2338 frm = (uint8_t *)&txf[1]; 2339 } 2340 else { 2341 htc->endpoint_id = usc->usc_ep_mgmt; 2342 2343 txm = (struct ar_tx_mgmt *)&htc[1]; 2344 memset(txm, 0, sizeof(*txm)); 2345 txm->node_idx = sta_index; 2346 txm->vif_idx = 0; 2347 txm->key_idx = 0xff; 2348 frm = (uint8_t *)&txm[1]; 2349 } 2350 /* Copy payload. */ 2351 m_copydata(m, 0, m->m_pkthdr.len, (void *)frm); 2352 frm += m->m_pkthdr.len; 2353 2354 /* Finalize headers. */ 2355 htc->payload_len = htobe16(frm - (uint8_t *)&htc[1]); 2356 hdr->len = htole16(frm - (uint8_t *)&hdr[1]); 2357 xferlen = frm - data->buf; 2358 2359 s = splnet(); 2360 usbd_setup_xfer(data->xfer, usc->usc_tx_data_pipe, data, data->buf, 2361 xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, 2362 athn_usb_txeof); 2363 error = usbd_transfer(data->xfer); 2364 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) { 2365 splx(s); 2366 return error; 2367 } 2368 splx(s); 2369 return 0; 2370 } 2371 2372 Static void 2373 athn_usb_start(struct ifnet *ifp) 2374 { 2375 struct athn_softc *sc = ifp->if_softc; 2376 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2377 struct ieee80211com *ic = &sc->sc_ic; 2378 struct athn_usb_tx_data *data; 2379 struct ether_header *eh; 2380 struct ieee80211_node *ni; 2381 struct mbuf *m; 2382 2383 if (usc->usc_dying) 2384 return; 2385 2386 DPRINTFN(DBG_FN, sc, "\n"); 2387 2388 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 2389 return; 2390 2391 data = NULL; 2392 for (;;) { 2393 mutex_enter(&usc->usc_tx_mtx); 2394 if (data == NULL && !TAILQ_EMPTY(&usc->usc_tx_free_list)) { 2395 data = TAILQ_FIRST(&usc->usc_tx_free_list); 2396 TAILQ_REMOVE(&usc->usc_tx_free_list, data, next); 2397 } 2398 mutex_exit(&usc->usc_tx_mtx); 2399 2400 if (data == NULL) { 2401 ifp->if_flags |= IFF_OACTIVE; 2402 return; 2403 } 2404 2405 /* Send pending management frames first. */ 2406 IF_DEQUEUE(&ic->ic_mgtq, m); 2407 if (m != NULL) { 2408 ni = (void *)m->m_pkthdr.rcvif; 2409 m->m_pkthdr.rcvif = NULL; 2410 goto sendit; 2411 } 2412 if (ic->ic_state != IEEE80211_S_RUN) 2413 break; 2414 2415 /* Encapsulate and send data frames. */ 2416 IFQ_DEQUEUE(&ifp->if_snd, m); 2417 if (m == NULL) 2418 break; 2419 2420 if (m->m_len < (int)sizeof(*eh) && 2421 (m = m_pullup(m, sizeof(*eh))) == NULL) { 2422 ifp->if_oerrors++; 2423 continue; 2424 } 2425 eh = mtod(m, struct ether_header *); 2426 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 2427 if (ni == NULL) { 2428 m_freem(m); 2429 ifp->if_oerrors++; 2430 continue; 2431 } 2432 2433 bpf_mtap(ifp, m); 2434 2435 if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 2436 ieee80211_free_node(ni); 2437 ifp->if_oerrors++; 2438 continue; 2439 } 2440 sendit: 2441 bpf_mtap3(ic->ic_rawbpf, m); 2442 2443 if (athn_usb_tx(sc, m, ni, data) != 0) { 2444 m_freem(m); 2445 ieee80211_free_node(ni); 2446 ifp->if_oerrors++; 2447 continue; 2448 } 2449 data = NULL; 2450 m_freem(m); 2451 ieee80211_free_node(ni); 2452 sc->sc_tx_timer = 5; 2453 ifp->if_timer = 1; 2454 } 2455 2456 /* Return the Tx buffer to the free list */ 2457 mutex_enter(&usc->usc_tx_mtx); 2458 TAILQ_INSERT_TAIL(&usc->usc_tx_free_list, data, next); 2459 mutex_exit(&usc->usc_tx_mtx); 2460 } 2461 2462 Static void 2463 athn_usb_watchdog(struct ifnet *ifp) 2464 { 2465 struct athn_softc *sc = ifp->if_softc; 2466 2467 DPRINTFN(DBG_FN, sc, "\n"); 2468 2469 ifp->if_timer = 0; 2470 2471 if (sc->sc_tx_timer > 0) { 2472 if (--sc->sc_tx_timer == 0) { 2473 aprint_error_dev(sc->sc_dev, "device timeout\n"); 2474 /* athn_usb_init(ifp); XXX needs a process context! */ 2475 ifp->if_oerrors++; 2476 return; 2477 } 2478 ifp->if_timer = 1; 2479 } 2480 ieee80211_watchdog(&sc->sc_ic); 2481 } 2482 2483 Static int 2484 athn_usb_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2485 { 2486 struct athn_softc *sc = ifp->if_softc; 2487 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2488 struct ieee80211com *ic = &sc->sc_ic; 2489 int s, error = 0; 2490 2491 if (usc->usc_dying) 2492 return EIO; 2493 2494 DPRINTFN(DBG_FN, sc, "cmd=0x%08lx\n", cmd); 2495 2496 s = splnet(); 2497 2498 switch (cmd) { 2499 case SIOCSIFFLAGS: 2500 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 2501 break; 2502 2503 switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 2504 case IFF_UP | IFF_RUNNING: 2505 break; 2506 case IFF_UP: 2507 error = athn_usb_init(ifp); 2508 break; 2509 case IFF_RUNNING: 2510 athn_usb_stop(ifp); 2511 break; 2512 case 0: 2513 default: 2514 break; 2515 } 2516 break; 2517 2518 case SIOCADDMULTI: 2519 case SIOCDELMULTI: 2520 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 2521 /* setup multicast filter, etc */ 2522 error = 0; 2523 } 2524 break; 2525 2526 case SIOCS80211CHANNEL: 2527 error = ieee80211_ioctl(ic, cmd, data); 2528 if (error == ENETRESET && 2529 ic->ic_opmode == IEEE80211_M_MONITOR) { 2530 if (IS_UP_AND_RUNNING(ifp)) 2531 athn_usb_switch_chan(sc, ic->ic_curchan, NULL); 2532 error = 0; 2533 } 2534 break; 2535 2536 default: 2537 error = ieee80211_ioctl(ic, cmd, data); 2538 break; 2539 } 2540 if (error == ENETRESET) { 2541 error = 0; 2542 if (IS_UP_AND_RUNNING(ifp) && 2543 ic->ic_roaming != IEEE80211_ROAMING_MANUAL) { 2544 athn_usb_stop(ifp); 2545 error = athn_usb_init(ifp); 2546 } 2547 } 2548 splx(s); 2549 return error; 2550 } 2551 2552 Static int 2553 athn_usb_init(struct ifnet *ifp) 2554 { 2555 struct athn_softc *sc = ifp->if_softc; 2556 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2557 struct athn_ops *ops = &sc->sc_ops; 2558 struct ieee80211com *ic = &sc->sc_ic; 2559 struct ieee80211_channel *curchan, *extchan; 2560 struct athn_usb_rx_data *data; 2561 struct ar_htc_target_vif hvif; 2562 struct ar_htc_target_sta sta; 2563 struct ar_htc_cap_target hic; 2564 uint16_t mode; 2565 size_t i; 2566 int error; 2567 2568 if (usc->usc_dying) 2569 return USBD_CANCELLED; 2570 2571 DPRINTFN(DBG_FN, sc, "\n"); 2572 2573 /* Init host async commands ring. */ 2574 mutex_spin_enter(&usc->usc_task_mtx); 2575 usc->usc_cmdq.cur = usc->usc_cmdq.next = usc->usc_cmdq.queued = 0; 2576 mutex_spin_exit(&usc->usc_task_mtx); 2577 2578 /* Allocate Tx/Rx buffers. */ 2579 error = athn_usb_alloc_rx_list(usc); 2580 if (error != 0) 2581 goto fail; 2582 error = athn_usb_alloc_tx_list(usc); 2583 if (error != 0) 2584 goto fail; 2585 /* Steal one buffer for beacons. */ 2586 mutex_enter(&usc->usc_tx_mtx); 2587 usc->usc_tx_bcn = TAILQ_FIRST(&usc->usc_tx_free_list); 2588 TAILQ_REMOVE(&usc->usc_tx_free_list, usc->usc_tx_bcn, next); 2589 mutex_exit(&usc->usc_tx_mtx); 2590 2591 curchan = ic->ic_curchan; 2592 extchan = NULL; 2593 2594 /* In case a new MAC address has been configured. */ 2595 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 2596 2597 error = athn_set_power_awake(sc); 2598 if (error != 0) 2599 goto fail; 2600 2601 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_FLUSH_RECV); 2602 if (error != 0) 2603 goto fail; 2604 2605 error = athn_hw_reset(sc, curchan, extchan, 1); 2606 if (error != 0) 2607 goto fail; 2608 2609 ops->set_txpower(sc, curchan, extchan); 2610 2611 mode = htobe16(IEEE80211_IS_CHAN_2GHZ(curchan) ? 2612 AR_HTC_MODE_11NG : AR_HTC_MODE_11NA); 2613 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_SET_MODE, 2614 &mode, sizeof(mode), NULL); 2615 if (error != 0) 2616 goto fail; 2617 2618 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_ATH_INIT); 2619 if (error != 0) 2620 goto fail; 2621 2622 error = athn_usb_wmi_cmd(usc, AR_WMI_CMD_START_RECV); 2623 if (error != 0) 2624 goto fail; 2625 2626 athn_rx_start(sc); 2627 2628 /* Create main interface on target. */ 2629 memset(&hvif, 0, sizeof(hvif)); 2630 hvif.index = 0; 2631 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); 2632 switch (ic->ic_opmode) { 2633 case IEEE80211_M_STA: 2634 hvif.opmode = htobe32(AR_HTC_M_STA); 2635 break; 2636 case IEEE80211_M_MONITOR: 2637 hvif.opmode = htobe32(AR_HTC_M_MONITOR); 2638 break; 2639 #ifndef IEEE80211_STA_ONLY 2640 case IEEE80211_M_IBSS: 2641 hvif.opmode = htobe32(AR_HTC_M_IBSS); 2642 break; 2643 case IEEE80211_M_AHDEMO: 2644 hvif.opmode = htobe32(AR_HTC_M_AHDEMO); 2645 break; 2646 case IEEE80211_M_HOSTAP: 2647 hvif.opmode = htobe32(AR_HTC_M_HOSTAP); 2648 break; 2649 #endif 2650 } 2651 hvif.rtsthreshold = htobe16(ic->ic_rtsthreshold); 2652 DPRINTFN(DBG_INIT, sc, "creating VAP\n"); 2653 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_CREATE, 2654 &hvif, sizeof(hvif), NULL); 2655 if (error != 0) 2656 goto fail; 2657 2658 /* Create a fake node to send management frames before assoc. */ 2659 memset(&sta, 0, sizeof(sta)); 2660 IEEE80211_ADDR_COPY(sta.macaddr, ic->ic_myaddr); 2661 sta.sta_index = 0; 2662 sta.is_vif_sta = 1; 2663 sta.vif_index = hvif.index; 2664 sta.maxampdu = 0xffff; 2665 2666 DPRINTFN(DBG_INIT | DBG_NODES, sc, "creating default node %u\n", 2667 sta.sta_index); 2668 error = athn_usb_create_hw_node(usc, &sta); 2669 if (error != 0) 2670 goto fail; 2671 2672 /* Update target capabilities. */ 2673 memset(&hic, 0, sizeof(hic)); 2674 hic.flags = htobe32(0x400c2400); 2675 hic.flags_ext = htobe32(0x00106080); 2676 hic.ampdu_limit = htobe32(0x0000ffff); 2677 hic.ampdu_subframes = 20; 2678 hic.protmode = 1; /* XXX */ 2679 hic.lg_txchainmask = sc->sc_txchainmask; 2680 hic.ht_txchainmask = sc->sc_txchainmask; 2681 DPRINTFN(DBG_INIT, sc, "updating target configuration\n"); 2682 error = athn_usb_wmi_xcmd(usc, AR_WMI_CMD_TARGET_IC_UPDATE, 2683 &hic, sizeof(hic), NULL); 2684 if (error != 0) 2685 goto fail; 2686 2687 /* Queue Rx xfers. */ 2688 for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { 2689 data = &usc->usc_rx_data[i]; 2690 2691 usbd_setup_xfer(data->xfer, usc->usc_rx_data_pipe, data, data->buf, 2692 ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, 2693 USBD_NO_TIMEOUT, athn_usb_rxeof); 2694 error = usbd_transfer(data->xfer); 2695 if (error != 0 && error != USBD_IN_PROGRESS) 2696 goto fail; 2697 } 2698 /* We're ready to go. */ 2699 ifp->if_flags &= ~IFF_OACTIVE; 2700 ifp->if_flags |= IFF_RUNNING; 2701 2702 #ifdef notyet 2703 if (ic->ic_flags & IEEE80211_F_WEPON) { 2704 /* Install WEP keys. */ 2705 for (i = 0; i < IEEE80211_WEP_NKID; i++) 2706 athn_usb_set_key(ic, NULL, &ic->ic_nw_keys[i]); 2707 } 2708 #endif 2709 if (ic->ic_opmode == IEEE80211_M_HOSTAP) 2710 ic->ic_max_aid = AR_USB_MAX_STA; /* Firmware is limited to 8 STA */ 2711 else 2712 ic->ic_max_aid = sc->sc_max_aid; 2713 2714 if (ic->ic_opmode == IEEE80211_M_MONITOR) 2715 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2716 else 2717 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2718 athn_usb_wait_async(usc); 2719 return 0; 2720 fail: 2721 athn_usb_stop(ifp); 2722 return error; 2723 } 2724 2725 Static void 2726 athn_usb_stop(struct ifnet *ifp) 2727 { 2728 struct athn_softc *sc = ifp->if_softc; 2729 struct athn_usb_softc *usc = ATHN_USB_SOFTC(sc); 2730 struct ieee80211com *ic = &sc->sc_ic; 2731 struct ar_htc_target_vif hvif; 2732 struct mbuf *m; 2733 uint8_t sta_index; 2734 int s; 2735 2736 DPRINTFN(DBG_FN, sc, "\n"); 2737 2738 s = splusb(); 2739 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2740 athn_usb_wait_async(usc); 2741 splx(s); 2742 2743 sc->sc_tx_timer = 0; 2744 ifp->if_timer = 0; 2745 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2746 2747 callout_stop(&sc->sc_scan_to); 2748 callout_stop(&sc->sc_calib_to); 2749 2750 /* Abort Tx/Rx. */ 2751 usbd_abort_pipe(usc->usc_tx_data_pipe); 2752 usbd_abort_pipe(usc->usc_rx_data_pipe); 2753 2754 /* Free Tx/Rx buffers. */ 2755 athn_usb_free_tx_list(usc); 2756 athn_usb_free_rx_list(usc); 2757 2758 /* Flush Rx stream. */ 2759 CTASSERT(sizeof(m) == sizeof(void *)); 2760 m = atomic_swap_ptr(&usc->usc_rx_stream.m, NULL); 2761 m_freem(m); 2762 usc->usc_rx_stream.left = 0; 2763 2764 /* Remove main interface. */ 2765 memset(&hvif, 0, sizeof(hvif)); 2766 hvif.index = 0; 2767 IEEE80211_ADDR_COPY(hvif.myaddr, ic->ic_myaddr); 2768 (void)athn_usb_wmi_xcmd(usc, AR_WMI_CMD_VAP_REMOVE, 2769 &hvif, sizeof(hvif), NULL); 2770 2771 /* Remove default node. */ 2772 sta_index = 0; 2773 DPRINTFN(DBG_NODES, usc, "removing node %u\n", sta_index); 2774 (void)athn_usb_remove_hw_node(usc, &sta_index); 2775 2776 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DISABLE_INTR); 2777 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_DRAIN_TXQ_ALL); 2778 (void)athn_usb_wmi_cmd(usc, AR_WMI_CMD_STOP_RECV); 2779 2780 athn_reset(sc, 0); 2781 athn_init_pll(sc, NULL); 2782 athn_set_power_awake(sc); 2783 athn_reset(sc, 1); 2784 athn_init_pll(sc, NULL); 2785 athn_set_power_sleep(sc); 2786 } 2787 2788 MODULE(MODULE_CLASS_DRIVER, if_athn_usb, "bpf"); 2789 2790 #ifdef _MODULE 2791 #include "ioconf.c" 2792 #endif 2793 2794 static int 2795 if_athn_usb_modcmd(modcmd_t cmd, void *aux) 2796 { 2797 int error = 0; 2798 2799 switch (cmd) { 2800 case MODULE_CMD_INIT: 2801 #ifdef _MODULE 2802 error = config_init_component(cfdriver_ioconf_if_athn_usb, 2803 cfattach_ioconf_if_athn_usb, cfdata_ioconf_if_athn_usb); 2804 #endif 2805 return error; 2806 case MODULE_CMD_FINI: 2807 #ifdef _MODULE 2808 error = config_fini_component(cfdriver_ioconf_if_athn_usb, 2809 cfattach_ioconf_if_athn_usb, cfdata_ioconf_if_athn_usb); 2810 #endif 2811 return error; 2812 default: 2813 return ENOTTY; 2814 } 2815 } 2816